Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 求解前一时间步的ODE函数(延迟微分方程)_Python_Scipy_Ode - Fatal编程技术网

Python 求解前一时间步的ODE函数(延迟微分方程)

Python 求解前一时间步的ODE函数(延迟微分方程),python,scipy,ode,Python,Scipy,Ode,我有一组微分方程: dy/dt = a*y - b*x*y dx/dt = b*x*y - c*y(t - t_0) t_0是一个常数时间,当t在问题的早期版本中,该问题仅说明了一个简单的ODE系统时,该术语被忽略。然后,它被改为一个延迟微分方程,下面的答案不再有效。我把它留作将来参考 要解决具有延迟的系统,必须使用额外的python包。例如,软件包允许求解此类方程。 这里提出了一个相关问题: 旧答案 scipy函数ode可能就是您要寻找的: 让我们首先定义这两个方程组。一个用于tt

我有一组微分方程:

dy/dt = a*y   - b*x*y  
dx/dt = b*x*y - c*y(t - t_0)

t_0
是一个常数时间,当
t在问题的早期版本中,该问题仅说明了一个简单的ODE系统时,该术语被忽略。然后,它被改为一个延迟微分方程,下面的答案不再有效。我把它留作将来参考

要解决具有延迟的系统,必须使用额外的python包。例如,软件包允许求解此类方程。 这里提出了一个相关问题:


旧答案 scipy函数
ode
可能就是您要寻找的:

让我们首先定义这两个方程组。一个用于
tt0
。我们称这些函数为
f
f2
。此外,我们还计算了雅可比矩阵,该矩阵稍后可由积分器使用

def f(t,y,a,b,c,t_0):                                  
    return [b*y[0]*y[1]-c*(t-t_0), a*y[1]-b*y[0]*y[1]]

def f2(t,y,a,b,c):                           
    return [b*y[0]*y[1], a*y[1]-b*y[0]*y[1]] 
def jac_f(t,y,a,b):                            
    return [[b*y[1],b*y[0]],[-b*y[1],a-b*y[1]]]
然后我们导入
ode
并调用积分器两次。第一次,我们从开始值(我将其设置为t=0)开始积分,直到达到
t0
,然后开始第二次积分,方程组对
t>t0
有效。我们将最后计算的值作为初始条件传递给积分器,并继续积分,直到达到
t=4
(任意选择)

我们得到了一个很好的图表:

似乎对全局变量
sol_y
执行插值也有效:

import numpy as np
from scipy.integrate import ode
import matplotlib.pyplot as plt

def dudt(t, u, params):
    x, y = u
    a, b, c, t0 = params

    dydt = a*y   - b*x*y  
    if t <= t0:
        dxdt = b*x*y
    else:
        dxdt = b*x*y - c*get_old_y(t-t0)

    return [dxdt, dydt]

def get_old_y(old_t):
    return np.interp(old_t, sol_t, sol_y)

def jac_dudt(t, u, params):
    x, y = u
    a, b, c, t0 = params
    jac = [[ b*y, b*x-c],
           [-b*y, a-b*y]]
    return jac

# parameters
t0 = 1
params = 1, 1, 2, t0

u0 = [1, 2]

t_end = 3*t0
dt = 0.05

# integration
r = ode(dudt, jac_dudt).set_integrator("vode",
                            method="adams",
                            with_jacobian=True)

r.set_initial_value(u0, 0).set_f_params(params).set_jac_params(params)

sol_t, sol_x, sol_y = [], [], []                             
while r.successful() and r.t < t_end:
    r.integrate(r.t + dt)
    sol_x.append(r.y[0])
    sol_y.append(r.y[1])
    sol_t.append(r.t)

# graph
plt.plot(sol_t, sol_x, '-|', label='x(t)')
plt.plot(sol_t, sol_y, '-|', label='y(t)')
plt.legend(); plt.xlabel('time'); plt.ylabel('solution');
将numpy导入为np
从scipy.integrate导入ode
将matplotlib.pyplot作为plt导入
def dudt(t、u、参数):
x、 y=u
a、 b,c,t0=参数
dydt=a*y-b*x*y

如果t如果
t忽略哪个项如果t退出,则忽略c*(t-t_0)项,则系统是一个延迟微分方程,需要使用DDE解算器。虽然这些都存在于matlab中,但python的标准软件包并未涵盖这些方程。请您简要解释一下“vode”和“adams”以及集成代码,好吗?另外,如果我有更多的方程现在具有t-t_0依赖性,该怎么办?如果您只拥有一个函数,可以使用
c*max(0,t-t0)
。由于这是连续的,解算器在该点上积分应该没有问题,即使它必须将步长调低到
t0
@LutzL左右,这实际上是一种比我的尝试更好的解决方法。@在Duckgoesquark中,您可以在各种书籍和出版物中阅读不同的集成方法。如果你有一个关于这些方法如何工作的具体问题,请问一个新问题,或者直接转到math.SE。阅读vode的一个起点是Brown等人的著作:但我想要的是t-t_0的函数,而不是t-t_0本身的值。我该怎么做呢?如果我有另一个方程,它有一个变量z,它依赖于t,它的导数依赖于x,y和t,那么我该如何找到两个以上方程的雅可比矩阵并绘制一条曲线呢?@Duckgoesquark雅可比矩阵是不必要的,如果不提供,它将通过数值进行估计,你可以先不用它试试。(雅可比矩阵将是具有相应导数的3x3矩阵)
import matplotlib.pyplot as plt
yy=np.stack(y_res)
plt.plot(t_list, yy[:,0], label="x(t)")
plt.plot(t_list, yy[:,1], label="y(t)")
plt.legend()
plt.show()
import numpy as np
from scipy.integrate import ode
import matplotlib.pyplot as plt

def dudt(t, u, params):
    x, y = u
    a, b, c, t0 = params

    dydt = a*y   - b*x*y  
    if t <= t0:
        dxdt = b*x*y
    else:
        dxdt = b*x*y - c*get_old_y(t-t0)

    return [dxdt, dydt]

def get_old_y(old_t):
    return np.interp(old_t, sol_t, sol_y)

def jac_dudt(t, u, params):
    x, y = u
    a, b, c, t0 = params
    jac = [[ b*y, b*x-c],
           [-b*y, a-b*y]]
    return jac

# parameters
t0 = 1
params = 1, 1, 2, t0

u0 = [1, 2]

t_end = 3*t0
dt = 0.05

# integration
r = ode(dudt, jac_dudt).set_integrator("vode",
                            method="adams",
                            with_jacobian=True)

r.set_initial_value(u0, 0).set_f_params(params).set_jac_params(params)

sol_t, sol_x, sol_y = [], [], []                             
while r.successful() and r.t < t_end:
    r.integrate(r.t + dt)
    sol_x.append(r.y[0])
    sol_y.append(r.y[1])
    sol_t.append(r.t)

# graph
plt.plot(sol_t, sol_x, '-|', label='x(t)')
plt.plot(sol_t, sol_y, '-|', label='y(t)')
plt.legend(); plt.xlabel('time'); plt.ylabel('solution');