Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Cephes/ode/   (Cephes Mathematical Library ©)  Datei vom 12.5.2026 mit Größe 7 kB image not shown  

Quelle  adams3.c

  Sprache: C
 

/* Adams-Bashforth-Moulton integration formulas.
 *
 * Reference:
 * Shampine, L. F. and M. K. Gordon, _Computer Solution of
 * Ordinary Differential Equations_, W. H. Freeman, 1975.
 *
 * Program by Steve Moshier.
 */


#include "int.h"
/* Divided differences */
#define N 19

/*Predictor coefficients*/
double precof[N] = {
1.0,
1.0 / 2.0,
5.0 / 12.0,
3.0 / 8.0,
251.0 / 720.0,
95.0 / 288.0,
19087.0 / 60480.0,
5257.0 / 17280.0,
1070017.0 / 3628800.0,
25713.0 / 89600.0,
26842253.0 / 95800320.0,
4777223.0 / 17418240.0,
703604254357.0 / 2615348736000.0,
106364763817.0 / 402361344000.0,
1166309819657.0 / 4483454976000.0,
2.5221445e7 / 9.8402304e7,
8.092989203533249e15 / 3.201186852864e16,
8.5455477715379e13 / 3.4237292544e14,
1.2600467236042756559e19 / 5.109094217170944e19,
};

/*Corrector coefficients*/
double corcof[N] = {
 1.0,
 -1.0 / 2.0,
 -1.0 / 12.0,
 -1.0 / 24.0,
 -19.0 / 720.0,
 -3.0 / 160.0,
 -863.0 / 60480.0,
 -275.0 / 24192.0,
 -33953.0 / 3628800.0,
 -8183.0 / 1036800.0,
 -3250433.0 / 479001600.0,
 -4671.0 / 788480.0,
 -13695779093.0 / 2615348736000.0,
 -2224234463.0 / 475517952000.0,
 -132282840127.0 / 31384184832000.0,
 -2639651053.0 / 689762304000.0,
 1.11956703448001e14 / 3.201186852864e16,
 5.0188465e7 / 1.5613165568e10,
 2.334028946344463e15 / 7.86014494949376e17,
};

/* Compute zeroth through kth backward differences
 * of the data in the input array
 */

divdif(vec , k, diffn)
double vec[]; /* input array of k+1 data items */
double *diffn; /* output array of ith differences */
int k;
{
double diftbl[N];
double *p, *q;
double y;
int i, o;

/* Copy the given data (zeroth difference) into temp array
 */

p = diftbl;
q = vec;
for( i=0; i<=k; i++ )
 *p++ = *q++;

/* On the first outer loop, k-1 first differences are calculated.
 * These overwrite the original data in the temp array.
 */

o = k;
for( o=k; o>0; o-- )
 {
 p = diftbl;
 q = p;
 for( i=0; i<o; i++ )
  {
  y = *p++;
  *q++ = *p - y;
  }
 *diffn++ = *p; /* copy out the last (undifferenced) item */
#if DEBUG
 printf( "%.5e ", *p );
#endif
 }
#if DEBUG
 printf( "%.5e\n", *(q-1) );
#endif
*diffn++ = *(q-1);
}


/* Update array of differences, given new data value.
 * diffn is an array of k+1 differences, starting with the
 * zeroth difference (the previous original data value).
 */

dupdate( diffn, k, f )
register double *diffn;  /* input and output array of differences */
int k; /* max order of differences */
double f; /* new data point (zeroth difference) */
{
double new, old;
int i;

new = f;
for( i=0; i<k; i++ )
 {
 old = *diffn;
 *diffn++ = new;
#if DEBUG
 printf( "%.5e "new );
#endif
 new = new - old;
 }
#if DEBUG
 printf( "%.5e\n"new );
#endif
*diffn++ = new;
}




/* Evaluate the interpolating polynomial
 *
 *              (x - x )
 *                    n    1
 * P(x) = f  +  --------  D f   +  ...
 *         n       h         n
 *
 *     (x - x )(x - x   )...(x - x     )
 *           n       n-1          n+2-k    k-1
 *  +  ---------------------------------  D    f
 *                   k-1                        n
 *                  h     (k-1)!
 *
 *
 *         j
 *  where D denotes the jth backward difference, see dupdate(), and
 *
 *  f   =   f( x , y(x ) )  is the interpolated derivative y'(x ) .
 *   n          n     n                                        n
 *
 * The subroutine argument t is linearly scaled so that t = 1.0
 * will evaluate the polynomial at x = x_n + h,
 * t = 0.0 corresponds to x = x_n, etc.
 */

double difpol( diffn, k, t )
double *diffn;
int k; /* differences go up to order k-1 */
double t; /* scaled argument */
{
double f, fac, s, u;
int i;

f = *diffn++; /* the zeroth difference = nth data point */
u = 1.0;
/*s = x/h - n;*/
s = 1.0/* to evaluate the polynomial at x = xn + h */
fac = 1.0;
for( i=1; i<k; i++ )
 {
 if( s == 0.0 )
  break;
 u *= s / fac;
 f += u  *  (*diffn++);
 fac += 1.0;
 s += 1.0;
 }
return( f );
}


