ADMB Documentation  11.1.1020
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2lmn2.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2lmn2.cpp 542 2012-07-10 21:04:06Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California 
00006  */
00011 #include <sstream>
00012 using std::istringstream;
00013 
00014 #if defined(USE_LAPLACE)
00015 #  include <admodel.h>
00016 #  include <df1b2fun.h>
00017 #  include <adrndeff.h>
00018 //#include <vmon.h>
00019 static int no_stuff=0;
00020 //static void xxxy(void) {}
00021 
00026 void function_minimizer::limited_memory_quasi_newton_block(int nvar,int _crit,
00027   independent_variables& x,const dvector& _g,const double& _f,int nsteps)
00028 {
00029   int ifn_trap=0;
00030   int itn_trap=0;
00031   int on=0;
00032   int nopt=0;
00033   if ( (on=option_match(ad_comm::argc,ad_comm::argv,"-fntrap",nopt))>-1)
00034   {
00035     if (nopt !=2)
00036     {
00037       cerr << "Usage -fntrap option needs two non-negative integers  -- ignored" << endl;
00038     }
00039     else
00040     {   
00041       ifn_trap=atoi(ad_comm::argv[on+1]);
00042       itn_trap=atoi(ad_comm::argv[on+2]);
00043     }
00044   }
00045 
00046   double & f= (double&)_f;
00047   dvector & g= (dvector&)_g;
00048   // *********************************************************
00049   // block for quasi-newton minimization
00050   //int itnold=0;
00051   int nx=nvar;
00052   if (negdirections) 
00053   {
00054     nx=negdirections->indexmax(); 
00055   }
00056   fmmt1 fmc(nx,nsteps);
00057   int on1;
00058   if ( (on1=option_match(ad_comm::argc,ad_comm::argv,"-nox"))>-1)
00059   {
00060     fmc.noprintx=1;
00061   }
00062   fmc.maxfn= maxfn;
00063   if ( (on1=option_match(ad_comm::argc,ad_comm::argv,"-dd",nopt))>-1)
00064   {
00065     if (!nopt)
00066     {
00067       cerr << "Usage -iprint option needs integer  -- ignored" << endl;
00068       //fmc.iprint=iprint;
00069     }
00070     else
00071     {   
00072       int jj=atoi(ad_comm::argv[on1+1]);
00073       fmc.dcheck_flag=jj;
00074     }
00075   }
00076   nopt=0;
00077   if ( (on1=option_match(ad_comm::argc,ad_comm::argv,"-iprint",nopt))>-1)
00078   {
00079     if (!nopt)
00080     {
00081       cerr << "Usage -iprint option needs integer  -- ignored" << endl;
00082       fmc.iprint=iprint;
00083     }
00084     else
00085     {   
00086       int jj=atoi(ad_comm::argv[on1+1]);
00087       fmc.iprint=jj;
00088     }
00089   }
00090   else
00091   {
00092     fmc.iprint= iprint;
00093   }
00094   fmc.crit = crit;
00095   fmc.imax = imax;
00096   fmc.dfn= dfn;
00097 
00098   double _dfn=1.e-2;
00099   if ( (on=option_match(ad_comm::argc,ad_comm::argv,"-dfn",nopt))>-1)
00100   {
00101     if (!nopt)
00102     {
00103       cerr << "Usage -dfn option needs number  -- ignored" << endl;
00104     }
00105     else
00106     {   
00107   
00108       istringstream ist(ad_comm::argv[on+1]);
00109       ist >> _dfn;
00110   
00111       if (_dfn<0)
00112       {
00113         cerr << "Usage -dfn option needs positive number  -- ignored" << endl;
00114         _dfn=0.0;
00115       } 
00116     }
00117   }
00118   if (_dfn>=0) 
00119   {
00120     fmc.dfn=_dfn;
00121   }
00122 
00123   fmc.scroll_flag= scroll_flag;
00124   fmc.min_improve=min_improve;
00125   gradient_structure::set_YES_DERIVATIVES();
00126   // set convergence criterion for this phase
00127   if (_crit)
00128   {
00129     fmc.crit = _crit;
00130   }
00131   if (!(!convergence_criteria))
00132   {
00133     int ind=min(convergence_criteria.indexmax(),
00134       initial_params::current_phase);
00135     fmc.crit=convergence_criteria(ind);
00136   }
00137   if (!(!maximum_function_evaluations))
00138   {
00139     int ind=min(maximum_function_evaluations.indexmax(),
00140       initial_params::current_phase);
00141     fmc.maxfn= (int) maximum_function_evaluations(ind);
00142   }
00143   int unvar=1;
00144   if (random_effects_flag)
00145   {
00146     initial_params::set_active_only_random_effects(); 
00147     //cout << nvar << endl;
00148     unvar=initial_params::nvarcalc(); // get the number of active
00149     initial_params::restore_start_phase(); 
00150     initial_params::set_inactive_random_effects(); 
00151     int nvar1=initial_params::nvarcalc(); // get the number of active
00152     if (nvar1 != nvar)
00153     {
00154       cerr << "failed sanity check in "
00155        "void function_minimizer::quasi_newton_block" << endl;
00156       ad_exit(1);
00157     }
00158   }
00159 
00160   
00161   if (!random_effects_flag || !unvar)
00162   {
00163     dvariable xf=initial_params::reset(dvar_vector(x));
00164     reset_gradient_stack();
00165     gradcalc(0,g);
00166     if (negdirections==0)
00167     {
00168       while (fmc.ireturn>=0)
00169       {
00170         fmc.fmin(f,x,g);
00171         if (fmc.ireturn>0)
00172         {
00173           dvariable vf=0.0;
00174           vf=initial_params::reset(dvar_vector(x));
00175           *objective_function_value::pobjfun=0.0;
00176           pre_userfunction();
00177           if ( no_stuff ==0 && quadratic_prior::get_num_quadratic_prior()>0)
00178           {
00179             quadratic_prior::get_M_calculations();
00180           }
00181           vf+=*objective_function_value::pobjfun;
00182           f=value(vf);
00183           gradcalc(nvar,g);
00184         }
00185       }
00186     }
00187     else
00188     {
00189       int i;
00190       int nx=negdirections->indexmax();
00191       independent_variables u(1,nx);
00192       dvector gu(1,nx);
00193       for (i=1;i<=nx;i++) u(i)=1.e-3;
00194       dvector x0(1,x.indexmax());
00195       x0=x;
00196       while (fmc.ireturn>=0)
00197       {
00198         fmc.fmin(f,u,gu);
00199         if (fmc.ireturn>0)
00200         {
00201           dvariable vf=0.0;
00202           x=x0;
00203           for (i=1;i<=nx;i++)
00204           {
00205             x+=u(i)*(*negdirections)(i);
00206           }
00207           vf=initial_params::reset(dvar_vector(x));
00208           *objective_function_value::pobjfun=0.0;
00209           pre_userfunction();
00210           if ( no_stuff ==0 && quadratic_prior::get_num_quadratic_prior()>0)
00211           {
00212             quadratic_prior::get_M_calculations();
00213           }
00214           vf+=*objective_function_value::pobjfun;
00215           f=value(vf);
00216           gradcalc(nvar,g);
00217           gu=(*negdirections)*g;
00218         }
00219       }
00220       x=x0;
00221       for (i=1;i<=nx;i++)
00222       {
00223         x+=u(i)*(*negdirections)(i);
00224       }
00225       delete negdirections;
00226       negdirections=0;
00227     }
00228   }
00229   else
00230   {
00231     // calculate the number of random effects unvar
00232     // this turns on random effects variables and turns off
00233     // everything else
00234     //cout << nvar << endl;
00235     initial_params::set_active_only_random_effects(); 
00236     //cout << nvar << endl;
00237     int unvar=initial_params::nvarcalc(); // get the number of active
00238     //df1b2_gradlist::set_no_derivatives();
00239 
00240     if (funnel_init_var::py)
00241     {
00242       delete funnel_init_var::py;
00243       funnel_init_var::py=0;
00244     }
00245     if (lapprox)
00246     {
00247       delete lapprox;
00248       lapprox=0;
00249       df1b2variable::pool->deallocate();
00250 
00251       for (int i=1;i<df1b2variable::adpool_counter;i++)
00252       {
00253         delete df1b2variable::adpool_vector[i];
00254         df1b2variable::adpool_vector[i]=0;
00255         df1b2variable::nvar_vector[i]=0;
00256       }
00257       df1b2variable::adpool_counter=0;
00258     }
00259     lapprox=new laplace_approximation_calculator(nvar,unvar,1,nvar+unvar,
00260       this); 
00261     if (lapprox==0)
00262     {
00263       cerr << "Error allocating memory for lapprox" << endl;
00264       ad_exit(1);
00265     }
00266     initial_df1b2params::current_phase=initial_params::current_phase;
00267     
00268     initial_df1b2params::save_varsptr();
00269     allocate();
00270     initial_df1b2params::restore_varsptr();
00271 
00272     df1b2_gradlist::set_no_derivatives();
00273     int nvar=initial_params::nvarcalc_all(); 
00274     dvector y(1,nvar);
00275     initial_params::xinit_all(y); 
00276     initial_df1b2params::reset_all(y);
00277 
00278     gradient_structure::set_NO_DERIVATIVES();
00279     //vmon_begin();
00280     // see what kind of hessian we are dealing with
00281     if (lapprox->have_users_hesstype==0)
00282     {
00283       if (initial_df1b2params::separable_flag)
00284       {
00285         if ( (on=option_match(ad_comm::argc,ad_comm::argv,"-newht",nopt))>-1)
00286         {
00287           lapprox->check_hessian_type2(this);
00288         }
00289         else
00290         { 
00291           lapprox->check_hessian_type(this);
00292         }
00293         cout << "Hessian type = " << lapprox->hesstype << endl;
00294       }
00295     }
00296 
00297    /*
00298     cout << "NEED to remove !!!! " << endl;
00299     initial_df1b2params::separable_flag=0;
00300     lapprox->hesstype=1;
00301    */
00302 
00303     // linear mixed effects optimization
00304     if (laplace_approximation_calculator::variance_components_vector) 
00305     {
00306       if (!lapprox)
00307       {
00308         cerr << "this can't happen" << endl;
00309         ad_exit(1);
00310       }
00311       lapprox->get_hessian_components_banded_lme(this);
00312     }
00313 
00314     if (negdirections==0)
00315     {
00316       while (fmc.ireturn>=0)
00317       {
00318         fmc.fmin(f,x,g);
00319         if (fmc.ireturn>0)
00320         {
00321           if (ifn_trap)
00322           {
00323             if (ifn_trap==fmc.ifn && itn_trap == fmc.itn)
00324             {
00325               cout << "we are here" << endl;
00326             }
00327           }
00328           g=(*lapprox)(x,f,this);
00329          /*   don't have this in official yet
00330           if (bad_step_flag==1)
00331           {
00332             g=1.e+4;
00333             f=100.*fmc.fbest;
00334           }
00335          */
00336           if (lapprox->init_switch==0)
00337           {
00338             if (f<fmc.fbest)
00339             {
00340               lapprox->ubest=lapprox->uhat;
00341             }
00342           }
00343         }
00344       }
00345     }
00346     else
00347     {
00348       int i;
00349       int nx=negdirections->indexmax();
00350       independent_variables u(1,nx);
00351       dvector x0(1,x.indexmax());
00352       x0=x;
00353       dvector gu(1,nx);
00354       for (i=1;i<=nx;i++) u(i)=1.e-3;
00355       while (fmc.ireturn>=0)
00356       {
00357         fmc.fmin(f,u,gu);
00358         if (fmc.ireturn>0)
00359         {
00360           x=x0;
00361           for (i=1;i<=nx;i++)
00362           {
00363             x+=u(i)*(*negdirections)(i);
00364           }
00365           g=(*lapprox)(x,f,this);
00366           gu=(*negdirections)*g;
00367         }
00368       }
00369       x=x0;
00370       for (i=1;i<=nx;i++)
00371       {
00372         x+=u(i)*(*negdirections)(i);
00373       }
00374       delete negdirections;
00375       negdirections=0;
00376     }
00377     initial_params::set_inactive_only_random_effects(); 
00378   }
00379 
00380   if (funnel_init_var::py)
00381   {
00382     delete funnel_init_var::py;
00383     funnel_init_var::py=0;
00384   }
00385   gradient_structure::set_NO_DERIVATIVES();
00386   ffbest=fmc.fbest;
00387   g=fmc.gbest(1,fmc.gbest.indexmax());
00388   iexit=fmc.iexit;
00389   ifn=fmc.ifn;
00390   ihflag=fmc.ihflag;
00391   ihang=fmc.ihang;
00392   maxfn_flag=fmc.maxfn_flag;
00393   quit_flag=fmc.quit_flag;
00394   objective_function_value::gmax=fabs(fmc.gmax);
00395 } // end block for quasi newton minimization
00396 
00397 #endif