ADMB Documentation  11.1.1016
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2impf.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2impf.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 double calculate_importance_sample_funnel(const dvector& x,const dvector& u0,
00021   const dmatrix& Hess,const dvector& _xadjoint,const dvector& _uadjoint,
00022   const dmatrix& _Hessadjoint,function_minimizer * pmin)
00023 {
00024   ADUNCONST(dvector,xadjoint)
00025   ADUNCONST(dvector,uadjoint)
00026   ADUNCONST(dmatrix,Hessadjoint)
00027   const int xs=x.size();
00028   const int us=u0.size();
00029   gradient_structure::set_YES_DERIVATIVES();
00030   int nvar=x.size()+u0.size()+u0.size()*u0.size();
00031   independent_variables y(1,nvar);
00032   
00033   // need to set random effects active together with whatever
00034   // init parameters should be active in this phase
00035   initial_params::set_inactive_only_random_effects(); 
00036   initial_params::set_active_random_effects(); 
00037   /*int onvar=*/initial_params::nvarcalc(); 
00038   initial_params::xinit(y);    // get the initial values into the
00039   // do we need this next line?
00040   y(1,xs)=x;
00041 
00042   int i,j;
00043   dvar_vector d(1,xs+us);
00044 
00045   // contribution for quadratic prior
00046   if (quadratic_prior::get_num_quadratic_prior()>0)
00047   {
00048     //Hess+=quadratic_prior::get_cHessian_contribution();
00049     int & vxs = (int&)(xs);
00050     quadratic_prior::get_cHessian_contribution(Hess,vxs);
00051   }
00052  // Here need hooks for sparse matrix structures
00053   int ii=xs+us+1;
00054   for (i=1;i<=us;i++)
00055     for (j=1;j<=us;j++)
00056     y(ii++)=Hess(i,j);
00057 
00058   dvar_vector vy=dvar_vector(y); 
00059   initial_params::stddev_vscale(d,vy);
00060   dvar_matrix vHess(1,us,1,us);
00061   ii=xs+us+1;
00062   if (initial_df1b2params::have_bounded_random_effects)
00063   {
00064     cerr << "can't do importance sampling with bounded random effects"
00065      " at present" << endl;
00066     ad_exit(1);
00067   }
00068   else
00069   {
00070     for (i=1;i<=us;i++)
00071     {
00072       for (j=1;j<=us;j++)
00073       {
00074         vHess(i,j)=vy(ii++);
00075       }
00076     }
00077   }
00078 
00079    int nsamp=pmin->lapprox->num_importance_samples;
00080    dvar_vector sample_value(1,nsamp);
00081    sample_value.initialize();
00082    dvar_matrix ch=choleski_decomp(inv(vHess));
00083 
00084    dvariable vf=0.0;
00085 
00086    // **************************************************************
00087    // **************************************************************
00088    // **************************************************************
00089    int& nfunnelblocks=pmin->lapprox->nfunnelblocks;
00090    int lbound=1;
00091    int samplesize=nsamp/nfunnelblocks;
00092    int ubound=samplesize;
00093    int mean_count=0;
00094    dvar_vector fvalues(1,nfunnelblocks);
00095    ivector blocksizes(1,nfunnelblocks);
00096    for (int iblock=1;iblock<=nfunnelblocks;iblock++)
00097    {
00098      funnel_dvariable fdv;
00099      if (lbound>nsamp) break;
00100      ad_begin_funnel();
00101      int icount=0;
00102 
00103   
00104      for (int is=lbound;is<=ubound;is++)
00105      {
00106        if (is>nsamp) break;
00107        icount++;
00108        dvar_vector tau=ch*pmin->lapprox->epsilon(is);
00109       
00110        vy(xs+1,xs+us).shift(1)+=tau;
00111        initial_params::reset(vy);    // get the values into the model
00112        vy(xs+1,xs+us).shift(1)-=tau;
00113   
00114        *objective_function_value::pobjfun=0.0;
00115        pmin->AD_uf_outer();
00116   
00117        if (pmin->lapprox->use_outliers==0)
00118        {
00119          sample_value(icount)=*objective_function_value::pobjfun
00120            -0.5*norm2(pmin->lapprox->epsilon(is));
00121        }
00122        else
00123        {
00124          dvector& e=pmin->lapprox->epsilon(is);
00125   
00126          sample_value(icount)=*objective_function_value::pobjfun
00127            +sum(log(.95*exp(-0.5*square(e))+.05/3.0*exp(-square(e)/18.0))); 
00128        }
00129      }
00130   
00131      if (icount>0)
00132      {
00133        mean_count+=1;
00134        dvar_vector tsp=sample_value(1,icount);
00135        double min_vf=min(value(tsp));
00136        fdv=log(mean(exp(min_vf-tsp)))-min_vf; 
00137        dvariable tmp;
00138        tmp=fdv;
00139        fvalues(mean_count)=tmp;
00140        blocksizes(mean_count)=icount;
00141      }
00142      lbound+=samplesize;
00143      ubound+=samplesize;
00144   
00145    } 
00146   
00147    double fm=mean(value(fvalues(1,mean_count)));
00148    dvar_vector nfval=exp(fvalues(1,mean_count)-fm);
00149    vf=-fm-log(nfval*blocksizes(1,mean_count)/sum(blocksizes(1,mean_count)));
00150    //vf-=us*.91893853320467241; 
00151 
00152    
00153    int sgn=0;
00154    dvariable ld;
00155    if (ad_comm::no_ln_det_choleski_flag)
00156      ld=0.5*ln_det(vHess,sgn);
00157    else
00158      ld=0.5*ln_det_choleski(vHess);
00159 
00160    vf+=ld;
00161    double f=value(vf);
00162    dvector g(1,nvar);
00163    gradcalc(nvar,g);
00164 
00165    // put uhat back into the model
00166    gradient_structure::set_NO_DERIVATIVES();
00167    vy(xs+1,xs+us).shift(1)=u0;
00168    initial_params::reset(vy);    // get the values into the model
00169    gradient_structure::set_YES_DERIVATIVES();
00170   
00171   ii=1;
00172   for (i=1;i<=xs;i++)
00173     xadjoint(i)=g(ii++);
00174   for (i=1;i<=us;i++)
00175     uadjoint(i)=g(ii++);
00176   for (i=1;i<=us;i++)
00177     for (j=1;j<=us;j++)
00178       Hessadjoint(i,j)=g(ii++);
00179   return f;
00180 }
00181 
00182 #endif