I'm trying to write a tool that needs to be able to integrate n-dimensional systems of 1st order differential equations. I need to be able to basically plug various dynamical systems, along with their Jacobians, and any associated parameters that occur on the RHS of the ODE's that may need to be varied. My issue is with how scipy.odeint handles extra function arguments. My differential equations are of the form: def f(x,t,param): ... return dxdt def J(x,t,param): ... return dfdx The param argument would be a rank 1 array (or list), that gets used in the function definitions of the RHS. For example, the Lorenz equations have three parameters, sigma, r, and b, but other systems have other numbers of parameters, so it makes sense to just pass this as a vector (or list). If it is not done in this fashion, then systems with different numbers of parameters have to be hard-coded... really annoying. I would like to be able to call scipy.odeint something like: y = scipy.odeint(f, x0, t, args = param, Dfun = J) or y = scipy.odeint(f, x0, t, args = (param), Dfun = J) This is where I can't get things to work -- odeint needs a tuple for the args argument, and I can't figure out how to make it work. The following works, but is way to restrictive for what I need because I want to be able to make my code modular enough to be able to integrate *any* dynamical system that has an arbritrary number of parameters. Here is what works, for a system with three parameters, a, b, and c; def f(x,t,a,b,c): ... return dxdt def J(x,t,a,b,c): ... return dfdx y = scipy.odeint(f, x0, t, args = (a,b,c), Dfun = J) This above works fine, but again, if you need to evaluate f anywhere, then you have to know how many parameters it takes and call the function in a fashion that explicitly lays out how each parameter gets passed. Am I overlooking something really simple here that would make this work? I know in matlab's ode45 you can just pass scalars or arrays or matrices of additional parameters and it doesn't really matter -- you just pass them through. Thanks, ~Luke
Pass the list "param" to odeint like this: y = scipy.odeint(f, x0, t, args = (param,), Dfun = J) Note the extra comma. Then, for example, f might start like this: def f(x,t,param) a = param[0] b = param[1] c = param[2] ... return dxdt This works for me. Warren Weckesser On Tue, 2007-06-05 at 19:19 -0700, Luke wrote:
I'm trying to write a tool that needs to be able to integrate n-dimensional systems of 1st order differential equations. I need to be able to basically plug various dynamical systems, along with their Jacobians, and any associated parameters that occur on the RHS of the ODE's that may need to be varied. My issue is with how scipy.odeint handles extra function arguments.
My differential equations are of the form:
def f(x,t,param): ... return dxdt
def J(x,t,param): ... return dfdx
The param argument would be a rank 1 array (or list), that gets used in the function definitions of the RHS. For example, the Lorenz equations have three parameters, sigma, r, and b, but other systems have other numbers of parameters, so it makes sense to just pass this as a vector (or list). If it is not done in this fashion, then systems with different numbers of parameters have to be hard-coded... really annoying.
I would like to be able to call scipy.odeint something like:
y = scipy.odeint(f, x0, t, args = param, Dfun = J) or y = scipy.odeint(f, x0, t, args = (param), Dfun = J)
This is where I can't get things to work -- odeint needs a tuple for the args argument, and I can't figure out how to make it work. The following works, but is way to restrictive for what I need because I want to be able to make my code modular enough to be able to integrate *any* dynamical system that has an arbritrary number of parameters. Here is what works, for a system with three parameters, a, b, and c;
def f(x,t,a,b,c): ... return dxdt
def J(x,t,a,b,c): ... return dfdx
y = scipy.odeint(f, x0, t, args = (a,b,c), Dfun = J)
This above works fine, but again, if you need to evaluate f anywhere, then you have to know how many parameters it takes and call the function in a fashion that explicitly lays out how each parameter gets passed.
Am I overlooking something really simple here that would make this work? I know in matlab's ode45 you can just pass scalars or arrays or matrices of additional parameters and it doesn't really matter -- you just pass them through.
Thanks, ~Luke _______________________________________________ SciPy-user mailing list SciPy-user@scipy.org http://projects.scipy.org/mailman/listinfo/scipy-user
Warren Weckesser wrote:
Pass the list "param" to odeint like this:
y = scipy.odeint(f, x0, t, args = (param,), Dfun = J)
Note the extra comma.
Then, for example, f might start like this:
def f(x,t,param) a = param[0] b = param[1] c = param[2] ... return dxdt
See also http://docs.python.org/tut/node7.html#SECTION007300000000000000000 -- cheers, steve I love deadlines. I like the whooshing sound they make as they fly by. -- Douglas Adams
participants (3)
-
Luke -
Steve Schmerler -
Warren Weckesser