#

常微分方程数值解法


微分方程数值解

核心思想:用差分代替微分

常微分方程

eg1:$$\begin{equation}
\begin{cases}
y’=y-\frac{2x}{y}, 0<x<1 \\
y\left( 0 \right) =1 \
\end{cases}
\end{equation}$$

欧拉法

迭代方程:

yn+1=yn+hf(xn,yn)y_{n+1}=y_n+hf\left( x_n,y_n \right)

将例题1微分方程转化为迭代方程:

yn+1=yn+h(yn2xnyn)y_{n+1}=y_n+h\left( y_n-\frac{2x_n}{y_n} \right)

function yn1=myfun(xn,yn,h)
yn1=yn+h*(yn-2*xn/yn);
end

直接一个循环就出来了:

clc;clear;
yn=1;%设置初值
xn=0;%设置起点
Xs=1;%设置终点
h=0.1;%设置步长
x(1)=xn;y(1)=yn;%用于存储变量与函数值
i=1;
while xn<Xs             %当xn达到研究区间上限结束
    yn=myfun(xn,yn,h);
    xn=xn+h;
    i=i+1;
    x(i)=xn;y(i)=yn;
end
plot(x,y,x,sqrt(1+2*x));
xlabel('自变量x')
ylabel('函数值y')
legend('欧拉法','实际值');
figure;
plot(x,y-sqrt(1+2*x))
legend('误差值')

结果如下:

改进欧拉法

改进欧拉法实则首先用欧拉法进行预测估计:

yˉn+1=yn+hf(xn,yn)\bar{y}_{n+1}=y_n+hf\left( x_n,y_n \right)

再利用梯形公式估计:

yn+1=yn+h2[f(xn,yn)+f(xn+1,yˉn+1)]y_{n+1}=y_n+\frac{h}{2}\left[ f\left( x_n,y_n \right) +f\left( x_{n+1},\bar{y}_{n+1} \right) \right]

转化为平均化形式:

