在 Python 中从 MATLAB 模仿 ode45 函数

新手上路,请多包涵

我想知道如何将 MATLAB 函数 ode45 导出到 python。根据文档应该如下:

  MATLAB:  [t,y]=ode45(@vdp1,[0 20],[2 0]);

 Python:  import numpy as np
          def  vdp1(t,y):
              dydt= np.array([y[1], (1-y[0]**2)*y[1]-y[0]])
              return dydt
          import scipy integrate
          l=scipy.integrate.ode(vdp1([0,20],[2,0])).set_integrator("dopri5")

结果完全不同,Matlab 返回的维度与 Python 不同。

原文由 Migui Mag 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.7k
2 个回答

integrate.ode 的界面不像更简单的方法 odeint 那样直观,但是它不支持选择 ODE 积分器。主要区别在于 ode 不会为您运行循环;如果你在一堆点上需要一个解决方案,你必须说出在哪些点上,然后一次计算一个点。

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

def vdp1(t, y):
    return np.array([y[1], (1 - y[0]**2)*y[1] - y[0]])
t0, t1 = 0, 20                # start and end
t = np.linspace(t0, t1, 100)  # the points of evaluation of solution
y0 = [2, 0]                   # initial value
y = np.zeros((len(t), len(y0)))   # array for solution
y[0, :] = y0
r = integrate.ode(vdp1).set_integrator("dopri5")  # choice of method
r.set_initial_value(y0, t0)   # initial values
for i in range(1, t.size):
   y[i, :] = r.integrate(t[i]) # get one more value, add it to the array
   if not r.successful():
       raise RuntimeError("Could not integrate")
plt.plot(t, y)
plt.show()

解决方案

原文由 user6655984 发布,翻译遵循 CC BY-SA 3.0 许可协议

正如@LutzL 提到的,您可以使用更新的 API solve_ivp

 results = solve_ivp(obj_func, t_span, y0, t_eval = time_series)

如果未指定 t_eval ,那么每个时间戳都不会有一条记录,这主要是我假设的情况。

Another side note is that for odeint and often other integrators, the output array is a ndarray of a shape of [len(time), len(states)] , however for solve_ivp ,输出是 list(length of state vector) 一维 ndarray(其长度等于 t_eval )。

所以如果你想要相同的订单,你必须合并它。你可以这样做:

 Y =results
merged = np.hstack([i.reshape(-1,1) for i in Y.y])

首先,您需要对其进行整形,使其成为 [n,1] 数组,然后水平合并。希望这可以帮助!

原文由 extraymond 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题