我正在使用Scipy的odeint(scipy.integrate.odeint
)为我解决一些ODE,而且一切都运行良好。但是,我现在想在计算中包含另一个与时间相关的数据集,即t = [0, 1, 2, 3]
我已将数据z = [0.1, 0.2, 0.25, 0.22]
包含在计算中。我可以将向量作为参数传递,但是这给了我每个时间步的整个向量。是否有一种有效的方法来获取计算的当前步骤(迭代器)?这样我就可以获得z[i]
第i个时间步。请注意,z
的长度为t
,并且两者都可以包含数千个元素。
由于
一个非常简单的例子:
import numpy as np
from scipy.integrate import odeint
def func(y, t, z):
# I'd like to get the i-th element
# of z, corresponding to t[i]
return y+z[i]
result = odeint(func, [0], t, (z,))
答案 0 :(得分:1)
此问题的解决方法是使用更通用的scipy.integrate.ode
函数。此函数内置了几个集成方案,您可以更好地控制每次迭代期间发生的事情。请参阅以下示例:
import numpy as np
from scipy.integrate import ode
def func(t, y, z):
return y+z
t = np.linspace(0, 1.0, 100)
dt = t[1]-t[0]
z = np.random.rand(100)
output = np.empty_like(t)
r = ode(func).set_integrator("dop853")
r.set_initial_value(0, 0).set_f_params(z[0])
for i in xrange(len(t)):
r.set_f_params(z[i])
r.integrate(r.t+dt)
output[i] = r.y
在每次迭代期间,解算器的z
值都会相应更新。
答案 1 :(得分:0)
对于ode求解器,您可以使用interpolation作为时变输入。在这种情况下:
import numpy as np
from scipy.integrate import odeint
from scipy.interpolate import interp1d
t_arr = np.array([0,1,2,3])
z_arr = np.array([0.1, 0.2, 0.25, 0.22])
finterp = interp1d(t_arr,z_arr,fill_value='extrapolate') #create interpolation function
def func(y,t,z):
print(t)
zt = finterp(t) # call interpolation at time t
return y+zt
result = odeint(func, [0], t_arr, (z_arr,))
但是,odeint中的求解器可能会请求超出t_arr的时间瞬间(在您的情况下为3.028),因此您必须指定超过t = 3的z值或允许使用fill_value进行外推(如上所示)。选择一种插值时要小心,以反映您期望的行为。