使用C语言解常微分方程-C-ODE.docx

上传人:scccc 文档编号:11282498 上传时间:2021-07-20 格式:DOCX 页数:26 大小:312.27KB
返回 下载 相关 举报
使用C语言解常微分方程-C-ODE.docx_第1页
第1页 / 共26页
使用C语言解常微分方程-C-ODE.docx_第2页
第2页 / 共26页
使用C语言解常微分方程-C-ODE.docx_第3页
第3页 / 共26页
使用C语言解常微分方程-C-ODE.docx_第4页
第4页 / 共26页
使用C语言解常微分方程-C-ODE.docx_第5页
第5页 / 共26页
点击查看更多>>
资源描述

《使用C语言解常微分方程-C-ODE.docx》由会员分享,可在线阅读,更多相关《使用C语言解常微分方程-C-ODE.docx(26页珍藏版)》请在三一文库上搜索。

1、如果您需要使用本文档,请点击下载按钮下载!解常微分方程姓名:Vincent年级:2010,学号:1033*,组号:5(小组),4(大组)1. 数值方法:我们的实验目标是解常微分方程,其中包括几类问题。一阶常微分初值问题,高阶常微分初值问题,常微分方程组初值问题,二阶常微分方程边值问题,二阶线性常微分方程边值问题。对待上面的几类问题,我们分别使用不同的方法。 初值问题使用 龙格-库塔 来处理 边值问题用打靶法来处理 线性边值问题有限差分法初值问题我们分别使用 二阶 龙格-库塔 方法 4阶 龙格-库塔 方法来处理一阶常微分方程。理论如下:对于这样一个方程当h很小时,我们用泰勒展开,当我们选择正确的

2、参数 aij,bij之后,就可以近似认为这就是泰勒展开。对于二阶,我们有:其中经过前人的计算机经验,我们有,1 / 26Vincent. Wang 1quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!选择 A=1/2,B=1/2,则 P=1,Q=1,于是又如下形式,这也使休恩方法的表达式。所以我们称其为 龙格(库塔)休恩方法对于4阶龙格方法,我们有类似的想法,我们使用前人经验的出的系数,有如下公式对于高阶微分方程及微分方程组我们用 4阶龙格-库塔方法来解对于一个如下的微分方程组我们可以认为是一个一阶向量微分方程,所以可以用龙格-库塔方法的向量形式解

3、。对于一个高阶的微分方程,形式如下:我们可以构建出一个一阶的微分方程组,令则有2 / 26Vincent. Wang 2quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!所以我们实际只要解一个微分方程组 其中初值为 使用4阶龙格-库塔方法, 使用这个向量形式的龙格-库塔方法我们便可就出方程的数值解。边值问题对于边值问题,我们分为两类 一般的边值问题 线性边值微分方程一般的边值问题,我们是使用打靶法来求解,对于这样一个方程主要思路是,化成初值问题来求解。我们已有3 / 26Vincent. Wang 3quipe de Neutrons Dosimt

4、rie如果您需要使用本文档,请点击下载按钮下载! 这样我们便可求出方程的解。 线性微分方程边值问题对于这样的问题,我们可以使用一个更加高效的方法,有限差分法。对于如下方程 我们对其进行差分这样的话,我们的微分方程可以写成,于是我们得到了个线性方程组4 / 26Vincent. Wang 4quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!这样的话我们求解出x对于上面的矩阵,我们可以分解出两个三角阵,然后回代求解便可。我们用回代法可以直接求解5 / 26Vincent. Wang 5quipe de Neutrons Dosimtrie如果您需要使用

