牛小贱 发表于 2014-3-8 21:10

【分享】关于Matlab求解微分方程的那些事!!!

本帖最后由 牛小贱 于 2014-5-24 14:02 编辑

看到论坛里,有很多人问关于Matlab求解微分方程的问题。所以,鄙人不才,根据自己的个人经验,以及结合相关论坛、博客,将Matlab求解微分方程的相关内容和大家分享一下!!首先,我们讲一下关于可以求得解析解的微分方程。大家应该都知道,函数dsolve可以解决一部分能够解析求解的微分方程、微分方程组。关于该函数的调用格式,如下:y=dsolve(f1,f2,...,fm,'x');先举个例子,如图:
程序如下: syms t y;
u=exp(-5*t)*cos(2*t-1)+5;
uu=5*diff(u,t,2)+4*diff(u,t)+2*u;
y=dsolve(['D4y+10*D3y+35*D2y+24*Dy= uu '])接下来,介绍一下关于数值解的解法。大家应该都有这种意识:能够解析求解的微分方程(组)占少数,对于大多数微分方程(组)而言不能得到解析解,这时只能进行数值求解。关于数值分析方法,比较著名的当属Eular法、 Runge-Kutta了!在matlab中内置的ode求解器可以实现不同求解方法的相同格式的调用,而不必太关心matlab究竟是用什么算法完成的。在这里,我主要和大家分享关于ode45等求解器的具体使用方法,其他的求解器的使用有相似之处,在此不再赘述。先不介绍其具体调用格式,先来个例子,看看他的庐山真面目:求解方程组Dx=y+x(1-x^2-y^2);Dy=-x+y*(1-x^2-y^2)初值x=0.1;y=0.2;程序:function weifen1
clear;clc
x0=;
=ode45(@jxhdot,,x0);
plot(x(:,1),x(:,2))

