MATLAB R2021b--求解常微分方程

05-14 阅读 0评论

记录常微分方程MATLAB解法的学习

目录

一·连续系统的数学建模方法

(一)连续系统

1.微分方程模型

2.传递函数模型

3.状态空间模型

(二)微分方程建模

微分方程的机理建模法(解析法)

二·常微分方程的数值解法

1.微分方程

2.常用方法

(1)欧拉法

      从导数的角度理解欧拉公式:

欧拉法的应用:

      从数值积分角度理解欧拉公式:

(2)改进的欧拉法

改进的欧拉法的应用:

(3)龙格-库塔法(Runger-Kutta法)

局部截断误差和阶

标准(经典)四阶龙格-库塔法:

龙格-库塔法的应用:

(4)亚当姆斯法

线性多步法的概念:

3.一阶常微分方程组的数值解法

4.高阶常微分方程的数值解法

三·MATLAB求解常微分方程

(一)解析解

1.dsolve

 (二)数值解

1.solver

​编辑

 2.高阶常微分方程

(三)综合实例

1.一阶微分方程

(1)将方程写成函数文件

  (2)解析解

(3) 求解器法

(4)欧拉法

(5)改进欧拉法

(6)龙格-库塔法

结果:

 2.二阶微分方程

(1)把方程写成函数文件

(2)解析解

(3)欧拉法

(4)改进欧拉法

(5)龙格-库塔法

(6)求解器

结果:


一·连续系统的数学建模方法

(一)连续系统

连续系统是指系统的状态变量随着时间连续变化的系统,可通过常微分方程或偏微分方程来描述。

常用的连续系统数学模型有: 微分方程模型 ,传递函数模型 , 状态空间模型。

1.微分方程模型

MATLAB R2021b--求解常微分方程

2.传递函数模型

MATLAB R2021b--求解常微分方程

3.状态空间模型

MATLAB R2021b--求解常微分方程

由微分方程可以导出系统的传递函数和状态方程等多种数学模型。 因此,建立系统的微分方程是建模技术中的重要内容。

MATLAB R2021b--求解常微分方程

(二)微分方程建模

微分方程的机理建模法(解析法)

(1)使用前提:该方法是依据基本的物理、化学等定律,进行机理分析,确定模型结构、参数;   使用该方法的前提是对系统的运行机理完全清楚。

(2)基本原理:机理建模法又称为直接分析法或解析法,是应用最广泛的一种建模方法,一般是在若干简化假设条件下,以各学科专业知识为基础, 通过分析变量间的关系和规律,而获得解析型数学模型。

(3)建模步骤:

                    ① 分析系统功能、原理,对系统做出与建模目标相关的描述 (系统原理图);

                    ② 找出系统的输入变量和输出变量;

                    ③ 按照系统(部件、元件)遵循的内在规律(物化、生态、经济 规律),列写

                         出各部分的微分方程,建立微分方程组。

                    ④ 消去中间变量,导出只含有输入、输出量的微分方程;

                    ⑤ 标准化微分方程,将输出各项移到方程左侧,输入各项移到方程右侧,各阶导数项

                         按阶次从高到低的顺序排列。

  例1.1:机械平移系统

MATLAB R2021b--求解常微分方程

这是一个由阻尼器,弹簧,物体构成的系统。f是阻尼器的阻尼系数,k是弹簧的弹性系数。

输入:外力x

输出:物体的位移y

设阻尼器施加给物体的力为 x1,弹簧施加给物体的力为 x2

根据牛顿第二定律列方程:

MATLAB R2021b--求解常微分方程

消去中间变量 x1,x2

MATLAB R2021b--求解常微分方程                 MATLAB R2021b--求解常微分方程

标准化微分方程:

MATLAB R2021b--求解常微分方程           这是一个线性常系数二阶微分方程

例1.2 :R-L-C电路

MATLAB R2021b--求解常微分方程

输入:电压u(t)

输出:电量q(t)

设电阻R上的电压为 uR,电感L上的电压为 uL,电容C上的电压为 uC

根据基尔霍夫电压定律列方程:

      MATLAB R2021b--求解常微分方程

消去中间变量:

MATLAB R2021b--求解常微分方程补充一个(这里没用到)电容电流  MATLAB R2021b--求解常微分方程

标准化微分方程:

MATLAB R2021b--求解常微分方程              也是一个线性常系数二阶微分方程

