文章目录
- 龙格库塔法的原理
- 利用四阶龙格库塔法求解一个案例
- 用MATLAB编程
龙格库塔法的原理
在百度百科中是这么解释的:在各种龙格-库塔法当中有一个方法十分常用,以至于经常被称为“RK4”或者就是“龙格-库塔法”。该方法主要是在已知方程导数和初值信息,利用计算机仿真时应用,省去求解微分方程的复杂过程。
令初值问题表述如下。
y ′ = f ( x n , y n ) , y ( x 0 ) = y 0 y^{\prime}= f(x_n,y_n),y(x_0)=y_0 y′=f(xn,yn),y(x0)=y0
则,对于该问题的RK4由如下方程给出:
y n + 1 = y n + h 6 ( k 1 + 2 k 2 + 2 k 3 + k 4 ) y_{n+1}=y_n+\frac h 6(k_1+2k_2+2k_3+k_4) yn+1=yn+6h(k1+2k2+2k3+k4)
其中,
k 1 = f ( x n , y n ) k_1= f(x_n,y_n) k1=f(xn,yn)
k 2 = f ( x n + h 2 , y n + h 2 k 1 ) k_2= f(x_n+{h\over2},y_n+{h\over2}k_1) k2=f(xn+2h,yn+2hk1)
k 3 = f ( x n + h 2 , y n + h 2 k 2 ) k_3= f(x_n+{h\over2},y_n+{h\over2}k_2) k3=f(xn+2h,yn+2hk2)
k 4 = f ( x n + h , y n + h k 3 ) k_4= f(x_n+h,y_n+hk_3) k4=f(xn+h,yn+hk3)
我开始在理解的时候花了挺长时间,毕竟公式很难让人理解,因此我才想把我遇到的困难和理解写下来,帮助大家理解龙格库塔这个方法。
在我看来龙格库塔方法就是改良之后的欧拉法,求解精度更高。就是用已知点和所求点这两个点之间几个点的斜率,加权平均后得出的斜率就为所求点与已知点的斜率。
上图就是我所举的例子,事实上我们只知晓 y ′ y^{\prime} y′,即 k 1 k_1 k1, k 2 k_2 k2, k 3 k_3 k3, k 4 k_4 k4,以及 y 0 y_0 y0。这样我们就可以通过四阶龙格库塔方法进行不断迭代,求出 y 1 , y 2 … y n y_1,y_2 \dots y_n y1,y2…yn。
利用四阶龙格库塔法求解一个案例
如 y ′ = x + x y y^{\prime}=x+xy y′=x+xy这样一个表达式,我们若用正常的数学方法求解或许并不困难。但是一旦表达式变得很复杂, 例如 y ′ = sin ( x ) cos ( y ) + x y y^{\prime}=\sin(x)\cos(y)+xy y′=sin(x)cos(y)+xy这样的微分方程,求解起来就会相当麻烦。因此利用龙格库塔法求解,会使问题变得较简单方便。一般我们使用四阶龙格库塔方程解决问题,这样求解的精度较高,且求解速度较快。
我们举 y = x + x y y=x+xy y=x+xy这样一个简单的微分方程来说明一下,由于 y ′ = f ( x , y ) y^{\prime}=f(x,y) y′=f(x,y),因此 f ( x , y ) = d y d x = x + x y f(x,y)={dy \over dx}=x+xy f(x,y)=dxdy=x+xy,我们需要知道 y ( x 0 ) = y 0 y(x_0)=y_0 y(x0)=y0为多少,在此案例中,我们设 x 0 = 0 x_0=0 x0=0, y ( 0 ) = y 0 = 0 y(0)=y_0=0 y(0)=y0=0,我们设步长 h = 0.1 h=0.1 h=0.1,计算公式如下所示:
k 1 = f ( x 0 , y 0 ) = f ( 0 , 0 ) = 0 + 0 = 0 k_1= f(x_0,y_0)=f(0,0)=0+0=0 k1=f(x0,y0)=f(0,0)=0+0=0
k 2 = f ( x 0 + h 2 , y 0 + k 1 × h 2 ) = f ( 0 + 0.05 , 0 + 0 × 0.05 ) = 0.05 + 0 = 0.05 k_2= f(x_0+\frac h 2,y_0+ k_1 \times{h \over 2})=f(0+0.05,0+0\times0.05)=0.05+0=0.05 k2=f(x0+2h,y0+k1×2h)=f(0+0.05,0+0×0.05)=0.05+0=0.05
k 3 = f ( x 0 + h 2 , y 0 + k 2 × h 2 ) = f ( 0 + 0.05 , 0 + 0.05 × 0.05 ) = 0.05 + 0.05 × 0.0025 = 0.050125 k_3= f(x_0+\frac h 2,y_0+k_2\times{h \over 2})=f(0+0.05,0+0.05\times0.05)=0.05+0.05\times0.0025=0.050125 k3=f(x0+2h,y0+k2×2h)=f(0+0.05,0+0.05×0.05)=0.05+0.05×0.0025=0.050125
k 4 = f ( x 0 + h 2 , y 0 + k 3 × h 2 ) = f ( 0 + 0.1 , 0 + 0.050125 × 0.1 ) = 0.1 + 0.1 × 0.050125 = 0.10050125 k_4= f(x_0+\frac h 2,y_0+k_3\times{h \over 2})=f(0+0.1,0+0.050125\times0.1)=0.1+0.1\times0.050125=0.10050125 k4=f(x0+2h,y0+k3×2h)=f(0+0.1,0+0.050125×0.1)=0.1+0.1×0.050125=0.10050125
y 1 = y 0 + h 6 ( k 1 + 2 k 2 + 2 k 3 + k 4 ) ≈ 0 + 0.1 6 × 0.3008 = 0.0050 y_1=y_0+\frac h 6(k_1+2k_2+2k_3+k_4)\approx0+\frac {0.1}{6} \times 0.3008= 0.0050 y1=y0+6h(k1+2k2+2k3+k4)≈0+60.1×0.3008=0.0050
到此我们已经求出 y 1 = 0.0050 y_1= 0.0050 y1=0.0050,就可把 y 1 y_1 y1带入下一步继续迭代,可是有的同学就会问 x 1 x_1 x1等于多少,由于我们设的步长 h = 0.1 h=0.1 h=0.1,因此 x 1 = x 0 + h = 0.1 x_1=x_0+h=0.1 x1=x0+h=0.1,扩展后则为 x n = x 0 + n h x_n=x_0+nh xn=x0+nh。
我们需要验通过四阶龙格库塔法求解的值准不准确,因此我们用经典的微分方程解法去求解,求解过程如下:
y ′ = d y d x = x + x y y^{\prime}=\frac {dy}{dx}=x+xy y′=dxdy=x+xy
d y d x = x ( 1 + y ) \frac {dy}{dx}=x(1+y) dxdy=x(1+y)
d y 1 + y = x d x \frac {dy}{1+y}=xdx 1+ydy=xdx
两边同时积分
ln ( 1 + y ) = 1 2 x 2 + C \ln{(1+y)}={1\over 2}x^2+C ln(1+y)=21x2+C
y = e 1 2 x 2 + C y=e^{{1\over 2}x^2}+C y=e21x2+C
我们设 x 0 = 0 x_0=0 x0=0时, y 0 = 0 y_0=0 y0=0,因此 C = − 1 C=-1 C=−1,即 y = e 1 2 x 2 − 1 y=e^{{1\over 2}x^2}-1 y=e21x2−1,当 x 1 = 0.1 x_1=0.1 x1=0.1时, y 1 = 0.0050 y_1=0.0050 y1=0.0050。验证后我们发现四阶龙格库塔法的精确度确实很高。
用MATLAB编程
clc,clear;
syms x y %设置符号变量x,y
f(x,y)=x*y+x;
z(x)=exp(1/2*x^2)-1%我们计算得出的方程,用于验算
df=f;
y0=0;%设y0=0
a=0;%设起始点
b=3;%设终点
h=0.1;%设步长
[x1,y1]=FourLongkuta(df,y0,a,b,h);%用四阶龙格库塔法求解
figure
plot(a:h:b,z(a:h:b))
hold on
plot(a:h:b,y1,'r')
legend('原函数','龙格库塔法')
hold off
下面是四阶龙格库塔方法的函数:
function [x1,y1]=FourLongkuta(df,y0,a,b,h)%从左到右依次为已知的导函数,初始函数值,初始横坐标值,终止横坐标值,步长
n=floor((b-a)/h);%求解所需的总步长,floor的用法是取一个小数的最小整数值
y1(1)=y0;%赋值y1(1)=y(t0),且数为双精度,这样以后计算的符号值都会转换成双精度
x1=a:h:b;%设xn的值
for i=1:n%龙格库塔方法进行数值求值 k1=double (df( x1(i),y1(i) ) ) ;%double将符号值转为双精度值可以提高运算速度k2=double (df( x1(i)+h/2,y1(i)+k1*h/2 ) );k3=double (df( x1(i)+h/2,y1(i)+k2*h/2 ) );k4=double (df( x1(i)+h,y1(i)+k3*h ) );y1(i+1)=y1(i)+h*(k1+2*k2+2*k3+k4)/6;
end
end
由图可以看到四阶龙格库塔法的精度很高,几乎覆盖在原函数上。
创作不易,请大家多多支持!