home *** CD-ROM | disk | FTP | other *** search
- /*
- ### Bulirsch-Stoer integration one stepper ###
-
- Note: a slightly modified version of bsstep in "Numerical Recipes"
- c convention of [0,n-1] is used for array indices
- */
-
- #include <math.h>
- #define IMAX 11
- #define NUSE 7
- #define SHRINK 0.95
- #define GROW 1.2
-
- extern int_option;
- double **ddd = 0, *xxx = 0;
-
- void bsstep(y,dydx,nv,xx,htry,eps,yscal,hdid,hnext)
- double y[],dydx[],*xx,htry,eps,yscal[],*hdid,*hnext;
- int nv;
- {
- int i,j;
- double xsav,xest,h,errmax,errnew,temp;
- double *ysav,*dysav,*yseq,*yerr,*dvector(),**dmatrix();
- static int nseq[IMAX]={2,4,6,8,12,16,24,32,48,64,96};
- void free_dmatrix(),free_dvector();
-
- ysav = dvector(0,nv-1);
- dysav = dvector(0,nv-1);
- yseq = dvector(0,nv-1);
- yerr = dvector(0,nv-1);
- xxx = dvector(0,IMAX-1);
- ddd = dmatrix(0,nv-1,0,NUSE-1);
- h = htry;
- xsav = (*xx);
- for(i=0;i<nv;i++) {
- ysav[i] = y[i];
- dysav[i] = dydx[i];
- }
- for(;;){
- for(i=0;i<IMAX;i++){
- (void) mmid(ysav,dysav,nv,xsav,h,nseq[i],yseq,0);
- xest = (temp = h / nseq[i] , temp * temp);
- (void) rzextr(i,xest,yseq,y,yerr,nv,NUSE);
- errmax = 0.0;
- for(j=0;j<nv;j++){
- if(errmax < (errnew = fabs(yerr[j] / yscal[j])))
- errmax = errnew;
- }
- if(errmax < eps) {
- if(int_option)
- (void) mmid(ysav,dysav,nv,xsav,h,nseq[i],yseq,1);
- *xx += h;
- *hdid = h;
- *hnext = i == NUSE-1 ? h * SHRINK :
- i == NUSE-2 ? h * GROW : (h * nseq[NUSE-2]) / nseq[i];
- free_dmatrix(ddd,0,nv-1,0,NUSE-1);
- free_dvector(xxx,0,IMAX-1);
- free_dvector(yerr,0,nv-1);
- free_dvector(yseq,0,nv-1);
- free_dvector(dysav,0,nv-1);
- free_dvector(ysav,0,nv-1);
- return;
- }
- }
- h *= 0.25;
- for(i=0;i < (IMAX - NUSE)/2;i++) h /= 2.0;
- if((*xx + h) == (*xx)) system_mess_proc(1,"bsstep: step size underflow. Stop!");
- }
- }
-