/** * 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; }
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); }
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; }
/** 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(); }
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; }
/** * 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; }
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; }
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(); }
/** * 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; }