Pass args to solve_ivp (new SciPy ODE API)

To solve simple ODEs using SciPy, I used the odeint function with the 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 integrable function may include additional arguments in the form:

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

In SciPy 1.0, it seems that the ode and odeint functions have been replaced by the 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, it seems that there is neither the args parameter, nor any guidance in the documentation on the implementation of passing arguments.

So I'm wondering if passing arguments using the new API is possible, or is this function not yet added? (It would seem to me an oversight if these functions were intentionally removed?)

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

+14
source share
5

, args. ,

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

.

+7

scipy github. lambda:

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

, , .

+9

lambda t,y: fun(t,y,args). , rhs ODE . .

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


def rhs_2nd_order_ode(t, y, a, b):
    """
    2nd order ODE function handle for use with scipy.integrate.solve_ivp
    Solves u'' + au'+ bu = 0 after reducing order with y[0]=u and y[1]=u'.

    :param t: dependent variable
    :param y: independent variables
    :param a: a
    :param b: b
    :return: Returns the rhs of y[0]' = y[1] and y[1]' = -a*y[1] - b*y[0]
    """
    return [y[1], -a*y[1] - b*y[0]]


if __name__ == "__main__":
    t_span = (0, 10)
    t_eval = np.linspace(t_span[0], t_span[1], 100)
    y0 = [0, 1]
    a = 1
    b = 2
    sol = integrate.solve_ivp(lambda t,y: rhs_2nd_order_ode(t,y,a,b), t_span, y0, 
                              method='RK45', t_eval=t_eval)

    fig, ax = plt.subplots(1, 1)
    ax.plot(sol.t, sol.y[0])
    ax.set(xlabel='t',ylabel='y')
0

For completeness, I think you can do this as well, but I'm not sure why you will worry about the other two options posted here that look perfect.

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)
0
source

Source: https://habr.com/ru/post/1692149/


All Articles