龙格——库塔(Rungekutta)法求解常微分方程

1.龙格库塔法的基本原理

该算法是构建在数学支持的基础之上的。对于一阶精度的拉格朗日中值定理有:

对于微分方程

y'=f(x,y)
y(n+1)=y(n)+h*K1
K1=f(xn,yn)
当用点xn处的斜率近似值K1与右端点xn+1处的斜率K2的算术平均值作为平均斜率K*的近似值,那么就会得到二阶精度的改进拉格朗日中值定理:
y(n+1)=y(n)+[h*( K1+ K2)/2]
K1=f(xn,yn)
K2=f(x(n)+h,y(n)+h*K1)
依次类推,如果在区间[xn,xn+1]内多预估几个点上的斜率值K1、K2、……Km,并用他们的加权平均数作为平均斜率K*的近似值,显然能构造出具有很高精度的高阶计算公式。经数学推导、求解,可以得出四阶龙格-库塔公式,也就是在工程中应用广泛的经典龙格-库塔算法:
y(n+1)=y(n)+h*( K1+ 2*K2 +2*K3+ K4)/6
K1=f(x(n),y(n))
K2=f(x(n)+h/2,y(n)+h*K1/2)
K3=f(x(n)+h/2,y(n)+h*K2/2)
K4=f(x(n)+h,y(n)+h*K3)

注:

通常所说的龙格-库塔法是指四阶而言的,我们可以仿二阶、三阶的情形推导出常用的标准四阶龙格-库塔法公式

2.龙格-库塔(Runge-Kutta)方法


经典四阶法

在各种龙格-库塔法当中有一个方法十分常用,以至于经常被称为“RK4”或者就是“龙格-库塔法”。该方法主要是在已知方程导数和初值信息,利用计算机仿真时应用,省去求解微分方程的复杂过程。 [1]

初值问题表述如下。

image

则,对于该问题的RK4由如下方程给出:

image

其中

image
image
image
image

这样,下一个值(yn+1)由现在的值(yn)加上时间间隔(h)和一个估算的斜率的乘积所决定。该斜率是以下斜率的加权平均:

  • k1是时间段开始时的斜率;

  • k2是时间段中点的斜率,通过欧拉法采用斜率k1来决定y在点tn+h/2的值;

  • k3也是中点的斜率,但是这次采用斜率k2决定y值;

  • k4是时间段终点的斜率,其y值用k3决定。

当四个斜率取平均时,中点的斜率有更大的权值:

image

RK4法是四阶方法,也就是说每步的误差是h,而总积累误差为h阶。

注意上述公式对于标量或者向量函数(y可以是向量)都适用。


显式法

显式龙格-库塔法是上述RK4法的一个推广。它由下式给出 [1]

image

其中

image
image
image
image
image

(注意:上述方程在不同著述中有不同但却等价的定义)。

要给定一个特定的方法,必须提供整数s(级数),以及系数aij(对于1 ≤j<is),bi(对于i= 1, 2, ...,s)和ci(对于i= 2, 3, ...,s)。

龙格库塔法是自洽的,如果

image

如果要求方法的精度为p阶,即截断误差为O(h)的,则还有相应的条件。这些可以从截断误差本身的定义中导出。例如,一个2级2阶方法要求b1+b2= 1,b2c2= 1/2, 以及b2a21= 1/2。

例子

RK4法处于这个框架之内。其表为:

0
1/2 1/2
1/2 0 1/2
1 0 0 1
_ 1/6 1/3 1/3 1/6

然而,最简单的龙格-库塔法是(更早发现的)欧拉方法,其公式为

image

。这是唯一自洽的一级显式龙格库塔方法。相应的表为:

0
_ 1

隐式方法

以上提及的显式龙格库塔法一般来讲不适用于求解刚性方程。这是因为显式龙格库塔方法的稳定区域被局限在一个特定的区域里。显式龙格库塔方法的这种缺陷使得人们开始研究隐式龙格库塔方法,一般而言,隐式龙格库塔方法具有以下形式:

image

其中

image

在显式龙格库塔方法的框架里,定义参数

image

的矩阵是一个下三角矩阵,而隐式龙格库塔方法并没有这个性质,这是两个方法最直观的区别:

image

需要注意的是,与显式龙格库塔方法不同,隐式龙格库塔方法在每一步的计算里需要求解一个线性方程组,这相应的增加了计算的成本。


龙格-库塔法的C语言实现

#include "stdio.h"
#include "stdlib.h" 
void RKT(t,y,n,h,k,z)
int n;              /*微分方程组中方程的个数,也是未知函数的个数*/
int k;              /*积分的步数(包括起始点这一步)*/
double t;           /*积分的起始点t0*/
double h;           /*积分的步长*/
double y[];         /*存放n个未知函数在起始点t处的函数值,返回时,其初值在二维数组z的第零列中*/
double z[];         /*二维数组,体积为n x k.返回k个积分点上的n个未知函数值*/
{    
    extern void Func();             /*声明要求解的微分方程组*/   
    int i,j,l;
    double a[4],*b,*d;
    b=malloc(n*sizeof(double));     /*分配存储空间*/
    if(b == NULL){ 
       printf("内存分配失败\n");
        exit(1);
    }
    d=malloc(n*sizeof(double));     /*分配存储空间*/
    if(d == NULL){
        printf("内存分配失败\n");
        exit(1);
    }   
   /*后面应用RK4公式中用到的系数*/    
   a[0]=h/2.0;
   a[1]=h/2.0;
   a[2]=h; 
   a[3]=h;
   for(i=0; i<=n-1; i++)
         z[i*k]=y[i];                /*将初值赋给数组z的相应位置*/
   for(l=1; l<=k-1; l++){
        Func(y,d);        
        for (i=0; i<=n-1; i++)
            b[i]=y[i];
        for (j=0; j<=2; j++){ 
           for (i=0; i<=n-1; i++){ 
               y[i]=z[i*k+l-1]+a[j]*d[i];
               b[i]=b[i]+a[j+1]*d[i]/3.0;
           }           
           Func(y,d);
        }
        for(i=0; i<=n-1; i++)
          y[i]=b[i]+h*d[i]/6.0;
        for(i=0; i<=n-1; i++)
          z[i*k+l]=y[i];
          t=t+h;
    } 
   free(b);/*释放存储空间*/
   free(d);            /*释放存储空间*/
   return;
}
main(){
    int i,j;
    double t,h,y[3],z[3][11];
    y[0]=-1.0;
    y[1]=0.0;
    y[2]=1.0;
    t=0.0;
    h=0.01;
    RKT(t,y,3,h,11,z);
    printf("\n");
    for (i=0; i<=10; i++){/*打印输出结果*/
        t=i*h;
        printf("t=%5.2f\t   ",t);
        for (j=0; j<=2; j++) 
         printf("y(%d)=%e  ",j,z[j][i]);        printf("\n");
    }
} 
void Func(y,d)double y[],d[];{    
  d[0]=y[1];      /*y0'=y1*/
  d[1]=-y[0];     /*y1'=y0*/
  d[2]=-y[2];     /*y2'=y2*/
  return;
} 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容