Using adaptive step sizes with scipy.integrate.ode

前端 未结 5 1769
忘掉有多难
忘掉有多难 2020-12-08 08:01

The (brief) documentation for scipy.integrate.ode says that two methods (dopri5 and dop853) have stepsize control and dense output. L

5条回答
  •  不知归路
    2020-12-08 08:23

    Since SciPy 0.13.0,

    The intermediate results from the dopri family of ODE solvers can now be accessed by a solout callback function.

    import numpy as np
    from scipy.integrate import ode
    import matplotlib.pyplot as plt
    
    
    def logistic(t, y, r):
        return r * y * (1.0 - y)
    
    r = .01
    t0 = 0
    y0 = 1e-5
    t1 = 5000.0
    
    backend = 'dopri5'
    # backend = 'dop853'
    solver = ode(logistic).set_integrator(backend)
    
    sol = []
    def solout(t, y):
        sol.append([t, *y])
    solver.set_solout(solout)
    solver.set_initial_value(y0, t0).set_f_params(r)
    solver.integrate(t1)
    
    sol = np.array(sol)
    
    plt.plot(sol[:,0], sol[:,1], 'b.-')
    plt.show()
    

    Result:

    The result seems to be slightly different from Tim D's, although they both use the same backend. I suspect this having to do with FSAL property of dopri5. In Tim's approach, I think the result k7 from the seventh stage is discarded, so k1 is calculated afresh.

    Note: There's a known bug with set_solout not working if you set it after setting initial values. It was fixed as of SciPy 0.17.0.

提交回复
热议问题