全区间积分的定步长欧拉方法(常微分方程组的求解)

11 篇文章 0 订阅

/*
代码作者:不详
代码整理者:设计天下 MySDN网站 算法天下工作室 LS
代号: _MySDN_SFTX_LS
网址:http://www.my-sdn.net

功能:全区间积分的定步长欧拉方法(常微分方程组的求解)

*/

#include "stdio.h"
#include "stdlib.h"
/*全区间积分的定步长欧拉方法*/
/*全区间积分的维梯方法*/
/*全区间积分的定步长龙格-库塔方法*/
typedef struct _fode {
 int        n;      /*微分方程组中方程个数,也是未知函数的个数*/
 int        steps;  /*积分步数(包括起始点这一步)*/
 double     lens;   /*积分的步长*/
 double     t;      /*对微分方程进行积分的起始点 */
 double    *y;      /*存放n个未知函数在起始点t处的函数值*/
 double    *z;      /*返回steps个积分点(包括起始点)上的未知函数值*/
 void     (*ptr)(); /*指向计算微分方程组中各方程右端函数值的函数名(由用户自编)*/
} FODE, *FODEP;

/*全区间积分的变步长默森方法*/
/*全区间积分的双边法*/
/*全区间积分的阿当姆斯预报校正法*/
/*全区间积分的哈明方法*/
typedef struct _fode2 {
 int        n;      /*微分方程组中方程个数,也是未知函数的个数*/
 int        steps;  /*积分步数(包括起始点这一步)*/
 double     lens;   /*积分的步长*/
 double     eps;    /*控制精度要求*/
 double     t;      /*对微分方程进行积分的起始点 */
 double    *y;      /*存放n个未知函数在起始点t处的函数值*/
 double    *z;      /*返回steps个积分点(包括起始点)上的未知函数值*/
 void     (*ptr)(); /*指向计算微分方程组中各方程右端函数值的函数名(由用户自编)*/
} FODE2, *FODE2P;

/*积分一步的特雷纳方法*/
typedef struct _tlode {
 int        n;      /*微分方程组中方程个数,也是未知函数的个数*/
 double     lens;   /*积分的步长*/
 double     t;      /*对微分方程进行积分的起始点 */
 double    *y;      /*存放n个未知函数在起始点t处的函数值。返回t+lens点处的n个未知函数值*/
 void     (*ptr)(); /*指向计算微分方程组中各方程右端函数值的函数名(由用户自编)*/
} TODE, *TODEP;

/*积分一步的变步长欧拉方法*/
/*积分一步的变步长龙格-库塔方法*/
/*积分一步的连分式法*/
typedef struct _eode {
 int        n;      /*微分方程组中方程个数,也是未知函数的个数*/
 double     lens;   /*积分的步长*/
 double     eps;    /*积分的精度要求*/
 double     t;      /*对微分方程进行积分的起始点 */
 double    *y;      /*存放n个未知函数在起始点t处的函数值。返回t+lens点处的n个未知函数值*/
 void     (*ptr)(); /*指向计算微分方程组中各方程右端函数值的函数名(由用户自编)*/
} EODE, *EODEP;

/*积分一步的变步长基尔方法*/
typedef struct _eode2 {
 int        n;      /*微分方程组中方程个数,也是未知函数的个数*/
 double     lens;   /*积分的步长*/
 double     eps;    /*积分的精度要求*/
 double     t;      /*对微分方程进行积分的起始点 */
 double    *y;      /*存放n个未知函数在起始点t处的函数值。返回t+lens点处的n个未知函数值*/
 double    *q;      /*在主函数第一次调用本函数时,应赋值0,
        以后每调用一次函数(即每积分一步),将由本函数的返回值以便循环使用。*/
 void     (*ptr)(); /*指向计算微分方程组中各方程右端函数值的函数名(由用户自编)*/
} EODE2, *EODE2P;

/*二阶微分方程边值问题的数值解法*/
typedef struct _dode {
 int        n;      /*求解区间[a,b]的等分点数(包括左端点a与右端点b)*/
 double     a;      /*求解区间的左端点*/
 double     b;      /*求解区间的右端点求*/
 double     ya;     /*未知函数在求解区间左端点处的函数值y(a)*/
 double     yb;     /*未知函数在求解区间右端点处的函数值y(b)*/
 double    *y;      /*返回n个等距离散点上的未知函数值*/
 void     (*ptr)(); /*指向计算二阶微分方程中函数值的函数名(由用户自编)*/
} DODE, *DODEP;


void euler_step_lis(FODEP ap)
{
 int    n,steps,i,j;
 double x,lens,t,*y,*z,*d;

 n=ap->n;
 steps=ap->steps;
 lens=ap->lens;
 t=ap->t;
 y=ap->y;
 z=ap->z;
 d=malloc(n*sizeof(double));
 for (i=0; i<n; i++)
 {
  z[i*steps]=y[i];
 }
 for (j=1; j<steps; j++)
 {
  x=t+(j-1)*lens;
  (*ap->ptr)(y,d);
  for (i=0; i<n; i++)
  {
   y[i]=z[i*steps+j-1]+lens*d[i];
  }
  x=t+j*lens;
  (*ap->ptr)(y,d);
  for (i=0; i<n; i++)
  {
   d[i]=z[i*steps+j-1]+lens*d[i];
  }
  for (i=0; i<n; i++)  
  {
   y[i]=0.5*(y[i]+d[i]);
   z[i*steps+j]=y[i];
  }
 }
 free(d);/*释放动态分配的内存*/
}
 
void step_ptr_lis(double y[],double d[])
{
 d[0]=2.0*y[1];
 d[1]=-2.0*y[0];
 d[2]=-2.0*y[2];
}
 
int main()
{
 int i,j;
 double y[3] = {-1.5, 0.0, 1.5};
 double z[3][11] = {0};
 FODE   fa = {3, 11, 0.01, 0.0, y, (double*)z, step_ptr_lis};

 euler_step_lis(&fa);
 printf("/n");
 for (i=0; i<fa.steps; i++)
 {
  printf("t=%5.2f/n",i* fa.lens);
  for (j=0; j<fa.n; j++)
  {
   printf("y(%d)=%e  ",j,z[j][i]);
  }
  printf("/n");
 }
 printf("/n");
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值