使用scipy.integrate.odeint求解odes系统(具有不断变化的常数!)? [英] Solving a system of odes (with changing constant!) using scipy.integrate.odeint?
问题描述
我目前有一个随时间变化的常数的odes系统.例如
I currently have a system of odes with a time-dependent constant. E.g.
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求解器时,我想在每个时间步中插入...可以吗?
The constants are "a", "b" and "c". I currently have a list of "a"s for every time-step which I would like to insert at every time-step, when using the scipy ode solver...is this possible?
谢谢!
推荐答案
是的,这是可能的.在a
为常数的情况下,我猜您调用了scipy.integrate.odeint(fun, u0, t, args)
,其中fun
的定义与您的问题相同,u0 = [x0, y0, z0]
是初始条件,t
是需要解决的时间点序列ODE和args = (a, b, c)
是传递给fun
的额外参数.
Yes, this is possible. In the case where a
is constant, I guess you called scipy.integrate.odeint(fun, u0, t, args)
where fun
is defined as in your question, u0 = [x0, y0, z0]
is the initial condition, t
is a sequence of time points for which to solve for the ODE and args = (a, b, c)
are the extra arguments to pass to fun
.
如果a
取决于时间,则只需重新考虑a
作为一个函数,例如(给定常量a0
):
In the case where a
depends on time, you simply have to reconsider a
as a function, for example (given a constant a0
):
def a(t):
return a0 * t
然后,您将不得不修改fun
,该计算将在每个时间步计算导数,以将先前的更改考虑在内:
Then you will have to modify fun
which computes the derivative at each time step to take the previous change into account:
def fun(u, t, a, b, c):
x = u[0]
y = u[1]
z = u[2]
dx_dt = a(t) * x + y * z # A change on this line: a -> a(t)
dy_dt = b * (y - z)
dz_dt = - x * y + c * y - z
return [dx_dt, dy_dt, dz_dt]
最后,请注意u0
,t
和args
保持不变,您可以再次调用scipy.integrate.odeint(fun, u0, t, args)
.
Eventually, note that u0
, t
and args
remain unchanged and you can again call scipy.integrate.odeint(fun, u0, t, args)
.
关于这种方法的正确性的一句话.数值积分逼近的性能会受到影响,我不知道具体如何实现(没有理论保证),但这是一个简单的示例,可以工作:
A word about the correctness of this approach. The performance of the approximation of the numerical integration is affected, I don't know precisely how (no theoretical guarantees) but here is a simple example which works:
import matplotlib.pyplot as plt
import numpy as np
import scipy as sp
import scipy.integrate
tmax = 10.0
def a(t):
if t < tmax / 2.0:
return ((tmax / 2.0) - t) / (tmax / 2.0)
else:
return 1.0
def func(x, t, a):
return - (x - a(t))
x0 = 0.8
t = np.linspace(0.0, tmax, 1000)
args = (a,)
y = sp.integrate.odeint(func, x0, t, args)
fig = plt.figure()
ax = fig.add_subplot(111)
h1, = ax.plot(t, y)
h2, = ax.plot(t, [a(s) for s in t])
ax.legend([h1, h2], ["y", "a"])
ax.set_xlabel("t")
ax.grid()
plt.show()
我希望这会对您有所帮助.
I Hope this will help you.
这篇关于使用scipy.integrate.odeint求解odes系统(具有不断变化的常数!)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!