{yp=yn+hf(xn,yn)yc=yn+hf(xn+1,yp)yn+1=12(yp+yc)\begin{cases} y_p=y_n+hf\left( x_n,y_n \right)\\ y_c=y_n+hf\left( x_{n+1},y_p \right)\\ y_{n+1}=\frac{1}{2}\left( y_p+y_c \right)\\ \end{cases}

相比于欧拉法只是迭代方程产生区别:

function yn1=myfun(xn,yn,h)
yp=yn+h*(yn-2*xn/yn);
yc=yn+h*(yn-2*(xn+h)/yp);
yn1=1/2*(yp+yc);
end


可以看出确实改善了求解精度

显式R-K方法

R-K方法是对欧拉方法的推广,只是将:

Δy=yn+1yn=xnxn+1f(x,y(x))dxhi=1rcif(xn+λih,y(xn+λih))\varDelta y=y_{n+1}-y_n=\int_{x_n}^{x_{n+1}}{f\left( x,y\left( x \right) \right) dx}\approx h\sum_{i=1}^r{c_if\left( x_n+\lambda _ih,y\left( x_n+\lambda _ih \right) \right)}

积分的精度调高了,为了保证精度和减少计算,一般采用四阶龙格库塔法,通过待定系数可以求出四阶R-K方程模型:

{yn+1=yn+h6(K1+2K2+2K3+K4)K1=f(xn,yn)K2=f(xn+h2,yn+h2K1)K3=f(xn+h2,yn+h2K2)K4=f(xn+h,yn+hK3)\begin{cases} y_{n+1}=y_n+\frac{h}{6}\left( K_1+2K_2+2K_3+K_4 \right)\\ K_1=f\left( x_n,y_n \right)\\ K_2=f\left( x_n+\frac{h}{2},y_n+\frac{h}{2}K_1 \right)\\ K_3=f\left( x_n+\frac{h}{2},y_n+\frac{h}{2}K_2 \right)\\ K_4=f\left( x_n+h,y_n+hK_3 \right)\\ \end{cases}

注意:R-K法是基于泰勒展开的方法,要求解具有较好的光滑性质,如果解得光滑性差,使用四阶龙格库塔求得的结果效果反而不如改进的欧拉方法,建模时需要对不同问题进行判断使用

结果:

其截断误差是:

o(h5)o(h^5)

刚性方程组

eg2:

{u=1000.25u+999.75v+0.5v=999.75u1000.25v+0.5u(0)=1v(0)=1\begin{cases} u'=-1000.25u+999.75v+0.5\\ v'=999.75u-1000.25v+0.5\\ u\left( 0 \right) =1\\ v\left( 0 \right) =-1\\ \end{cases}

利用龙格库塔求出结果:

我针对特殊情况总结了一下流程:

首先对方程组进行降阶处理转化为一阶n元微分方程组:

{y1=f1(x,y1,y2yN)y2=f2(x,y1,y2yN)yN=fN(x,y1,y2yN)y1(x0)=a1y2(x0)=a2yN(x0)=aN\begin{cases} y_{1}^{'}=f_1\left( x,y_1,y_2\cdots y_N \right)\\ y_{2}^{'}=f_2\left( x,y_1,y_2\cdots y_N \right)\\ \vdots\\ y_{N}^{'}=f_N\left( x,y_1,y_2\cdots y_N \right)\\ y_1\left( x_0 \right) =a_1\\ y_2\left( x_0 \right) =a_2\\ \vdots\\ y_N\left( x_0 \right) =a_N\\ \end{cases}

其次根据R-K公式得到:

{yn+11=yn1+h6(K11+2K21+2K31+K41)yn+12=yn2+h6(K12+2K22+2K32+K42)yn+1N=ynN+h6(K1N+2K2N+2K3N+K4N)\begin{cases} y_{n+1}^{1}=y_{n}^{1}+\frac{h}{6}\left( K_{1}^{1}+2K_{2}^{1}+2K_{3}^{1}+K_{4}^{1} \right)\\ y_{n+1}^{2}=y_{n}^{2}+\frac{h}{6}\left( K_{1}^{2}+2K_{2}^{2}+2K_{3}^{2}+K_{4}^{2} \right)\\ \vdots\\ y_{n+1}^{N}=y_{n}^{N}+\frac{h}{6}\left( K_{1}^{N}+2K_{2}^{N}+2K_{3}^{N}+K_{4}^{N} \right)\\ \end{cases}

其中:

{K1i=fi(x,y1,y2yN)K2i=fi(x+h2,y1+h2K11,y2+h2K12,,yN+h2K1N)K3i=fi(x+h2,y1+h2K21,y2+h2K22,,yN+h2K2N)K4i=fi(x+h,y1+hK31,y2+hK32,,yN+hK3N)\begin{cases} K_{1}^{i}=f_i\left( x,y_1,y_2\cdots y_N \right)\\ K_{2}^{i}=f_i\left( x+\frac{h}{2},y_1+\frac{h}{2}K_{1}^{1},y_2+\frac{h}{2}K_{1}^{2},\cdots ,y_N+\frac{h}{2}K_{1}^{N} \right)\\ K_{3}^{i}=f_i\left( x+\frac{h}{2},y_1+\frac{h}{2}K_{2}^{1},y_2+\frac{h}{2}K_{2}^{2},\cdots ,y_N+\frac{h}{2}K_{2}^{N} \right)\\ K_{4}^{i}=f_i\left( x+h,y_1+hK_{3}^{1},y_2+hK_{3}^{2},\cdots ,y_N+hK_{3}^{N} \right)\\ \end{cases}

即可


文章作者: 王胜鹏
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 王胜鹏 !
评论
 上一篇
偏微分方程数值方法 偏微分方程数值方法
偏微分方程数值解 工具箱使用 步骤如下: 画区域,Draw或者直接在菜单栏上找,(画圆时,需要按住 Ctrl) 设置边界条件,Boundary进入边界模式,按住shift选择边界进行设置 设置方程:PDE Specification 网格
2020-08-01
下一篇 
混沌优化算法 混沌优化算法
混沌优化算法 基于Logistic映射产生混沌运动轨道的遍历性,可将其混沌用于函数优化问题: 混沌优化算法的基本思想是将变量从混沌空间变换到解空间,然后利用混沌变量所具有的丰富的非线性动力学特征————随机性、遍历性、规律性的特点进行搜索。
2020-07-18
  目录