【发布时间】:2017-09-11 23:42:10
【问题描述】:
我目前正在为一个涉及求解微分方程的项目从 MATLAB 切换到 Python。
在 MATLAB 中,如果传递的 t 数组仅包含两个元素,则求解器会输出仿真的所有中间步骤。但是,在 Python 中,您只知道起点和终点。要获得介于两者之间的时间点,您必须明确指定所需的时间点。
from scipy import integrate as sp_int
import numpy as np
def odeFun(t,y):
k = np.ones((2))
dy_dt = np.zeros(y.shape)
dy_dt[0]= k[1]*y[1]-k[0]*y[0]
dy_dt[1]=-dy_dt[0]
return(dy_dt)
t = np.linspace(0,10,1000)
yOut = sp_int.odeint(odeFun,[1,0],t)
我还研究了以下方法:
solver = sp_int.ode(odefun).set_integrator('vode', method='bdf')
solver.set_initial_value([1,0],0)
dt = 0.01
solver.integrate(solver.t+dt)
但是,它仍然需要明确的dt。通过阅读,我了解到 Python 的求解器(例如 'vode')为请求的 dt 计算中间步骤,然后对该时间点进行插值并输出。我想要的是直接获得所有这些中间步骤而无需插值。这是因为它们代表了在积分容差内完全描述时间序列所需的最少点数。
有没有可用的选项来做到这一点?
我正在使用 Python 3。
【问题讨论】:
-
"然后对那个时间点进行插值并输出" 你确定吗?对我来说听起来有点不寻常。正常的程序是缩短会超调的第一步,因此它会达到要求的点。 - 重新掌握时间步长。如果你真的很绝望,你可以随时检测被积函数并记录调用它的 t。
-
@PaulPanzer:对于某些可以假设插值足够准确并且缩短时间步长相对乏味的方法来说,插值是很常见的。
scipy.integrate.odeint插值,从tcur数据(请参阅我的回答)以及您建议的日志中可以看出 - 两者都不包含初始时间步长。 -
@PaulPanzer:如果你真的很绝望,你可以随时检测被积函数并记录调用它的 t。 - 这不会给你想要的结果,因为许多求解器还需要在步骤之间有时评估导数 (
odeFun),例如,explicit midpoint method 举一个简单的例子。 -
这是因为它们代表了在积分容差范围内完整描述时间序列所需的最少点数。 – 您能否详细说明为什么需要此信息?我感觉到XY problem。
-
@Wrzlprmft 哇,即使按照我的标准,一条评论中也有很多错误的陈述。感谢您正确设置它们。