以上推出的各种系统的运动方程(数学模型),尽管它们的物理模型不同,却可能具有相同的数学模型,这种具有相同的微分形式的系统称为相似系统。将作用相同(在微分方程中占据相同位置) 的物理量称为相似量。

比较两个例子可以看出它们具有相同的数学模型,是相似系统。

MATLAB R2021b--求解常微分方程

小结一下:

MATLAB R2021b--求解常微分方程

二·常微分方程的数值解法

1.微分方程

在许多实际问题中,往往不能完全清楚系统机理直接写出函数的解析表达式,但根据已知条件,有时可列出含有待求函数及其导数的关系式——微分方程。

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

以上两个例子抽象出来实际上就是一阶微分方程的初值问题:

MATLAB R2021b--求解常微分方程

实际上,只有少数问题如 例2.1 例2.2 能求出y(x)的解析表达式,对大多数微分方程要求出函数的准确表达式,计算量大、甚至不可能,但是实用上有时只需得到在某些点处的函数近似值即可。

MATLAB R2021b--求解常微分方程

求yk的离散化方法:欧拉法,改进欧拉法,龙格-库塔法,亚当姆斯法。

下面对这几种方法做简单介绍

这里不做过多的数学深究,只在于运用。

2.常用方法

(1)欧拉法
      从导数的角度理解欧拉公式:

            ①向前差商

              我们知道导数可以近似为差商的形式:

              Ⅰ :  MATLAB R2021b--求解常微分方程        h称为步长,

                令:

               Ⅱ :   MATLAB R2021b--求解常微分方程MATLAB R2021b--求解常微分方程

             图示如下:yk+1与y(xk+1)不同,前者是近似值后者是实际值,而初值yk与y(xk)相等

              MATLAB R2021b--求解常微分方程

              将Ⅱ式带入Ⅰ式得到欧拉公式:

                       MATLAB R2021b--求解常微分方程

              ②向后差商

                MATLAB R2021b--求解常微分方程

                令:

                MATLAB R2021b--求解常微分方程MATLAB R2021b--求解常微分方程

                图示如下:

                MATLAB R2021b--求解常微分方程

                 同理,得到后退欧拉公式:

                 MATLAB R2021b--求解常微分方程

              ③中心差商

                MATLAB R2021b--求解常微分方程

                同理,得到中点欧拉公式:

                MATLAB R2021b--求解常微分方程

                图示如下:

                MATLAB R2021b--求解常微分方程

       其实我们常用的是一般的欧拉公式

      公式:

      MATLAB R2021b--求解常微分方程

      MATLAB R2021b--求解常微分方程

      以此类推可以得到欧拉法的几何意义:

      MATLAB R2021b--求解常微分方程

       欧拉法也称 欧拉折线法

       注意:“折线法” 而非“切线法” 除第一个点是曲线切线外,其他点均不是

欧拉法的应用:

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

      除了从微分(导数)的角度推出欧拉公式外,我们还可以从积分的角度推公式。

      从数值积分角度理解欧拉公式:

             MATLAB R2021b--求解常微分方程

            MATLAB R2021b--求解常微分方程

            MATLAB R2021b--求解常微分方程

            MATLAB R2021b--求解常微分方程

 在梯形公式中,计算yk+1时,计算式中含有未知的yk+1,这样的公式称为隐式公式。

(2)改进的欧拉法

将梯形公式和欧拉公式结合使用,先用欧拉公式由已知的初值计算第一次yk+1,然后把初值和第一次计算的yk+1代入梯形公式计算修正后的yk+1

两个公式组合如下:

MATLAB R2021b--求解常微分方程

此公式也称为预估-校正公式。

预估---由欧拉公式求第一次yk+1的过程;

校正---代入梯形公式迭代计算第二次yk+1的过程。

用预估-校正公式求解常微分方程的方法即为——改进的欧拉法。

此公式可以改写为

MATLAB R2021b--求解常微分方程

改进的欧拉法的应用:

MATLAB R2021b--求解常微分方程对比欧拉法,精确了很多

MATLAB R2021b--求解常微分方程

(3)龙格-库塔法(Runger-Kutta法)

使用泰勒公式也可以推导欧拉法和改进的欧拉法,这里主要是为了引出龙格-库塔法的推导。

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

插播一下 。。。。。。

局部截断误差和阶

这里需要了解误差分析中,局部截断误差和阶的概念

MATLAB R2021b--求解常微分方程

