首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用Python语言模拟MATLAB中的ode45函数

用Python语言模拟MATLAB中的ode45函数
EN

Stack Overflow用户
提问于 2018-01-25 01:14:45
回答 3查看 22.1K关注 0票数 6

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

代码语言:javascript
运行
复制
 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不同。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-01-26 02:01:20

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

代码语言:javascript
运行
复制
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()

票数 4
EN

Stack Overflow用户

发布于 2018-04-19 23:15:34

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

代码语言:javascript
运行
复制
results = solve_ivp(obj_func, t_span, y0, t_eval = time_series)

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

另一个注意事项是,对于odeint以及通常是其他积分器,输出阵列是[len(time), len(states)]形状的ndarray,然而对于solve_ivp,输出是一维ndarray(其长度等于t_eval)的list(length of state vector)

因此,如果您想要相同的顺序,则必须合并它。您可以通过以下方式执行此操作:

代码语言:javascript
运行
复制
Y =results
merged = np.hstack([i.reshape(-1,1) for i in Y.y])

首先,您需要重塑它的形状,使其成为[n,1]数组,然后水平合并它。希望这能有所帮助!

票数 9
EN

Stack Overflow用户

发布于 2021-01-28 07:56:48

默认情况下,函数scipy.integrate.solve_ivp使用RK45方法,类似于ODE45函数使用的方法,因为两者都使用具有四阶方法精度的多曼德-皮尔斯公式。

代码语言:javascript
运行
复制
vdp1 = @(T,Y) [Y(2); (1 - Y(1)^2) * Y(2) - Y(1)];
[T,Y] = ode45 (vdp1, [0, 20], [2, 0]);
代码语言:javascript
运行
复制
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)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48428140

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档