词条 | 龙格库塔 |
释义 | 龙格库塔法的c++编程龙格库塔法的c++编程 CODE: #include<stdlib.h> #include<stdio.h> /*n表示几等分,n+1表示他输出的个数*/ int RungeKutta(double y0,double a,double b,int n,double *x,double *y,int style,double (*function)(double,double)) { double h=(b-a)/n,k1,k2,k3,k4; int i; // x=(double*)malloc((n+1)*sizeof(double)); // y=(double*)malloc((n+1)*sizeof(double)); x[0]=a; y[0]=y0; switch(style) { case 2: for(i=0;i<n;i++) { x[i+1]=x[i]+h; k1=function(x[i],y[i]); k2=function(x[i]+h/2,y[i]+h*k1/2); y[i+1]=y[i]+h*k2; } break; case 3: for(i=0;i<n;i++) { x[i+1]=x[i]+h; k1=function(x[i],y[i]); k2=function(x[i]+h/2,y[i]+h*k1/2); k3=function(x[i]+h,y[i]-h*k1+2*h*k2); y[i+1]=y[i]+h*(k1+4*k2+k3)/6; } break; case 4: for(i=0;i<n;i++) { x[i+1]=x[i]+h; k1=function(x[i],y[i]); k2=function(x[i]+h/2,y[i]+h*k1/2); k3=function(x[i]+h/2,y[i]+h*k2/2); k4=function(x[i]+h,y[i]+h*k3); y[i+1]=y[i]+h*(k1+2*k2+2*k3+k4)/6; } break; default: return 0; } return 1; } double function(double x,double y) { return y-2*x/y; } //例子求y'=y-2*x/y(0<x<1);y0=1; /* int main() { double x[6],y[6]; printf("用二阶龙格-库塔方法\"); RungeKutta(1,0,1,5,x,y,2,function); for(int i=0;i<6;i++) printf("x[%d]=%f,y[%d]=%f\",i,x[i],i,y[i]); printf("用三阶龙格-库塔方法\"); RungeKutta(1,0,1,5,x,y,3,function); for(i=0;i<6;i++) printf("x[%d]=%f,y[%d]=%f\",i,x[i],i,y[i]); printf("用四阶龙格-库塔方法\"); RungeKutta(1,0,1,5,x,y,4,function); for(i=0;i<6;i++) printf("x[%d]=%f,y[%d]=%f\",i,x[i],i,y[i]); return 1; 龙格库塔求解微分方程数值解工程中很多的地方用到龙格库塔求解微分方程的数值解, 龙格库塔是很重要的一种方法,尤其是四阶的,精确度相当的高。 此代码只是演示求一个微分方程 /*y'=y-2x/y,x∈[0,0.6] /*y(0)=1 的解,要求解其它的微分方程,可以自己定义借口函数,替换程序里面的函数: float f(float , float)即可; CODE: /* /*编程者: /*完成日期:XXXX,XX,XX /*e.g:y'=y-2x/y,x∈[0,0.6] /* y(0)=1 /*使用经典四阶龙格-库塔算法进行高精度求解 /* y(i+1)=yi+( K1+ 2*K2 +2*K3+ K4)/6 /* K1=h*f(xi,yi) /* K2=h*f(xi+h/2,yi+K1/2) /* K3=h*f(xi+h/2,yi+K2/2) /* K4=h*f(xi+h,yi+K3) */ #include <stdio.h> #include <math.h> float f(float den,float p0) //要求解的微分方程的右部的函数 e.g: y-2x/y { float rus; // den=w/(W0+sl); // rus=k*A*f/Wp*sqrt(RTp)-(k-1)*..... rus=p0-2*den/p0; return(rus); } //float fden() //{ //} void main() { float x0; //范围上限 int x1; //范围下限 float h; //步长 int n; //计算出的点的个数 float k1,k2,k3,k4; float y[3]; //用于存放计算出的常微分方程数值解 int i=0; int j; //以下为函数的接口 printf("intput x0:"); scanf("%f",&x0); printf("input x1:"); scanf("%f",&x1); printf("input y[0]:"); scanf("%f",&y[0]); printf("input h:"); scanf("%f",&h); // 以下为核心程序 n=((x1-x0)/h); n=3; for(j=0;j<n;j++) { k1=h*f(x0,y[i]); //求K1 k2=h*f((x0+h/2),(y[i]+k1/2)); //求K2 k3=h*f((x0+h/2),(y[i]+k2/2)); //求K3 k4=h*f((x0+h),(y[i]+k3)); //求K4 y[i+1]=y[i]+((k1+2*k2+2*k3+k4)/6); //求yi+1 x0+=float(0.2); printf("y[%f]=%f\",x0,y[i+1]); ++i; } } 定义 龙格-库塔(Runge-Kutta)方法是一种在工程上应用广泛的高精度单步算法。由于此算法精度高,采取措施对误差进行抑制,所以其实现原理也较复杂。该算法是构建在数学支持的基础之上的。 公式对于一阶精度的欧拉公式有: yi+1=yi+h*K1 K1=f(xi,yi) 当用点xi处的斜率近似值K1与右端点xi+1处的斜率K2的算术平均值作为平均斜率K*的近似值,那么就会得到二阶精度的改进欧拉公式: yi+1=yi+h*( K1+ K2)/2 K1=f(xi,yi) K2=f(xi+h,yi+h*K1) 依次类推,如果在区间[xi,xi+1]内多预估几个点上的斜率值K1、K2、……Km,并用他们的加权平均数作为平均斜率K*的近似值,显然能构造出具有很高精度的高阶计算公式。经数学推导、求解,可以得出四阶龙格-库塔公式,也就是在工程中应用广泛的经典龙格-库塔算法: yi+1=yi+h*( K1+ 2*K2 +2*K3+ K4)/6 K1=f(xi,yi) K2=f(xi+h/2,yi+h*K1/2) K3=f(xi+h/2,yi+h*K2/2) K4=f(xi+h,yi+h*K3) 龙格-库塔(Runge-Kutta)法到目前为止,我们已经学习了多步法,例如:亚当斯-巴什福思(Adams -Bashorth)法,亚当斯-莫尔顿(Adams-Monlton)法,都是常微分方程的积分 方法。它们需要在每一次迭代时重新计算一遍等式右边的结果(非线性隐含问 题忽略计算多个 f (ω)值的可能性) 龙格-库塔(Runge-Kutta)法是一种不同的处理,作为多级方法为人们所知。 它要求对于一个简单的校正计算多个 f 的值。 下面,我们列出了 3 种最流行的龙格-库塔(Runge-Kutta)法: 改进的欧拉方法(精度:p=2): V a = V n + Δtf (V n,tn) 2 Δt)二阶格式 V n+1 = V n +Δtf (V a,tn + 2 Hevn’s 方法(p=2): 这是另一种二阶格式: V a = V n +Δtf (V n,tn) V n = V n + +1 Δt[ f (V n,tn) + f (V a,tn +Δt)] 2 注意: f (Vn,tn)在运算中应该只被计算一次。 四次龙格-库塔(Runge-Kutta)法(p=4): 这是一个 4 阶格式。这次我们写的形式有点不同: a = Δtf (V n,tn) b = Δtf (V n + 1 a,tn + 1 2 2 Δt) c = Δtf (V n + 1 b,tn + Δt) 1 2 2 d = Δtf (V n + c,tn +Δt) V n =V n + +1 1 (a +2b +2c +d)。 6 龙格库塔法的c++编程 |
随便看 |
百科全书收录4421916条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。