Search code examples
python-2.7scipydimensionsodeint

Converting odeint system to solve_ivp, dimensions problem


I use solve_ivp to solve a system of differential equations (6 x 6). The system reads 4 arrays (with shape (8000, ) ) as inputs and saves the results in arrays with the same shape (8000, ). I want to repeat a part of the same system (only the last 2 equations). The problem is that, when I was doing the same with odeint the length of my final results (theta_i and theta_deg_i) was 8000. Now, because the arguments are written with the opposite order in solve_ivp, the length of my results is 6. How can I fix that?

t = np.linspace(0,100,8000) # s

xdot = np.array(.....) # shape (8000, )
ydot = np.array(.....)
xdotdot = np.array(.....)
ydotdot = np.array(.....)

interp = interp1d(t,(xdot,ydot,xdotdot,ydotdot))


def inverse(t,k):
    vcx_i = k[0]
    vcy_i = k[1]
    psi_i = k[2]
    wz_i = k[3]
    theta_i = k[4]
    theta_deg_i = k[5]

    # equations of the system...

    return [vcxdot_i, vcydot_i, psidot_i, wzdot_i, theta_i, theta_deg_i]


k0 = [0.1257, 0, 0, 0, 0, 0]

steps = 1
method = 'RK23'
atol = 1e-3
k = solve_ivp(inverse, (0, 100), k0, method=method, t_eval=t, atol=atol, vectorized=True)


vcx_i = k.y[0,:]
vcy_i = k.y[1,:]
psi_i = k.y[2,:]
wz_i = k.y[3,:]
theta_i = k.y[4,:]
theta_deg_i = k.y[5,:]

theta_i = [inverse(t_i, k_i)[4] for t_i, k_i in zip(t, k.y)]
theta_deg_i = [inverse(t_i, k_i)[5] for t_i, k_i in zip(t, k.y)]

the last two lines, in odeint version are:

theta_i = [inverse(k_i, t_i)[4] for t_i, k_i in zip(t, k)]
theta_deg_i = [inverse(k_i, t_i)[5] for t_i, k_i in zip(t, k)]

The shape of k.y in solve_ivp solution is (6, 8000), while the shape of k in odeint solution is (8000, 6). I am new to python and I use python 2.7.12 on Ubuntu 16.04 LTS. Thank you in advance.


Solution

  • I located the problem in the dimensions of the array in which each function saves the results. With the solve_ivp solution the k.y array has shape (6,8000), while the shape of the array k in odeint solution is (8000,6). I just added some lines in order to transpose the array before I repeated the system.

    k_new = np.transpose(k.y) # antistrofi diastasewn k.y apo (6,8000) se (8000,6) 
    theta_i = [inverse(t_i, k_i)[4] for t_i, k_i in zip(t, k_new)]
    theta_deg_i = [inverse(t_i, k_i)[5] for k_i, t_i in zip(k_new, t)]
    

    Note: The transpose function changes the dimension of an array like this:

    ([[1,  2,  3,  4,  5]              ([[1,10,100]
      [10, 20, 30, 40, 50]     --->      [2,20,200]
      [100,200,300,400,500]])            [3,30,300]
                                         [4,40,400]
                                         [5,50,500]])
      # with shape (3,5)             # with shape(5,3)