我现在有一个时间依赖常数的颂歌系统。例如
def fun(u, t, a, b, c):
x = u[0]
y = u[1]
z = u[2]
dx_dt = a * x + y * z
dy_dt = b * (y-z)
dz_dt = -x*y+c*y-z
return [dx_dt, dy_dt, dz_dt]
常数是“a”、“B”和“c”。我目前有一个列表的“a“的每一个时间步,我想插入在每一个时间步,当使用scipy ode求解器.这是可能的吗?
谢谢你,谢谢
4条答案
按热度按时间z9ju0rcb1#
是的,这是可能的。在
a
是常数的情况下,我猜你调用了scipy.integrate.odeint(fun, u0, t, args)
,其中fun
的定义与你的问题一样,u0 = [x0, y0, z0]
是初始条件,t
是要求解ODE的时间点序列,args = (a, b, c)
是传递给fun
的额外参数。在
a
依赖于时间的情况下,你只需将a
重新考虑为一个函数,例如(给定一个常数a0
):然后你需要修改
fun
,它在每个时间步计算导数,以考虑之前的变化:最后,请注意
u0
、t
和args
保持不变,您可以再次调用scipy.integrate.odeint(fun, u0, t, args)
。关于这种方法的正确性的一句话。数值积分近似的性能受到影响,我不知道确切的方式(没有理论保证),但这里有一个简单的例子:
我希望这对你有帮助。
ycggw6v22#
不,从字面意义上来说,
“我目前有一个列表的“a“的每个时间步,我想插入在每个时间步”
因为求解器具有自适应步长控制,也就是说,它将使用您无法控制的内部时间步长,并且每个时间步长使用函数的几个求值。因此,求解器时间步和数据时间步之间没有联系。
然而,在给定数据定义分段常数阶跃函数的扩展意义上,有几种方法可以得到解。
1.您可以使用此时间段的常参数ODE函数从跳跃点到跳跃点进行积分。之后,使用numpy数组操作(如
concatenate
)来组装完整的解决方案。1.可以使用插值函数,如
numpy.interp
或scipy.interpolate.interp1d
。第一个给出了分段线性插值,这在这里可能不是期望的。第二个返回一个函数对象,可以配置为“零阶保持”,这是一个分段常数阶跃函数。1.您可以实现自己的逻辑,从时间
t
到这些参数的正确值。这主要适用于数据有某种结构的情况,例如,如果它们具有f(int(t/h))
的形式。注意,数值积分的逼近阶不仅受RK(solve_ivp)或多步(odeint)方法的阶的限制,而且还受微分方程(部分)的可微阶的限制。如果ODE比方法的阶次更不光滑,则违反了步长控制机制的隐式假设,这可能导致非常小的步长需要大量的积分步骤。
t1qtbnec3#
我可能有点晚了,但最近出现了这个问题,因为系统需要在运动历史上进行卷积积分(波流体动力学)。
我找到了一个解决方案,它不需要知道常数
a
作为时间先验的函数。这个简化的问题是一个Spring,有阻尼,以及一个卷积的Spring速度的历史在一个脉冲响应函数,结果在一个
fbias
项。解决方案是用
set_f_params
不断更新ode
积分器。这要求传递所有参数。n3schb8v4#
我也遇到了类似的问题。在我的例子中,参数
a, b,
和c
不是与时间的直接函数,而是由当时的x, y,
和z
确定的。所以我必须在时间t
得到x, y, z
,并计算a, b, c
,用于在t+dt
对x, y, z
的积分计算。事实证明,如果我改变dt
值,整个积分结果将发生巨大变化,甚至是不合理的。