设yn是准确的,用某种方法计算yn+1时产生截断误差 实际上yn不是准确的,因此它的误差会传播下去。 实际计算时,每一步都可能产生舍入误差。

MATLAB R2021b--求解常微分方程

知道概念后可以得到欧拉公式的局部截断误差和阶

MATLAB R2021b--求解常微分方程

同理,改进欧拉公式取到泰勒的二阶展开式,局部截断误差为三阶,公式是二阶。

小结一下:

MATLAB R2021b--求解常微分方程

    结论:计算几次K(f),公式就是几阶

               局部截断误差比公式高1阶

龙格-库塔法就是按照上述的思想构造

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

从几何意义上看,欧拉法是用斜率f(xn ,yn )逼近,而龙格-库塔法则是 可以看成用p个斜率

Kr=f(xr ,yr )的一种加权平均逼近,因此能够提供计算精度。

MATLAB R2021b--求解常微分方程

采用类似二阶龙格-库塔法的构造方法,即可得三阶龙格-库塔法 (截断误差为O(h^4 ))和四阶龙格-库塔法(截断误差为O(h^5 ))。

标准(经典)四阶龙格-库塔法:

MATLAB R2021b--求解常微分方程

龙格-库塔法的应用:

MATLAB R2021b--求解常微分方程

(4)亚当姆斯法

单步法:从x0开始,逐步求取x1,x2,...,xn处的函数 值近似值y1,y2,...,yn,求yn+1时要用到前一步结果yn。(改进的欧拉法)

两步法:每前进1步,即求yn+1时要用到前2步结果yn-1和yn。(中点欧拉公式)

单步法优点: 原理简单并可根据需要调整步长大小;

单步法缺点: 要得到高精度解,计算量大。 如四阶龙格-库塔法,每前进一步(求yn+1)需计算4次f(x,y)函数值。

亚当姆斯法属于线性多步法

线性多步法的概念:

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

如果对xn-2、xn-1、xn、三点做二次拉格朗日插值多项式 L2 (x)近似取代y'(x),则有:

MATLAB R2021b--求解常微分方程

以此类推可以得到曲线的近似。

MATLAB R2021b--求解常微分方程

二阶隐式Adams公式,也就是梯形公式。

3.一阶常微分方程组的数值解法

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

4.高阶常微分方程的数值解法

MATLAB R2021b--求解常微分方程

三·MATLAB求解常微分方程

(一)解析解

1.dsolve

MATLAB R2021b--求解常微分方程

 例3.1:

MATLAB R2021b--求解常微分方程

y=dsolve('D2y+4*Dy+29*y=0','y(0)=0,Dy(0)=15','x') 
%结果   y = 3*sin(5*x)*exp(-2*x)

例3.2:

MATLAB R2021b--求解常微分方程

注:解微分方程组时,如果所给的输出个数与方程个数相同,则方程组的解按词典顺序输出;如果只给一个输出,则输出的是一个包含解的结构(structure)类型的数据。 

%输出形式1:
[x,y,z]=dsolve('Dx=2*x-3*y+3*z','Dy=4*x-5*y+3*z','Dz=4*x-4*y+2*z','t')
%结果  
%x = C1*exp(-t) + C3*exp(2*t)
%y = C1*exp(-t) + C2*exp(-2*t) + C3*exp(2*t)
%z = C2*exp(-2*t) + C3*exp(2*t)
%输出形式2
r=dsolve('Dx=2*x-3*y+3*z','Dy=4*x-5*y+3*z','Dz=4*x-4*y+2*z','t')
%结果2
%r = 
%包含以下字段的 struct:
    %y: C1*exp(-t) + C2*exp(-2*t) + C3*exp(2*t)
    %x: C1*exp(-t) + C3*exp(2*t)
    %z: C2*exp(-2*t) + C3*exp(2*t)

 (二)数值解

事实上只有很少一部分微分方程能解出解析解。

多数情况下还是使用数值解的解法

1.solver

MATLAB R2021b--求解常微分方程

关于求解器的对比:

MATLAB R2021b--求解常微分方程

若 odefun 为显式常微分方程,可以用命令 inline 定义,或在函数文件中定义,然后通过函数句柄调用。

例3.3:求下列微分方程的数值解,求解范围为 [0,0.5]

MATLAB R2021b--求解常微分方程

fun=inline('-2*y+2*x^2+2*x','x','y')
[x,y]=ode23(fun,[0,0.5],1)
%结果     fun =
     %内联函数:
     %fun(x,y) = -2*y+2*x^2+2*x
