home *** CD-ROM | disk | FTP | other *** search
Text File | 1986-03-31 | 51.2 KB | 2,180 lines |
- /* GLOBAL.H 08/18/85
- *
- * Global include file for the Variable Metric Minimizer program.
- *
- * (c) Copyright 1985, Billybob Software. All rights reserved.
- * This program may be reproduced for personal, non-profit use only.
- */
-
- #define C80
-
- /*
- * remove the above line if you are not using C/80
- */
-
- #ifdef C80
-
- /*
- * required for the Software Toolworks C/80 Version 3.0 compiler
- */
-
- #define double float
- #include "fprintf.h"
- #include "scanf.h"
-
- /*
- * the following is the <math.h> for C/80
- */
-
- float sin() , cos() , atan() , sqrt() , exp() ,
- pow() , pow10() , ln() , log() , fabs() , atof() ;
-
- #else
-
- /*
- * other compilers
- */
-
- #include <stdio.h>
- #include <math.h>
- #include <ctype.h>
-
- /*
- * ctype.h may be needed for an isspace used in read.c
- * some systems need it, some don't!
- * check your math.h for fabs and atof declarations!
- */
-
- #endif
-
- double dot() ;
- struct bound
- {
- int fl ;
- double up ;
- double lo ;
- double mi ;
- };
-
- struct xydata
- {
- double x ;
- double y ;
- };
-
- #define BOUND struct bound
- #define DATA struct xydata
- #define VECMAX 10
- #define MATMAX VECMAX*VECMAX
- #define NEPS 2
- #define STDES 0
- #define DFP 1
- #define BFGS 2
- #define ALLDONE -1
- #define NEGEDM -3000
- #define BADMIN -2000
- #define BADLS -1000
- #define MAXITERS 0
- #define OK 0
- #define EDM1 1000
- #define EDM2 2000
- #define TOOSML 3000
-
- Listing TWO
- /* VMM.C 11/04/85
- *
- * The main driver routine, function library routine
- * and all library functions for vmm.
- * (c) Copyright 1985, Billybob Software. All rights reserved.
- * This program may be reproduced for personal, non-profit use only.
- */
-
- #include "global.h"
-
- #define DMAX 50 /* Size of experimental data array */
- #define NFUN 3 /* Num of functions in function library */
-
- /************************************************************************/
-
- main()
- {
- static int nparam ; /* number of parameters */
- static double const[VECMAX] ; /* constants used in function */
- static double param[VECMAX] ; /* parameters to be found */
- static double dstep[VECMAX] ; /* step sizes for derivatives */
- static double epsilon[VECMAX];/* stopping criteria */
- static BOUND limit[VECMAX] ; /* limits if constrained */
- static char *pname[VECMAX] ;/* parameter names */
- static double g0 ; /* expected value of minimum */
- static int debug ; /* debug level, 0 if off */
- static int itermin ; /* minimum number of iterations */
- static int iterlim ; /* maximum number of iterations */
- static int nreset ; /* reset y after this many iters*/
- static DATA exp[DMAX] ; /* xy experimental data */
- static int npoints ; /* number of data points */
- static double *(*fun)() ; /* ptr to function to minimize */
- static int iters ; /* number of iterations it took */
- static int retcode ; /* return code from minimization*/
- static double gmin ; /* the value at the minimum */
- static int method ; /* method used to update y */
- static int control ;
- int i , j ;
-
- for ( i=1 ; ; ++i )
- {
- raz ( &nparam , &itermin , &iterlim , &nreset , &debug ,
- limit , dstep , param , &g0 , epsilon , &method ) ;
-
- if( (control = reader ( &fun , const , &nparam , param ,
- limit , dstep , pname , epsilon , &itermin ,
- &iterlim , &nreset , &g0 , &debug , exp ,
- &npoints , DMAX , &method)) == ALLDONE )
- break ;
-
- if ( control )
- continue ;
-
- if ( dfault ( nparam , &itermin , &iterlim , &nreset ,
- epsilon , limit , dstep , debug ) )
- continue ;
-
- retcode = minim ( nparam , fun , param , dstep , limit ,
- g0 , itermin , iterlim , epsilon , &gmin ,
- &iters , debug , nreset , exp , npoints ,
- const , method ) ;
-
- printf("\t***************************\n") ;
- printf("\t* results from dataset %2d *\n", i ) ;
- printf("\t***************************\n") ;
- printf("stopped after %1d iterations, ", iters ) ;
-
- switch ( retcode )
- {
- case NEGEDM : printf("negative e.d.m.\n") ; break ;
- case BADMIN : printf("new min > last min\n") ; break ;
- case BADLS : printf("line search failed\n") ; break ;
- case MAXITERS: printf("maximum iterations\n"); break ;
- case EDM1 : printf("e.d.m. within tol.\n") ; break ;
- case EDM2 : printf("e.d.m. within tol.\n") ; break ;
- case TOOSML : printf("change too small\n") ; break ;
- default : printf("unknown reason!!!\n") ; break ;
- }
-
- printf("value of the minimum was %11.4e\n", gmin ) ;
- printf("parameter values at minimum:\n") ;
-
- for (j=0 ; j<nparam ; ++j)
- printf("%15s %11.4e\n" , pname[j] , param[j]);
-
- printf("*********************************************\n") ;
- }
- }
-
- /************************************************************************
- * Function library. Note that NFUN is #defined at the top of this
- * module.
- */
-
- funlib ( funname , fun , np , nc , pname )
- char funname[] ; /* name of function to be minimized */
- int *fun ; /* address of function (non-portable) */
- int *np ; /* number of parameters in the function */
- int *nc ; /* number of constants in the function */
- char *pname[] ; /* parameter names vector */
- {
- /*
- * use funname to return fun and np, nc from a list
- * for each new function in the library, you must:
- * (1) declare the function "double" and link it in the load module
- * (2) declare the function below under "functions available"
- * (3) add an entry in the function table,including parameter names
- * (4) add an entry in the switch table in the code
- * (5) update the value of NFUN
- *
- * Available functions are:
- */
-
- double cohen() ;
- double sinus() ;
- double rosen() ;
-
- /*
- * function table
- */
-
- static struct
- {
- char *name ; /* function name in funname call */
- int nnpp ; /* number of parameters in the function */
- int nncc ; /* number of constants in the function */
- char *ppnn[VECMAX]; /* list of names for the parameters */
-
- } fctlib[NFUN] = {
-
- /* 0 */ { "cohen" , 2, 0 , "alpha" , "beta" } ,
- /* 1 */ { "sine" , 4, 0 , "P0" , "P1" , "P2" , "P3" } ,
- /* 2 */ { "rosen" , 10, 5 , "x1" , "x2" , "x3" , "x4" , "x5" ,
- "x6" , "x7" , "x8" , "x9" , "x10" }
- } ;
-
- int j, k;
-
- for ( j=0 ; j<NFUN ; ++j )
- if ( ! strcmp( funname , fctlib[j].name ) )
- break ;
-
- if (j==NFUN)
- return( 1 ) ;
-
- *np = fctlib[j].nnpp ;
- *nc = fctlib[j].nncc ;
-
- for (k=0 ; k < *np ; ++k)
- pname[k] = fctlib[j].ppnn[k] ;
-
- switch( j )
- {
- case 0 : *fun = cohen ; break ;
- case 1 : *fun = sinus ; break ;
- case 2 : *fun = rosen ; break ;
- }
-
- return( 0 ) ;
- }
-
- /************************************************************************/
-
- double cohen ( const , xx , data , npoints , user )
- double const[] ; /* vector of constants used by this fcn */
- double xx[] ; /* the current values of the vector x */
- DATA data[] ; /* dummy */
- int npoints ; /* dummy */
- int user ; /* dummy, reserved for each user! */
- {
- /*
- * computes the function to be minimized
- *
- * this is the test function given in Cohen, page 280
- * note that there are no constants for this fcn --
- * the vector const is included for compatability with other fcns
- *
- * note program calls function with user = 0
- */
-
- double t1 , t2 , t3 , t4 ;
-
- t1 = (xx[1] - xx[0]*xx[0]) ;
- t2 = t1 * t1 ;
- t3 = (xx[0] * (1.0 - xx[1]) + 1.0) ;
- t4 = t3 * t3 ;
- return ( t2 + t4 ) ;
- }
-
- /************************************************************************/
-
- double sinus ( const , xx , data , npoints , user )
- double const[] ; /* vector of constants for this fcn */
- double xx[] ; /* parameter vector */
- DATA data[] ; /* data from file */
- int npoints ; /* number of data points */
- int user ; /* user parameter */
- {
- /*
- * extract parameters for polynomial fit to sine function
- */
-
- double t1 , t2 , t3 , t4 ;
- int i;
-
- for ( i=0 , t4 = 0.0 ; i<npoints ; i++ )
- {
- t1 = data[i].x * data[i].x ;
- t2 = data[i].x *
- (xx[0] + t1*(xx[1] + t1*(xx[2] + t1*xx[3]) )) ;
- t3 = (data[i].y - t2)/data[i].y ;
- t4 += t3 * t3 ;
- }
-
- return( t4 /= (double)(npoints-4) ) ;
- }
-
- /************************************************************************/
-
- double rosen ( const , xx , data , npoints , user )
- double const[] ; /* vector of constants used by this fcn */
- double xx[] ; /* the current values of the vector x */
- DATA data[] ; /* dummy */
- int npoints ; /* dummy */
- int user ; /* dummy, reserved for each user! */
- {
- /*
- * Rosenbrock's test function
- */
-
- double t1 , t2 , t3 ;
- int l , m ;
-
- for ( l=0 , m=0 , t3 = 0.0 ; l<10 ; l += 2 , ++m )
- {
- t1 = xx[l] ;
- t2 = xx[l+1] ;
- t3 += const[m]*(t2-t1*t1)*(t2-t1*t1) + (1.0-t1)*(1.0-t1) ;
- }
- return( t3 ) ;
- }
-
- /* LISTING THREE
- * MINIM.C 11/04/85
- *
- * The main minimization routine
- * (c) Copyright 1985, Billybob Software. All rights reserved.
- * This program may be reproduced for personal, non-profit use only.
- */
-
- #include "global.h"
-
- /***************************************************************************/
-
- minim ( n , fun , xextern , xstep , xlim , g0 , itermin , iterlim , epsilon ,
- gmin , iters , debug , nreset , data , npoints , const , method )
-
- int n ; /* number of parameters in the fit */
- double (*fun)() ; /* pointer to the function to minimize */
- double xextern[] ; /* vector containing the starting values of
- the parameters; returns values at minimum */
- double xstep[] ; /* step sizes on parameters for deriv calcs */
- BOUND xlim[] ; /* limits on the vector x */
- double g0 ; /* expected value of the minimum of the fcn */
- int itermin ; /* minimum number of iterations */
- int iterlim ; /* limit on the number of iterations */
- double epsilon[] ; /* iteration control parameters */
- double *gmin ; /* value of minimum for returned vector x */
- int *iters ; /* number of iterations to converge */
- int debug ; /* flag = 0 for no print, >0 for debug print */
- int nreset ; /* reset limit for the y matrix */
- DATA data[] ; /* the data */
- int npoints ; /* number of data points */
- double const[] ; /* vector of constants required by fcn */
- int method ; /* update method for the matrix y */
- {
- /*
- * variable metric minimization algorithm
- * Reference (using DFP method) is: Numerical Analysis
- * A.M. Cohen et. al.
- * Halstead Press
- * John Wiley and Sons
- * 1973
- * pages 276-280
- * See also original papers by Fletcher and Powell
- */
-
- int i , j , rc ;
- static int ycount ; /* counter for resetting the Y matrix */
- static double y[MATMAX] ; /* the Y matrix */
- static double a[MATMAX] ; /* the A and B matrices are calculated to */
- static double b[MATMAX] ; /* update the Y matrix at each iteration */
- static double xintern[VECMAX];/* parameters in internal coordinates */
- static double zint[VECMAX] ; /* gradients in internal coordinates */
- static double znewi[VECMAX] ; /* same for the next iteration */
- static double sigma[VECMAX] ; /* changes vector */
- static double s[VECMAX] ; /* changes direction vector */
- static double xi[VECMAX] ; /* change in gradient vector between */
- * iterations */
- static double xold[VECMAX] ; /* holds previous values of x */
- static double alpha ; /* change scaling parameter */
- static double g ; /* value of fcn for a given vector x */
- static double gnew ; /* likewise for the next iteration */
- double dot() ;
-
- /*
- * get started
- */
-
- g = (*fun)( const , xextern , data , npoints , 0 ) ;
-
- gozinta( n , xintern , xextern , xlim ) ;
- derivs ( n , fun , xintern , xstep , xlim , zint , data ,
- npoints , const , debug);
- /*
- * main loop
- */
-
- for ( i = 1 , ycount = nreset ; i <= iterlim ; ++i , ++ycount )
- {
- if (ycount == nreset)
- {
- reset( n , y );
- ycount = 0 ;
- }
- if (debug)
- {
- printf("\t\t++++++++++++++++++++++\n") ;
- printf("\t\t+ Begin iteration %2d +\n", i ) ;
- printf("\t\t++++++++++++++++++++++\n") ;
- printf("external parameter values are:\n") ;
- vout( n , xextern ) ;
- printf("internal parameter values are:\n") ;
- vout( n , xintern ) ;
- printf("internal gradient vector is:\n") ;
- vout( n , zint ) ;
- printf("approximate inverse hessian matrix is:\n") ;
- mout( n , y ) ;
- printf("the current minimum is --->%11.4e<---\n", g ) ;
- }
-
- matvec ( n , y , zint , s ) ;
- for (j=0 ; j<n ; ++j)
- {
- xold[j] = xintern[j] ;
- s[j] *= -1.0 ;
- }
-
- if (debug>1)
- {
- printf("vector s is:\n"); vout( n , s ) ;
- }
-
- /*
- * do line search and quit if it fails
- * line search was successful if getalpha returns OK ( zero )
- */
-
- if ( rc = getalpha ( n , fun , xintern , xstep , xlim , zint ,
- s , g ,g0 , &alpha , debug , data , npoints , const ) )
- break ;
- /*
- * update parameters
- */
-
- for (j=0 ; j<n ; ++j)
- {
- sigma[j] = alpha * s[j] ;
- xintern[j] += sigma[j];
- }
- if (debug>1)
- {
- printf("vector sigma is:\n") ; vout( n , sigma ) ;
- }
-
- /*
- * get values for next iteration
- */
-
- gozouta ( n , xintern , xextern , xlim );
- gnew = (*fun)( const , xextern , data , npoints , 0 ) ;
-
- derivs (n , fun , xintern , xstep , xlim , znewi ,
- data , npoints , const , debug ) ;
-
- for (j=0 ; j<n ; ++j)
- xi[j] = znewi[j] - zint[j] ;
-
- if (debug>1)
- {
- printf("orthogonality satisfied to %11.4e\n",
- dot ( n , znewi , sigma ) ) ;
- printf("vector xi is:\n") ;
- vout( n , xi ) ;
- }
-
- /*
- * decide whether to continue or not
- * continue if decide returns OK ( zero )
- */
-
- if ( rc = decide( g , gnew , n , znewi , sigma , y ,
- epsilon , itermin , i , debug ) )
- break ;
- /*
- * update all other quantities for the next pass
- * three methods available:
- * steepest descent (slowest and included only for completeness)
- * Davidon Fletcher Powell (default, empirically the favorite)
- * Broyden Fletcher Goldfarb Shanno (thought to be better by
- * some)
- * The method is selected by keyword on input.
- */
-
- if ( method == STDES )
- ; /* nothing to do, y is not updated */
-
- else if ( method == DFP )
- {
- dfpa ( n , sigma , xi , a , debug ) ;
- dfpb ( n , y , xi , b , debug ) ;
- gety ( n , a , b , y , debug ) ;
- }
- else if ( method == BFGS )
- {
- bfgsa ( n , y , sigma , xi , a , debug ) ;
- bfgsb ( n , y , sigma , xi , b , debug ) ;
- gety ( n , a , b , y , debug ) ;
- }
-
- for (j=0 ; j<n ; ++j)
- zint[j] = znewi[j] ;
-
- gozouta ( n , xintern , xextern , xlim ) ;
- g = gnew ;
-
- /*
- * all done with this pass
- */
- }
-
- /*
- * outside of the main loop here
- */
-
- *iters = ( i > iterlim ) ? iterlim : i ;
-
- /*
- * first handle the case of abnormal exits
- * these have returned rc negative above, from either getalpha or decide
- */
-
- if ( rc < 0 )
- {
- for (j=0; j<n; ++j)
- xintern[j] = xold[j] ;
- gozouta ( n , xintern , xextern , xlim ) ;
- *gmin = g ;
- }
- else
- {
- /*
- * regular exit and fall through These represent positive or
- * zero values of rc; zero means max iterations.
- */
-
- gozouta ( n , xintern , xextern , xlim ) ;
- *gmin = gnew ;
- }
-
- if (debug)
- {
- printf("\t\t++++++++++++++++++++++++\n") ;
- printf("\t\t+ exiting minimization +\n") ;
- printf("\t\t++++++++++++++++++++++++\n") ;
- printf("\tnumber of iterations was: %11d\n",*iters) ;
- printf("\t return code is: %11d\n",rc) ;
- printf("\t minimum is: %11.4e\n", *gmin) ;
- printf("best parameter values:\n") ;
- vout( n , xextern ) ;
- printf("last internal gradient vector:\n") ;
- vout( n , znewi ) ;
- }
- return( rc ) ;
- }
-
- /* LISTING FOUR
- * AUXL.C 11/04/85
- *
- * The line search and decision routines
- * (c) Copyright 1985, Billybob Software. All rights reserved.
- * This program may be reproduced for personal, non-profit use only.
- */
-
- #include "global.h"
-
- /************************************************************************/
-
- getalpha ( n , fun , xx , xstep , xlim , z , s , g , g0 ,
- alpha , debug , data , npoints , const )
- int n ; /* number of parameters */
- double (*fun)() ; /* pointer to the function to minimize */
- double xx[] ; /* parameter vector */
- double xstep[] ; /* stepsize for parameter derivative calcs */
- BOUND xlim[] ; /* limits on parameters */
- double z[] ; /* gradient vector */
- double s[] ; /* changes direction vector */
- double g ; /* value of fcn for the given vector xx */
- double g0 ; /* expected value of the minimum of the fcn */
- double *alpha ; /* scaling parameter we are trying to find */
- int debug ; /* flag = 0 for no print, >0 for debug print */
- DATA data[] ; /* the data */
- int npoints ; /* number of data points */
- double const[] ; /* constants vector needed by fcn */
- {
- /*
- * find alpha according to Cohen, pp 279-280
- */
-
- int i ;
- static double u ; /* see Cohen */
- static double eta ; /* see Cohen */
- static double t[VECMAX] ; /* see Cohen */
- static double text[VECMAX] ; /* same, in external coordinates */
- static double zt[VECMAX] ; /* the z for fcn evaluated at x = t */
- static double gt ; /* the g that results from fcn at */
- /* x = t */
- static double nu ; /* see Cohen */
- static double d ; /* see Cohen */
- static double w ; /* see Cohen */
- static double temp1 ;
- static double temp2 ;
-
- if (debug>1) {
- printf("\t\t+++++++++++++++++++++++++\n") ;
- printf("\t\t+ line search procedure +\n") ;
- printf("\t\t+++++++++++++++++++++++++\n") ;
- }
-
- u = dot ( n , z , s ) ;
- eta = -2.0 * ( g - g0 ) / u ;
-
- if (eta > 1.0)
- eta = 1.0 ;
-
- for (i=0 ; i<n ; ++i)
- t[i] = xx[i] + eta * s[i] ;
-
- gozouta ( n , t , text , xlim ) ;
-
- gt = (*fun)( const , text , data , npoints , 0 ) ;
- derivs ( n, fun, t, xstep, xlim, zt, data, npoints, const, debug );
- nu = dot ( n , zt , s ) ;
-
- if (debug>1)
- {
- printf("u and nu are: %11.4e %11.4e\n", u , nu ) ;
- printf("g and gt are: %11.4e %11.4e\n", g , gt ) ;
- printf("eta is: %11.4e\n", eta ) ;
- if (debug>2)
- {
- printf("vector t is:\n") ;
- vout( n , t ) ;
- printf("vector zt is:\n") ;
- vout( n , zt ) ;
- }
- }
-
- d = 3*(g - gt)/eta + u + nu ;
-
- if ( (temp1 = d*d) < (temp2 = u*nu) )
- {
- if (debug>1)
- {
- printf("cubic interpolation has failed, ") ;
- printf("about to take sqrt of negative number!\n") ;
- printf("d squared is %11.4e ", temp1 ) ;
- printf("and u*nu is %11.4e\n", temp2 ) ;
- printf("difference is %11.4e\n", temp1-temp2 ) ;
- }
- if ( u < 0.0 && nu < 0.0 && gt < g )
- {
- *alpha = eta ;
- if (debug>1)
- printf("return with alpha = eta\n") ;
- return( OK ) ;
- }
- else
- {
- *alpha = 0.0 ;
- if (debug>1)
- printf("line search has failed\n") ;
- return( BADLS ) ;
- }
- }
- else
- {
- w = sqrt(temp1 - temp2) ;
- *alpha = eta * ( 1.0 - (nu+w-d)/(nu-u+2.0*w) ) ;
- if (debug>1)
- printf("alpha returned is %11.4e\n", *alpha ) ;
- return( OK ) ;
- }
- }
-
- /***************************************************************************/
-
- decide ( g , gnew , n , znewi , sigma , y ,
- epsilon , itermin , iterations , debug )
-
- double g ; /* old value of minimum */
- double gnew ; /* new value of minimum */
- int n ; /* number of parameters */
- double znewi[] ; /* vector of new gradients */
- double sigma[] ; /* change vector for parameters */
- double y[] ; /* the transformation matrix */
- double epsilon[] ; /* cutoff criteria vector */
- int itermin ; /* minimum number of iterations */
- int iterations ; /* current iteration number */
- int debug ; /* debug flag */
- {
- /*
- * makes the decision to continue iterating or not
- * returns a zero if we want to keep going
- * returns a positive number if we have a normal stopping reason
- * returns a negative number if we have a catastrophic stopper
- */
-
- static double edm ;
- static double temp[VECMAX] ;
-
- if (debug>1)
- {
- printf("\t\t+++++++++++++++++++++++++\n") ;
- printf("\t\t+ decision making logic +\n") ;
- printf("\t\t+++++++++++++++++++++++++\n") ;
- printf("old minimum was: %11.4e, new minimum is %11.4e\n",
- g , gnew ) ;
- printf("ratio new/old is: %11.4e\n", gnew/g ) ;
- }
-
- /*
- * exit if the new "minimum" is greater than or equal to the old minimum
- */
-
- if (gnew >= g)
- {
- if (debug>1)
- printf("STOP!!! new minimum is not lower!\n") ;
- return( BADMIN ) ;
- }
-
- /*
- * if the edm (estimated distance to the minimum) is negative we have
- * a catastrophic problem and should stop
- */
-
- matvec( n , y , znewi , temp ) ;
- edm = dot( n , znewi , temp ) ;
-
- if( edm < 0.0 )
- {
- if (debug>1)
- printf("STOP!!! edm is negative = %11.4e\n", edm);
- return( NEGEDM ) ;
- }
-
- /*
- * now look at normal exits if the minimum number of iterations has
- * been accomplished
- */
-
- if (iterations < itermin) {
- if (debug>1) printf("-->keep going, too few iterations\n") ;
- return( OK ) ;
- }
-
- /*
- * edm test: two ways to calculate, stop if either satisfies
- */
-
- if (edm < epsilon[0])
- {
- if (debug>1)
- printf("STOP, close enough, edm = %11.4e\n", edm);
- return( EDM1 ) ;
- }
-
- edm = dot( n , sigma , sigma ) ;
-
- if (edm < epsilon[0])
- {
- if (debug>1)
- printf("STOP, close enough, edm = %11.4e\n", edm);
- return( EDM2 ) ;
- }
-
- /*
- * % change in g less than "something" means that approach is too slow
- */
-
- if ( g-gnew < epsilon[1]*g )
- {
- if (debug>1)
- printf("STOP, too slow, fractional change = %11.4e\n",
- (g-gnew)/g ) ;
- return( TOOSML ) ;
- }
-
- /*
- * fall through case
- * note that case of maximum number of iterations is handled in the
- * calling program
- */
-
- if (debug>1)
- printf("--->keep going, no stoppers found...\n") ;
-
- return( OK ) ;
- }
-
- /* LISTING FIVE
- * UP.C 11/04/85
- *
- * Routines for updating the matrix y
- * (c) Copyright 1985, Billybob Software. All rights reserved.
- * This program may be reproduced for personal, non-profit use only.
- */
-
- #include "global.h"
-
- /*-----------------------------------------------------------------*/
-
- dfpa ( n , sigma , xi , a , debug )
- int n ; /* number of parameters */
- double *sigma ; /* changes vector */
- double *xi ; /* change in gradient vector */
- double *a ; /* the result */
- int debug ; /* flag = 0 for no print, >0 for debug print */
- {
- /*
- * Compute the matrix A which is used to correct Y
- * Davidon Fletcher Powell method
- */
-
- int i ;
- double norm ;
- double *t ;
-
- t = a ;
- cross( n , sigma , sigma , a ) ;
- norm = 1.0 / dot( n , sigma , xi ) ;
- i = n*n ;
-
- while( i-- )
- *a++ *= norm ;
-
- if (debug>1)
- {
- printf("AAAAA correcting matrix AAAAA is:\n") ;
- mout( n , t ) ;
- }
- }
-
- /*-----------------------------------------------------------------*/
-
- dfpb ( n , y , xi , b , debug )
- int n ; /* number of parameters */
- double *y ; /* current Y matrix */
- double *xi ; /* change in gradient vector */
- double *b ; /* the result */
- int debug ; /* flag = 0 if no print, >0 for debug print */
- {
- /*
- * compute the matrix B which is used to update Y
- * Davidon Fletcher Powell method
- */
-
- int i ;
- static double temp[VECMAX] ;
- double *t ;
- double norm ;
-
- t = b ;
- matvec( n , y , xi , temp ) ;
- norm = - 1.0 / dot( n , temp , xi ) ;
- cross( n , temp , temp , b ) ;
- i = n*n ;
-
- while( i-- )
- *b++ *= norm ;
-
- if (debug>1)
- {
- printf("BBBBB correcting matrix BBBBB is:\n") ;
- mout( n , t ) ;
- }
- }
-
- /*-----------------------------------------------------------------*/
-
- bfgsa ( n , y , sigma , xi , a , debug )
- int n ; /* number of parameters */
- double *y ; /* current Y matrix */
- double *sigma ; /* changes vector */
- double *xi ; /* change in gradient vector */
- double *a ; /* the result */
- int debug ; /* flag = 0 for no print, >0 for debug print */
- {
- /*
- * compute the matrix A which is used to correct Y
- * Broyden Fletcher Goldfarb Shanno method
- */
-
- int i , j ;
- static double temp[VECMAX] ;
- static double tmpa[MATMAX] ;
- double norm ;
-
- norm = 1.0 / dot ( n , sigma , xi ) ;
- matvec( n , y , xi , temp ) ;
-
- for (j=0 ; j<n ; ++j)
- temp[j] = sigma[j] - temp[j] ;
-
- cross( n , temp , sigma , tmpa ) ;
- cross( n , sigma , temp , a ) ;
- i = n*n ;
-
- for (j=0 ; j<i ; ++j)
- a[j] = norm * ( a[j] + tmpa[j] ) ;
-
- if (debug>1)
- {
- printf("AAAAA correcting matrix AAAAA is:\n") ;
- mout( n , a ) ;
- }
- }
-
- /*-----------------------------------------------------------------*/
-
- bfgsb ( n , y , sigma , xi , b , debug )
- int n ; /* number of parameters */
- double *y ; /* current Y matrix */
- double *sigma ; /* changes vector */
- double *xi ; /* change in gradient vector */
- double *b ; /* the result */
- int debug ; /* flag = 0 if no print, >0 for debug print */
- {
- /*
- * compute the matrix B which is used to update Y
- * Broyden Fletcher Goldfarb Shanno method
- */
-
- int i ;
- static double temp[VECMAX] ;
- double *t ;
- double norm ;
-
- t = b ;
- norm = 1.0 / dot( n , sigma , xi ) ;
- norm = - norm * norm ;
- matvec( n , y , xi , temp ) ;
-
- for (i=0 ; i<n ; ++i)
- temp[i] = sigma[i] - temp[i] ;
-
- norm *= dot( n , temp , xi ) ;
- cross( n , sigma , sigma , b ) ;
- i = n*n ;
-
- while( i-- )
- *b++ *= norm ;
-
- if (debug>1)
- {
- printf("BBBBB correcting matrix BBBBB is:\n") ;
- mout( n , t ) ;
- }
- }
-
- /*-----------------------------------------------------------------*/
-
- gety ( n , a , b , y , debug )
- int n ;
- double *a ;
- double *b ;
- double *y ;
- int debug ;
- {
- /*
- * use matrices A and B to correct Y
- */
- int i ;
- double *t ;
-
- t = y ;
- i = n*n ;
-
- while( i-- )
- *y++ += *a++ + *b++ ;
-
- if (debug>1)
- {
- printf("YYYYY new matrix YYYYY is:\n") ;
- mout( n , t ) ;
- }
- }
-
- * LISTING SIX
- * UTIL.C 11/04/85
- *
- * Contains miscellaneous routines needed for variable metric minimization
- * program, including matrix and vector utilities
- * (c) Copyright 1985, Billybob Software. All rights reserved.
- * This program may be reproduced for personal, non-profit use only.
- */
-
- #include "global.h"
- #define INALINE 6
-
- /*-----------------------------------------------------------------*/
-
- gozinta( n , xintern , xextern , xlim )
- int n ;
- double xintern[] ;
- double xextern[] ;
- BOUND xlim[] ;
- {
- /*
- * transform all external coordinates to internal coordinates
- */
-
- int i ;
-
- for ( i=0 ; i<n ; ++i )
- tointern( i , xintern , xextern , xlim ) ;
- }
-
- /*-----------------------------------------------------------------*/
-
- gozouta( n , xintern , xextern , xlim )
- int n ;
- double xintern[] ;
- double xextern[] ;
- BOUND xlim[] ;
- {
- /*
- * transform all internal coordinates to external coordinates
- */
-
- int i ;
-
- for ( i=0 ; i<n ; ++i )
- toextern( i , xintern , xextern , xlim ) ;
- }
-
- /*-----------------------------------------------------------------*/
-
- tointern ( j , xintern , xextern , xlim )
- int j ; /* parameter to transform */
- double xintern[] ; /* internal coordinates */
- double xextern[] ; /* external coordinates */
- BOUND xlim[] ; /* limits on the parameters */
- {
- /*
- * transform to unbounded "internal" coordinates used by
- * minimization program.
- */
-
- double y ;
-
- if( xlim[j].fl )
- {
- if ( xlim[j].mi == 0.0 )
- xintern[j] = xextern[j] ;
- else
- {
- y = ( (xextern[j]-xlim[j].lo) / xlim[j].mi ) - 1.0 ;
- xintern[j] = atan( y / sqrt( 1.0 - y*y ) ) ;
- }
- }
- else
- xintern[j] = xextern[j] ;
- }
-
- /*-----------------------------------------------------------------*/
-
- toextern ( j , xintern , xextern , xlim )
- int j ; /* parameter to transform */
- double xintern[] ; /* internal coordinates */
- double xextern[] ; /* external coordinates */
- BOUND xlim[] ; /* limits on the parameters */
- {
- /*
- * transforms to bounded "external" coordinates known to the real world
- */
-
- if( xlim[j].fl )
- xextern[j] = xlim[j].lo + xlim[j].mi *
- ( sin(xintern[j]) + 1.0 ) ;
- else
- xextern[j] = xintern[j] ;
- }
-
- /*-----------------------------------------------------------------*/
-
- derivs ( n , fun , xintern , xstep , xlim , z , data , m , const , debug )
- int n ; /* number of parameters */
- double (*fun)() ; /* pointer to the function to minimize */
- double xintern[] ; /* coordinates vector */
- double xstep[] ; /* step size to take on each component */
- BOUND xlim[] ; /* limit vector */
- double z[] ; /* derivative vector */
- DATA data[] ; /* the data */
- int m ; /* number of data points */
- double const[] ; /* constants required by fcn */
- int debug ; /* debug flag */
- {
- /*
- * compute the derivatives of the vector x using a simple
- * finite difference.
- */
-
- int i ;
- static double xextern[VECMAX];/* throwaway vector in ext coords */
- static double f1 , f2 ; /* values of fcn at +/- stepsize */
- static double xtemp ;
- static double eps ;
-
- gozouta( n , xintern , xextern , xlim ) ;
- for ( i=0 ; i<n ; ++i )
- {
- xtemp = xintern[i] ;
- eps = fabs( xtemp ) * xstep[i] ;
- xintern[i] = xtemp + eps ;
-
- toextern( i , xintern , xextern , xlim ) ;
- f1 = (*fun)( const , xextern , data , m , 0 ) ;
- xintern[i] = xtemp - eps ;
-
- toextern( i , xintern , xextern , xlim ) ;
- f2 = (*fun)( const , xextern , data , m , 0 ) ;
- z[i] = (f1 - f2) / ( 2.0 * eps ) ;
-
- if (debug>2)
- printf("i,f1,f2,step,deriv %d %12e %12e %12e %12e\n",
- i, f1, f2, eps , z[i] ) ;
- xintern[i] = xtemp ;
- toextern( i , xintern , xextern , xlim ) ;
- }
-
- if (debug==2)
- {
- printf("derivatives are:\n");
- vout( n , z ) ;
- }
- }
-
- /*-----------------------------------------------------------------*/
-
- raz ( nparam , itermin , iterlim , nreset , debug , limit , dstep ,
- param , g0 , epsilon , method )
- int *nparam ; /* number of parameters */
- int *itermin ; /* minimum number of iterations */
- int *iterlim ; /* maximum number of iterations */
- int *nreset ; /* reset y after nreset iters */
- int *debug ; /* debug flag */
- BOUND limit[] ; /* limit vector */
- double dstep[] ; /* step size for derivatives */
- double param[] ; /* initial values of parameters */
- double *g0 ; /* expected value of minimum */
- double epsilon[] ; /* stopping criteria vector */
- int *method ; /* update method for y */
- {
- /*
- * reinitialize important parameters before reading, so that we
- * can later test to see if they were set in the dataset
- */
-
- int j ;
-
- *debug = *nparam = *itermin = *iterlim = *nreset = 0 ;
- *g0 = 0.0 ;
- *method = DFP ;
-
- for ( j=0 ; j<VECMAX ; ++j )
- {
- limit[j].fl = 0 ;
- dstep[j] = 0.0 ;
- epsilon[j] = 0.0 ;
- param[j] = 0.0 ;
- }
- }
-
- /*-----------------------------------------------------------------*/
-
- dfault ( n , itermin , iterlim , nreset , epsilon , xlim , dstep , debug )
- int n ; /* number of parameters */
- int *itermin ; /* minimum number of iterations */
- int *iterlim ; /* maximum number of iterations */
- int *nreset ; /* reset y matrix after this many iters */
- double epsilon[] ; /* stopping criteria vector */
- BOUND xlim[] ; /* limit vector for parameters */
- double dstep[] ; /* step sizes for derivative calc */
- int debug ; /* flag for debug */
- {
- /*
- * this routine sets defaults if parameters not set with input data
- */
-
- int j ;
-
- if (debug)
- {
- printf("\t\t+++++++++++++++++++\n") ;
- printf("\t\t+ initializations +\n") ;
- printf("\t\t+++++++++++++++++++\n") ;
- }
-
- /*
- * check that the number of parameters has been set; fatal error if not!
- */
-
- if ( !n )
- return( -1 ) ;
-
- /*
- * set up other defaults as required -- these depend on knowing n
- */
-
- if ( !*itermin )
- *itermin = n ;
-
- if ( !*iterlim )
- *iterlim = 2*n ;
-
- if ( !*nreset )
- *nreset = (3*n)/2 ;
-
- for (j=0 ; j<n ; ++j)
- if (dstep[j] == 0.0)
- dstep[j] = 0.01 ;
- if (debug)
- {
- printf("min iters = %3d, max iters = %3d, ", *itermin ,
- *iterlim ) ;
- printf("reset y every %3d iterations\n", *nreset ) ;
- printf("step sizes for derivatives:\n") ; vout( n , dstep ) ;
- }
-
- if ( epsilon[0] == 0.0 )
- {
- epsilon[0] = 1.0e-06 ;
- epsilon[1] = 0.001 ;
- if (debug) printf("epsilons set to defaults:\n") ;
- }
- else if (debug)
- printf("epsilons from input data:\n") ;
-
- if (debug)
- vout( NEPS , epsilon ) ;
-
- /*
- * note that if you add other stopping criteria (more elements in
- * the epsilon vector) you will have to modify this code
- *
- * the following defaults were set in raz and remain if not changed
- * by the data read in reader:
- * starting values of parameters: 0.0
- * expected value of minimum: 0.0
- * constrained/unconstrained: unconstrained (all)
- * parameter names: blank
- * updating method for y : Davidon-Fletcher-Powell (DFP)
- *
- * variables used for intern<-->extern conversions:
- */
-
- for (j=0 ; j<n ; j++)
- if (xlim[j].fl)
- xlim[j].mi = (xlim[j].up - xlim[j].lo) / 2.0 ;
-
- return( 0 ) ;
- }
-
- /*-----------------------------------------------------------------*/
-
- vout ( n , a )
- int n ;
- double *a ;
- {
- /*
- * output the floating point vector a with n components
- * INALINE values to a line, indent succeeding lines appropriately
- */
-
- praline( n , a , 0 ) ;
- putchar('\n') ;
- }
-
- /*-----------------------------------------------------------------*/
-
- praline( n , a , indent )
- int n ;
- double *a ;
- int indent ;
- {
- /*
- * print out as many lines as required, indenting as we go
- */
-
- int i ;
-
- if ( indent )
- {
- putchar('\n') ;
- for ( i=indent ; i ; --i )
- putchar(' ');
- }
-
- for ( i=INALINE ; i && n ; --i , --n )
- printf("%11.4e " , *a++ ) ;
-
- if ( !n )
- return ;
-
- praline( n , a , ++indent ) ;
- }
-
- /*-----------------------------------------------------------------*/
-
- mout ( n , a )
- int n ;
- double *a ;
- {
- /*
- * output the floating point matrix a with n by n components
- */
-
- int i ;
- double *p ;
-
- for (i=n , p=a ; i ; --i , p += n )
- vout( n , p ) ;
- }
-
- /*-----------------------------------------------------------------*/
-
- double dot( n , a , b )
- int n ;
- double *a , *b ;
- {
- /*
- * dot product of the vectors a and b, n components each
- */
-
- double c ;
-
- c = 0.0 ;
- while( n-- )
- c += *a++ * *b++ ;
- return( c ) ;
- }
-
- /*-----------------------------------------------------------------*/
-
- reset ( n , y )
- int n ;
- double *y ;
- {
- /*
- * set the n by n matrix y equal to the identity matrix
- */
-
- int i, j;
-
- for( i = n-1, j = n ; i ; --i, j = n )
- {
- *y++ = 1.0 ;
- while ( j-- )
- *y++ = 0.0 ;
- }
- *y = 1.0 ;
- }
-
- /*-----------------------------------------------------------------*/
-
- cross( n , v1 , v2 , m )
- int n ;
- double *v1 ;
- double *v2 ;
- double *m ;
- {
- /*
- * product of two vectors of dimension n yielding an n by n matrix
- */
-
- int i , j ;
- double *p ;
-
- for( i=n , p=v2 ; i ; --i , ++v1 , p=v2 )
- for( j=n ; j ; --j )
- *m++ = *v1 * *p++ ;
- }
-
- /*-----------------------------------------------------------------*/
-
- matvec( n , m , v1 , v2 )
- int n ;
- double *m ;
- double *v1 ;
- double *v2 ;
- {
- /*
- * product of an n by n matrix and a column vector with n components
- * yielding a second n component vector: m * v1 = v2
- */
- int i , j ;
- double *p ;
-
- for ( i=n , p=v1 ; i ; --i , ++v2 , p=v1 )
- for ( j=n , *v2=0.0 ; j ; --j )
- *v2 += *m++ * *p++ ;
- }
-
- /* LISTING SEVEN
- * READ.C 12/05/85
- *
- * reads standard input to get appropriate parameters
- * echoes the data as it is read
- * (c) Copyright 1985, Billybob Software. All rights reserved.
- * This program may be reproduced for personal, non-profit use only.
- */
-
- #include "global.h"
- #define LEN 130
- #define MAXKEY 19
- #define DEBUGON if (*debug)
- #define LF putchar('\n')
-
- /************************************************************************/
-
- reader ( fun , const , nparam , param , limit , dstep , pname ,
- epsilon , itermin , iterlim , nreset , g0 , debug ,
- data , npoints , npmax , method )
-
- int *fun ; /* address of function (non-portable) */
- double const[] ; /* values of constants used in fcn */
- int *nparam ; /* number of parameters to be found by fitting */
- double param[] ; /* starting values of parameters */
- BOUND limit[] ; /* on-off flag, upper and lower limits */
- double dstep[] ; /* step sizes used to calculate derivatives */
- char *pname[] ; /* parameter names */
- double epsilon[] ; /* vector of stopping criteria for iteration */
- int *itermin ; /* minimum number of iterations required */
- int *iterlim ; /* maximum number of iterations allowed */
- int *nreset ; /* # of iters to reset y matrix */
- double *g0; /* expected value of minimum */
- int *debug ; /* debug mode */
- DATA data[] ; /* data from input file */
- int *npoints ; /* number of data points */
- int npmax ; /* maximum number of data points allowed */
- int *method ; /* dfp or bfgs updating method */
- {
- int nconst ; /* number of constants used in fcn */
- char instring[LEN] ;
- char *restofline ;
- char *firstword ;
- static char funname[] = " " ;
- static char *key[MAXKEY] =
- {
- "bfgs" , /* 0 */
- "constants" , /* 1 */
- "debug" , /* 2 */
- "derivsteps" , /* 3 */
- "dfp" , /* 4 */
- "end" , /* 5 */
- "epsilons" , /* 6 */
- "exmin" , /* 7 */
- "funname" , /* 8 */
- "iterlim" , /* 9 */
- "itermin" , /* 10 */
- "limitflags" , /* 11 */
- "lowerlimits" , /* 12 */
- "newdata" , /* 13 */
- "next" , /* 14 */
- "pstart" , /* 15 */
- "reset" , /* 16 */
- "sd" , /* 17 */
- "upperlimits" /* 18 */
- } ;
-
- /*
- * note above order; keywords are tested below in same order...
- * remember this when adding keywords!
- */
-
- int i , j , ncmd , ncom , bad ;
-
- #ifdef C80
- int chan ;
- #else
- FILE *chan ;
- FILE *fopen() ;
- char *fgets() ;
- #endif
-
- /*
- * loop until a "next" or "end" command is picked up
- */
-
- ncmd = ncom = bad = 0 ;
- for (;;)
- {
-
- #ifdef C80
- if ( ! getline( instring , LEN ) )
- return( ALLDONE ) ;
-
- printf("%s\n", instring) ;
-
- /*
- * C-80 library routine getline returns the line stored into
- * "instring" with the null at the end, but with the '\n'
- * stripped off.
- */
-
- #else
- if (fgets( instring , LEN , stdin ) == NULL)
- return(ALLDONE);
-
- printf("%s", instring) ;
- #endif
-
- restofline = instring ;
- getnext( &restofline , &firstword ) ;
-
- for ( j=0 ; j<MAXKEY ; ++j )
- if ( ! strcmp( firstword , key[j] ) )
- break ;
-
- switch (j)
- {
- /* bfgs */
- case 0:
- ++ncmd ;
- DEBUGON printf("bfgs update requested\n") ;
- *method = BFGS ;
- break ;
- /* constants */
- case 1:
- ++ncmd ;
- DEBUGON printf("%d constants in %s:\n", nconst ,
- funname );
- for (i=0 ; i < nconst ; ++i)
- {
- getnext( &restofline , &firstword ) ;
- if( check( firstword ) )
- {
- ++bad;
- break;
- }
- const[i] = (double) atof( firstword ) ;
- DEBUGON printf("%e ", const[i]);
- }
- DEBUGON LF;
- break ;
- /* debug */
- case 2:
- ++ncmd ;
- getnext( &restofline , &firstword ) ;
- if ( check( firstword ) )
- {
- ++bad;
- break;
- }
-
- *debug = atoi( firstword ) ;
- DEBUGON printf("debug level is %d\n", *debug);
- break ;
- /* derivsteps */
- case 3:
- ++ncmd ;
- DEBUGON printf("derivsteps are:\n");
- for (i=0 ; i < *nparam ; ++i)
- {
- getnext( &restofline , &firstword ) ;
- if ( check( firstword ) )
- {
- ++bad;
- break;
- }
- dstep[i] = (double) atof( firstword ) ;
- DEBUGON printf("%e ", dstep[i]);
- }
- DEBUGON LF;
- break ;
- /* dfp */
- case 4:
- ++ncmd ;
- DEBUGON printf("dfp update requested\n") ;
- *method = DFP ;
- break ;
- /* end */
- case 5:
- DEBUGON printf("end of all data\n") ;
- return( ALLDONE ) ;
- /* epsilons */
- case 6:
- ++ncmd ;
- DEBUGON printf("%d epsilons for cutoffs:\n",
- NEPS );
- for (i=0 ; i < NEPS ; ++i)
- {
- getnext( &restofline , &firstword ) ;
- if( check( firstword ) )
- {
- ++bad;
- break;
- }
- epsilon[i] = (double) atof( firstword );
- DEBUGON printf("%e ", epsilon[i]);
- }
- DEBUGON LF;
- break ;
- /* exmin */
- case 7:
- ++ncmd ;
- getnext( &restofline , &firstword ) ;
- if ( check( firstword ) )
- {
- ++bad;
- break;
- }
- *g0 = (double) atof( firstword ) ;
- DEBUGON printf("expected minimum is %11.4e\n", *g0);
- break ;
- /* funname */
- case 8:
- ++ncmd ;
- getnext( &restofline , &firstword ) ;
- if( check( firstword ) )
- {
- ++bad;
- break;
- }
- strcpy( funname , firstword ) ;
- DEBUGON printf("function to minimize is %s\n",
- funname ) ;
-
- if ( funlib( funname, fun, nparam, &nconst, pname))
- {
- DEBUGON printf("function not in library!\n") ;
- ++bad ;
- }
- break ;
- /* iterlim */
- case 9:
- ++ncmd ;
- getnext( &restofline , &firstword ) ;
- if( check( firstword ))
- {
- ++bad;
- break;
- }
- *iterlim = atoi( firstword ) ;
- DEBUGON printf("iterlim is %d\n", *iterlim);
- break ;
- /* itermin */
- case 10:
- ++ncmd ;
- getnext( &restofline , &firstword ) ;
- if( check( firstword ) )
- {
- ++bad;
- break;
- }
- *itermin = atoi( firstword ) ;
- DEBUGON printf("itermin is %d\n", *itermin);
- break ;
- /* limitflags */
- case 11:
- ++ncmd ;
- DEBUGON printf("limitflags are:\n") ;
- for (i=0 ; i < *nparam ; ++i)
- {
- getnext( &restofline , &firstword ) ;
- if ( check( firstword ) )
- {
- ++bad;
- break;
- }
- limit[i].fl = atoi( firstword ) ;
- DEBUGON printf("%d ", limit[i].fl);
- }
- DEBUGON LF;
- break ;
- /* lowerlimits */
- case 12:
- ++ncmd ;
- DEBUGON printf("lowerlimits are:\n") ;
- for (i=0 ; i < *nparam ; ++i)
- {
- getnext( &restofline , &firstword ) ;
- if ( check( firstword ) )
- {
- ++bad;
- break;
- }
- limit[i].lo = (double) atof( firstword ) ;
- DEBUGON printf("%e ", limit[i].lo);
- }
- DEBUGON LF;
- break ;
- /* newdata */
- case 13:
- ++ncmd ;
- getnext( &restofline , &firstword ) ;
- DEBUGON printf("datafile requested was %s\n" ,
- firstword ) ;
- if ( check( firstword ) )
- {
- ++bad;
- break;
- }
-
- chan = fopen( firstword , "r");
-
- if ( !chan )
- {
- printf("datafile can't be opened!\n") ;
- return( ALLDONE ) ;
- }
-
- fscanf( chan , "%d" , npoints ) ;
- DEBUGON printf("%d datapoints in file\n", *npoints);
-
- if (*npoints > npmax)
- {
- ++bad ;
- printf("more data than allowed!\n") ;
- printf("%d datapoints in file\n", *npoints);
- printf("%d points allowed for\n", npmax ) ;
- break ;
- }
-
- for (i=0 ; i<*npoints ; ++i)
- {
- #ifdef C80
- fscanf(chan, "%f %f", &data[i].x, &data[i].y);
- #else
- fscanf(chan,"%lf %lf",&data[i].x, &data[i].y);
- #endif
- DEBUGON printf("%3d %f %f\n" , i+1 ,
- data[i].x , data[i].y ) ;
- }
- fclose( chan ) ;
- break ;
- /* next */
- case 14:
- ++ncmd ;
- DEBUGON printf("end of this data set\n");
- printf("%2d command lines read\n", ncmd) ;
- printf("%2d comment lines read\n", ncom) ;
-
- if( ! *nparam )
- ++bad ;
-
- return( bad ) ;
- /* pstart */
- case 15:
- ++ncmd ;
- DEBUGON printf("starting values are:\n" ) ;
- for (i=0 ; i < *nparam ; ++i)
- {
- getnext( &restofline , &firstword ) ;
- if ( check( firstword ) )
- {
- ++bad;
- break;
- }
- param[i] = (double) atof( firstword ) ;
- DEBUGON printf("%e ", param[i]);
- }
- DEBUGON LF;
- break ;
- /* reset */
- case 16:
- ++ncmd ;
- getnext( &restofline , &firstword ) ;
- if( check( firstword ) )
- {
- ++bad;
- break;
- }
- *nreset = atoi( firstword ) ;
- DEBUGON printf("reset is %d\n", *nreset);
- break ;
- /* sd */
- case 17:
- ++ncmd ;
- DEBUGON printf("steepest descent update requested\n") ;
- *method = STDES ;
- break ;
- /* upperlimits */
- case 18:
- ++ncmd ;
- DEBUGON printf("upperlimits are:\n");
- for (i=0 ; i < *nparam ; ++i)
- {
- getnext( &restofline , &firstword ) ;
- if ( check( firstword ) )
- {
- ++bad;
- break;
- }
- limit[i].up = (double) atof( firstword ) ;
- DEBUGON printf("%e ", limit[i].up);
- }
- DEBUGON LF;
- break ;
-
- /*
- * anything else is a comment; throw away and go
- * to next line.
- */
-
- default:
- ++ncom ;
- DEBUGON printf("***%s*** taken as comment\n",
- firstword ) ;
- }
- }
- }
-
- /*************************************************************************/
-
- getnext( string , next )
- char **string ;
- char **next ;
- {
- /*
- * splits the input string "string" into two pieces:
- * "next" contains the first word with no leading or trailing blanks
- * "string" then contains the rest of the line
- */
-
- int length ;
- char *p ;
-
- length = strlen( p = *string ) ;
- while( length-- > 0 && isspace( *p++ ) )
- ;
-
- *next = --p ;
-
- while( length-- >= 0 && !isspace( *++p ) )
- ;
-
- *p = '\0' ;
- *string = ++p ;
- }
- /*************************************************************************/
-
- check( string )
- char *string ;
- {
- /*
- * checks if a string starts with a blank
- * if the string was obtained with getnext, this means the string
- * is blank unconditionally report this error
- */
-
- if ( ! *string )
- {
- printf("Unexpected blank encountered!\n") ;
- return( 1 ) ;
- }
- else
- return( 0 ) ;
- }
-
-
- LISTING EIGHT
- Test input for the VMM program
- File name is "a1.dat"
- Sample input using the Cohen function
- Demonstrates using the limit flags and detail debug printout
- funname cohen
- pstart 1.0 1.0
- limitflags 1 1
- lowerlimits 0.5 0.75
- upperlimits 2.0 3.0
- iterlim 10
- debug 2
- next
- This case tests a function which uses "experimental" data
- Note the non-default epsilons for this case
- funname sine
- pstart 1.57 -0.65 0.08 -0.005
- epsilons 1.0e-14 1.0e-6
- newdata b:sine.dat
- iterlim 12
- reset 8
- debug 1
- next
- The following cases use the Rosenbrock function
- These correspond to the benchmarks...
- Case 1
- funname rosen
- pstart -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0
- constants 100. 100. 100. 100. 100.
- sd
- next
- Case 2
- funname rosen
- pstart -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0
- constants 10. 10. 10. 10. 10.
- sd
- next
- Case 3
- funname rosen
- pstart -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0
- constants 1. 1. 1. 1. 1.
- sd
- next
- Case 4
- funname rosen
- pstart 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8
- constants 100. 100. 100. 100. 100.
- sd
- next
- Case 5
- funname rosen
- pstart 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8
- constants 10. 10. 10. 10. 10.
- sd
- next
- Case 6
- funname rosen
- pstart 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8
- constants 1. 1. 1. 1. 1.
- sd
- next
- Case 7
- funname rosen
- pstart -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0
- constants 100. 100. 100. 100. 100.
- dfp
- reset 5
- next
- Case 8
- funname rosen
- pstart -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0
- constants 10. 10. 10. 10. 10.
- dfp
- reset 5
- next
- Case 9
- funname rosen
- pstart -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0
- constants 1. 1. 1. 1. 1.
- dfp
- reset 5
- next
- Case 10
- funname rosen
- pstart 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8
- constants 100. 100. 100. 100. 100.
- dfp
- reset 5
- next
- Case 11
- funname rosen
- pstart 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8
- constants 10. 10. 10. 10. 10.
- dfp
- reset 5
- next
- Case 12
- funname rosen
- pstart 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8
- constants 1. 1. 1. 1. 1.
- dfp
- reset 5
- next
- Case 13
- funname rosen
- pstart -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0
- constants 100. 100. 100. 100. 100.
- bfgs
- reset 5
- next
- Case 14
- funname rosen
- pstart -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0
- constants 10. 10. 10. 10. 10.
- bfgs
- reset 5
- next
- Case 15
- funname rosen
- pstart -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0 -1.2 1.0
- constants 1. 1. 1. 1. 1.
- bfgs
- reset 5
- next
- Case 16
- funname rosen
- pstart 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8
- constants 100. 100. 100. 100. 100.
- bfgs
- reset 5
- next
- Case 17
- funname rosen
- pstart 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8
- constants 10. 10. 10. 10. 10.
- bfgs
- reset 5
- next
- Case 18
- funname rosen
- pstart 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8 1.2 0.8
- constants 1. 1. 1. 1. 1.
- bfgs
- reset 5
- next
- end
-
-
- /* LISTING NINE
- * The way it is done in vmm
- * This works and will be portable
- * so long as addresses are the
- * same size as ints.
- * Fine on 16 bit systems with "small
- * model" e.g. 64K programs
- */
-
- #define double float
- #include "fprintf.h"
- #include "scanf.h"
- /*---------------------------------*/
- main()
- {
- double *(*fun)() ;
- double a , b ;
-
- while(1) {
- readit( &fun , &a , &b ) ;
- doit( fun , a , b ) ;
- }
- }
- /*----------------------------------*/
- readit( fun , a , b )
- int *fun ;
- double *a ;
- double *b ;
- {
- char string[10] ;
-
- scanf("%s %f %f", string , a , b ) ;
-
- funlib( fun , string ) ;
- }
- /*------------------------------------*/
- funlib( fun , string )
- int *fun ;
- char string[] ;
- {
- double sum() ;
- double mul() ;
-
- if ( !strcmp( string, "add" ) ) *fun = sum ;
- else if ( !strcmp( string, "mul" ) ) *fun = mul ;
- else exit(0);
- }
- /*---------------------------------------*/
- doit( fun , a , b )
- double (*fun)() ;
- double a ;
- double b ;
- {
- double g ;
- g = (*fun)( a , b ) ;
- printf("%f is the result\n" , g ) ;
- }
- /*----------------------------------------*/
- double sum( a , b )
- double a ;
- double b ;
- {
- printf("%f + %f = %f\n" , a , b , a+b ) ;
- return( a + b ) ;
- }
- /*----------------------------------------*/
- double mul( a , b )
- double a ;
- double b ;
- {
- printf("%f * %f = %f\n" , a , b , a*b ) ;
- return( a * b ) ;
- }
-
-
- /* LISTING TEN
- * The correct and most portable way to pass an object which is a
- * pointer to a function
- */
-
- #include <stdio.h>
- /*---------------------------------*/
- main()
- {
- double (*fun)() ; /* fun is a pointer to a function
- * which returns a double
- */
- double (*readit())() ; /* readit is a function that
- * returns a pointer to a function
- * that returns a double
- */
- double a , b ;
-
- while(1) {
- fun = readit( &a , &b ) ;
- doit( fun , a , b ) ;
- }
- }
-
- /*----------------------------------*/
-
- double (*readit( a , b ))() /* note position of arguments */
- double *a ;
- double *b ;
- {
- double (*fun)() ;
- double (*funlib())() ; /* funlib is a function which
- * returns a pointer to a function
- * which returns a double
- */
- char string[10] ;
-
- scanf("%s %lf %lf", string , a , b ) ;
-
- fun = funlib( string ) ;
- return( fun ) ;
- }
-
- /*------------------------------------*/
-
- double (*funlib( string ))() /* note position of arguments */
- char string[] ;
- {
- double (*fun)() ;
- double sum() ;
- double mul() ;
-
- if ( !strcmp( string, "add" ) )
- fun = sum ;
- else if ( !strcmp( string, "mul" ) )
- fun = mul ;
- else
- exit(0);
-
- return( fun ) ;
- }
-
- /*---------------------------------------*/
- doit( fun , a , b )
- double (*fun)() ;
- double a ;
- double b ;
- {
- double g ;
- g = (*fun)( a , b ) ;
- printf("%f is the result\n" , g ) ;
- }
- /*----------------------------------------*/
- double sum( a , b )
- double a ;
- double b ;
- {
- printf("%f + %f = %f\n" , a , b , a+b ) ;
- return( a + b ) ;
- }
- /*----------------------------------------*/
- double mul( a , b )
- double a ;
- double b ;
- {
- printf("%f * %f = %f\n" , a , b , a*b ) ;
- return( a * b ) ;
- }
-
- *END OF LISTINGS
-