Pass args for solve_ivp (new SciPy ODE API)

12,002

Solution 1

It doesn't seem like the new function has an args parameter. As a workaround you can create a wrapper like

def wrapper(t, y):
    orig_func(t,y,hardcoded_args)

and pass that in.

Solution 2

Relatively recently there appeared a similar question on scipy's github. Their solution is to use lambda:

solve_ivp(fun=lambda t, y: fun(t, y, *args), ...)

And they argue that there is already enough overhead for this not to matter.

Solution 3

Recently the 'args' option was added to solve_ivp, see here: https://github.com/scipy/scipy/issues/8352#issuecomment-535689344

Solution 4

For completeness, I think you can also do this but I'm not sure why you would bother since the other two options posted here are perfectly fine.

from functools import partial
fun = partial(dy_dt, arg1=arg1, arg2=arg2)
scipy.integrate.solve_ivp(fun, t_span, y0, method='RK45', t_eval=None, dense_output=False, events=None, vectorized=False, **options)

Solution 5

According to Javier-Acuna's ultra-brief, ultra-useful answer, the feature that you (as well as I) desire has recently been added. This was announced on Github by none other than the great Warren Weckesser (See his Github, StackOverflow) himself. Anyway, jokes aside the docstring of solve_ivp has an example using it in for the `Lotka-Volterra equations

solve_ivp( fun, t_span, y0, method='RK45', t_eval=None, dense_output=False, events=None, vectorized=False, args=None, **options, )

So, just include args as a tuple. In your case

args = (arg1, arg2)

Please don't use my answer unless your scipy version >= 1.4 . There is no args parameter in solve_ivp for versions below it. I have personally experienced my answer failing for version 1.2.1.

The implementation by zahabaz would probably still work fine in case your scipy version < 1.4

Share:
12,002
sharkmas
Author by

sharkmas

Updated on August 02, 2022

Comments

  • sharkmas
    sharkmas almost 2 years

    For solving simple ODEs using SciPy, I used to use the odeint function, with form:

    scipy.integrate.odeint(func, y0, t, args=(), Dfun=None, col_deriv=0, full_output=0, ml=None, mu=None, rtol=None, atol=None, tcrit=None, h0=0.0, hmax=0.0, hmin=0.0, ixpr=0, mxstep=0, mxhnil=0, mxordn=12, mxords=5, printmessg=0)[source]
    

    where a simple function to be integrated could include additional arguments of the form:

    def dy_dt(t, y, arg1, arg2):
        # processing code here
    

    In SciPy 1.0, it seems the ode and odeint funcs have been replaced by a newer solve_ivp method.

    scipy.integrate.solve_ivp(fun, t_span, y0, method='RK45', t_eval=None, dense_output=False, events=None, vectorized=False, **options)
    

    However, this doesn't seem to offer an args parameter, nor any indication in the documentation as to implementing the passing of args.

    Therefore, I wonder if arg passing is possible with the new API, or is this a feature that has yet to be added? (It would seem an oversight to me if this features has been intentionally removed?)

    Reference: https://docs.scipy.org/doc/scipy/reference/integrate.html

  • sharkmas
    sharkmas over 6 years
    Thanks, although this seems a serious issue with solve_ivp (the wrapper would like increase overheads and be slower in my application). Consequently, I'll just go back to the old API. I wonder why the devs made such a backwards move?
  • rhody
    rhody about 5 years
    I read the comments and it looks like many people aren't happy with the use of lambda compared to the simple arg=(). They still done have example, since I don't use lambda I'm still not sure what to do. Could you post a complete example, I think a lot of people would benefit.
  • rhody
    rhody about 5 years
    Agreed, this is too complicated for novice and causal users. Not sure what the developers where thinking. Even worse they don't even provide an example in the docs for this very common situation.
  • Alessio
    Alessio over 4 years
    A link to a solution is welcome, but please ensure your answer is useful without it: add context around the link so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. Answers that are little more than a link may be deleted..
  • Lutz Lehmann
    Lutz Lehmann over 4 years
    You should perhaps add directly that it is expected to be available from scipy version 1.4 on.