Sindbad~EG File Manager

Current Path : /usr/home/beeson/Otter-Lambda/yyy/trigcalc/
Upload File :
Current File : /usr/home/beeson/Otter-Lambda/yyy/trigcalc/numint.c

/* Numerical integration of a function of one variable using
Runge-Kutta solver rk4 similar to the one in Numerical Recipes */
/* M. Beeson, for MathXpert */
/* code last modified 12.20.95
   1.29.98, TRIGCALC_DLL etc.
   3.25.01  changed hmin in numint to be nonzero
            and changed TINY  to 1.0e-10 instead of 1.0e-30
*/


#include <string.h>
#include <assert.h>
#include <math.h>
#define TRIGCALC_DLL
#include "globals.h"
#include "numint.h"
#include "ode.h"
#include "userint.h"
#include "symbols.h"
#include "errbuf.h"

#define EPS 1.0e-6
#define FIRSTSTEP 1.0e-6
#define MAXSTP 10000
#define _TINY 1.0e-10  

/*_______________________________________________________________________*/
/* This function is like odeint (in ode.c) but does not draw the solution,
and nvar is 1 */

int odeint2(double ystart, /*  the initial value */
            double x1,    /* starting value of independent variable */
            double x2,    /* ending value of independent variable */
            double eps,   /* accuracy desired */
            double h1,    /* guessed first stepsize */
            double hmin,  /* minimum allowed stepsize (can be zero) */
            int *nok,    /* number of good steps taken */
            int *nbad,   /* number of bad, but retried and fixed, steps */
            term *f,
            double *xptr,   /* pointer to value of independent variable */
            double *yptr,  /* pointer to value of dependent variable */
            double xtol,
            double ytol
           )
{ int nstp;
  double x,hnext,hdid,h;
  double *yscal,*y,*dydx;
  double y1,yscal1,dydx1;
  yscal= &yscal1-1;
  y= &y1-1;
  dydx= &dydx1-1;
  x=x1;
  h=(x2 > x1) ? fabs(h1) : -fabs(h1);
  *nok = (*nbad) = 0;
  y[1]=ystart;
  for (nstp=1;nstp<=MAXSTP;nstp++)
     { derivs(f,1,x,y,dydx,xptr,&yptr-1);
       yscal[1]=fabs(y[1])+fabs(dydx[1]*h)+_TINY;
/*
       if ((nstp & 0x000f) == 0 && user_interrupt())
          return 5;  user interrupt
*/
       if ((x+h-x2)*(x+h-x1) > 0.0) h=x2-x;
       rkqc(y,dydx,1,&x,h,eps,yscal,&hdid,&hnext,f,xptr,&yptr-1,xtol,ytol);
       if (hdid == h)
          ++(*nok);
       else
          ++(*nbad);
       if ((x-x2)*(x2-x1) >= 0.0)  /* are we done? */
          { *yptr = y[1];
              /*  before this, *yptr contains the
                  NEXT TO LAST value of y, not the last one */
            return 0;
          }
       if (fabs(hnext) <= hmin)
          return 2; /* step size too small */
       h=hnext;
     }
  return 3; /* too many steps */
}

#undef MAXSTP
#undef _TINY


/*_______________________________________________________________________*/
MEXPORT_TRIGCALC int numint(term u,term x,double a,double b,double *ans)
/* evaluate integral(u,x,a,b) numerically
   using 4th-order Runge-Kutta as implemented in ode.c
*/
{ term y;  /* solve y' = u  */
  int err;
  // double hmin = 0.0;  /* minimum allowed stepsize (can be zero) */
  double hmin =  fabs(b-a) * 1.0e-12;  /* minimum allowed stepsize */
  double xtol = fabs(b-a);  /* not necessary but rkqc expects them */
  double ytol = xtol;
  int nok;    /* number of good steps taken */
  int nbad;   /* number of bad, but retried and fixed, steps */
  double ystart = 0.0;
  double *xptr = (double *) x.args;
  double *yptr;
  y.args = (void *) mallocate(sizeof(double));
  yptr = (double *) y.args;
     /* pointer to value of y, which is NOT on the value list since y
        is not a MathXpert object variable */
  *xptr = a;
  err = odeint2( ystart,a,b, EPS,FIRSTSTEP,hmin,&nok,&nbad,&u-1,xptr,yptr,xtol,ytol);
  if(err)
    { errbuf(0, english(809));
          /* Can't integrate numerically. There must be */
      errbuf(1, english(810));
          /* something unusual about this integral! */
      return 1;
    }
  *ans = VALUE(y);
  return 0;
}

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists