[英]Imitate ode45 function from MATLAB in Python
I am wondering how to export MATLAB function ode45 to python.我想知道如何将 MATLAB 函数 ode45 导出到 python。 According to the documentation is should be as follows:根据文档是应该如下:
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")
The results are completely different, Matlab returns different dimensions than Python.结果完全不同,Matlab 返回的维度与 Python 不同。
As @LutzL mentioned, you can use the newer API, solve_ivp
.正如@LutzL 提到的,您可以使用较新的 API, solve_ivp
。
results = solve_ivp(obj_func, t_span, y0, t_eval = time_series)
If t_eval
is not specified, then you won't have one record per one timestamp, which is mostly the cases I assume.如果未指定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
, the output is a list(length of state vector)
of 1-dimension ndarray(which length is equal to t_eval
).另一个方面说明的是,对odeint
和经常其他积分,输出阵列是ndarray
的形状的[len(time), len(states)]
,但是对于solve_ivp
,输出是一个list(length of state vector)
的一维 ndarray(其长度等于t_eval
)。
So you have to merge it if you want the same order.所以如果你想要相同的顺序,你必须合并它。 You can do so by:你可以这样做:
Y =results
merged = np.hstack([i.reshape(-1,1) for i in Y.y])
First you need to reshape to make it a [n,1]
array, and merge it horizontally.首先,您需要重塑以使其成为[n,1]
数组,然后将其水平合并。 Hope this helps!希望这有帮助!
The interface of integrate.ode is not as intuitive as of a simpler method odeint which, however, does not support choosing an ODE integrator. integration.ode的界面不像更简单的方法odeint那样直观,但是它不支持选择 ODE 积分器。 The main difference is that ode
does not run a loop for you;主要区别在于ode
不会为您运行循环; if you need a solution at a bunch of points, you have to say at what points, and compute it one point at a time.如果你需要一堆点的解决方案,你必须说在哪些点上,并一次计算一个点。
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()
The function scipy.integrate.solve_ivp uses the method RK45 by default, similar the method used by Matlab's function ODE45 as both use the Dormand-Pierce formulas with fourth-order method accuracy.功能scipy.integrate.solve_ivp默认使用方法RK45,类似于使用Matlab的功能ODE45既使用Dormand-皮尔斯式与四阶方法准确性的方法。
vdp1 = @(T,Y) [Y(2); (1 - Y(1)^2) * Y(2) - Y(1)];
[T,Y] = ode45 (vdp1, [0, 20], [2, 0]);
from scipy.integrate import solve_ivp
vdp1 = lambda T,Y: [Y[1], (1 - Y[0]**2) * Y[1] - Y[0]]
sol = solve_ivp (vdp1, [0, 20], [2, 0])
T = sol.t
Y = sol.y
Ordinary Differential Equations (solve_ivp) 常微分方程 (solve_ivp)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.