Matlab 微分方程 ode45 求解并绘制曲线

  • 2. 用 ode45() 求解
    • 2.1 ode45() 函数用法
    • 2.2 示例:求解一阶微分方程
      • 2.2.1 Matlab 代码如下
      • 2.2.2 代码效果
    • 2.3 示例:求解矩阵一阶微分方程
      • 2.3.1 Matlab 代码
      • 2.3.2 代码效果
    • 2.4 示例:将上述示例代码写成两个函数
      • 2.4.1 主函数如下
      • 2.4.2 子函数如下
  • 1. ode45-官方释义
    • 1.1 语法 / 说明
    • 1.2 示例
      • 1.2.1 具有一个解分量的 ODE
      • 1.2.2 van der Pol 方程为二阶 ODE
      • 1.2.3 向 ODE 函数传递额外的参数
      • 1.3.4 带有时变项的 ODE
      • 1.2.5 计算和扩展结构体
    • 1.3 输入参数
      • 1.3.1 options - options 结构体

2. 用 ode45() 求解

2.1 ode45() 函数用法

[t, Xt] = ode45(odefun, tspan, X0)

  • odefun 是函数句柄,可以是函数文件名,匿名函数句柄或内联函数名
  • tspan 是区间 [t0 tfinal] 或者一系列散点[t0,t1,…,tf]
  • X0 是初始值向量
  • t 返回列向量的时间点
  • Xt 返回对应T的求解列向量

2.2 示例:求解一阶微分方程

求解单变量微分方程的解
x˙(t)=2∗x(t)\dot{x}(t) = 2 * x(t)x˙(t)=2∗x(t)

2.2.1 Matlab 代码如下

clear;
clc;% 程序主函数代码如下:
t0 = 0;
tfinal = 10;
X0 = 1;[t, Xt] = ode45(@SunFun, [t0 tfinal], X0);% 绘制结果图
plot(t,Xt)
grid% 微分方程函数,状态导数
function xdot = SunFun(t,x)
% 导数关系式
xdot = 2 * x;end

2.2.2 代码效果


2.3 示例:求解矩阵一阶微分方程

求解一阶微分方程
X˙(t)=−L∗X(t)\dot{X}(t) = -L * X(t)X˙(t)=−L∗X(t)

其中,X(t)X(t)X(t) 是列向量。

2.3.1 Matlab 代码

clear;
clc;% 程序主函数代码如下:
t0 = 0;
tfinal = 10;
X0 = [0; 1; 3; 3; 5; 6;];[t, Xt] = ode45(@SunFun, [t0 tfinal], X0);% 绘制结果图
plot(t,Xt(:,1), t,Xt(:,2), t,Xt(:,3), t,Xt(:,4), t,Xt(:,5), t,Xt(:,6))
grid% 微分方程函数,状态导数
function xdot = SunFun(t,x)D = [1 0 0 0 0 0; 0 1 0 0 0 0; 0 0 1 0 0 0; 0 0 0 1 0 0; 0 0 0 0 1 0; 0 0 0 0 0 1;];
A = [0 1 0 0 0 0; 0 0 1 0 0 0; 0 0 0 1 0 0; 0 0 0 0 1 0; 0 0 0 0 0 1; 1 0 0 0 0 0;];
L = D - A;% 导数关系式
xdot = -L * x;end

2.3.2 代码效果


2.4 示例:将上述示例代码写成两个函数

2.4.1 主函数如下

clear;
clc;% 程序主函数代码如下:
t0 = 0;
tfinal = 10;
X0 = [0; 1; 3; 3; 5; 6;];[t, Xt] = ode45('SunFun', [t0 tfinal], X0);% 绘制结果图
plot(t,Xt)
grid

2.4.2 子函数如下

% 微分方程函数,状态导数
function xdot = SunFun(t,x)D = [1 0 0 0 0 0; 0 1 0 0 0 0; 0 0 1 0 0 0; 0 0 0 1 0 0; 0 0 0 0 1 0; 0 0 0 0 0 1;];
A = [0 1 0 0 0 0; 0 0 1 0 0 0; 0 0 0 1 0 0; 0 0 0 0 1 0; 0 0 0 0 0 1; 1 0 0 0 0 0;];
L = D - A;% 导数关系式
xdot = -L * x;

