Alam
Alam

Reputation: 315

How to pass an array as argument (in Python) when solving ODE by odeint function

My ODE is given as Mx''+Lx'+f(x)=0 where f(x) is a polynomial function. Please look at my FULL CODE where I defined the differential equation in a function namely 'diff'. Then I use 'odeint' which calls 'diff' along with the necessary arguments to solve the differential equaion.

Now I consider f(x)=ax. Here I have to pass three parameters in total (M,L,a) as the argument to the 'diff' function. As a matter of fact the code works if I write: (see full code)

 sol = odeint(diff, y0, t, args=(M,L, a))

But when f(x) is a polynomial up to 10 power of 'x', then the parameter list becomes too long. Therefore I want to put all the parameters in an array and then pass that array as argument. I tried in this way:

def diff(y, t, inertia):
    M=inertia[0]
    L=inertia[1]
    a=inertia[2]

    x,v = y
    dydt = [v, (-L*v - a*x)/M]
    return dydt

M=5
L = 0.5
a = 5.0
Inertia=(M,L,a)

sol = odeint(diff, y0, t, args=Inertia)

But this approach doen't work. It says 'TypeError: diff() takes 3 positional arguments but 5 were given'.

How can I can I make this approach work, or how to send a list of parameters as argument?

Full Code:

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt



def diff(y, t, M, L, a):   
    x,v = y
    dydt = [v, (-L*v - a*x)/M]
    return dydt

M=5
L = 0.5
a = 5.0

#Inertia=(M,L,a)
#But I cant pass the 'Inertia' as an argument 


y0 = [- 0.1, 0.0]
t = np.linspace(0, 10, 101)
sol = odeint(diff, y0, t, args=(M,L, a))



plt.plot(t, sol[:, 0], 'b', label='x(t)')
plt.plot(t, sol[:, 1], 'g', label='v(t)')
plt.legend(loc='best')
plt.show()

Upvotes: 1

Views: 3225

Answers (2)

Jesse Bakker
Jesse Bakker

Reputation: 2623

Inertia in this case is a tuple. odeint expects a tuple of arguments as its args parameter, so Inertia gets unpacked and the arguments to diff become y0, t, M, L, a. To circumvent this, you should pack Inertia in another tuple to make Inertia a single argument, like so:

sol = odeint(diff, y0, t, args=(Inertia,))

Note the , after Inertia. this makes it a tuple ((a) == a, (a,) == tuple(a))

Upvotes: 3

Sim Son
Sim Son

Reputation: 308

Your approach doesn't work because you have assigned inertia as a tuple instead of an array. Correct is inertia=[a,b,c]. As arguments are passed to functions as well, your "array" gets appended to the other argumenty when passing it to a function an so this function receives 5 arguments.

Upvotes: 2

Related Questions