示例#1
0
文件: minfil.cpp 项目: cran/marked
/**
 * Description not yet available.
 * \param
 */
dmatrix laplace_approximation_calculator::get_gradient_for_hessian_calcs
  (const dmatrix& local_Hess,double & f)
{
  int us=local_Hess.indexmax();
  int nvar=us*us;
  independent_variables cy(1,nvar);
  cy.initialize();
  int ii=1; int i,j;
  for (i=1;i<=us;i++)
    for (j=1;j<=us;j++)
      cy(ii++)=local_Hess(i,j);

  dvar_vector vy=dvar_vector(cy); 
  dvar_matrix vHess(1,us,1,us);
  
  ii=1;
  for (i=1;i<=us;i++)
    for (j=1;j<=us;j++)
      vHess(i,j)=vy(ii++);

  dvariable vf=0.0;
  int sgn=0;
    vf+=0.5*ln_det(vHess,sgn);
  f=value(vf);
  dvector g(1,nvar);
  gradcalc(nvar,g);
  dmatrix hessadjoint(1,us,1,us);
  ii=1;
  for (i=1;i<=us;i++)
    for (j=1;j<=us;j++)
      hessadjoint(i,j)=g(ii++);

  return hessadjoint;
}
示例#2
0
TEST_F(test_move, independents_gradcalc)
{
  independent_variables independents(1, 2);
  independents(1) = 1.5;
  independents(2) = 3.5;

  gradient_structure gs;

  ASSERT_EQ(0, gradient_structure::GRAD_STACK1->total());
  ASSERT_EQ(1750, gradient_structure::GRAD_LIST->total_addresses());

  dvar_vector variables(independents);

  auto sum = [&variables]()
  {
    dvariable a(variables(1));
    dvariable b(variables(2));
    return a + b;
  };

  dvariable result = sum();
  double v = value(result);

  ASSERT_DOUBLE_EQ(value(variables(1)), 1.5);
  ASSERT_DOUBLE_EQ(value(variables(2)), 3.5);

  dvector g(1, 2);
  gradcalc(2, g);

  ASSERT_DOUBLE_EQ(g(1), 1.0);
  ASSERT_DOUBLE_EQ(g(2), 1.0);
  ASSERT_DOUBLE_EQ(value(variables(1)), 1.0);
  ASSERT_DOUBLE_EQ(value(variables(2)), 1.0);
}
示例#3
0
文件: s1.cpp 项目: colemonnahan/admb
int main()
{
  double f;
  int i;
  int nvar=20;
  independent_variables x(1,nvar);  // Identify the independent variables
  dvector g(1,nvar);  // Holds the vector of partial derivatives (the gradient) 
  gradient_structure gs;    // must declare this structure to manage derivative
                            // calculations
  f=fcomp(nvar,x);
  gradcalc(nvar,g);        // The derivatives are calculated
  cout <<" The gradient vector is\n"<<g<<"\n"; // Print out the derivatives
                                               // on the screen
  return 0;
}
示例#4
0
文件: mod_hess.cpp 项目: pwoo/admb
/**
Calculate the derivatives of dependent variables with respect to
the independent variables.
*/
void function_minimizer::depvars_routine(void)
{
  reset_gradient_stack();
  dvector ggg(1,1);
  gradcalc(0,ggg);
  gradient_structure::set_YES_DERIVATIVES();
  initial_params::restore_start_phase();
  int nvar=initial_params::nvarcalc(); // get the number of active parameters
  int ndvar=stddev_params::num_stddev_calc();
  independent_variables x(1,nvar);
  initial_params::xinit(x);        // get the initial values into the x vector
  //double f;
  //double delta=1.e-7;
  adstring tmpstring="admodel.dep";
  if (ad_comm::wd_flag)
     tmpstring = ad_comm::adprogram_name + ".dep";
  ofstream ofs((char*)tmpstring);
  if (lapprox)
  {
    lapprox->no_function_component_flag=1;
  }

  dvariable vf;
  vf=initial_params::reset(dvar_vector(x));
  *objective_function_value::pobjfun=0.0;
  pre_userfunction();
  vf+=*objective_function_value::pobjfun;

  ofs << nvar << "  "  << ndvar << endl;
  int i;
  for (i=0;i< stddev_params::num_stddev_params;i++)
  {
     stddev_params::stddevptr[i]->set_dependent_variables();
  }
  gradient_structure::jacobcalc(nvar,ofs);
  for (i=0;i< stddev_params::num_stddev_params;i++)
  {
     ofs << stddev_params::stddevptr[i]->label() << "  ";
     ofs << stddev_params::stddevptr[i]->size_count() << endl;
  }
  if (lapprox)
  {
    lapprox->no_function_component_flag=0;
  }
  gradient_structure::set_NO_DERIVATIVES();
}
示例#5
0
double function_minimizer::get_monte_carlo_value(int nvar,
  const independent_variables& x,dvector& g)
{
  //initial_params::xinit(x);
  double f=0.0;
  if (mcmc2_flag==0 && lapprox)
  {
    g=(*lapprox)(x,f,this);
  }
  else
  {
    dvariable vf=0.0;
    vf=initial_params::reset(dvar_vector(x));
    *objective_function_value::pobjfun=0.0;
    userfunction();
    vf+=*objective_function_value::pobjfun;
    f=value(vf);
    gradcalc(nvar,g);
  }
  return f;
}
示例#6
0
/**
 * Description not yet available.
 * \param
 */