From: P4 控制系统数学模型-《Matlab/Simulink与控制系统仿真》程序指令总结

Ref: 【MATLAB】关于ode45的一部分用法的函数编写方式


1. ode45-官方释义

1.1 语法 / 说明

[t,y] = ode45(odefun,tspan,y0)

[t,y] = ode45(odefun,tspan,y0)(其中 tspan = [t0 tf])求微分方程组 y′=f(t,y) 从 t0 到 tf 的积分,初始条件为 y0。解数组 y 中的每一行都与列向量 t 中返回的值相对应。

所有 MATLAB® ODE 求解器都可以解算 y′=f(t,y) 形式的方程组,或涉及质量矩阵 M(t,y)y′=f(t,y) 的问题。求解器都使用类似的语法。ode23s 求解器只能解算质量矩阵为常量的问题。ode15s 和 ode23t 可以解算具有奇异质量矩阵的问题,称为微分代数方程 (DAE)。使用 odeset 的 Mass 选项指定质量矩阵。

ode45 是一个通用型 ODE 求解器,是您解算大多数问题时的首选。但是,对于刚性问题或需要较高准确性的问题,其他 ODE 求解器可能更适合。有关详细信息,请参阅选择 ODE 求解器。


[t,y] = ode45(odefun,tspan,y0,options)

[t,y] = ode45(odefun,tspan,y0,options) 还使用由 options(使用 odeset 函数创建的参数)定义的积分设置。例如,使用 AbsTolRelTol 选项指定绝对误差容限和相对误差容限,或者使用 Mass 选项提供质量矩阵。


[t,y,te,ye,ie] = ode45(odefun,tspan,y0,options)
[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(___)

sol = ode45(___) 返回一个结构体,您可以将该结构体与 deval 结合使用来计算区间 [t0 tf] 中任意点位置的解。您可以使用上述语法中的任何输入参数组合。


1.2 示例

1.2.1 具有一个解分量的 ODE

在对求解器的调用中,可将只有一个解分量的简单 ODE 指定为匿名函数。该匿名函数必须同时接受两个输入 (t,y),即使其中一个输入未使用也是如此。

解算 ODE
y′=2ty' = 2ty′=2t

使用时间区间 [0,5] 和初始条件 y0 = 0。

tspan = [0 5];
y0 = 0;
[t,y] = ode45(@(t,y) 2*t, tspan, y0);% 对解绘图。
plot(t,y,'-o')


1.2.2 van der Pol 方程为二阶 ODE

y1′′−μ(1−y12)y1′+y1=0y''_1 - \mu (1-y_1^2)y'_1 + y_1 = 0y1′′​−μ(1−y12​)y1′​+y1​=0

其中,μ>0\mu>0μ>0 为标量参数。通过执行 y1′=y2y'_1=y_2y1′​=y2​ 代换,将此方程重写为一阶 ODE 方程组。生成的一阶 ODE 方程组为
y1′=y2y2′=μ(1−y12)y2−y1y'_1 = y_2 \\ y'_2 = \mu(1-y_1^2)y_2-y_1 y1′​=y2​y2′​=μ(1−y12​)y2​−y1​

函数文件 vdp1.m 代表使用 μ=1\mu = 1μ=1 的 van der Pol 方程。变量 y1y_1y1​ 和 y2y_2y2​ 是二元素向量 dydt 的项 y(1)y(1)y(1) 和 y(2)y(2)y(2)。

function dydt = vdp1(t,y)dydt = [y(2); (1-y(1)^2)*y(2)-y(1)];
end

使用 ode45 函数、时间区间 [0 20] 和初始值 [2 0] 来解算该 ODE。生成的输出即为时间点 ttt 的列向量和解数组 yyy。yyy 中的每一行都与 ttt 的相应行中返回的时间相对应。yyy 的第一列与 y1y_1y1​ 相对应,第二列与 y2y_2y2​ 相对应。

[t,y] = ode45(@vdp1,[0 20],[2; 0]);% 绘制 $y_1$ 和 $y_2$ 的解对 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')

整体写成一个函数

[t,y] = ode45(@vdp1,[0 20],[2; 0]);% 绘制 $y_1$ 和 $y_2$ 的解对 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')function dydt = vdp1(t,y)p = y(1);dp = y(2);ddp = (1-p^2)*dp-p;dydt = [dp; ddp];
end

再做一下转换,换成常见的二阶智能体形式:
p˙=vv˙=(1−p2)∗v−p\dot{p}=v \\ \dot{v}=(1-p^2)*v-pp˙​=vv˙=(1−p2)∗v−p

[t,y] = ode45(@vdp1,[0 20],[2; 0]);% 绘制 $y_1$ 和 $y_2$ 的解对 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')function out = vdp1(t,y)p = y(1,:);v = y(2,:);ddp = (1-p^2)*v-p;out = [v; ddp];
end

因为对ode的使用方法(求二阶微分方程)还是不够熟悉,因此,再做一次离散化处理,来验证下自己的离散化方法是否正确。

图像变化趋势没有错误,证明离散化的思路正确,再把时间间隔由 dT=0.1dT = 0.1dT=0.1 调整为 dT=0.01dT=0.01dT=0.01,结果如下

最后,附上完整版代码:

tBegin = 0;
tFinal = 20;
dT = 0.01;
times = (tFinal - tBegin)/dT;p(:,1) = 2;
v(:,1) = 0;
t(:,1) = 0;for i = 1:timest(i+1,1) = t(i,1) + dT;p(i+1,1) = p(i,1) + dT * v(i,1);v(i+1,1) = v(i,1) + dT * ((1-p(i,1)^2)*v(i,1)-p(i,1));
endy = [p,v];% 绘制 $y_1$ 和 $y_2$ 的解对 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')

1.2.3 向 ODE 函数传递额外的参数

ode45 仅适用于使用两个输入参数(ttt 和 yyy)的函数。但是,通过在函数外部定义参数并在指定函数句柄时传递这些参数,可以传入额外参数。

解算 ODE
y′′=ABtyy'' = \frac{A}{B}tyy′′=BA​ty

将该方程重写为一阶方程组可以得到
y1′=y2y2′=ABty1y'_1 = y_2 \\ y'_2 = \frac{A}{B}\ t\ y_1y1′​=y2​y2′​=BA​ t y1​

odefcn.m 将此方程组表示为接受四个输入参数(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);

使用 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),'-.')


