scipy odeint中的当前迭代

时间:2015-08-14 07:36:26

标签: python scipy

我正在使用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,))

2 个答案:

答案 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进行外推(如上所示)。选择一种插值时要小心,以反映您期望的行为。