Ryu
Ryu

Reputation: 13

scipy odeint fails, somehow returning a complex number

I want to solve for an ODE. after getting the 2nd order and turning it into a bunch of 1st order equations, and trying to solve it using odeint it always says the number returned is complex therefore it always fails.

x_dd_l = sols[x_dd]
dQ1dt_f = smp.lambdify((mx, my, mp, j, k1, k2, k3, k4, k5, r, b1, b2, f1, f2, Bp, tau,
                        x, x_d, y, y_d,
                        P1, P1_d, P2, P2_d,
                        P3, P3_d, P4, P4_d, P5, P5_d, P6, P6_d,
                        P7, P7_d, P8, P8_d, P9, P9_d, P10, P10_d,
                        Signum_x, Signum_y, Signum_P1, Signum_P2, Signum_P3, Signum_P4,
                        Signum_P5, Signum_P6, Signum_P7, Signum_P8, Signum_P9, Signum_P10
                        ), x_dd_l)

y_dd_l = sols[y_dd]
dQ2dt_f = smp.lambdify((mx, my, mp, j, k1, k2, k3, k4, k5, r, b1, b2, f1, f2, Bp, tau,
                        x, x_d, y, y_d,
                        P1, P1_d, P2, P2_d,
                        P3, P3_d, P4, P4_d, P5, P5_d, P6, P6_d,
                        P7, P7_d, P8, P8_d, P9, P9_d, P10, P10_d,
                        Signum_x, Signum_y, Signum_P1, Signum_P2, Signum_P3, Signum_P4,
                        Signum_P5, Signum_P6, Signum_P7, Signum_P8, Signum_P9, Signum_P10
                        ), y_dd_l)

dxdt_f = smp.lambdify((x_d),x_d)
dydt_f = smp.lambdify((y_d),y_d)

....

and the functions to solve the ode

def dSdt(S,t):
    x, y, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12 = S
    #Constant
    mx, my, mp, j, k1, k2, k3, k4, k5, r, b1, b2, f1, f2, Bp, tau, Signum_x, Signum_y, Signum_P1, Signum_P2, Signum_P3, Signum_P4, Signum_P5, Signum_P6, Signum_P7, Signum_P8, Signum_P9, Signum_P10, = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
    return[
        dxdt_f(Q1),dydt_f(Q2),
        dP1dt_f(Q3),dP2dt_f(Q4),
        dP3dt_f(Q5),dP4dt_f(Q6),
        dP5dt_f(Q7),dP6dt_f(Q8),
        dP7dt_f(Q9),dP8dt_f(Q10),
        dP9dt_f(Q11),dP10dt_f(Q12),

        dQ1dt_f(mx, my, mp, j, k1, k2, k3, k4, k5, r, b1, b2, f1, f2, Bp, tau,
                        Signum_x, Signum_y, Signum_P1, Signum_P2, Signum_P3, Signum_P4,
                        Signum_P5, Signum_P6, Signum_P7, Signum_P8, Signum_P9, Signum_P10,
                        x, x_d, y, y_d,
                        P1, P1_d, P2, P2_d,
                        P3, P3_d, P4, P4_d, P5, P5_d, P6, P6_d,
                        P7, P7_d, P8, P8_d, P9, P9_d, P10, P10_d),

....
t = np.linspace(0, 40, 1001)
S0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0,] 

#sol = odeint(func=dSdt, y0=S0, t=t)
ans = odeint(dSdt, y0=S0, t=t)

I always get the error:

xpr.__float__(self)
    325 if result.is_number and result.as_real_imag()[1]:
    326     raise TypeError("can't convert complex to float")
--> 327 raise TypeError("can't convert expression to float")

TypeError: can't convert expression to float

I'm confused why the equations become a complex number with a normal initial conditions, is it the nature of the ODE? is there another way to solve it?

edit: add more error

TypeError                                 Traceback (most recent call last)
Cell In [16], line 5
      2 S0 = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0)
      4 #sol = odeint(func=dSdt, y0=S0, t=t)
----> 5 sol = odeint(dSdt, y0=S0, t=t)

File c:\Users\Richie Ryu\AppData\Local\Programs\Python\Python310\lib\site-packages\scipy\integrate\_odepack_py.py:241, in odeint(func, y0, t, args, Dfun, col_deriv, full_output, ml, mu, rtol, atol, tcrit, h0, hmax, hmin, ixpr, mxstep, mxhnil, mxordn, mxords, printmessg, tfirst)
    239 t = copy(t)
    240 y0 = copy(y0)
--> 241 output = _odepack.odeint(func, y0, t, args, Dfun, col_deriv, ml, mu,
    242                          full_output, rtol, atol, tcrit, h0, hmax, hmin,
    243                          ixpr, mxstep, mxhnil, mxordn, mxords,
    244                          int(bool(tfirst)))
    245 if output[-1] < 0:
    246     warning_msg = _msgs[output[-1]] + " Run with full_output = 1 to get quantitative information."

File c:\Users\Richie Ryu\AppData\Local\Programs\Python\Python310\lib\site-packages\sympy\core\expr.py:351, in Expr.__float__(self)
    349 if result.is_number and result.as_real_imag()[1]:
    350     raise TypeError("Cannot convert complex to float")
--> 351 raise TypeError("Cannot convert expression to float")

TypeError: Cannot convert expression to float

Upvotes: 0

Views: 142

Answers (1)

hpaulj
hpaulj

Reputation: 231540

If x is sympy.symbol, then ask for a float produces your error:

In [8]: float(x)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [8], in <cell line: 1>()
----> 1 float(x)

File ~\anaconda3\lib\site-packages\sympy\core\expr.py:345, in Expr.__float__(self)
    343 if result.is_number and result.as_real_imag()[1]:
    344     raise TypeError("Cannot convert complex to float")
--> 345 raise TypeError("Cannot convert expression to float")

TypeError: Cannot convert expression to float

Similarly if I make an array from x:

In [9]: np.array(x)
Out[9]: array(x, dtype=object)

odeint probably does attempts this when receiving a value from the func:

In [10]: np.array(x, dtype=float)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [10], in <cell line: 1>()
----> 1 np.array(x, dtype=float)

File ~\anaconda3\lib\site-packages\sympy\core\expr.py:345, in Expr.__float__(self)
    343 if result.is_number and result.as_real_imag()[1]:
    344     raise TypeError("Cannot convert complex to float")
--> 345 raise TypeError("Cannot convert expression to float")

TypeError: Cannot convert expression to float

You don't show enough of the error traceback, but I suspect that's where the error is occuring.

Upvotes: 1

Related Questions