dvector laplace_approximation_calculator::get_uhat_quasi_newton_block_diagonal
  (const dvector& x,function_minimizer * pfmin)
{
  if (separable_function_difference)
  {
    delete separable_function_difference;
    separable_function_difference=0;
  }
#ifndef OPT_LIB
  assert(num_separable_calls > 0);
#endif

  separable_function_difference = new dvector(1,num_separable_calls);

  fmm** pfmc1 = new pfmm[static_cast<unsigned int>(num_separable_calls)];
  pfmc1--;
  ivector ishape(1,num_separable_calls);
  dvector gmax(1,num_separable_calls);
  gmax.initialize();

  for (int i=1;i<=num_separable_calls;i++)
  {
    int m=(*derindex)(i).indexmax();
    ishape(i)=m;
    if (m>0)
    {
    pfmc1[i] = new fmm(m);
    pfmc1[i]->iprint=0;
    pfmc1[i]->crit=inner_crit;
    pfmc1[i]->ireturn=0;
    pfmc1[i]->itn=0;
    pfmc1[i]->ifn=0;
    pfmc1[i]->ialph=0;
    pfmc1[i]->ihang=0;
    pfmc1[i]->ihflag=0;
    pfmc1[i]->maxfn=100;
    pfmc1[i]->gmax=1.e+100;
    pfmc1[i]->use_control_c=0;
    }
    else
    {
      pfmc1[i]= (fmm *)(0);
    }
  }
  dmatrix gg(1,num_separable_calls,1,ishape);
  dmatrix ggb(1,num_separable_calls,1,ishape);
  dmatrix uu(1,num_separable_calls,1,ishape);
  dmatrix uub(1,num_separable_calls,1,ishape);
  dvector ff(1,num_separable_calls);
  dvector ffb(1,num_separable_calls);
  ivector icon(1,num_separable_calls);
  icon.initialize();
  ffb=1.e+100;

  double f=0.0;
  double fb=1.e+100;
  dvector g(1,usize);
  dvector ub(1,usize);
  independent_variables u(1,usize);
  gradcalc(0,g);
  fmc1.itn=0;
  fmc1.ifn=0;
  fmc1.ireturn=0;
  initial_params::xinit(u);    // get the initial values into the
  fmc1.ialph=0;
  fmc1.ihang=0;
  fmc1.ihflag=0;

  if (init_switch)
  {
    u.initialize();
  }

  for (int ii=1;ii<=2;ii++)
  {
    // get the initial u into the uu's
    for (int i=1;i<=num_separable_calls;i++)
    {
      int m=(*derindex)(i).indexmax();
      for (int j=1;j<=m;j++)
      {
        uu(i,j)=u((*derindex)(i)(j));
      }
    }

#ifdef DIAG
    bool loop_flag = false;
    int loop_counter = 0;
#endif

    fmc1.dfn=1.e-2;
    dvariable pen=0.0;
    int converged=0;
    int initrun_flag=1;
    while (converged==0)
    {
#ifdef DIAG
      if (loop_flag) loop_counter++;
      if (loop_counter > 18)
      {
        cout << loop_counter;
      }
#endif
      if (!initrun_flag)
      {
        converged=1;
      }
      for (int i=1;i<=num_separable_calls;i++)
      {
        if (ishape(i)>0) //check to see if there are any active randoem effects
        {               // in this function call
          if (!icon(i))
          {
            independent_variables& uuu=*(independent_variables*)(&(uu(i)));
            (pfmc1[i])->fmin(ff[i],uuu,gg(i));
            gmax(i)=fabs(pfmc1[i]->gmax);
            if (!initrun_flag)
            {
              if (gmax(i)<1.e-4  || pfmc1[i]->ireturn<=0)
              {
                icon(i)=1;
              }
              else
              {
                converged=0;
              }
            }
          }
        }
      }
      initrun_flag=0;
      for (int i2=1;i2<=num_separable_calls;i2++)
      {
        int m=(*derindex)(i2).indexmax();
        for (int j=1;j<=m;j++)
        {
          u((*derindex)(i2)(j))=uu(i2,j);
        }
      }
      // put the
      //if (fmc1.ireturn>0)
      {
        dvariable vf=0.0;
        pen=initial_params::reset(dvar_vector(u));
        *objective_function_value::pobjfun=0.0;

        //num_separable_calls=0;

        pmin->inner_opt_flag=1;
        pfmin->AD_uf_inner();
        pmin->inner_opt_flag=0;

        if (saddlepointflag)
        {
          *objective_function_value::pobjfun*=-1.0;
        }
        if ( no_stuff==0 && quadratic_prior::get_num_quadratic_prior()>0)
        {
          quadratic_prior::get_M_calculations();
        }
        vf+=*objective_function_value::pobjfun;

        objective_function_value::fun_without_pen=value(vf);
        vf+=pen;

        gradcalc(usize,g);
        for (int i=1;i<=num_separable_calls;i++)
        {
          int m=(*derindex)(i).indexmax();
          for (int j=1;j<=m;j++)
          {
            gg(i,j)=g((*derindex)(i)(j));
          }
        }
        {
          ofstream ofs("l:/temp1.dat");
          ofs << g.indexmax() << " " << setprecision(15) << g << endl;
        }
        if (saddlepointflag==2)
        {
          ff[1]=-(*separable_function_difference)(1);
          for (int i=2;i<=num_separable_calls;i++)
          {
            ff[i]=-(*separable_function_difference)(i);
            //ff[i]=-(*separable_function_difference)(i)
             // +(*separable_function_difference)(i-1);

            if (ff[i] < ffb[i])
            {
              ffb[i]=ff[i];
              uub[i]=uu[i];
              ggb[i]=gg[i];
            }
          }
        }
        else
        {
          ff[1]=(*separable_function_difference)(1);
          for (int i=2;i<=num_separable_calls;i++)
          {
            ff[i]=(*separable_function_difference)(i);
            //ff[i]=(*separable_function_difference)(i)
             // -(*separable_function_difference)(i-1);

            if (ff[i] < ffb[i])
            {
              ffb[i]=ff[i];
              uub[i]=uu[i];
              ggb[i]=gg[i];
            }
          }
        }
        f=0.0;
        for (int i2=1;i2<=num_separable_calls;i2++)
        {
          f+=ff[i2];
        }
        if (f<fb)
        {
          fb=f;
          ub=u;
        }
      }
      u=ub;
    }
    double tmax=max(gmax);
    cout <<  " inner maxg = " << tmax << endl;

    if (tmax< 1.e-4) break;
  }
  fmc1.ireturn=0;
  fmc1.fbest=fb;
  gradient_structure::set_NO_DERIVATIVES();
  //num_separable_calls=0;
  pmin->inner_opt_flag=1;
  pfmin->AD_uf_inner();
  pmin->inner_opt_flag=0;
  if ( no_stuff==0 && quadratic_prior::get_num_quadratic_prior()>0)
  {
    quadratic_prior::get_M_calculations();
  }
  gradient_structure::set_YES_DERIVATIVES();
  for (int i=1;i<=num_separable_calls;i++)
  {
    if (pfmc1[i])
    {
      delete pfmc1[i];
    }
  }
  pfmc1++;
  delete [] pfmc1;
  pfmc1 = 0;
  return u;
}
示例#7
0
文件: mod_hess.cpp 项目: pwoo/admb
void function_minimizer::hess_routine_noparallel(void)
{
  int nvar=initial_params::nvarcalc(); // get the number of active parameters
  //if (adjm_ptr) set_labels_for_hess(nvar);
  independent_variables x(1,nvar);
  initial_params::xinit(x);        // get the initial values into the x vector
  double delta=1.e-5;
  dvector g1(1,nvar);
  dvector g2(1,nvar);
  dvector gbest(1,nvar);
  dvector hess(1,nvar);
  dvector hess1(1,nvar);
  dvector hess2(1,nvar);
  double eps=.1;
  gradient_structure::set_YES_DERIVATIVES();
  gbest.fill_seqadd(1.e+50,0.);

  adstring tmpstring="admodel.hes";
  if (ad_comm::wd_flag)
     tmpstring = ad_comm::adprogram_name + ".hes";
  uostream ofs((char*)tmpstring);

  ofs << nvar;
  {
    {
      dvariable vf=0.0;
      vf=initial_params::reset(dvar_vector(x));
      *objective_function_value::pobjfun=0.0;
      pre_userfunction();
      vf+=*objective_function_value::pobjfun;
      gradcalc(nvar, g1, vf);
    }
    double sdelta1;
    double sdelta2;
    for (int i=1;i<=nvar;i++)
    {
      hess_calcreport(i,nvar);

      double xsave=x(i);
      sdelta1=x(i)+delta;
      sdelta1-=x(i);
      x(i)=xsave+sdelta1;
      dvariable vf=0.0;
      vf=initial_params::reset(dvar_vector(x));
      *objective_function_value::pobjfun=0.0;
      pre_userfunction();
      vf+=*objective_function_value::pobjfun;
      gradcalc(nvar, g1, vf);

      sdelta2=x(i)-delta;
      sdelta2-=x(i);
      x(i)=xsave+sdelta2;
      vf=0.0;
      vf=initial_params::reset(dvar_vector(x));
      *objective_function_value::pobjfun=0.0;
      pre_userfunction();
      vf+=*objective_function_value::pobjfun;
      gradcalc(nvar, g2, vf);
      x(i)=xsave;
      hess1=(g1-g2)/(sdelta1-sdelta2);

      sdelta1=x(i)+eps*delta;
      sdelta1-=x(i);
      x(i)=xsave+sdelta1;
      vf=0.0;
      vf=initial_params::reset(dvar_vector(x));
      *objective_function_value::pobjfun=0.0;
      pre_userfunction();
      vf+=*objective_function_value::pobjfun;
      gradcalc(nvar, g1, vf);

      x(i)=xsave-eps*delta;
      sdelta2=x(i)-eps*delta;
      sdelta2-=x(i);
      x(i)=xsave+sdelta2;
      vf=0.0;
      vf=initial_params::reset(dvar_vector(x));
      *objective_function_value::pobjfun=0.0;
      pre_userfunction();
      vf+=*objective_function_value::pobjfun;
      gradcalc(nvar, g2, vf);
      x(i)=xsave;

      vf=initial_params::reset(dvar_vector(x));
      double eps2=eps*eps;
      hess2=(g1-g2)/(sdelta1-sdelta2);
      hess=(eps2*hess1-hess2) /(eps2-1.);

      ofs << hess;
      //if (adjm_ptr) ad_update_hess_stats_report(nvar,i);
    }
  }
  ofs << gradient_structure::Hybrid_bounded_flag;
  dvector tscale(1,nvar);   // need to get scale from somewhere
  /*int check=*/initial_params::stddev_scale(tscale,x);
  ofs << tscale;
}
示例#8
0
文件: mod_hess.cpp 项目: pwoo/admb
void function_minimizer::hess_routine_and_constraint(int iprof,
  const dvector& g, dvector& fg)
{
  int nvar=initial_params::nvarcalc(); // get the number of active parameters
  independent_variables x(1,nvar);
  initial_params::xinit(x);        // get the initial values into the x vector
  double delta=1.e-6;
  dvector g1(1,nvar);
  dvector g2(1,nvar);
  dvector gbest(1,nvar);
  dvector hess(1,nvar);
  dvector hess1(1,nvar);
  dvector hess2(1,nvar);
  //double eps=.1;
  gradient_structure::set_YES_DERIVATIVES();
  gbest.fill_seqadd(1.e+50,0.);
  uostream ofs("admodel.hes");
  //ofstream ofs5("tmphess");
  double lambda=fg*g/norm2(g);
  cout << fg-lambda*g << endl;
  cout << norm(fg-lambda*g) << " " << fg*g/(norm(g)*norm(fg)) << endl;
  ofs << nvar;
  {
    {
      dvariable vf=0.0;
      vf=initial_params::reset(dvar_vector(x));
      *objective_function_value::pobjfun=0.0;
      pre_userfunction();
      vf+=*objective_function_value::pobjfun;
      vf-=lambda*likeprof_params::likeprofptr[iprof]->variable();
      gradcalc(nvar, g1, vf);
    }
    double sdelta1;
    double sdelta2;

    for (int i=1;i<=nvar;i++)
    {
      hess_calcreport(i,nvar);

      double xsave=x(i);
      sdelta1=x(i)+delta;
      sdelta1-=x(i);
      x(i)=xsave+sdelta1;
      dvariable vf=0.0;
      vf=initial_params::reset(dvar_vector(x));
      *objective_function_value::pobjfun=0.0;
      pre_userfunction();
      vf+=*objective_function_value::pobjfun;
      vf-=lambda*likeprof_params::likeprofptr[iprof]->variable();
      gradcalc(nvar, g1, vf);

      sdelta2=x(i)-delta;
      sdelta2-=x(i);
      x(i)=xsave+sdelta2;
      vf=0.0;
      vf=initial_params::reset(dvar_vector(x));
      *objective_function_value::pobjfun=0.0;
      pre_userfunction();
      vf+=*objective_function_value::pobjfun;
      vf-=lambda*likeprof_params::likeprofptr[iprof]->variable();
      gradcalc(nvar, g2, vf);
      x(i)=xsave;
      hess1=(g1-g2)/(sdelta1-sdelta2);
  /*
      sdelta1=x(i)+eps*delta;
      sdelta1-=x(i);
      x(i)=xsave+sdelta1;
      vf=0.0;
      vf=initial_params::reset(dvar_vector(x));
      *objective_function_value::pobjfun=0.0;
      pre_userfunction();
      vf+=*objective_function_value::pobjfun;
      vf-=lambda*likeprof_params::likeprofptr[iprof]->variable();
      f=value(vf);
      gradcalc(nvar,g1);

      x(i)=xsave-eps*delta;
      sdelta2=x(i)-eps*delta;
      sdelta2-=x(i);
      x(i)=xsave+sdelta2;
      vf=0.0;
      vf=0.0;
      vf=initial_params::reset(dvar_vector(x));
      *objective_function_value::pobjfun=0.0;
      pre_userfunction();
      vf+=*objective_function_value::pobjfun;
      vf-=lambda*likeprof_params::likeprofptr[iprof]->variable();
      f=value(vf);
      gradcalc(nvar,g2);
      x(i)=xsave;

      double eps2=eps*eps;
      hess2=(g1-g2)/(sdelta1-sdelta2);
      hess=(eps2*hess1-hess2) /(eps2-1.);
    */
      hess=hess1;
      ofs << hess;
    }
  }
  gradient_structure::set_NO_DERIVATIVES();
}
示例#9
0
/**
 * Description not yet available.
 * \param
 */
