/* @(#)besz.c 1.12 (8/9/93) */ /* BESZ fast zero finder for bessel functions J_nu(x) command line switches: -n number of zeroes -d dimension of working array (d >> 4 n) -i index nu (double) -v verbose (gives deviation from asymptotic estimate) -p precision (1.e-8 ... 1.e-18) -F enforce d > 5n+offset -s dump setup usage: besz [-p ][-v][-i ][-d ][-n ] algorithm: inverse recursion + asymptotic estimate for speeding up E.Onofri (c) 1993 (onofri@parma.infn.it) */ #include #include #include #include #define M_PI 3.1415926535897931160E0 #define sqr(x) ((x)*(x)) #define cube(x) ((x)*(x)*(x)) #define PREC 1.E-16 #define NOFFSET 50 #define CLEAN 0 #define VERBOSE 1 #define FALSE 0 #define TRUE 1 char mode = CLEAN; char force = 0; int npts = 500; int neig = 20; int Nd ; int offs = NOFFSET; char dump = FALSE; double tol,maxerror = 0.0; double bes_nu=0.0, prec; void examine_command_line(argc,argv) int argc; char **argv; { extern char *optarg; extern int optind; int c; while ((c = getopt(argc, argv, "svFi:n:d:p:o:")) != EOF) { switch(c) { case 'v': mode = VERBOSE; break; case 'F': force=TRUE; break; case 'i': bes_nu = atof(optarg); break; case 'd': npts = atoi(optarg); break; case 'n': neig = atoi(optarg); break; case 'o': offs=atoi(optarg); break; case 's': dump = TRUE; break; case 'p': prec = atof(optarg)/100; if(prec<1.0E-18) { fprintf(stderr,"Accuracy cannot be that high!\n"); fprintf(stderr,"assuming prec=%le\n",PREC); prec=PREC/100; } break; default: fprintf(stderr,"Usage: besz [-options]\nOptions:\n"); fprintf(stderr," -i bessel index (float) \n"); fprintf(stderr," -d dimension (int) \n"); fprintf(stderr," -n number of zeroes (int) \n"); fprintf(stderr," -p precision (%le) \n"); fprintf(stderr," -F enforce dim>5 n + offs \n"); fprintf(stderr," -v verbose output \n"); fprintf(stderr," -s dump setup (stderr)\n"); exit(1); break; } } } double bisec(k,Max) int k; double Max; { register int i, index; register double p0, p1, p2; register double x, xmin=0.0, xmax=2.0*Max; register double delta=xmax-xmin; while( delta > prec) { x = xmin+xmax; index=1; p0=1.0; p1=x*bes_nu; for(i = 1;i< Nd;++i) { p2 = x*p1*((double)i+bes_nu) - p0; if(p1*p2<0) index++; p0 = p1; p1 = p2; } if(index <= k) xmax = 0.5*x; else xmin = 0.5*x; delta*=0.5; } return x*0.5; } void main(argc,argv) int argc; char **argv; { char format[60], str[30]; double eigenv, error; int i=1,j,k; double tmp, *asy; double Max = 10.0; prec=PREC; examine_command_line(argc,argv); if(force) npts=5*neig+NOFFSET; else neig=(neig*5