%x =[0 0.0400 0.0900 0.1400 0.1900 0.2400 0.2900 0.3400 0.3900 0.4400 0.4900 0.5000]
%y =[1.0000 0.9247 0.8434 0.7754 0.7199 0.6764 0.6440 0.6222 0.6105 0.6084 0.6154 0.6179]
%注:也可以在 tspan 中指定对求解区间的分割,如:
[x,y]=ode23(fun,[0:0.1:0.5],1); %此时 x=[0:0.1:0.5]
% x = [0 0.1000 0.2000 0.3000 0.4000 0.5000]
%y = [1.0000 0.8287 0.7103 0.6388 0.6093 0.6179]

 2.高阶常微分方程

如果需求解的问题是高阶常微分方程,则需将其化为一阶常微分方程组, 此时需用函数文件来定义该常微分方程组。

例3.4:

MATLAB R2021b--求解常微分方程

 MATLAB R2021b--求解常微分方程

%先编写函数文件 vdp1000.m
function dy=vdp1000(t,y) %定义函数vdp1000
dy=zeros(2,1); %2行1列列向量
dy(1)=y(2); 
dy(2)=1000*(1-y(1)^2)*y(2)-y(1);
%然后在命令窗口运行
clear;
clc;
[T,Y]=ode15s(‘vdp1000’,[0,3000],[2 0]); %调用ode15s求解vdp1000 
plot(T,Y(:,1),‘-’); %Y=[y(1) y(2)],画出y(1)

 MATLAB R2021b--求解常微分方程

(三)综合实例

求解下列微分方程:

MATLAB R2021b--求解常微分方程

1.一阶微分方程

(1)将方程写成函数文件
%fun1.m
function f=fun1(x,y)
    f = sin(x)+y;
end 
  (2)解析解
y=dsolve('Dy=sin(x)+y','y(0)=1','x')

MATLAB R2021b--求解常微分方程  

从输出得知,此方程有解析解,我们可以取一些x值带入解析解,求出y,然后画出精确的曲线

画出解析解的图形

%完整脚本
f=dsolve('Dy=sin(x)+y','y(0)=1','x')
X=0:0.1:3;    %取[0,3]区间的值
n=length(X);  %所取值的数量
df=zeros(1,n);%生成与x取值数量对应的y的数组
for i=1:n     %写一个循环,把根据解析方程求得的y值放入数组df
    temp=subs(f,'x',X(i));   %subs(方程,‘待取代的变量’,‘取代变量的实际值’)
    df(i)=double(vpa(temp));  %把求得的y值转换为双精度,否则会因为运算强制取整
end
plot(X,df,'-k')        %绘图
(3) 求解器法

使用MATLAB自带求解器求解

为了保证算法的通用性,后面都用函数文件的形式保存

%o45.m
function o45(fun,t0,tm,y0)
%(函数,自变量区间初值,自变量区间末值,y值初值)
%命令窗口输入:
%o45(@fun1,0,3,1)
%@fun1是直接调用前面我们写好的函数文件中的函数
[t,y]=ode45(fun,[t0 tm],y0);
plot(t,y,'-g')
hold on   %保留绘图窗口,下一次绘图也在这个窗口
(4)欧拉法

写代码的思路和手算例题的思路一致,确定f(x,y)的方程,步长,x的取值,然后按公式计算yk

只是多了一步,需要写一个保存yk的数组

%oula.m
function oula(f,h,xm,x0,y0)
% f切线方程  h步长 xf自变量最大值  x0,y0初值 
%oula(@fun1,0.1,3,0,1)
x = [x0:h:xm];
% length函数是求数组维度的长度。
n = length(x);
%用数组y保存计算得到的yk值
y = zeros(1,n);
y(1) = y0;
for i= 1:n-1
    y(i+1) = y(i) + h*f(x(i),y(i));
end
plot(x,y,'-m')
grid on
hold on
 
(5)改进欧拉法
%oulagai.m
function oulagai(f,h,xm,x0,y0)
% f切线方程  h步长 xf自变量最大值  x0,y0初值 
%oulagai(@fun1,0.1,3,0,1)
x = [x0:h:xm];
n = length(x);
y = zeros(1,n);
y(1) = y0;
for i= 1:n-1
    K1 = h*f(x(i),y(i));
    K2 = h*f(x(i+1),y(i)+K1);
    y(i+1) = y(i)+0.5*(K1+K2);
     %下面是另外一种写法 
     %y(i+1)=y(i)+h*f(x(i),y(i));
     %y(i+1)=y(i)+h/2*(f(x(i),y(i))+f(x(i+1),y(i+1)))
