ImageVerifierCode 换一换
格式:DOCX , 页数:37 ,大小:331.46KB ,
资源ID:9588759      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9588759.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(使用C语言解常微分方程 C ODE.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

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

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

2、之后,就可以近似认为这就是泰勒展开。对于二阶,我们有:其中经过前人的计算机经验,我们有,选择 A=1/2,B=1/2,则 P=1,Q=1,于是又如下形式,这也使休恩方法的表达式。所以我们称其为 龙格(库塔)休恩方法对于4阶龙格方法,我们有类似的想法,我们使用前人经验的出的系数,有如下公式对于高阶微分方程及微分方程组我们用4阶龙格-库塔方法来解对于一个如下的微分方程组我们可以认为是一个一阶向量微分方程,所以可以用龙格-库塔方法的向量形式解。对于一个高阶的微分方程,形式如下:我们可以构建出一个一阶的微分方程组,令则有所以我们实际只要解一个微分方程组 其中初值为 使用4阶龙格-库塔方法, 使用这个向

3、量形式的龙格-库塔方法我们便可就出方程的数值解。边值问题对于边值问题,我们分为两类一般的边值问题线性边值微分方程一般的边值问题,我们是使用打靶法来求解,对于这样一个方程主要思路是,化成初值问题来求解。我们已有 这样我们便可求出方程的解。线性微分方程边值问题对于这样的问题,我们可以使用一个更加高效的方法,有限差分法。对于如下方程 我们对其进行差分这样的话,我们的微分方程可以写成,于是我们得到了个线性方程组这样的话我们求解出x对于上面的矩阵,我们可以分解出两个三角阵,然后回代求解便可。我们用回代法可以直接求解至此,我们便求出了目标方程的解2.流程图二阶龙格-库塔对于i = 0到M-1; yi+1

4、= 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) +fun(t + h, yi+h*fun(t + h / 2, yi + h / 2 * fun(t + h / 2, yi

5、 + 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 * dy2j; fun(t + h, tempdy, dy3); yk+1i = yki + h / 6 *

6、(dy0i + 2 * dy1i + 2 * dy2i + dy3i); return y;打靶法当errepsilon 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 = y01; x2= u1 - f0 * (v1-u1)/(f1-f0); u1 = v1; v1 = x2; err = fabs(u1 - v1); return y;有限差分法对i 从 0到 m;求出,b,r,a,c bi

7、 = 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 = b0; u0 = c0 / b0;对i 从 1到m - 1 di = bi - ai * ui - 1; ui = ci / di;dm - 1 = bm - 1 - am - 1 * um - 2;回代

8、y0 = r0 / d0;对于i 从 到 m; yi = (ri - ai * yi - 1) / di;xm = ym -1;对i 从 m 2到0 xi + 1 = yi - ui * xi + 2; x0 = alpha;xM - 1 = beta;return x; 3.代码实现过程查看附件4.数值例子与分析I.解下面的方程求t=5时,y的值 使用3中代码执行得到My(5) 2阶方法解y(5)4阶方法解2阶方法误差4阶方法误差1017.48396030236717.2874974364310.1973667048670.0009038389302017.33330232997517.28

9、66491508970.0467087324740.0000555533974017.29797386145017.2865970413230.0113802639490.0000034438228017.289403465806 17.286593811875 0. 0028098683050. 00000021437416017.28729178163917.2865936108720.0006981841380.000000013372对比发现4阶精度远高于2阶精度当我们细分到一定程度之后,我们发现误差的减小慢慢变小。所以,若需要极高的精度的话会花费大量的计算资源。II.解下面的方程组我

10、们选择M=1000来细分运用3中代码,我们求解得 III.解下面高阶微分方程(震动方程)运用3中代码,我们取步长h=0.02, 我们求解得画出解y1,y2有,IV.解洛伦兹方程方程如下,使用不同的初始值,观察差别分别使用初值解查看附件我们查看初始值和结束值。txyzxyz05555.001550.016.2015960.6576426.3873596.20241310.6585266.3877950.029.37401417.4526590.7163959.37497817.45400710.71778349.983.2582763.36921920.608133-7.008305-12.89

11、172411.71253449.993.5494584.58850818.661441-10.450006-18.17170016.66638050.004.3004856.27903317.322649-14.303620-21.25238326.374359我们发现尽管初值仅有很小的区别,但是终值有的巨大的差别(与0.001相比)。初值为画出yz,xz,xy有,初值为画出yz,xz,xy有,V.边值问题我们考虑这样一个方程使用3中代码求解有详细答案参看附件。我们看看几个均分点的值ty(t) 打靶法y(t)差分法0.01.0000001.0000000.11.2392241.2392240.

12、31.7030171.7030170.52.1442612.1442610.72.5609032.5609040.92.9528452.9528451.03.1400003.140000在算法上,打靶法计算量明显高于差分法,但是打靶法具有更高的普适性。在进行,有解析解的方程求解时,发现在步长相同时,差分法具有更高的精度。画出解的图有,Shooting 解法 有限差分解法End.代码:文件 main_ode.cpp#include #include #include #include ode.h/#include ./array.hvoid free2DArray(double *a, int

13、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;void funv1(double t,double y,double fv) / / fv0= y0 + 2.*y1; /fv1=3*y0 + 2.*y1; / Lotka-Volterra equation fv0= y0 - y0*y1 - 0.1 *y0*y0; fv1= y0*y1 - y1 - 0.05*y1*y1;void funv2(double

14、 t,double y,double fv) / y=x*x+x+1 fv0= y1; fv1= 4.*y0 - 4.*t*t - 4.*t - 2.;void funv3(double t, double y, 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 + y

15、0 + (1. - t*t)*exp(-t);double pfun(double t) return -(t+1.);double qfun(double t) return 1.;double rfun(double t) return (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); fv1= 28.*x - y - x*z; fv2= -8./3.*z + x*y;int m

16、ain( int argc, char *argv ) int i,M; double a = 0, 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 ODE M=21; yv = RungeKutta_Heum( fun, t0, y0, tn, M); printf(y(5.)=%16.12f,

17、 %16.12f n, yvM-1, fabs(yvM-1-sqrt(2.*exp(5.)+2.); free(yv); 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 system yMa = RKSystem4th( funv1, 2, 0., yv0, 30., 1000);/* yv00 = 21.; yv01 = -9.; yMa = RKSystem4th(

18、 funv2, 2, -5., yv0, 5., 3001);*/ printf( y130=%f, y230=%f n, yMa9990,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., y

19、v0, 30., 1000); fp=fopen(lv.dat,w+); for(i=0;i1000;i+) fprintf(fp,%ft %fn,yMai0,yMai1); fclose(fp); free2DArray(yMa,1000); 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); fre

20、e2DArray(yMa, 11); / Lorenz equ M = 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(Loren

21、z02.dat, w+); for (i = 0; iM; i+) fprintf(fp, %ft %ft %fn, yMai0, yMai1, yMai2); fclose(fp); / high order ODE / BVP M = 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);

22、fclose(fp); free2DArray(yMa,M); /BVP FD M = 101; t0 = 0.; tn = 1.; a = 1.; b = 3.14; 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 #include ode.h#include

23、 #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; y0 = y0; fo

24、r (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 M) dou

25、ble 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, yi) + 2 * fun(t + h / 2, yi + h / 2 * fun(t + h / 2, yi + h / 2 * f

26、un(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) / (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 =

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1