将ode与scipy集成时,ode接受一个参数多于t和y的函数。例如:
def fun(t, y, param1, param2):
这些参数的值可以使用set_f_params
方法设置。在
但是,当同时使用set_solout
方法并尝试在该函数内用set_f_params
更新参数时,集成保持不变,就好像没有修改参数一样。在
你如何使用sol\u out修改参数?我想从dopri5密集输出中获益,但我需要在每个时间步更新非齐次项。在
下面是一个最小的例子。在
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import ode
def fun(t, x, param):
return x - param
def f_param(t):
return t
ode1 = ode(fun).set_integrator('dopri5').set_initial_value([10.0])
ode1.set_f_params(f_param(0))
results1 = ([], [])
ode2 = ode(fun).set_integrator('dopri5').set_initial_value([10.0])
ode2.set_f_params(f_param(0))
results2 = ([], [])
def callback1(t, x):
results1[0].append(t)
results1[1].append(x.copy())
def callback2(t, x):
results2[0].append(t)
results2[1].append(x.copy())
ode2.set_f_params(f_param(t))
ode1.set_solout(callback1)
ode2.set_solout(callback2)
ode1.integrate(3)
ode2.integrate(3)
plt.plot(results1[0], results1[1], 'o-', alpha=0.7, label='ode1')
plt.plot(results2[0], results2[1], '.--', label='ode2')
plt.legend()
结果如下:
这是在scipy1.0中发布的the new ODE solvers的方法:
受@Wrzlprmft注释的启发,如果参数不是常量,则更安全的做法是调用直接在要更新的函数中更新参数的函数。正如他所说,这意味着:
但是,该函数(
f_param
在本例中)可能无法在要集成的函数的命名空间中访问(在上面的示例中是fun
)。因此,将函数设置为要集成的函数的参数并在开始时只使用一次set_f_params
来指定函数,这样会更方便。在作为问题代码的延续:
^{pr2}$显示ode3和ode4提供相同的解决方案:
相关问题 更多 >
编程相关推荐