function dx=jxhdot(t,x)
dx=;结果如图1所示:看完例子,我说明一下最常用的ode45调用方式,和相应的函数文件定义格式。=ode45(odefun,tspan,x0);其中,Fun就是导函数,tspan为求解的时间区间(或时间序列,如果采用时间序列,则必须单调),x0为初值。这时,函数文件可以采用如下方式定义:function dx=odefun(t,x)接着, (1)刚性方程的求解:刚性方程就是指各个自变量的变化率差异很大,会造成通常的求解方法失效。下面是matlab中自带的一个例子,使用ode15s求解,如果用ode45求解就会出现错误。function myode15study
= ode15s(@vdp1000,,);
plot(T,Y(:,1),'-o')
figure;plot(Y(:,1),Y(:,2))
function dy = vdp1000(T,y)
dy = zeros(2,1);   
dy(1) = y(2);
dy(2) = 1000*(1 - y(1)^2)*y(2) - y(1);
结果如图2和图3.
(2)高阶微分方程的求解!通常的方法是进行变量替换,将原方程降阶,转换成更多变量的一阶方程组进行求解。在这个例子里我们求解一个动力学系统里最常见的一个运动方程。程序:function myhighoder
clear;clc
x0=zeros(6,1);
=ode45(@myhigh,,x0);
plot(t,x(:,1))
function dx=myhigh(t,x)
f=;
M=eye(3);
C=eye(3)*0.1;
K=eye(3)-0.5*diag(ones(2,1),1)-0.5*diag(ones(2,1),-1);
dx=;结果如图4.(3)延迟微分方程:matlab提供了dde23求解非中性微分方程。dde23的调用格式如下:sol = dde23(ddefun,lags,history,tspan)lags是延迟量,比如方程中包含y1(t-0.2)和y2(t-0.3)则可以使用lags=。这里的ddefun必须采用如下的定义方式:dydt = ddefun(t,y,Z)其中的Z(:,1)就是y(t-lags(1)),Z(:,2)就是y(t-lags(2))...下面是个使用dde23求解延迟微分方程的例子:function mydde23study
%   The differential equations
%
%      y'_1(t) = y_1(t-1)
%      y'_2(t) = y_1(t-1)+y_2(t-0.2)
%      y'_3(t) = y_2(t)
%
%   are solved on with history y_1(t) = 1, y_2(t) = 1, y_3(t) = 1 for
%   t <= 0.
clear;clc
lags=;
history=;
tspan=;
sol = dde23(@myddefun,lags,history,tspan)
plot(sol.x,sol.y)
function dy = myddefun(t,y,Z)
dy=;
结果如图5所示。(4)隐式微分方程:求解此类方程需要使用ode15i函数。调用格式: = ode15i(odefun,tspan,y0,yp0)yp0为y'的初值。odefun的格式如下dy =odefun(t,y,yp),yp表示y',而方程中应该使得f(t,y,y')=0function myodeIMP
%   The problem is
%
%         y(1)' = -0.04*y(1) + 1e4*y(2)*y(3)
%         y(2)' =0.04*y(1) - 1e4*y(2)*y(3) - 3e7*y(2)^2
%         y(3)' =3e7*y(2)^2
%
%   It is to be solved with initial conditions y(1) = 1, y(2) = 0, y(3) = 0
%   to steady state.
clear;clc
y0=;
fixed_y0=;
yp0=;
fixed_yp0=[];
=decic(@myodefunimp,0,y0,fixed_y0,yp0,fixed_yp0);
tspan=;
= ode15i(@myodefunimp,tspan,y0mod,yp0mod);
y(:,2)=1e4*y(:,2);
semilogx(t,y)
function res=myodefunimp(t,y,yp)
res=[ -yp(1)-0.04*y(1)+1e4*y(2)*y(3);-yp(2)+0.04*y(1)-1e4*y(2)*y(3)-3e7*y(2)^2;-yp(3)+3e7*y(2)^2 ];运行结果如图6.
在讲了这么多之后,我想大家也看烦了!所以,我结合相关论坛、帖子总结一个新的求解ode的方法——那就是使用simulink的积分器求解!!
还是咱们举的第一个例子:Dx=y+x(1-x^2-y^2);Dy=-x+y*(1-x^2-y^2)初值x=0.1;y=0.2;积分器中设置初始条件;f(u)中指定Dx,Dy的计算公式。在Simulink中建立模块框图,如图7所示。运行这个仿真,scope中可以看到两个变量的时程如图8.在WorkSpace里可以得到tout和yout,执行plot(yout(:,1),yout(:,1))得到与ode45求解相似的结果!!!除此之外,使用simulink还可以求解的一类延迟微分方程。(PS:transportDelay,就可以实现对于信号的延迟!!)实例:x'(t)=A1*x(t-t1)+A2*x'(t-t2)+B*u(t)t1=0.15;t2=0.5A1=[-12   3   -3]      A2=    B=                                                Simulink中建立的模块框图和仿真结果图,如图9和10所示.最后,给大家一些matlab求解微分方程的资料!见附件(本人强烈推荐一本书      薛定宇编写的《高等应用数学问题的MATLAB求解》,很不错!链接地址为http://ishare.iask.sina.com.cn/f/7453073.html)。不足之处,还请大家补充、指正。





Matlab及ADAMS集中营

晓凡 发表于 2014-3-9 19:19

关于Matlab求解微分方程的那些事!!!讲的真心不错啊!!楼主真的很有耐心啊!32个赞{:{39}:}

ChaChing 发表于 2014-5-23 16:28

LZ第一个例子好像式子与代码就不一致了
可能误值了

牛小贱 发表于 2014-5-23 20:00

ChaChing 发表于 2014-5-23 16:28
LZ第一个例子好像式子与代码就不一致了
可能误值了

貌似应该没有吧~呵呵。

ChaChing 发表于 2014-5-24 13:42

本帖最后由 ChaChing 于 2014-5-24 13:43 编辑

图 u=exp(-5*t)*cos(2*t+1)+5
程序u=exp(-5*t)*cos(2*t-1)+5

图 y''''+10y'''+35y''+24y'=5u''+4u'+2u
程序 y=dsolve(['D4y+10*D3y+35*D2y+50*Dy+24*y=87*exp(-5*t)*cos(2*t-1)+92*exp(-5*t)*sin(2*t-1)+10'])

TWO-SOCKS 发表于 2014-6-17 22:36

谢谢楼主分享!

danzhilan 发表于 2014-12-23 12:45

学习啦 谢谢

小鱼爱吃猫 发表于 2014-12-23 16:43

楼主,高人!

lanbingmengyi 发表于 2014-12-25 16:29

感谢楼主分享,学习了{:{05}:}

阳光醉卧 发表于 2015-1-5 21:43

楼猪好帅!

marloan 发表于 2015-5-26 11:01

很全面 感谢楼主分享

xhlym1 发表于 2015-11-11 16:44

好书啊 啊啊

xuzhibin040 发表于 2015-11-11 22:21

学习了,感谢楼主,感谢老师,给我们发群了

cy9663 发表于 2015-12-30 17:58

值得关注,很好的指导

LEO_Zhang 发表于 2016-1-23 13:20

感谢楼主
页: [1] 2
查看完整版本: 【分享】关于Matlab求解微分方程的那些事!!!