用MATLAB求解非线性微分方程

总结一下MATLAB中求解微分方程的思路和步骤。固然,网上很多关于此类的技术型文章,但往往一看下来发现,文章中的友情链接比文章字数还多,要了解这一篇文章,你要先了解那个;要了解那个,你又要了解那个那个;以此类推。了解完了,花都谢了。我在这里要写的是娱乐型文章,即试图用最少的字数陈述出MATLAB的求解微分方程方法,看完后可以记得清楚且不亦乐乎。其实个人十分推荐MATLAB中的帮助文件,内容实在是特别给力,简明的不能再简明了。可惜了是英文写的,即使是天天要面对英语的我,也颇为头疼。那么以下我将结合我对MATLAB中帮助文档的理解,提出我对求解最简单微分方程的方法的总结。以求解一个经典的非线性方程为例。

         做一个最基本的假设:你们都看过高数。

 

一。老湿发话了:童鞋们,求解一下这个方程,判断她是否稳定。要是稳定,那么她是否存在极限环:

一看明白了,这不就是传说中的范德普方程。地球人都知道她稳定并有极限环。现在我们就看看如何用MATLAB求解她的轨迹。

 

二。一般的计算机求解方程的方法无外乎是这样:首先把该方程改写成一个规范的形式,一般使用状态空间表示法;而后调用已有的算法进行求解;最后对得出的结果进行处理,比如画图之类的。接下来就对这三大步分别作出解释。

 

三。输入待求解的方程。

         首先我们知道,状态空间的标准形式(自由系统)是:

这里X是列向量,F是作用于列向量的函数,可以是线性也可以是非线性。范德普方程可以改写成这样的标准形式:

MATLAB中关于输入输入待解方程的语句特别简单。需要先定义一个普通函数,函数名任意,姑且叫做myFcn,格式如下

function xdot = myFcn (t, x)  

 

需要注意的是,函数必须含有t, x两个参数,名称可以自己任意定。xdot是这个函数本身的返回值,只出现在这个函数内部,因此也可以任意定。

定义中的x被视为是一个列向量,x(i)表示列向量中的第i个分量。那么F函数的每一个分量即简单地用表达时给出即可。其中的自变量可以引用x(i)。以范德普方程为例:

 

xdot = [x(2) ; u(1-x(1)^2)*x(2)-x(1)]  

 

于是,这两句话便构成了待解函数。

 

 

四。调用MATLAB函数进行求解

         通常人工求解微分方程需要知道初始值,计算机求解也不例外。另外,由于非线性方程一般只有数值解,故计算精度也可以调整。这些都是可以自己调整的参数。

         调用MATLAB计算求解常微分方程的模式很简单,格式为:

 

[t, x] = ode45(@myFcn, [开始时间 结束时间], [初始值列向量], options)

 

注意到求解出来的结果是[t, x]即一堆数,所以需要我们进行后处理比如画图之类的。

ode45表示了MATLAB中的一种内置计算微分方程的算法,最为常用,出于娱乐目的,就先用这个。

@表示待求解的方程,如myFcn

[开始时间 结束时间]表示求解的时间段,不必定义间隔。

[初始值列向量]就不用多说了。通常在求解之前定义一个变量x0列向量表示初始值,然后输入起来就方便多了。

options本身是一个变量。注意,她的名称不固定,但是他是一个以结构体为类型的变量。options很重要,稍后讨论。

 

五。进行后处理。在得到[t, x]后可以自己用plot神马的进行画图。不过我一般不这样,各位看官不必惊慌。

 

六。options的用法。

         optionsMATLAB帮助中是这样定义格式的:

         options = odeset (“Name”, Value, “Name”, Value, …)

         意思是,options这个变量要用到odeset这个函数来对他进行赋值。而odeset这个函数的参数必须是成对出现的:一个名称对应一个数值。

         我们要用到的是这样的:

 

         options= odeset(“OutputFcn”, @odephas2, “reltol”, 1e-5);

 