/* Integrate the interpolating polynomial from x[n] to x[n+1]
 * to obtain the change in the integrated function from y[n] to y[n+1]
 * given by:
 *
 *                     k-1
 *                      -       i
 *  y    =  y   +   h   >   c  D  f    .
 *   n+1     n          -    i     n
 *                     i=0
 *
 *  This subroutine returns the summation term, not multiplied by h.
 *  The coefficients c_i of the integration formula are either
 *  precof[] or corcof[], given above.
 */

double intpol( diffn, coeffs, k )
double *diffn; /* array of backward differences */
double *coeffs; /* coefficients of integration formula */
int k; /* differences used go up to order k-1 */
{
double s;
int i;

s = 0.0;
coeffs += k;
diffn += k;
for( i=0; i<k; i++ )
 {
 s += (*--coeffs) * (*--diffn);
 }
return( s );
}



/* Copy array of n elements from p to q.
 */

vcopy( p, q, n )
register double *p, *q;
register int n;
{
do
 *q++ = *p++;
while( --n );
}


/* Adams initialization program.
 */


/* Addresses within the work array */
static double *dv;
static double *dvp;
static double *vp;
static double *yp;
static double *vn;
static double *delta;
static double *sdelta;
static double *y0;

static double ccor;
static double hstep; /* step size (constant) */
static int order; /* Order of the prediction formula */
static int ordp1;
static int asiz;
static int dsiz;
static int jstep; /* counts steps taken */

/* Initialize pointers in work array, compute derivatives at
 * initial position, and start the difference tables.
 * neq >= nequat in adstep() below.  If neq > nequat, unused space
 * is left for extra variables that are not actually integrated.
 */

adstart( h, yn, work, neq, ord, t )
double h;
double yn[], work[];
int neq, ord;
double t; 
{
double *p;
int j;

hstep = h;
ccor = hstep * precof[ord];
jstep = 0;
dsiz = ord + 2;
asiz = neq * dsiz;
order = ord;
ordp1 = ord + 1;
p = work;
dv = p;
p += asiz;
dvp = p;
p += dsiz;
vp = p;
p += neq;
yp = p;
p += neq;
vn = p;
p += neq;
delta = p;
p += neq;
sdelta = p;
p += neq;
y0 = p;


func( t, yn, vn );

p = dv;
for( j=0; j<neq; j++ )
 {
 dupdate( p, 0, vn[j] );
 p += dsiz;
 }
}





/* Adams-Bashforth-Moulton step.
 */


double adstep( t, yn, nequat )
double *t;
double yn[];
int nequat;
{
double e, e0, time;
double *pdv;
int i, j;
double intpol();

time = *t;
jstep += 1;

/* Do Runge-Kutta for the first ord + 1 steps.
 */

if( jstep <= ordp1 )
 {
 rungek(  nequat, time, yn, hstep, yn, delta );
 func( time+hstep, yn, vn );
 pdv = dv;
 for( j=0; j<nequat; j++ )
  {
  dupdate( pdv, jstep, vn[j] );
  pdv += dsiz;
  }
 e = 0.0;
 goto done;
 }



/* Predict the next position
 * based on current y' difference table dv[].
 */

 pdv = dv;
 for( i=0; i<nequat; i++ )
  {
  yp[i] = yn[i] + hstep * intpol( pdv, precof, order );
  pdv += dsiz;
  }
/* Evaluate derivatives at the predicted position
 */

 func( time+hstep, yp, vp );

/* Correct the predicted position and velocity using the derivatives
 * evalutated at yp.
 */

 pdv = dv;
 for( i=0; i<nequat; i++ )
  {
  vcopy( pdv, dvp, dsiz ); /* y' difference table */
  dupdate( dvp, ordp1, vp[i] );
/* Note, the following line is equivalent to:
 *  yn[i] = yn[i] + hstep * intpol( dap, corcof, ordp1 );
 * where e is the corrected value of the next vn.
 */

  yn[i] = yp[i] + ccor * dvp[order];
  pdv += dsiz;
  }

/* Evaluate derivative at the final position
 */

 func( time+hstep, yn, vn );

 e = 0.0;
 pdv = dv;
 for( i=0; i<nequat; i++ )
  {
  dupdate( pdv, ordp1, vn[i] );
/* Note, the following line is equivalent to:
 *  yn[i] = yn[i] + hstep * intpol( dap, corcof, ordp1 );
 * where e is the corrected value of the next vn.
 */

  yn[i] = yp[i] + ccor * pdv[order];
/* Estimate the error
 */

  e0 = hstep * pdv[order] * corcof[order];
  if( e0 < 0.0 )
   e0 = -e0;
  if( e0 > e )
   e = e0;
  pdv += dsiz;
  }
done:
time += hstep;
*t = time;
return( e );
}

Messung V0.5 in Prozent
C=91 H=74 G=82

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-06-14) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.