ADMB Documentation  11.1.1016
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2impspf.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2impspf.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 
00016 class dvar_hs_smatrix;
00017 
00022 double calculate_importance_sample_shess(const dvector& x,const dvector& u0,
00023   const dmatrix& Hess,const dvector& _xadjoint,const dvector& _uadjoint,
00024   const dmatrix& _Hessadjoint,function_minimizer * pmin)
00025 {
00026   ADUNCONST(dvector,xadjoint)
00027   ADUNCONST(dvector,uadjoint)
00028   ADUNCONST(dmatrix,Hessadjoint)
00029   const int xs=x.size();
00030   const int us=u0.size();
00031   gradient_structure::set_YES_DERIVATIVES();
00032 
00033   int nvar=0;
00034   if (pmin->lapprox->sparse_hessian_flag==0)
00035   {
00036     cerr << "Error we should not be here" << endl;
00037     ad_exit(1);
00038   }
00039 
00040   dcompressed_triplet & lst = *(pmin->lapprox->sparse_triplet2);
00041   int smin=lst.indexmin();
00042   int smax=lst.indexmax();
00043   int sz= smax-smin+1;
00044   nvar=x.size()+u0.size()+sz;
00045   independent_variables y(1,nvar);
00046 
00047   
00048   // need to set random effects active together with whatever
00049   // init parameters should be active in this phase
00050   initial_params::set_inactive_only_random_effects(); 
00051   initial_params::set_active_random_effects(); 
00052   int onvar=initial_params::nvarcalc(); 
00053   initial_params::xinit(y);    // get the initial values into the
00054   // do we need this next line?
00055   y(1,xs)=x;
00056 
00057   int i,j;
00058   dvar_vector d(1,xs+us);
00059 
00060   // contribution for quadratic prior
00061   if (quadratic_prior::get_num_quadratic_prior()>0)
00062   {
00063     //Hess+=quadratic_prior::get_cHessian_contribution();
00064     int & vxs = (int&)(xs);
00065     quadratic_prior::get_cHessian_contribution(Hess,vxs);
00066   }
00067  // Here need hooks for sparse matrix structures
00068 
00069   int ii=xs+us+1;
00070   for (i=smin;i<=smax;i++)
00071     y(ii++)=lst(i);
00072 
00073   dvar_vector vy=dvar_vector(y); 
00074   initial_params::stddev_vscale(d,vy);
00075 
00076 
00077   ii=xs+us+1;
00078   if (initial_df1b2params::have_bounded_random_effects)
00079   {
00080     cerr << "can't do importance sampling with bounded random effects"
00081      " at present" << endl;
00082     ad_exit(1);
00083   }
00084   else
00085   {
00086 
00087     dcompressed_triplet & lst = *(pmin->lapprox->sparse_triplet2);
00088     int mmin=lst.indexmin();
00089     int mmax=lst.indexmax();
00090     dvar_compressed_triplet * vsparse_triplet = 
00091       pmin->lapprox->vsparse_triplet;
00092  
00093     if (vsparse_triplet==0)
00094     {
00095       pmin->lapprox->vsparse_triplet=
00096         new dvar_compressed_triplet(mmin,mmax,us,us);
00097       vsparse_triplet = pmin->lapprox->vsparse_triplet;
00098       for (i=mmin;i<=mmax;i++)
00099       {
00100         (*vsparse_triplet)(1,i)=lst(1,i);
00101         (*vsparse_triplet)(2,i)=lst(2,i);
00102       }
00103     }
00104     else
00105     {
00106       if (!allocated(*vsparse_triplet))
00107       {
00108         (*vsparse_triplet).allocate(mmin,mmax,us,us);
00109         for (i=mmin;i<=mmax;i++)
00110         {
00111           (*vsparse_triplet)(1,i)=lst(1,i);
00112           (*vsparse_triplet)(2,i)=lst(2,i);
00113         }
00114       } 
00115     }
00116     dcompressed_triplet * vsparse_triplet_adjoint = 
00117       pmin->lapprox->vsparse_triplet_adjoint;
00118  
00119     if (vsparse_triplet_adjoint==0)
00120     {
00121       pmin->lapprox->vsparse_triplet_adjoint=
00122         new dcompressed_triplet(mmin,mmax,us,us);
00123       vsparse_triplet_adjoint = pmin->lapprox->vsparse_triplet_adjoint;
00124       for (i=mmin;i<=mmax;i++)
00125       {
00126         (*vsparse_triplet_adjoint)(1,i)=lst(1,i);
00127         (*vsparse_triplet_adjoint)(2,i)=lst(2,i);
00128       }
00129     }
00130     else
00131     {
00132       if (!allocated(*vsparse_triplet_adjoint))
00133       {
00134         (*vsparse_triplet_adjoint).allocate(mmin,mmax,us,us);
00135         for (i=mmin;i<=mmax;i++)
00136         {
00137           (*vsparse_triplet_adjoint)(1,i)=lst(1,i);
00138           (*vsparse_triplet_adjoint)(2,i)=lst(2,i);
00139         }
00140       } 
00141     }
00142     vsparse_triplet->get_x()=vy(ii,ii+mmax-mmin).shift(1);
00143 
00144   }
00145 
00146    int nsamp=pmin->lapprox->num_importance_samples;
00147    dvar_vector sample_value(1,nsamp);
00148    sample_value.initialize();
00149    //dvar_matrix ch=choleski_decomp(inv(vHess));
00150 
00151    dvar_compressed_triplet * vsparse_triplet  
00152      = pmin->lapprox->vsparse_triplet;
00153 
00154    dvar_hs_smatrix * dhs= return_choleski_decomp(*vsparse_triplet);
00155 
00156    dvariable vf=0.0;
00157 
00158    // get fhat for ocputing weighted sums.
00159    initial_params::reset(vy);    // get the values into the model
00160    *objective_function_value::pobjfun=0.0;
00161     pmin->AD_uf_outer();
00162     double fhat=value(*objective_function_value::pobjfun);
00163    // check if we do this in a group of funnels
00164    if (pmin->lapprox->isfunnel_flag==0)
00165    {
00166      for (int is=1;is<=nsamp;is++)
00167      {
00168        //dvar_vector tau=ch*pmin->lapprox->epsilon(is);
00169        dvar_vector tau=return_choleski_factor_solve(dhs,
00170          pmin->lapprox->epsilon(is));
00171       
00172        vy(xs+1,xs+us).shift(1)+=tau;
00173        initial_params::reset(vy);    // get the values into the model
00174        vy(xs+1,xs+us).shift(1)-=tau;
00175   
00176        *objective_function_value::pobjfun=0.0;
00177        pmin->AD_uf_outer();
00178   
00179       /*
00180        if (pmin->lapprox->istudent_flag==0)
00181       */
00182        {
00183          sample_value(is)=*objective_function_value::pobjfun
00184            -0.5*norm2(pmin->lapprox->epsilon(is));
00185        }
00186       /*
00187        else
00188        {
00189          sample_value(is)=*objective_function_value::pobjfun
00190            +sum(log_student_density(pmin->lapprox->istudent_flag,
00191            pmin->lapprox->epsilon(is)));
00192        }
00193       */
00194        if (pmin->lapprox->importance_sampling_values)
00195          (*(pmin->lapprox->importance_sampling_values))(is)
00196           =value(sample_value(is))-fhat;
00197      }
00198      dvariable min_vf=min(sample_value);
00199      vf=min_vf-log(mean(exp(min_vf-sample_value))); 
00200    
00201    }
00202    else
00203    {
00204      int& nfunnelblocks=pmin->lapprox->nfunnelblocks;
00205      int lbound=1;
00206      int samplesize=nsamp/nfunnelblocks;
00207      int ubound=samplesize;
00208      int mean_count=0;
00209      dvar_vector fvalues(1,nfunnelblocks);
00210      ivector blocksizes(1,nfunnelblocks);
00211      for (int iblock=1;iblock<=nfunnelblocks;iblock++)
00212      {
00213        funnel_dvariable fdv;
00214        if (lbound>nsamp) break;
00215        ad_begin_funnel();
00216        int icount=0;
00217 
00218 
00219        for (int is=lbound;is<=ubound;is++)
00220        {
00221          if (is>nsamp) break;
00222          icount++;
00223          dvar_vector tau=return_choleski_factor_solve(dhs,
00224            pmin->lapprox->epsilon(is));
00225          vy(xs+1,xs+us).shift(1)+=tau;
00226          initial_params::reset(vy);    // get the values into the model
00227          vy(xs+1,xs+us).shift(1)-=tau;
00228 
00229          *objective_function_value::pobjfun=0.0;
00230          pmin->AD_uf_outer();
00231        /*
00232          if (pmin->lapprox->istudent_flag==0)
00233        */
00234          {
00235            sample_value(icount)=*objective_function_value::pobjfun
00236              -0.5*norm2(pmin->lapprox->epsilon(is));
00237          }
00238         /*
00239          else
00240          {
00241            sample_value(icount)=*objective_function_value::pobjfun
00242              +sum(log_student_density(pmin->lapprox->istudent_flag,
00243               pmin->lapprox->epsilon(is)));
00244          }
00245        */
00246          if (pmin->lapprox->importance_sampling_values)
00247            (*(pmin->lapprox->importance_sampling_values))(is)
00248              =value(sample_value(icount))-fhat;
00249        }
00250 
00251        if (icount>0)
00252        {
00253          mean_count+=1;
00254          dvar_vector tsp=sample_value(1,icount);
00255          double min_vf=min(value(tsp));
00256          fdv=log(mean(exp(min_vf-tsp)))-min_vf;
00257          dvariable tmp;
00258          tmp=fdv;
00259          fvalues(mean_count)=tmp;
00260          blocksizes(mean_count)=icount;
00261        }
00262        lbound+=samplesize;
00263        ubound+=samplesize;
00264      }
00265 
00266      double fm=mean(value(fvalues(1,mean_count)));
00267      dvar_vector nfval=exp(fvalues(1,mean_count)-fm);
00268      vf=-fm-log(nfval*blocksizes(1,mean_count)/sum(blocksizes(1,mean_count)));
00269    }
00270   /*
00271    if (pmin->lapprox->istudent_flag==0)
00272   */
00273    {
00274      vf-=us*0.91893853320467241; 
00275    }
00276   /*
00277    else
00278    {
00279      (*(pmin->lapprox->importance_sampling_values))
00280         +=us*0.91893853320467241; 
00281    }
00282   */
00283 
00284    dvariable ld;
00285 
00286    //dvariable sld=0.5*ln_det_choleski(make_dvar_matrix(*vsparse_triplet));
00287    dvariable sld=0.5*ln_det(*vsparse_triplet);
00288    vf+=sld;
00289 
00290    double f=value(vf);
00291    dvector g(1,nvar);
00292    gradcalc(nvar,g);
00293 
00294    // put uhat back into the model
00295    gradient_structure::set_NO_DERIVATIVES();
00296    vy(xs+1,xs+us).shift(1)=u0;
00297    initial_params::reset(vy);    // get the values into the model
00298    gradient_structure::set_YES_DERIVATIVES();
00299   
00300   ii=1;
00301   for (i=1;i<=xs;i++)
00302     xadjoint(i)=g(ii++);
00303   for (i=1;i<=us;i++)
00304     uadjoint(i)=g(ii++);
00305    
00306   dcompressed_triplet * vsparse_triplet_adjoint = 
00307     pmin->lapprox->vsparse_triplet_adjoint;
00308   int mmin=vsparse_triplet_adjoint->indexmin();
00309   int mmax=vsparse_triplet_adjoint->indexmax();
00310   vsparse_triplet_adjoint->get_x()
00311     =g(ii,ii+mmax-mmin).shift(1);
00312 
00313   return f;
00314 }
00315 
00316 #endif