注意,odeset中的参数名称不可任意定,因为都是预定义好的。”OutputFcn”使用预定义的函数进行输出,而与定义的函数有好几种,使用@进行选择,我们选odephas2即画相平面图(phase portrait)。之后的那个参数表示相对误差的最大允许值,不说也明白。

         有一个问题,用odephas2画出的图图不好看,因为上面打了好多圈圈。解决办法是找到该文件,修改其中所有的plot语句即可,把那个”-o”去掉就行了。

 

七。就是这个样了。总结一下,求解范德普方程可以用如下语句:

 

首先是函数定义:

function xdot = myFcn (t, x)

xdot = [x(2) ; u(1-x(1)^2)*x(2)-x(1)]

 

其次是主程序:

% Solving options predetermined

options=odeset('OutputFcn',@odephas2,'reltol',1e-5);

% Solving vdp equation withdifferent ini conditions

for a = -3 : 0.1 : 3   

   b1=sqrt(25-a^2);

   b2=-sqrt(25-a^2);

   % Solve the problem

   [t,y]=ode45(@myFcn, [0 20], [a b1], options);

   hold on

   [t,y]=ode45(@myFcn, [0 20] ,[a b2], options);

   hold on    

end

grid on

  • 14
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
MATLAB求解微分方程有多种方法,其中常用的方法包括欧拉法、2阶R-K法、4阶R-K法、预测-校正法(M-S法、A-M法)、有限差分法和隐式法(如Crank-Nicholson方法)。 欧拉法是一种简单的数值近似方法,通过使用一阶导数的信息来估计下一个时间步的解。2阶和4阶R-K法是通过使用不同阶数的导数信息来提高数值解的精度。预测-校正法是一种迭代方法,先预测解的下一个时间步,然后根据校正因子对预测值进行修正。有限差分法是一种将偏微分方程离散化为差分方程的方法,通过求解差分方程来获得数值解。 隐式法(如Crank-Nicholson方法)是一种更稳定和精确的方法,它使用了时间和空间上的平均值来估计下一个时间步的解。 以下是一个MATLAB代码的例子,使用Crank-Nicholson方法求解抛物型偏微分方程: ```matlab % 设置问题的边界条件和初值条件 g_1 = @(t) 0; g_2 = @(t) 0; f = @(x) sin(pi .* x); % 设置网格参数 k = 0.01; % 时间步长 h = 0.1; % 空间步长 t_start = 0; t_end = 0.1; x_start = 0; x_end = 1; % 初始化解向量 u = zeros((t_end-t_start)/k + 1, (x_end-x_start)/h + 1); % 计算系数 r = k/(h^2); n = (x_end-x_start)/h + 1; % 迭代求解 for j = 1:(t_end-t_start)/k + 1 t = (j-1)*k; % 构建线性方程组 Ax = B A = zeros(n-2, n-2); B = zeros(n-2, 1); u(j,1) = g_1(t); u(j,n) = g_2(t); for i = 2:n-1 x = (i-1) * h; if j == 1 u(j,i) = f(x); else B(i-1) = r*u(j-1,i-1) + (2-2*r)*u(j-1,i) + r*u(j-1,i+1); if i == 2 A(i-1,1:2) = [2, 2*r, -r]; B(i-1) = B(i-1) + r*u(j,i-1); elseif i == n - 1 A(i-1,end-1:end) = [-r, 2, 2*r]; B(i-1) = B(i-1) + r*u(j,i+1); else A(i-1,i-2:i) = [-r, 2, 2*r, -r]; end end end % 解线性方程组并更新解向量 if j ~= 1 u(j,2:end-1) = (A\B)'; end end % 绘制数值解的图形 surf(x_start:h:x_end, t_start:k:t_end, u, 'FaceAlpha', 0.5, 'EdgeColor', 'interp') title('Numerical solution of the parabolic PDE') xlabel('Distance x') ylabel('Time t') ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值