很多去国外留学的同学听说国外数学教的很简单,又觉得自己数学还行,就想当然的选了数学专业。在这里AssignmentGod很负责的告诉你们,大家所听说的数学很简单只是针对高中一二年级,因为后面都是同学们按自己的兴趣选课,到了大学外国的数学一样很难,让很多留学生束手无策。今天小编就带大家了解一下如何使用Matlab去解数学微分方程。
ode的求解器
在help里可以查到很多ode的求解器,以下列出了每一种求解器的适应范围(stiff或者nonstiff)以及它采用的数学原理,比如Runge-Kutta,Adams,NDFs之类。 如果不懂那么多理论,可以优先采用ode45,但如果你发现它的计算效率特别低下或者是计算根本出不来,则可以考虑换ode15s。
对于怎么把要求解的方程写为function,你只需要告诉求解器你的公式、积分范围和初值 (输入参数),它就可以为你求解出y。
sol = ode45(@yourfun,[tmin,tmax],[y0,y0′])
你的公式 积分范围 初值
sol=ode45(@vdp1,[0,20],[2,0]);
把以上代码在命令行里直接执行,这便是matlab自带的一个例子。在workspace里你会看到多了一个变量叫sol.没错这就是求解器的返回值。它是一个1*1的结构体,双击它,你会看到它的内部组织,各个field以及它们的“形状”。每一个你都可以双击它,继续深入看它的结构。我现在关心的只有X,Y
solver
extdata,
x,
y,
stats,
idata
求解计算完毕后可以做什么
首先,当然是得到结果。
deval(sol,x,1)
sol就是上方写在求解等号左边的变量名字,是返回来的handles。x是一组向量,是你期望求值的点。数字1就表示你要y第一行的值(这个是在求解微分方程组的情况。不明白什么叫第一行,就去双击sol,再双击y),如果去掉1,则返回矩阵,也就是所有y的值。在matlab命令行运行以下代码:
sol=ode45(@vdp1,[0,20],[2,0]);
x=linspace(0,20,100);
y=deval(sol,x,1);
plot(x,y);
此外,我们还可以扩展,matlab叫做odextend。扩展什么?
odextend(sol,odefun,tfinal)
最后一个变量名是t_final,也就是,我之前算过的微分方程组,原来算到t1,我现在要接着继续计算到新的t_final。默认以上次计算的y终值,作为此次计算的初值。
odextend(sol,odefun,tfinal,yinit)
当然,如果你想重新给它赋初值,也可以加入参数yinit。
获取上次计算的Y的终值:
y=sol.y(:,end))
sol=odextend(sol,@vdp1,20);
plot(sol.x,sol.y(1,🙂)
求解器的参数设置
也就是option这个东西,既然是选项,则也可以不设置它,采用默认值。要设置的话,我们可以用odeset这个命令
option=odeset(‘name1′,value1,’name2’,value2……) (matlab所有参数设置基本上都是这种形式)
name自然就是属性名字,value就是你赋予它的值。求解器可以设置哪些参数?设置了这些参数有什么影响?这些参数应该怎么设置?建议大家在命令行里输入 help odeset😀 。看到的绝对比我讲得详细,所以在这里不多说了。(如果使用ode15,可以为它设置Jacobian这个参数,以更快更准更好的求解。)
O=odeget(option,’name’)
编过GUI的话这两个命令再熟悉不过了 。
一般问题求解nonstiff
用ode系列可以求解Y的微分方程,数值解法,得到y的数值解。可以涉及多阶微分。
函数形式:y‘=f(t,y) 这种我叫它显性函数
f(t,y,y’)=0 隐函数,这种用ode15i求解
求解器可以求解线性和隐性
对于求解微分问题都要为其指定初值
得到: y’=f(t,y) y(t0)=y0
所以告诉求解器如上的f(t,y),t0,y0,就可以解出y了。
ode只能直接求解一阶微分,那我有多级微分怎么办呢?学过现代控制理论就知道怎么处理了。不学也不影响,基本上就是把 一个N阶微分方程转化为N个一阶微分方程组。 比如y”’=f(t,y,y’,y”) 将y ,y’ ,y”设为y1,y2,y3,那么如上的三阶就可以表示为y3的一阶方程了。
则原来的一个三阶方程变为如下的三个一阶方程组。
y1’=y2 y2’=y3 y3’=f(t,y1,y2,y3)
基本例子Examples: Solving Explicit ODE Problems
Stiff问题
简单的说就是你用ode45求解发现速度很慢或者解不出来的时候,这种情况有些书上把它翻译成刚性,而我的理解是,梯度会发生剧变。
例二:以上的例子是将mu设置为1,用ode45求解顺顺当当,然后你再把mu改为1000,同样的步骤求解,试试看?
我是试过了,半天没反应(也可能是我电脑配置不够)。
matlab称,ode45适用于求解一些nonstiff的问题。当用这类专求解nonstiff的求解器来求stiff问题时,就会非常低效。此时,若采用ode15s求解器,一下代码可以直接运行,vdp1000内置。可以试试把ode15s改为ode45
[t,y] = ode15s(@vdp1000,[0 3000],[2; 0]);
plot(t,y(:,1),’-‘);
title(‘Solution of van der Pol Equation, \mu = 1000’);
xlabel(‘time t’);
ylabel(‘solution y_1’);
复制代码
附vdp1000的函数 function
dydt = vdp1000(t,y)
dydt = [y(2); 1000*(1-y(1)^2)*y(2)-y(1)];
复制代码
可以对比这个例子和上一个例子的图形。
例三 参数化方程
如果我的mu是作为一组变化的参数,要求解这一系列的微分方程,怎么办呢?一个方便的方法就是建一个function,将mu作为输入的参数,而ode求解器作为内置函数。
关于隐式微分方程的解法 形式如 f(t,y,y’)=0
使用ode15i求解器 [t,y]=ode15i(yourfun,tspan,y0,yp0,options) yourfun—–>@你的函数名 tspan—–>积分上下限,形式:[t0,tf] y0—–>y的初值 yp0———>y’的初值 option 同上上,一些求解参数设置
附:输入的初始值,要能满足方程f(t0,y0,yt0)=0.
初看起来,人们也许会感到困惑,但数学学生是可以慢慢理解的。若用MATLAB求解微分方程还有困难,可向我们的数学代写服务机构寻求帮助!扫描右侧二维码即可。
原创文章,作者:Assignment God,如若转载,请注明出处:https://www.assignmentgod.com/archives/541