end
plot(x,y,'-b')
hold on
(6)龙格-库塔法
%longge.m
function longge(f,h,xm,x0,y0)
% f切线方程  h步长 xf自变量最大值  x0,y0初值 
%longge(@fun1,0.1,3,0,1)
x = [x0:h:xm];
n = length(x);
y = zeros(size(x));
y(1) = y0;
for i= 1:n-1
    K1 = f(x(i),y(i));
    K2 = f(x(i)+0.5*h,y(i)+0.5*h*K1);
    K3 = f(x(i)+0.5*h,y(i)+0.5*h*K2);
    K4 = f(x(i)+h,y(i)+h*K3);
    y(i+1) = y(i)+(h/6)*(K1+2*K2+2*K3+K4);
end
plot(x,y,'-r')
hold on
结果:

可见欧拉法的误差很大,逐渐放大看,改进欧拉法其次,四阶龙格库塔和 ode45 的误差相近。

MATLAB R2021b--求解常微分方程

MATLAB R2021b--求解常微分方程

 2.二阶微分方程

MATLAB R2021b--求解常微分方程

首先就是把二阶化成一阶方程组

MATLAB R2021b--求解常微分方程

(1)把方程写成函数文件
%fun2.m
function F=fun2(t,Y)
    y = Y(1);
    z = Y(2);
    f1 = z;
    f2 = (-y-(-1+y^2)*z)/2;
    F = [f1;f2];
end

f1和f2对应的是方程组的输出,用数组F保存

y和z是方程的两个输入,用数组Y保存

这样写,方便之后的循环迭代

(2)解析解
 y=dsolve('2*D2y+(y^2-1)*Dy+y=0','y(0)=0.25','Dy(0)=0.0')

MATLAB R2021b--求解常微分方程 y为空没有解析解

(3)欧拉法
%oular2.m
function oular2(fun,t0,y0,z0,h,tm)
%oular2(@fun2,0,0.25,0.0,0.1,3)
    
    t=t0:h:tm;
    n=length(t);
    y(1)=y0;
    z(1)=z0;
    Y(:,1)=[y(1),z(1)];
    for i = 1:n-1
        Y(:,i+1)=Y(:,i)+h*fun(t(i),Y(:,i));
    end
    y=Y(1,:);
    figure(2)
    %黑色
    plot(t,y,'-m')
    hold on
    grid on
    
(4)改进欧拉法
%oulargai2.m
function oulargai2(fun,t0,y0,z0,h,tm)
%oulargai2(@fun2,0,0.25,0.0,0.1,3)
    t = [t0:h:tm];
    n = length(t);
    Y(:,1)=[y0,z0];
    for i= 1:n-1
        Y(:,i+1)=Y(:,i)+h*fun(t(i),Y(:,i));
        Y(:,i+1)=Y(:,i)+h/2*(fun(t(i),Y(:,i))+fun(t(i+1),Y(:,i+1)))
    end
    y=Y(1,:);
%蓝色
    plot(t,y,'-b')
    hold on
    
 
(5)龙格-库塔法
%longge2.m
function longge2(fun,t0,y0,z0,h,tm)
%longge2(@fun2,0,0.25,0.0,0.1,3)
     t = [t0:h:tm];
    n = length(t);
    Y(:,1)=[y0,z0];
    for i= 1:n-1
        K1 = fun(t(i),Y(:,i));
        K2 = fun(t(i)+0.5*h,Y(:,i)+0.5*h*K1);
        K3 = fun(t(i)+0.5*h,Y(:,i)+0.5*h*K2);
        K4 = fun(t(i)+h,Y(:,i)+h*K3);
        Y(:,i+1) = Y(:,i)+h/6*(K1+2*K2+2*K3+K4);
    end
   
    y=Y(1,:);
    %红色
    plot(t,y,'-r')
    hold on
(6)求解器
%o452.m
function o452(fun,t0,y0,z0,tm)
%o452(@fun2,0,0.25,0.0,3)
[t,y]=ode45(fun,[t0 tm],[y0 z0]);
%绿色
plot(t,y(:,1),'-g')
hold on
结果:

MATLAB R2021b--求解常微分方程


免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,人围观)

还没有评论,来说两句吧...

目录[+]