ADMB Documentation  11.1.1021
 All Classes Files Functions Variables Typedefs Friends Defines
lmnewton.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: lmnewton.cpp 899 2013-03-30 01:21:44Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00007 #include <admodel.h>
00008 
00009 #ifdef __cplusplus
00010 extern "C" {
00011 #endif
00012   int lbfgs_(long int *, long int *, double *, 
00013       double *, double *, long int *, double *, long int *, 
00014       double *, double *, double *, long int *,long int *,
00015             long int *);
00016 #ifdef __cplusplus
00017   }
00018 #endif
00019 
00020 void function_minimizer::limited_memory_quasi_newton(const independent_variables& _x, int m)
00021 {
00022   independent_variables& x = (independent_variables&) _x;
00023   if (m<=0)
00024   {
00025     cerr << "illegal value for number of steps in limited memory"
00026       " quasi-newton method -- set equal to 10" << endl;
00027   }
00028   int noprintx=0;
00029   int on;
00030   int maxfn_option=0;
00031   if ( (on=option_match(ad_comm::argc,ad_comm::argv,"-maxfn"))>-1)
00032   {
00033     maxfn_option=1;
00034   }
00035   if ( (on=option_match(ad_comm::argc,ad_comm::argv,"-nox"))>-1)
00036   {
00037     noprintx=1;
00038   }
00039   int nvar=initial_params::nvarcalc(); // get the number of active
00040   double _crit=0;
00041   int itn=0;
00042   int ifn=0;
00043   int nopt;
00044   // set the convergence criterion by command line
00045   if ( (on=option_match(ad_comm::argc,ad_comm::argv,"-crit",nopt))>-1)
00046   {
00047     if (!nopt)
00048     {
00049       cerr << "Usage -crit option needs number  -- ignored" << endl;
00050     }
00051     else
00052     {   
00053       char * end;
00054       _crit=strtod(ad_comm::argv[on+1],&end);
00055       if (_crit<=0)
00056       {
00057         cerr << "Usage -crit option needs positive number  -- ignored" << endl;
00058         _crit=0.0;
00059       } 
00060     }
00061   }
00062 
00063   gradient_structure::set_YES_DERIVATIVES();
00064   // set convergence criterion for this phase
00065   if (!(!convergence_criteria))
00066   {
00067     int ind=min(convergence_criteria.indexmax(),
00068     initial_params::current_phase);
00069     crit=convergence_criteria(ind);
00070   }
00071   if (_crit)
00072   {
00073     crit = _crit;
00074   } 
00075   if (!(!maximum_function_evaluations) && !maxfn_option)
00076   {
00077     int ind=min(maximum_function_evaluations.indexmax(),
00078       initial_params::current_phase);
00079     maxfn= (int) maximum_function_evaluations(ind);
00080   }
00081   dvariable vf=0.0;
00082 
00083   double xtol, f;
00084   dvector diag(1,nvar);
00085   //int j, n, iflag, icall;
00086   int iflag, icall;
00087   double fbest=1.e+100;
00088   dvector g(1,nvar);
00089   g.initialize();
00090   dvector xbest(1,nvar);
00091   dvector gbest(1,nvar);
00092   //double t1, t2;
00093   long int diagco=0.0;
00094   int iprintx[2];
00095   //double epsx;
00096   //m = 35;
00097   dvector w(1,nvar+2*m+2*nvar*m);
00098   nopt=0;
00099   int on1;
00100   if ( (on1=option_match(ad_comm::argc,ad_comm::argv,"-iprint",nopt))>-1)
00101   {
00102     if (!nopt)
00103     {
00104       cerr << "Usage -iprint option needs integer  -- ignored" << endl;
00105     }
00106     else
00107     {   
00108       int jj=atoi(ad_comm::argv[on1+1]);
00109       iprint=jj;
00110     }
00111   }
00112   iprintx[0] = iprint;
00113   iprintx[1] = 0;
00114   crit = 1e-5;
00115   xtol = 1e-16;
00116   icall = 0;
00117   iflag = 0;
00118   long int linfo=0;
00119 
00120 L20:
00121   f = 0.;
00122   vf=initial_params::reset(dvar_vector(x));
00123   *objective_function_value::pobjfun=0.0;
00124   userfunction();
00125   vf+=*objective_function_value::pobjfun;
00126   f=value(vf);
00127   ifn++;
00128   if (f<fbest)
00129   {
00130     fbest=f;
00131     xbest=x;
00132     gbest=g;
00133   }
00134   
00135   gradcalc(nvar,g);
00136   if(fmod(double(itn),double(iprint)) == 0)
00137   {
00138     if (iprint>0)
00139     {
00140       if (!itn)
00141       {
00142         if (ad_printf) (*ad_printf)("\nInitial statistics: ");
00143       }
00144       else
00145       {
00146         if (ad_printf) (*ad_printf)("\nIntermediate statistics: ");
00147       }
00148 
00149       if (ad_printf) (*ad_printf)("%d variables; iteration %ld; function evaluation %ld\n",
00150         nvar, itn, ifn);
00151 
00152       if (!itn)
00153       {
00154         if (ad_printf) (*ad_printf)("Function value %12.4le; maximum gradient component mag %12.4le\n",
00155           f, max(fabs(g)));
00156       }
00157       else
00158       {
00159 
00160         if (ad_printf) (*ad_printf)("Function value %12.4le; maximum gradient component mag %12.4le\n",
00161           fbest, max(gbest));
00162       }
00163       if (!noprintx)
00164       {
00165         if (!itn)
00166           fmmdisp(x, g, nvar, 0,noprintx);
00167   else
00168           fmmdisp(xbest, gbest, nvar, 0,noprintx);
00169       }
00170     }
00171   }
00172   
00173   long int lnvar=nvar;
00174   long int litn=itn;
00175   long int liprintx= *iprintx;
00176   long int liflag=iflag;
00177   long int lm=m;
00178   lbfgs_(&lnvar, &lm, &(x[1]) , &f, &(g[1]), &diagco, &(diag[1]),
00179     &liprintx, &crit, &xtol, &(w[1]), &liflag,&litn,&linfo);
00180   itn=int(litn);
00181   iflag=int(liflag);
00182 
00183   if (iflag <= 0)
00184   {
00185     goto L50;
00186   }
00187   ++icall;
00188   if (icall > maxfn)
00189   {
00190     goto L50;
00191   }
00192   goto L20;
00193 L50:
00194   if (iprint>0)
00195   {
00196     if (ad_printf) (*ad_printf)("\nfinal statistics: ");
00197 
00198     if (ad_printf) (*ad_printf)("%d variables; iteration %ld; function evaluation %ld\n",
00199       nvar, itn, ifn);
00200     if (ad_printf) (*ad_printf)("Function value %12.4le; maximum gradient component mag %12.4le\n",
00201       f, max(g));
00202     fmmdisp(x, g, nvar, 0,noprintx);
00203   }
00204   gradient_structure::set_NO_DERIVATIVES();
00205   x=xbest;
00206   objective_function_value::gmax=fabs(max(gbest));
00207 }
00208 
00209 void function_minimizer::limited_memory_quasi_newton
00210   (double& f, const independent_variables& _x, int m, int noprintx,
00211   int maxfn, double crit)
00212 {
00213   independent_variables& x = (independent_variables&) _x;
00214   if (m<=0)
00215   {
00216     cerr << "illegal value for number of steps in limited memory"
00217       " quasi-newton method -- set equal to 10" << endl;
00218   }
00219   int on;
00220 
00221   int nvar=initial_params::nvarcalc(); // get the number of active
00222   double _crit=0;
00223   int itn=0;
00224   int ifn=0;
00225   int nopt;
00226   // set the convergence criterion by command line
00227   if ( (on=option_match(ad_comm::argc,ad_comm::argv,"-crit",nopt))>-1)
00228   {
00229     if (!nopt)
00230     {
00231       cerr << "Usage -crit option needs number  -- ignored" << endl;
00232     }
00233     else
00234     {   
00235       char * end;
00236       _crit=strtod(ad_comm::argv[on+1],&end);
00237       if (_crit<=0)
00238       {
00239         cerr << "Usage -crit option needs positive number  -- ignored" << endl;
00240         _crit=0.0;
00241       } 
00242     }
00243   }
00244   gradient_structure::set_YES_DERIVATIVES();
00245   dvariable vf=0.0;
00246 
00247   double xtol;
00248   dvector diag(1,nvar);
00249   //int j, n, iflag, icall;
00250   int iflag, icall;
00251   double fbest=1.e+100;
00252   dvector g(1,nvar);
00253   g.initialize();
00254   dvector xbest(1,nvar);
00255   dvector gbest(1,nvar);
00256   //double t1, t2;
00257   long int diagco=0;
00258   int iprintx[2];
00259   //double epsx;
00260   //m = 35;
00261   dvector w(1,nvar+2*m+2*nvar*m);
00262   iprintx[0] = iprint;
00263   iprintx[1] = 0;
00264   crit = 1e-5;
00265   xtol = 1e-16;
00266   icall = 0;
00267   iflag = 0;
00268   long int linfo=0;
00269 
00270 L20:
00271   f = 0.;
00272   vf=initial_params::reset(dvar_vector(x));
00273   *objective_function_value::pobjfun=0.0;
00274   userfunction();
00275   vf+=*objective_function_value::pobjfun;
00276   f=value(vf);
00277   ifn++;
00278   if (f<fbest)
00279   {
00280     fbest=f;
00281     xbest=x;
00282     gbest=g;
00283   }
00284   
00285   gradcalc(nvar,g);
00286   if(fmod(double(itn),double(iprint)) == 0)
00287   {
00288     if (iprint>0)
00289     {
00290       if (!itn)
00291       {
00292         if (ad_printf) (*ad_printf)("\nInitial statistics: ");
00293       }
00294       else
00295       {
00296         if (ad_printf) (*ad_printf)("\nIntermediate statistics: ");
00297       }
00298 
00299       if (ad_printf) (*ad_printf)("%d variables; iteration %ld; function evaluation %ld\n",
00300         nvar, itn, ifn);
00301 
00302       if (!itn)
00303       {
00304         if (ad_printf) (*ad_printf)("Function value %12.4le; maximum gradient component mag %12.4le\n",
00305           f, max(g));
00306       }
00307       else
00308       {
00309         if (ad_printf) (*ad_printf)("Function value %12.4le; maximum gradient component mag %12.4le\n",
00310           fbest, max(gbest));
00311       }
00312       if (!noprintx)
00313       {
00314         if (!itn)
00315           fmmdisp(x, g, nvar, 0,noprintx);
00316   else
00317           fmmdisp(xbest, gbest, nvar, 0,noprintx);
00318       }
00319     }
00320   }
00321   long int lnvar=nvar;
00322   long int litn=itn;
00323   long int liprintx= *iprintx;
00324   long int liflag=iflag;
00325   long int lm=m;
00326   lbfgs_(&lnvar, &lm, &(x[1]) , &f, &(g[1]), &diagco, &(diag[1]),
00327     &liprintx, &crit, &xtol, &(w[1]), &liflag,&litn,&linfo);
00328   itn=int(litn);
00329   iflag=int(liflag);
00330 
00331   if (iflag <= 0)
00332   {
00333     goto L50;
00334   }
00335   ++icall;
00336   if (icall > maxfn)
00337   {
00338     goto L50;
00339   }
00340   goto L20;
00341 L50:
00342   if (iprint>0)
00343   {
00344     if (ad_printf) (*ad_printf)("\nfinal statistics: ");
00345 
00346     if (ad_printf) (*ad_printf)("%d variables; iteration %ld; function evaluation %ld\n",
00347       nvar, itn, ifn);
00348     if (ad_printf) (*ad_printf)("Function value %12.4le; maximum gradient component mag %12.4le\n",
00349       f, max(g));
00350     fmmdisp(x, g, nvar, 0,noprintx);
00351   }
00352   //gradient_structure::set_NO_DERIVATIVES();
00353   x=xbest;
00354   f=fbest;
00355   objective_function_value::gmax=fabs(max(gbest));
00356 }
00357