1.3.4 带有时变项的 ODE

请考虑以下带有时变参数的 ODE:

y′(t)+f(t)y(t)=g(t).y'(t) + f(t)y(t) = g(t).y′(t)+f(t)y(t)=g(t).

初始条件为 y0=1y_0 = 1y0​=1。函数 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 t
g = interp1(gt,g,t); % Interpolate the data set (gt,g) at time t
dydt = -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)


1.2.5 计算和扩展结构体

van der Pol 方程为二阶 ODE
y1′′−μ(1−y12)y1′+y1=0y''_1 -\mu(1-y_1^2) y'_1 + y_1 = 0y1′′​−μ(1−y12​)y1′​+y1​=0

使用 ode45 以及 μ=1 解算 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: [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 将解扩展到 tf=35t_f=35tf​=35,并将结果添加到原始图中。

sol_new = odextend(sol,@vdp1,35);
x = linspace(20,35,350);
y = deval(sol_new,x);
hold on
plot(x,y(1,:),'r')


1.3 输入参数

1.3.1 options - options 结构体

options 结构体,指定为结构体数组。使用 odeset 函数创建或修改 options 结构体。有关与每个求解器兼容的选项列表,请参阅 ODE 选项摘要。

示例:
options = odeset('RelTol',1e-5,'Stats','on','OutputFcn',@odeplot)

指定 1e-5 的相对误差容限、打开求解器统计信息的显示,并指定输出函数 @odeplot 在计算时绘制解。

数据类型: struct


From: ode45-MathWorks


【Matlab 控制】微分方程 ode45() 求解并绘制曲线相关推荐

  1. 微分方程 ode45() 求解并绘制曲线

    https://blog.csdn.net/weixin_36815313/article/details/109459892

  2. 机器学习(MACHINE LEARNING)MATLAB中微分方程的求解

    文章目录 1 MATLAB之极限.积分.微分 2 matlab中微分方程的求解 2.1 一阶微分方程 2.2 求解二阶线性微分方程 是指含有未知函数及其导数的关系式.解微分方程就是找出未知函数.微分方 ...

  3. 【Matlab 控制】构建系统,绘制零极点

    Matlab 构建系统 绘制零极点 >> num0 = 5*[1 5 6]; den0 = [1 6 10 8]; % 描述闭环传递函数的分子.分母多项式 >> sys0 = ...

  4. matlab控制倒立摆小车并绘制二维动态效果图

    clc;close all;clear A = [0 1 0 0;0 0 -1.176 0;0 0 0 1;0 0 18.293 0];%设置倒立摆小车控制系统参数 B = [0; 1 ;0;-1.6 ...

  5. matlab之常微分方程(ODE)求解

    问题描述:已知理想全混釜的初始进料条件,并知道各物料的动力学,求解足够长时间后全混釜中各物质的浓度 常微分方程:只包含一个自变量的微分方程是常微分方程(Ordinary differential eq ...

  6. matlab 龙格-库塔 法求解常微分方程

    最近学习分室模型,里面碰到了用matlab 龙格-库塔 法求解常微分方程 研究了一阵子终于明白到底怎么实现了: 1. matlab 新建.m文件,编写龙格-库塔法求解函数 function [x,y] ...

  7. matlab欧拉方程求解微分方程并和ode45对比结果

    1.内容简介 matlab欧拉方程求解微分方程并和ode45对比结果 2.内容说明 略 3.仿真分析 clc close all clear %% ode45方法 y0 = [8.5;2;1];%初始 ...

  8. MATLAB实战应用案例:欧拉法、改进欧拉法、ode45求解微分方程实例

    前言 ode45求解 clc clear 以下是我为大家准备的几个精品专栏,喜欢的小伙伴可自行订阅,你的支持就是我不断更新的动力哟! MATLAB-30天带你从入门到精通 MATLAB深入理解高级教程 ...

  9. 关于求解微分方程——初学Matlab里的 ODE求解器

    学习背景 最近想挖掘一下自己项目的理论深度,于是找到了老师.在老师的建议下,我们开始了漫长的研读老师的论文的旅程(论文名:Optimal Design of Adaptive Robust Contr ...

最新文章

  1. mysql优化说明_MySQL性能优化各个参数解释说明
  2. 【RocketMQ工作原理】订阅关系的一致性
  3. spark官方文档_Apache Spark 文档传送门
  4. python自学时间-学习Python、Python时间操作有哪些?
  5. 推荐系统笔记(深度学习)
  6. lintcode-102-带环链表
  7. 使用css将超出盒子的文字显示为省略号
  8. 判断扫码是支付宝还是微信
  9. Sql Server之旅——第九站 看看DML操作对索引的影响
  10. python 全解坦克大战 辅助类 附完整代码【雏形】
  11. facebook机器学习_如何为您的页面创建Facebook Messenger机器人
  12. 【HDU - 1078】FatMouse and Cheese (记忆化搜索dp)
  13. 信息学奥赛一本通 1018:其他数据类型存储空间大小 | OpenJudge NOI 1.2 03
  14. 【BZOJ1758】重建计划,点分治+单调队列
  15. 【TSP】基于matlab免疫算法求解31城市旅行商问题【含Matlab源码 1149期】
  16. 常用的ADB命令介绍
  17. 学习Oracle 最好的5本书
  18. J2EE快速入门之集合框架【01】
  19. 大学生数学竞赛(非数学类)经验
  20. 设备树slew-rate

热门文章

  1. 激活社保卡去哪个地方的银行都可以吗?
  2. 去掉图片转换后的黑色背景
  3. 使用谱减法对语音信号进行降噪(librosa),C#使用Speex
  4. html如何播放qsv,爱奇艺缓存的视频为qsv格式,怎么才能播放!
  5. php yof框架特点_在线竞拍系统的PHP实现框架(一)
  6. 市政管网检测机器人收费标准_当阳市水下作业收费情况,市政管网检测机器人费用...
  7. excel 数据标签格式/数据标签位置没有数据标签外选项
  8. mac扩展屏幕做主显示器关闭电脑屏幕,关闭键盘背光
  9. react-useId
  10. 【翻译】如何选择一个开源软件许可证 Choosing an OSS license doesn’t need to be scary...