ADMB Documentation  11.1.1015
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2lme.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2lme.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 #if defined(USE_LAPLACE)
00012 #  include <admodel.h>
00013 #  include <df1b2fun.h>
00014 #  include <adrndeff.h>
00015 
00020 void laplace_approximation_calculator::get_hessian_components_banded_lme
00021   (function_minimizer * pfmin)
00022 {
00023   int mmin=variance_components_vector->indexmin();
00024   int mmax=variance_components_vector->indexmax();
00025   dmatrix *tmpHess=0;
00026   switch(hesstype)
00027   {
00028   case 3:
00029     cerr << "error -- Has not been impelmented" << endl;
00030     ad_exit(1);
00031     break;
00032   case 4:
00033     if (Hess_components==0)
00034     {
00035       int umin=Hess.indexmin();
00036       int umax=Hess.indexmax();
00037       tmpHess=new dmatrix(umin,umax,umin,umax);
00038       Hess_components=new d3_array(mmin,mmax,umin,umax,umin,umax);
00039       if (tmpHess==0 || Hess_components==0)
00040       {
00041         cerr << "error allocating memory" << endl;
00042         ad_exit(1);
00043       }
00044       df1b2_gradlist::set_no_derivatives();
00045       int nvar=initial_params::nvarcalc_all(); 
00046       dvector x(1,nvar);
00047       initial_params::xinit_all(x); 
00048       initial_df1b2params::reset_all(x);
00049       for (int i=1;i<=nvar;i++) y(i)=x(i);
00050       step=get_newton_raphson_info_banded(pfmin);
00051       *tmpHess=Hess;
00052     }
00053     break;
00054   default:
00055     cerr << "Illegal value for hesstype here" << endl;
00056     ad_exit(1);
00057   }
00058 
00059   
00060   dvector df0=exp(-2.0*value(*variance_components_vector));
00061     
00062   dvector vsave(mmin,mmax);
00063   vsave=value(*variance_components_vector);
00064   for(int ic=mmin;ic<=mmax;ic++)
00065   {  
00066     (*variance_components_vector)(ic)+=0.2;
00067   
00068     // test newton raphson
00069     switch(hesstype)
00070     {
00071     case 3:
00072       bHess->initialize();
00073       break;
00074     case 4:
00075       Hess.initialize();
00076       break;
00077     default:
00078       cerr << "Illegal value for hesstype here" << endl;
00079       ad_exit(1);
00080     }
00081 
00082     df1b2_gradlist::set_no_derivatives();
00083     int nvar=initial_params::nvarcalc_all(); 
00084     dvector x(1,nvar);
00085     initial_params::xinit_all(x); 
00086     initial_df1b2params::reset_all(x);
00087     for (int i=1;i<=nvar;i++) y(i)=x(i);
00088     step=get_newton_raphson_info_banded(pfmin);
00089 
00090     switch(hesstype)
00091     {
00092     case 3:
00093       cerr << "error -- Has not been impelmented" << endl;
00094       ad_exit(1);
00095       //(*bHess_components)(ic)= *bHess;
00096       break;
00097     case 4:
00098       if (var_flag==1)
00099       {
00100         (*Hess_components)(ic)= (Hess-*tmpHess)/0.2;
00101       }
00102       else
00103       {
00104         double dfp=
00105         exp(-2.0*value(*variance_components_vector)(ic));
00106         (*Hess_components)(ic)= (Hess-*tmpHess)/(dfp-df0(ic));
00107       }
00108       (*variance_components_vector)(ic)-=0.2;
00109       break;
00110     default:
00111       cerr << "Illegal value for hesstype here" << endl;
00112       ad_exit(1);
00113     }
00114   }
00115   *variance_components_vector=vsave;
00116 }
00117 
00122 dvar_matrix laplace_approximation_calculator::get_hessian_from_components_lme
00123   (function_minimizer * pfmin)
00124 {
00125   int mmin=variance_components_vector->indexmin();
00126   int mmax=variance_components_vector->indexmax();
00127     
00128   initial_params::set_inactive_only_random_effects(); 
00129   independent_variables xx(1,mmax-mmin+1);
00130   initial_params::xinit(xx);    // get the initial values into the
00131   dvar_vector vxx=dvar_vector(xx);
00132   initial_params::reset(vxx);    // get current x values into the model
00133   int umin=Hess.indexmin();
00134   int umax=Hess.indexmax();
00135   dvar_matrix vHess(umin,umax,umin,umax);
00136   vHess.initialize();
00137   switch(hesstype)
00138   {
00139   case 3:
00140     cerr << "error -- Has not been impelmented" << endl;
00141     ad_exit(1);
00142     break;
00143   case 4:
00144     {
00145       for(int ic=mmin;ic<=mmax;ic++)
00146       {  
00147         if (var_flag==1)
00148         {
00149           vHess+= 
00150             (*variance_components_vector)(ic)*((*Hess_components)(ic));
00151         }
00152         else
00153         {
00154           vHess+= exp(-2.0*(*variance_components_vector)(ic))*
00155             ((*Hess_components)(ic));
00156         }
00157       }
00158     }
00159     break;
00160   default:
00161     cerr << "Illegal value for hesstype here" << endl;
00162     ad_exit(1);
00163   }
00164   return vHess;
00165 }
00166 
00167 
00172 dvector laplace_approximation_calculator::banded_calculations_lme
00173   (const dvector& _x,const double& _f,function_minimizer * pfmin)
00174 {
00175   // for use when there is no separability
00176   ADUNCONST(dvector,x)
00177   ADUNCONST(double,f)
00178   //int i,j;
00179 
00180   initial_params::set_inactive_only_random_effects(); 
00181   gradient_structure::set_NO_DERIVATIVES();
00182   initial_params::reset(x);    // get current x values into the model
00183   gradient_structure::set_YES_DERIVATIVES();
00184 
00185   initial_params::set_active_only_random_effects(); 
00186   dvector g=get_gradient_lme(pfmin);
00187 
00188   reset_gradient_stack();
00189   // this is the main loop to do inner optimization
00190   //for (i=1;i<=xsize;i++) { y(i)=x(i); }
00191   //for (i=1;i<=usize;i++) { y(i+xsize)=uhat(i); }
00192         
00193   dvar_matrix vHess=get_hessian_from_components_lme(pfmin);
00194   //cout << setprecision(12) << "norm(vHess) = " << norm(value(vHess)) << endl;
00195 
00196   dvariable ld;
00197   dvariable tmp=0.0;
00198   dvariable sgn;
00199 
00200   dvector step=value(solve(vHess,g,tmp,sgn)); 
00201   if (value(sgn)<=0) 
00202   {
00203     cerr << "sgn sucks" << endl;
00204   }
00205   int mmin=variance_components_vector->indexmin();
00206   int mmax=variance_components_vector->indexmax();
00207   int nv=mmax-mmin+1;
00208   dvector g1(1,nv);
00209   ld=0.5*tmp;
00210   gradcalc(nv,g1);
00211   uhat-=step;
00212  
00213   initial_params::set_active_only_random_effects(); 
00214   double maxg=max(fabs(get_gradient_lme(uhat,pfmin)));
00215   if (maxg > 1.e-12)
00216   {
00217     cout << "max g = " << maxg << endl;
00218   }
00219   
00220   double f2=0.0;
00221   dvector g2=get_gradient_lme_hp(f2,pfmin);
00222   f=f2+value(ld);
00223   return g1+g2;
00224     
00225 }
00226 
00231 dvector laplace_approximation_calculator::get_gradient_lme
00232   (function_minimizer * pfmin)
00233 {
00234   double f=0.0;
00235   //double fb=1.e+100;
00236   dvector g(1,usize);
00237   dvector ub(1,usize);
00238   independent_variables u(1,usize);
00239   gradcalc(0,g);
00240   initial_params::xinit(u);    // get the initial values into the
00241   uhat=u;
00242   
00243   dvariable pen=0.0;
00244   dvariable vf=0.0;
00245   pen=initial_params::reset(dvar_vector(u));
00246   *objective_function_value::pobjfun=0.0;
00247   pfmin->AD_uf_inner();
00248   vf+=*objective_function_value::pobjfun;
00249 
00250   objective_function_value::fun_without_pen=value(vf);
00251   vf+=pen;
00252   f=value(vf);
00253   gradcalc(usize,g);
00254   return g;
00255 }
00256 
00261 dvector laplace_approximation_calculator::get_gradient_lme
00262   (const dvector& x,function_minimizer * pfmin)
00263 {
00264   double f=0.0;
00265   //double fb=1.e+100;
00266   dvector g(1,usize);
00267   dvector ub(1,usize);
00268   independent_variables u(1,usize);
00269   u=x;
00270   gradcalc(0,g);
00271   
00272   dvariable pen=0.0;
00273   dvariable vf=0.0;
00274   pen=initial_params::reset(dvar_vector(u));
00275   *objective_function_value::pobjfun=0.0;
00276   pfmin->AD_uf_inner();
00277   vf+=*objective_function_value::pobjfun;
00278 
00279   objective_function_value::fun_without_pen=value(vf);
00280   vf+=pen;
00281   f=value(vf);
00282   gradcalc(usize,g);
00283   return g;
00284 }
00285 
00290 dvector laplace_approximation_calculator::get_gradient_lme_hp
00291   (const double& _f,function_minimizer * pfmin)
00292 {
00293   ADUNCONST(double,f)
00294   //double fb=1.e+100;
00295   dvector g(1,xsize);
00296   dvector ub(1,xsize);
00297   independent_variables u(1,xsize);
00298   //gradcalc(xsize,g);
00299   initial_params::restore_start_phase(); 
00300   initial_params::set_inactive_random_effects(); 
00301   initial_params::xinit(u);    // get the initial values into the
00302   
00303   dvariable pen=0.0;
00304   dvariable vf=0.0;
00305   pen=initial_params::reset(dvar_vector(u));
00306   *objective_function_value::pobjfun=0.0;
00307   pfmin->AD_uf_inner();
00308   vf+=*objective_function_value::pobjfun;
00309 
00310   objective_function_value::fun_without_pen=value(vf);
00311   vf+=pen;
00312   f=value(vf);
00313   gradcalc(xsize,g);
00314   return g;
00315 }
00316 
00317 #endif   //if defined(USE_LAPLACE)