5、本文档,请点击下载按钮下载!至此,我们便求出了目标方程的解2. 流程图 二阶龙格-库塔对于i = 0到M-1;yi+1 = yi + h / 2 * (fun(t, yi) + fun(t + h, yi + h*fun(t, yi);return y; 4阶龙格-库塔对于i = 0到M-1;yi + 1 = yi + h / 6 * (fun(t, yi) + 2 * fun(t + h / 2, yi + h / 2 * fun(t, yi) + 2 * fun(t + h / 2, yi + h / 2 * fun(t + h / 2, yi + h / 2 * fun(t, yi) +

6、fun(t + h, yi+h*fun(t + h / 2, yi + h / 2 * fun(t + h / 2, yi + h / 2 *fun(t, yi);return y; 4阶龙格-库塔解方程组对于k= 0到M-1;对于i= 0到N;fun(t, yk, dy0)对于i= 0到N;tempdyj = ykj + h / 2 * dy0j;fun(t + h / 2, tempdy, dy1);对于i= 0到N;tempdyj = ykj + h / 2 * dy1j;fun(t + h / 2, tempdy, dy2);对于i= 0到N;tempdyj = ykj + h * d

7、y2j;fun(t + h, tempdy, dy3);yk+1i = yki + h / 6 * (dy0i + 2 * dy1i + 2 * dy2i + dy3i);return y; 打靶法当errepsilon6 / 26Vincent. Wang 6quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!y = RKSystem4th( fun, 2, t0, u, tn, M);f0 = yM-10 - b;u1 = y01;y = RKSystem4th( fun, 2, t0, v, tn, M);f1 = yM-10 - b;v1 =

8、 y01;x2= u1 - f0 * (v1-u1)/(f1-f0);u1 = v1;v1 = x2;err = fabs(u1 - v1);return y; 有限差分法对i 从 0到 m;求出,b,r,a,cbi = 2 + h*h*qfun(t);ri = -h*h*rfun(t);ai = -h / 2 * pfun(t) - 1;ci = h / 2 * pfun(t) - 1;r0 = r0 - (-h / 2. )*( pfun(t0+h) - 1.)*alpha;rm - 1 = rm - 1 - (h / 2 * pfun(tn - h) - 1)*beta;求出d,ud0

9、= b0;u0 = c0 / b0;对i 从 1到m - 1di = bi - ai * ui - 1;ui = ci / di;dm - 1 = bm - 1 - am - 1 * um - 2;回代y0 = r0 / d0;对于i 从 到 m;yi = (ri - ai * yi - 1) / di;xm = ym -1;对i 从 m 2到0xi + 1 = yi - ui * xi + 2;x0 = alpha;xM - 1 = beta;return x;3. 代码实现过程查看附件4. 数值例子与分析7 / 26Vincent. Wang 7quipe de Neutrons Dosi

10、mtrie如果您需要使用本文档,请点击下载按钮下载!I. 解下面的方程求t=5时,y的值使用3中代码执行得到My(5) 2阶方法解y(5)4阶方法解2阶方法误差4阶方法误差1017.48396030236717.2874974364310.1973667048670.0009038389302017.33330232997517.2866491508970.0467087324740.0000555533974017.29797386145017.2865970413230.0113802639490.0000034438228017.289403465806 17.286593811875

11、0. 0028098683050. 00000021437416017.28729178163917.2865936108720.0006981841380.000000013372对比发现4阶精度远高于2阶精度当我们细分到一定程度之后,我们发现误差的减小慢慢变小。所以,若需要极高的精度的话会花费大量的计算资源。II. 解下面的方程组我们选择M=1000来细分运用3中代码,我们求解得 III. 解下面高阶微分方程(震动方程)运用3中代码,我们取步长h=0.02, 我们求解得8 / 26Vincent. Wang 8quipe de Neutrons Dosimtrie如果您需要使用本文档,请点

12、击下载按钮下载!画出解y1,y2有,IV. 解洛伦兹方程方程如下,使用不同的初始值,观察差别9 / 26Vincent. Wang 9quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!分别使用初值解查看附件我们查看初始值和结束值。txyzxyz05555.001550.016.2015960.6576426.3873596.20241310.6585266.3877950.029.37401417.4526590.7163959.37497817.45400710.71778349.983.2582763.36921920.608133-7.008

13、305-12.89172411.71253449.993.5494584.58850818.661441-10.450006-18.17170016.66638050.004.3004856.27903317.322649-14.303620-21.25238326.374359我们发现尽管初值仅有很小的区别,但是终值有的巨大的差别(与0.001相比)。初值为画出yz,xz,xy有,10 / 26Vincent. Wang 10quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!11 / 26Vincent. Wang 11quipe de Neut

14、rons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!初值为画出yz,xz,xy有,12 / 26Vincent. Wang 12quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!13 / 26Vincent. Wang 13quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!V. 边值问题我们考虑这样一个方程使用3中代码求解有详细答案参看附件。我们看看几个均分点的值ty(t) 打靶法y(t)差分法0.01.0000001.0000000.11.2392241.2392240.31.703

15、0171.7030170.52.1442612.1442610.72.5609032.5609040.92.9528452.9528451.03.1400003.140000在算法上,打靶法计算量明显高于差分法,但是打靶法具有更高的普适性。在进行,有解析解的方程求解时,发现在步长相同时,差分法具有更高的精度。画出解的图有,Shooting 解法14 / 26Vincent. Wang 14quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!有限差分解法15 / 26Vincent. Wang 15quipe de Neutrons Dosimtrie

16、如果您需要使用本文档,请点击下载按钮下载!End.代码:文件 main_ode.cpp#include #include #include #include ode.h/#include ./array.hvoid free2DArray(double *a, int m)int i;for( i=0; im; i+ )free(ai);free(a);/ y= f(t,y), fun = f(t,y)double fun(double t,double y)return exp(t)/y;16 / 26Vincent. Wang 16quipe de Neutrons Dosimtrie如果

17、您需要使用本文档,请点击下载按钮下载!void funv1(double t,double y,double fv)/ / fv0= y0 + 2.*y1; /fv1=3*y0 + 2.*y1;/ Lotka-Volterra equationfv0= y0 - y0*y1 - 0.1 *y0*y0;fv1= y0*y1 - y1 - 0.05*y1*y1;void funv2(double t,double y,double fv)/ y=x*x+x+1fv0= y1;fv1= 4.*y0 - 4.*t*t - 4.*t - 2.;void funv3(double t, double y,

18、 double fv)fv0 = y1;fv1 = -278.28 / 0.15*y0 + 110.57 / 0.15*y2;fv2 = y3;fv3 = -278.28 / 0.15*y2 + 110.57 / 0.15*y0;void funv4(double t, double y, double fv)fv0 = y1;fv1 = -(t + 1.)*y1 + y0 + (1. - t*t)*exp(-t);double pfun(double t)return -(t+1.);double qfun(double t)return 1.;double rfun(double t)re

19、turn (1. - t*t)*exp(-t);/ -4.*t*t - 4.*t - 2.;void funvLorenz(double t,double yv,double fv)double x=yv0, y=yv1, z=yv2;fv0= 10.*(-x+y);17 / 26Vincent. Wang 17quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!fv1= 28.*x - y - x*z;fv2= -8./3.*z + x*y;int main( int argc, char *argv )int i,M;double a = 0,

20、b = 0;FILE *fp;double t0=0.,y0=2., tn=5., *yv,*yv2, *yMa, *yFD, yv02=2.,1., yvLorenz3=5.,5.,5.; double yv34 = 0., 1., 0., 1. ;/ exact solution: y2 = 2*exp(x)+2/ 1st order ODEM=21;yv = RungeKutta_Heum( fun, t0, y0, tn, M);printf(y(5.)=%16.12f, %16.12f n, yvM-1, fabs(yvM-1-sqrt(2.*exp(5.)+2.);free(yv)

21、;M=21;yv2= RungeKutta4th( fun, t0, y0, tn, M);printf(y(5.)=%16.12f, %16.12f n, yv2M-1, fabs(yv2M-1-sqrt(2.*exp(5.)+2.);free(yv2);/ ODE systemyMa = RKSystem4th( funv1, 2, 0., yv0, 30., 1000);/*yv00 = 21.;yv01 = -9.;yMa = RKSystem4th( funv2, 2, -5., yv0, 5., 3001);*/printf( y130=%f, y230=%f n, yMa9990

22、,yMa9991);/*printf(erry1=%f,erry2=%f, 4. * exp(4.) + 2. * exp(-1.) - yMa990, 6. * exp(4.) - 2.*exp(-1.) - yMa991);printf(erry1=%f,erry2=%f, 31 - yMa30000, 11 - yMa30001);*/free2DArray(yMa,100);yMa = RKSystem4th( funv1, 2, 0., yv0, 30., 1000);fp=fopen(lv.dat,w+);for(i=0;i1000;i+)fprintf(fp,%ft %fn,yM

23、ai0,yMai1);fclose(fp);free2DArray(yMa,1000);18 / 26Vincent. Wang 18quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!yMa = RKSystem4th(funv3, 4, 0., yv3, 0.2, 11);fp = fopen(fv3.dat, w+);for (i = 0; i11; i+)fprintf(fp, %ft %ft %ft %ft %fn,0.02*i, yMai0, yMai1, yMai2, yMai3);fclose(fp);free2DArray(yMa,

24、 11);/ Lorenz equM = 1001;yMa = RKSystem4th( funvLorenz, 3, 0., yvLorenz, 50., M);fp = fopen(Lorenz01.dat,w+);for(i=0;iM;i+)fprintf(fp,%ft %ft %fn, yMai0,yMai1,yMai2);fclose(fp);M = 1001;yvLorenz0 = 5.001;yMa = RKSystem4th(funvLorenz, 3, 0., yvLorenz, 50., M);fp = fopen(Lorenz02.dat, w+);for (i = 0;

25、 iM; i+)fprintf(fp, %ft %ft %fn, yMai0, yMai1, yMai2);fclose(fp);/ high order ODE/ BVPM = 101;t0 = 0.;tn = 1.;a = 1.;b = 3.14;yMa = BVP_Shooting(funv4, t0, a, tn, b, M);fp=fopen(Shoot.dat,w+);for(i=0;iM;i+)fprintf(fp, %ft %fn, t0 + (tn - t0) / (M-1) *i, yMai0);fclose(fp);free2DArray(yMa,M);/BVP FDM

26、= 101;t0 = 0.;tn = 1.;a = 1.;b = 3.14;19 / 26Vincent. Wang 19quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!yFD = BVP_FD(pfun, qfun, rfun, t0, a, tn, b, M);fp = fopen(yFD.dat, w+);for (i = 0; iM; i+)fprintf(fp, %ft %fn, t0 +(tn-t0)/(M-1)*i, yFDi);fclose(fp);free(yFD);return 0;文件ode.cpp#include #inc

27、lude ode.h#include #include /#include ./array.hdouble* RungeKutta_Heum( double fun(double,double), double t0, double y0, double tn, int M)/y(t+h)=y(t)+h/2*(f(t,y)+f(t+h,y+hf(t,y)double h = (tn - t0) / (M-1);double t = t0;/double y100 = 0 ;double *y;y = (double *)malloc(M * sizeof(double);int i = 0;y

28、0 = y0;for (i = 0; i M-1; i+)yi+1 = yi + h / 2 * (fun(t, yi) + fun(t + h, yi + h*fun(t, yi);t = t + h;return y;/* double* RungeKutta_EulerCauchy( double fun(double,double), double a, double b, double y0, int M) */double* RungeKutta4th( double fun(double,double), double t0, double y0, double tn, int

29、M)20 / 26Vincent. Wang 20quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!double h = (tn - t0) / (M - 1);double t = t0;/double y100 = 0 ;double *y;y = (double *)malloc(M * sizeof(double);int i = 0;y0 = y0;for (i = 0; i M-1; i+)yi + 1 = yi + h / 6 * (fun(t, yi) + 2 * fun(t + h / 2, yi + h / 2 * fun(t,

30、 yi) + 2 * fun(t + h / 2, yi + h / 2 * fun(t + h / 2, yi + h / 2 * fun(t, yi) +fun(t + h, yi+h*fun(t + h / 2, yi + h / 2 * fun(t + h / 2, yi + h / 2 * fun(t, yi);t = t + h;return y;double* RKSystem4th( void fun(double,double,double ), int N, double t0, double y00,double tn, int M)double h = (tn - t0

31、) / (M - 1);double t = t0;/double y100 = 0 ;double *y;double *dy;double *tempdy;y = (double *)malloc(M * sizeof(double*);dy = (double *)malloc(4 * sizeof(double*);tempdy = (double *)malloc(N*sizeof(double);int i = 0, j = 0, k = 0;for (i = 0; i M; i+)yi = (double *)malloc(N * sizeof(double);for (i =

32、0; i 4; i+)dyi = (double *)malloc(N*sizeof(double);for (i = 0; i N; i+)y0i = y00i;21 / 26Vincent. Wang 21quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!for (k = 0; k M-1; k+)for (i = 0; i N; i+)fun(t, yk, dy0);for (j = 0; j N; j+)tempdyj = ykj + h / 2 * dy0j;fun(t + h / 2, tempdy, dy1);for (j = 0;

33、j N; j+)tempdyj = ykj + h / 2 * dy1j;fun(t + h / 2, tempdy, dy2);for (j = 0; j epsilon);return y;/*double* BVP_FD( double pfun(double), double qfun(double), double rfun(double), double t00,double alpha, double tn,double beta, int m )/y=p(t)y+q(t)y+r(t)int i = 0;int M = m - 2;double h = (tn - t00) /

34、(M+1);double t0 = t00 + h;double t = t0;/(-h/2*pj-1)*xj-1+(2+h*h*qj)*xj+(h/2*pj-1)*xj+1=-h*h*rj;double *a, *b, *c, *d, *u, *r, *y, *x; /double *l;a = (double *)malloc(M - 1) * sizeof(double);b = (double *)malloc(M * sizeof(double);c = (double *)malloc(M - 1) * sizeof(double);/l = (double *)malloc(M

35、- 1) * sizeof(double);d = (double *)malloc(M * sizeof(double);u = (double *)malloc(M - 1) * sizeof(double);r = (double *)malloc(M * sizeof(double);y = (double *)malloc(M * sizeof(double);x = (double *)malloc(M * sizeof(double);t = t0;for(i = 0; i M; i+)bi = -2. - h * h *qfun(t);ri =h * h * rfun(t);t

36、 = t + h;r0 = r0 - (h/2. * pfun(t0) + 1.) * alpha;/r0 = 1.0855;rM - 1 = rM - 1 - (1. - h/2. * pfun(tn) * beta;t = t0;for (i = 0; i M - 1; i+)ai = 1. + h / 2. * pfun(t + h);ci = 1. - h / 2. * pfun(t);/li = ai;t = t + h;23 / 26Vincent. Wang 23quipe de Neutrons Dosimtrie如果您需要使用本文档,请点击下载按钮下载!d0 = b0;u0 = c0 / b0;for (i = 0; i M - 2; i+)di + 1 = bi + 1 - ai * ui;if (0 = di + 1)printf(error!n);return 0;ui + 1 = ci + 1 / di + 1;dM - 1 =bM - 1-aM - 2 * uM - 2;/回代y0 = r0 / d0;for (i = 1; i = 0; i-)xi = yi - ui * yi + 1;return x;*/double* BVP_FD(double pfun(double), double qfun(double), double r

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1