double do_gauss_hermite_block_diagonal_multi(const dvector& x,
  const dvector& u0,const dmatrix& Hess,const dvector& _xadjoint,
  const dvector& _uadjoint,const dmatrix& _Hessadjoint,
  function_minimizer * pmin)
{
  ADUNCONST(dvector,xadjoint)
  ADUNCONST(dvector,uadjoint)
  //ADUNCONST(dmatrix,Hessadjoint)

  dvector & w= *(pmin->multinomial_weights);

  const int xs=x.size();
  const int us=u0.size();
  gradient_structure::set_NO_DERIVATIVES();
  int nsc=pmin->lapprox->num_separable_calls;
  const ivector lrea = (*pmin->lapprox->num_local_re_array)(1,nsc);
  int hroom =  sum(square(lrea));
  int nvar=x.size()+u0.size()+hroom;
  independent_variables y(1,nvar);
  
  // need to set random effects active together with whatever
  // init parameters should be active in this phase
  initial_params::set_inactive_only_random_effects(); 
  initial_params::set_active_random_effects(); 
  /*int onvar=*/initial_params::nvarcalc(); 
  initial_params::xinit(y);    // get the initial values into the
  // do we need this next line?
  y(1,xs)=x;

  int i,j;

  // contribution for quadratic prior
  if (quadratic_prior::get_num_quadratic_prior()>0)
  {
    //Hess+=quadratic_prior::get_cHessian_contribution();
    int & vxs = (int&)(xs);
    quadratic_prior::get_cHessian_contribution(Hess,vxs);
  }
 // Here need hooks for sparse matrix structures
  
  dvar3_array & block_diagonal_vhessian=
    *pmin->lapprox->block_diagonal_vhessian;
  block_diagonal_vhessian.initialize();
  dvar3_array& block_diagonal_ch=
    *pmin->lapprox->block_diagonal_vch;
    //dvar3_array(*pmin->lapprox->block_diagonal_ch);
  int ii=xs+us+1;
  d3_array& bdH=(*pmin->lapprox->block_diagonal_hessian);
  int ic;
  for (ic=1;ic<=nsc;ic++)
  {
    int lus=lrea(ic);
    for (i=1;i<=lus;i++)
      for (j=1;j<=lus;j++)
        y(ii++)=bdH(ic)(i,j);
  }

  dvector g(1,nvar);
  gradcalc(0,g);
  gradient_structure::set_YES_DERIVATIVES();
  dvar_vector vy=dvar_vector(y); 
  //initial_params::stddev_vscale(d,vy);
  ii=xs+us+1;
  if (initial_df1b2params::have_bounded_random_effects)
  {
    cerr << "can't do importance sampling with bounded random effects"
     " at present" << endl;
    ad_exit(1);
  }
  else
  {
    for (int ic=1;ic<=nsc;ic++)
    {
      int lus=lrea(ic);
      if (lus>0)
      {
        for (i=1;i<=lus;i++)
        {
          for (j=1;j<=lus;j++)
          {
            block_diagonal_vhessian(ic,i,j)=vy(ii++);
          }
        }
        block_diagonal_ch(ic)=
          choleski_decomp(inv(block_diagonal_vhessian(ic)));
      }
    }
  }

   int nsamp=pmin->lapprox->use_gauss_hermite;
   pmin->lapprox->in_gauss_hermite_phase=1;
   dvar_vector sample_value(1,nsamp);
   sample_value.initialize();

   dvar_vector tau(1,us);;
   // !!! This only works for one random efect in each separable call
   // at present.

   if (pmin->lapprox->gh->mi)
   {
     delete pmin->lapprox->gh->mi;
     pmin->lapprox->gh->mi=0;
   }
   
   pmin->lapprox->gh->mi=new multi_index(1,nsamp,
    pmin->lapprox->multi_random_effects);

   multi_index & mi = *(pmin->lapprox->gh->mi);

   //for (int is=1;is<=nsamp;is++)
   dvector& xx=pmin->lapprox->gh->x;
   do
   {
     int offset=0;
     pmin->lapprox->num_separable_calls=0;
     //pmin->lapprox->gh->is=is;
     for (ic=1;ic<=nsc;ic++)
     {
       int lus=lrea(ic);
       // will need vector stuff here when more than one random effect
       if (lus>0)
       {
         //tau(offset+1,offset+lus).shift(1)=block_diagonal_ch(ic)(1,1)*
         //  pmin->lapprox->gh->x(is);
         dvector xv(1,lus);
         for (int iu=1;iu<=lus;iu++)
         {
           xv(iu)= xx(mi()(iu));
         }
         tau(offset+1,offset+lus).shift(1)=block_diagonal_ch(ic)*xv;
           
         offset+=lus;
       }
     }
    
     // have to reorder the terms to match the block diagonal hessian
     imatrix & ls=*(pmin->lapprox->block_diagonal_re_list);
     int mmin=ls.indexmin();
     int mmax=ls.indexmax();
    
     int ii=1;
     int i;
     for (i=mmin;i<=mmax;i++)
     {
       int cmin=ls(i).indexmin();
       int cmax=ls(i).indexmax();
       for (int j=cmin;j<=cmax;j++)
       {
         vy(ls(i,j))+=tau(ii++);
       }
     }
     if (ii-1 != us)
     {
       cerr << "error in interface" << endl;
       ad_exit(1);
     }
     initial_params::reset(vy);    // get the values into the model
     ii=1;
     for (i=mmin;i<=mmax;i++)
     {
       int cmin=ls(i).indexmin();
       int cmax=ls(i).indexmax();
       for (int j=cmin;j<=cmax;j++)
       {
         vy(ls(i,j))-=tau(ii++);
       }
     }

     *objective_function_value::pobjfun=0.0;
     pmin->AD_uf_outer();
     ++mi;

   }
   while(mi.get_depth()<=pmin->lapprox->multi_random_effects);

   nsc=pmin->lapprox->num_separable_calls;

   dvariable vf=pmin->do_gauss_hermite_integration();

   int sgn=0;
   dvariable ld=0.0;
   if (ad_comm::no_ln_det_choleski_flag)
   {
     for (int ic=1;ic<=nsc;ic++)
     {
       if (allocated(block_diagonal_vhessian(ic)))
       {
         ld+=w(2*ic)*ln_det(block_diagonal_vhessian(ic),sgn);
       }
     }
     ld*=0.5;
   }
   else
   {
     for (int ic=1;ic<=nsc;ic++)
     {
       if (allocated(block_diagonal_vhessian(ic)))
       {
         ld+=w(2*ic)*ln_det_choleski(block_diagonal_vhessian(ic));
       }
     }
     ld*=0.5;
   }

   vf+=ld;
   //vf+=us*0.91893853320467241; 

   double f=value(vf);
   gradcalc(nvar,g);

   // put uhat back into the model
   gradient_structure::set_NO_DERIVATIVES();
   vy(xs+1,xs+us).shift(1)=u0;
   initial_params::reset(vy);    // get the values into the model
   gradient_structure::set_YES_DERIVATIVES();
  
   pmin->lapprox->in_gauss_hermite_phase=0;
  
  ii=1;
  for (i=1;i<=xs;i++)
    xadjoint(i)=g(ii++);
  for (i=1;i<=us;i++)
    uadjoint(i)=g(ii++);
  for (ic=1;ic<=nsc;ic++)
  {
    int lus=lrea(ic);
    for (i=1;i<=lus;i++)
    {
      for (j=1;j<=lus;j++)
      {
        (*pmin->lapprox->block_diagonal_vhessianadjoint)(ic)(i,j)=g(ii++);
      }
    }
  }
  return f;
}