求解非刚性微分方程 - 中阶方法
全页折叠
语法
[t,y] = ode45(odefun,tspan,y0)
[t,y] = ode45(odefun,tspan,y0,options)
[t,y,te,ye,ie] = ode45(odefun,tspan,y0,options)
sol = ode45(___)
说明
示例
[t,y] = ode45(odefun,tspan,y0)
(其中 tspan = [t0 tf]
)求微分方程组 从 t0
到 tf
的积分,初始条件为 y0
。解数组 y
中的每一行都与列向量 t
中返回的值相对应。
所有 MATLAB® ODE 求解器都可以解算 形式的方程组,或涉及质量矩阵 的问题。求解器都使用类似的语法。ode23s
求解器只能解算质量矩阵为常量的问题。ode15s
和 ode23t
可以解算具有奇异质量矩阵的问题,称为微分代数方程 (DAE)。使用 odeset 的 Mass
选项指定质量矩阵。
ode45
是一个通用型 ODE 求解器,是您解算大多数问题时的首选。但是,对于刚性问题或需要较高准确性的问题,其他 ODE 求解器可能更适合。有关详细信息,请参阅选择 ODE 求解器。
示例
[t,y] = ode45(odefun,tspan,y0,options)
还使用由 options
(使用 odeset
函数创建的参量)定义的积分设置。例如,使用 AbsTol
和 RelTol
选项指定绝对误差容限和相对误差容限,或者使用 Mass
选项提供质量矩阵。
[t,y,te,ye,ie] = ode45(odefun,tspan,y0,options)
还求 (t,y) 的函数(称为事件函数)在何处为零。在输出中,te
是事件的时间,ye
是事件发生时的解,ie
是触发的事件的索引。
对于每个事件函数,应指定积分是否在零点处终止以及过零方向是否重要。为此,请将 'Events'
属性设置为函数(例如 myEventFcn
或 @myEventFcn
),并创建一个对应的函数:[value
,isterminal
,direction
] = myEventFcn
(t
,y
)。有关详细信息,请参阅 ODE 事件位置。
示例
sol = ode45(___)
返回一个结构体,您可以将该结构体与 deval
结合使用来计算区间 [t0 tf]
中任意点位置的解。您可以使用上述语法中的任何输入参量组合。
示例
全部折叠
具有一个解分量的 ODE
打开实时脚本
在对求解器的调用中,可将只有一个解分量的简单 ODE 指定为匿名函数。该匿名函数必须同时接受两个输入 (t,y)
,即使在该函数中一个输入未使用也是如此。
解算 ODE
指定时间区间 [0 5]
和初始条件 y0 = 0
。
tspan = [0 5];y0 = 0;[t,y] = ode45(@(t,y) 2*t, tspan, y0);
对解绘图。
plot(t,y,'-o')
解算非刚性方程
打开实时脚本
van der Pol 方程为二阶 ODE
其中 为标量参数。通过执行 代换,将此方程重写为一阶 ODE 方程组。生成的一阶 ODE 方程组为
函数文件 vdp1.m
代表使用 的 van der Pol 方程。变量 和 是二元素向量 dydt
的项 y(1)
和 y(2)
。
function dydt = vdp1(t,y)%VDP1 Evaluate the van der Pol ODEs for mu = 1%% See also ODE113, ODE23, ODE45.% Jacek Kierzenka and Lawrence F. Shampine% Copyright 1984-2014 The MathWorks, Inc.dydt = [y(2); (1-y(1)^2)*y(2)-y(1)];
使用 ode45
函数、时间区间 [0 20]
和初始值 [2 0]
来解算该 ODE。生成的输出即为时间点 t
的列向量和解数组 y
。y
中的每一行都与 t
的相应行中返回的时间相对应。y
的第一列与 相对应,第二列与 相对应。
[t,y] = ode45(@vdp1,[0 20],[2; 0]);
绘制 和 的解对 t
的图。
plot(t,y(:,1),'-o',t,y(:,2),'-o')title('Solution of van der Pol Equation (\mu = 1) with ODE45');xlabel('Time t');ylabel('Solution y');legend('y_1','y_2')
向 ODE 函数传递额外的参数
打开实时脚本
ode45
仅适用于使用两个输入参量(t
和 y
)的函数。但是,通过在函数外部定义参数并在指定函数句柄时传递这些参数,可以传入额外参数。
解算 ODE
将该方程重写为一阶方程组可以得到
此示例末尾包含的局部函数 odefcn
将此方程组表示为接受四个输入参量(t
、y
、A
和 B
)的函数。
function dydt = odefcn(t,y,A,B) dydt = zeros(2,1); dydt(1) = y(2); dydt(2) = (A/B)*t.*y(1);end
使用 ode45
解算 ODE。指定函数句柄,使其将 A
和 B
的预定义值传递给 odefcn
。
A = 1;B = 2;tspan = [0 5];y0 = [0 0.01];[t,y] = ode45(@(t,y) odefcn(t,y,A,B), tspan, y0);
绘制结果。
plot(t,y(:,1),'-o',t,y(:,2),'-.')
function dydt = odefcn(t,y,A,B) dydt = zeros(2,1); dydt(1) = y(2); dydt(2) = (A/B)*t.*y(1);end
求解具有多个初始条件的 ODE
打开实时脚本
对于只有一个方程的简单 ODE 方程组,可以将 y0
指定为一个包含多个初始条件的向量。此方法通过标量扩展创建一个由独立方程组成的方程组,每个初始值对应一个方程,ode45
求解该方程组以针对每个初始值生成结果。
创建一个匿名函数来表示方程 。该函数必须接受分别对应于 t
和 y
的两个输入。
yprime = @(t,y) -2*y + 2*cos(t).*sin(2*t);
创建一个由范围 内的不同初始条件组成的向量。
y0 = -5:5;
使用 ode45
计算方程在时间区间 内针对每个初始条件的解。
tspan = [0 3];[t,y] = ode45(yprime,tspan,y0);
绘制结果。
plot(t,y)grid onxlabel('t')ylabel('y')title('Solutions of y'' = -2y + 2 cos(t) sin(2t), y(0) = -5,-4,...,4,5','interpreter','latex')
此方法对于求解具有多个初始条件的简单 ODE 非常有用。然而,该方法也有一些折衷:
您无法求解具有多个初始条件的方程组。该方法仅适用于求解一个具有多个初始条件的方程。
求解器在每步选择的时间步基于方程组中需要采取最小步长的方程。这意味着求解器可以采取小步长来满足一个初始条件的方程,但其他方程如果单独求解的话将使用不同步长。尽管如此,同时针对多个初始条件进行求解通常比使用
for
循环分别求解方程更快。
有关此方法的详细信息,请参阅求解具有多个初始条件的 ODE 方程组。
带有时间依赖项的 ODE
打开脚本
请考虑以下带有时间依赖参数的 ODE:
初始条件为 。函数 f(t)
由在时间 ft
时计算的 n×1 向量 f
定义。函数 g(t)
由在时间 gt
时计算的 m×1 向量 g
定义。
创建向量 f
和 g
。
ft = linspace(0,5,25);f = ft.^2 - ft - 3;gt = linspace(1,6,25);g = 3*sin(gt-0.25);
编写名为 myode
的函数,该函数通过对 f
和 g
进行插值获取时间依赖项在指定时间的值。将函数保存到您当前的文件夹中,以运行示例的其余部分。
myode
函数接受额外的输入参量以计算每个时间步的 ODE,但 ode45
只使用前两个输入参量 t
和 y
。
function dydt = myode(t,y,ft,f,gt,g)f = interp1(ft,f,t); % Interpolate the data set (ft,f) at time tg = interp1(gt,g,t); % Interpolate the data set (gt,g) at time tdydt = -f.*y + g; % Evaluate ODE at time t
使用 ode45
计算方程在时间区间 [1 5]
内的解。使用函数句柄指定函数,从而使 ode45
只使用 myode
的前两个输入参量。此外,使用 odeset
放宽误差阈值。
tspan = [1 5];ic = 1;opts = odeset('RelTol',1e-2,'AbsTol',1e-4);[t,y] = ode45(@(t,y) myode(t,y,ft,f,gt,g), tspan, ic, opts);
绘制解 y
对时间点 t
的函数图。
plot(t,y)
计算和扩展解结构体
打开实时脚本
van der Pol 方程为二阶 ODE
使用 ode45
以及 解算 van der Pol 方程。函数 vdp1.m
随 MATLAB® 一起提供,用于对方程进行编码。指定单个输出以返回包含解信息(如求解器和计算点)的结构体。
tspan = [0 20];y0 = [2 0];sol = ode45(@vdp1,tspan,y0)
sol = struct with fields: solver: 'ode45' extdata: [1x1 struct] x: [0 1.0048e-04 6.0285e-04 0.0031 0.0157 0.0785 0.2844 0.5407 0.8788 1.4032 1.8905 2.3778 2.7795 3.1285 3.4093 3.6657 3.9275 4.2944 4.9013 5.3506 5.7998 6.2075 6.5387 6.7519 6.9652 7.2247 7.5719 8.1226 8.6122 9.1017 9.5054 ... ] (1x60 double) y: [2x60 double] stats: [1x1 struct] idata: [1x1 struct]
使用 linspace
在区间 [0 20]
内生成 250 个点。使用 deval
计算在这些点上的解。
x = linspace(0,20,250);y = deval(sol,x);
绘制解的第一个分量。
plot(x,y(1,:))
使用 odextend
将解扩展到 ,并将结果添加到原始图中。
sol_new = odextend(sol,@vdp1,35);x = linspace(20,35,350);y = deval(sol_new,x);hold onplot(x,y(1,:),'r')
输入参数
全部折叠
输出参量
全部折叠
算法
ode45
基于显式龙格-库塔 (4,5) 公式多曼-普林斯对。这是一种单步求解器 – 在计算 y(tn)
时,该求解器仅需要最靠近该时间点的前一时间点处的解 y(tn-1)
[1], [2]。
参考
[1] Dormand, J. R. and P. J. Prince, “A family of embedded Runge-Kutta formulae,” J. Comp. Appl. Math., Vol. 6, 1980, pp. 19–26.
[2] Shampine, L. F. and M. W. Reichelt, “The MATLAB ODE Suite,” SIAM Journal on Scientific Computing, Vol. 18, 1997, pp. 1–22.
扩展功能
C/C++ 代码生成
使用 MATLAB® Coder™ 生成 C 代码和 C++ 代码。
用法说明和限制:
所有
odeset
选项参量都必须为常量。代码生成不支持在 options 结构体中使用常量质量矩阵。需以函数形式提供质量矩阵。
必须提供至少两个输出参量
T
和Y
。输入类型必须为同类 - 全部为双精度或全部为单精度。
必须启用可变大小支持。当
tspan
有两个元素或当您使用事件函数时,代码生成需要动态分配内存。
版本历史记录
在 R2006a 之前推出
另请参阅
ode23 | ode78 | ode89 | ode113 | ode15s | odeset | odeget | deval | odextend
主题
- 选择 ODE 求解器
- ODE 选项摘要
- 求解非刚性 ODE
- 匿名函数
- 常见 ODE 问题疑难解答
MATLAB 命令
您点击的链接对应于以下 MATLAB 命令:
请在 MATLAB 命令行窗口中直接输入以执行命令。Web 浏览器不支持 MATLAB 命令。
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 简体中文
- English
- 日本 (日本語)
- 한국 (한국어)
Contact your local office