54 cerr <<
endl <<
"Error: Negative iterations for MCMC not meaningful" <<
endl;
72 int old_Hybrid_bounded_flag=-1;
83 cerr <<
"Warning: No step size given after -hyeps, ignoring" <<
endl;
89 cerr <<
"Error: step size (-hyeps argument) needs positive number";
109 cerr <<
"Error: duration must be > 0" <<
endl;
113 duration=_duration*60;
122 cerr <<
"Error: chain must be >= 1" <<
endl;
130 if(nmcmc>10) refresh = (int)floor(nmcmc/10);
135 cerr <<
"Error: refresh must be >= -1. Use -1 for no refresh or positive integer for rate." <<
endl;
144 cerr <<
"Error: hynstep argument not allowed with NUTS " <<
endl;
149 int warmup= (int)nmcmc/2;
152 if (iii <=0 || iii > nmcmc) {
153 cerr <<
"Error: warmup must be 0 < warmup < nmcmc" <<
endl;
161 double adapt_delta=0.8;
166 if (_adapt_delta < 0 || _adapt_delta > 1 ) {
167 cerr <<
"Error: adapt_delta must be between 0 and 1" <<
endl;
170 adapt_delta=_adapt_delta;
178 ist >> _adapt_window;
179 if (_adapt_window < 1) {
180 cerr <<
"Error: adapt_window invalid" <<
endl;
183 adapt_window=_adapt_window;
187 int adapt_term_buffer=75;
190 int _adapt_term_buffer;
191 ist >> _adapt_term_buffer;
192 if (_adapt_term_buffer < 1 ) {
193 cerr <<
"Error: adapt_term_buffer invalid" <<
endl;
196 adapt_term_buffer=_adapt_term_buffer;
200 int adapt_init_buffer=50;
203 int _adapt_init_buffer;
204 ist >> _adapt_init_buffer;
205 if (_adapt_init_buffer < 1 ) {
206 cerr <<
"Error: adapt_init_buffer invalid" <<
endl;
209 adapt_init_buffer=_adapt_init_buffer;
215 int max_treedepth=12;
219 ist >> _max_treedepth;
220 if (_max_treedepth < 0) {
221 cerr <<
"Error: max_treedepth must be > 0" <<
endl;
224 max_treedepth=_max_treedepth;
241 int adapt_mass_dense=0;
244 cerr <<
"You can only specify one of adapt_mass and adapt_mass_dense" <<
endl;
251 int verbose_adapt_mass=0;
253 verbose_adapt_mass=1;
256 int verbose_find_epsilon=0;
258 verbose_find_epsilon=1;
261 int diagnostic_flag=0;
267 if(mcrestart_flag > -1){
268 cerr <<
endl <<
"Error: -mcr option not implemented for HMC" <<
endl;
273 cerr <<
endl <<
"Error: -mcec option not yet implemented with HMC" <<
endl;
278 cerr <<
"Option -mcsave does not currently work with HMC -- every iteration is saved" <<
endl;
297 bool rescale_covar=0;
300 for (
int i=1;i<=nvar;i++) {
308 if(old_Hybrid_bounded_flag != 1) {
321 cerr <<
"Error: To use -nuts a Hessian using the hybrid transformations is needed." <<
322 endl <<
"...Rerun model with '-hbf' and try again" <<
endl;
342 cerr <<
"Cannot start algorithm, something is wrong with the mass matrix" <<
endl;
359 cerr <<
"Error trying to open mcmc par input file "
365 cerr <<
"Error reading from mcmc par input file "
370 cerr <<
"Illegal option with -mcpin" <<
endl;
381 if (!pofs_psave|| !(*pofs_psave)) {
382 cerr <<
"Error trying to open file" <<
393 ofstream unbounded(
"unbounded.csv", ios::trunc);
396 (*pofs_psave) << nvar;
398 int iseed = iseed0 ? iseed0 : rand();
401 double time_warmup=0;
403 std::clock_t start = clock();
404 time_t now = time(0);
405 tm* localtm = localtime(&now);
407 cout <<
endl <<
endl <<
"Chain " << chain <<
": Starting NUTS for model '" << m <<
408 "' at " << asctime(localtm);
410 cout <<
"Chain " << chain <<
": Model will run for " << duration/60 <<
411 " minutes or until " << nmcmc <<
" total iterations" <<
endl;
415 int aws = adapt_window;
417 int anw =
compute_next_window(adapt_init_buffer, warmup, adapt_init_buffer, aws, adapt_term_buffer);
418 if(adapt_mass || adapt_mass_dense){
419 if(adapt_init_buffer + adapt_window + adapt_term_buffer >= warmup) {
420 cerr <<
"Chain " << chain <<
": Warning: Turning off mass matrix adaptation because warmup<= " <<
421 adapt_init_buffer+adapt_window + adapt_term_buffer <<
endl;
422 cerr <<
"Chain " << chain <<
": Warning: Either increase warmup, adjust adaptation inputs, or turn off adaptation" <<
endl;
423 adapt_mass=0; adapt_mass_dense=0;
427 cout <<
"Chain " << chain <<
": Using diagonal mass matrix adaptation" <<
endl;
428 }
else if(adapt_mass_dense) {
429 cout <<
"Chain " << chain <<
": Using dense mass matrix adaptation" <<
endl;
431 cout <<
"Chain " << chain <<
": Not using mass matrix adaptation" <<
endl;
434 if(verbose_adapt_mass==1){
436 cout <<
"Chain " << chain <<
": Initial margial variances: min=" <<
min(tmp) <<
" and max=" <<
max(tmp) <<
endl;
439 if(diag_option) cout <<
"Chain " << chain <<
": Initializing with unit diagonal mass matrix" <<
endl;
441 dvector epsvec(1,nmcmc+1), epsbar(1,nmcmc+1), Hbar(1,nmcmc+1);
442 epsvec.initialize(); epsbar.initialize(); Hbar.
initialize();
444 ofstream adaptation(
"adaptation.csv", ios::trunc);
445 adaptation <<
"accept_stat__,stepsize__,treedepth__,n_leapfrog__,divergent__,energy__,lp__" <<
endl;
491 std::clock_t start0 = clock();
493 double time_gradient =
static_cast<double>(std::clock()-start0) / CLOCKS_PER_SEC;
501 cout <<
"Chain " << chain <<
": Initial negative log density= " << userNLL <<
502 ", Jacobian= " << jac <<
", Total= " << userNLL-jac <<
endl;
503 cout <<
"Chain " << chain <<
": Gradient eval took " << time_gradient <<
504 " sec. " << nmcmc <<
" iter w/ 100 steps would take " ;
505 time_gradient*= (nmcmc*100);
506 if(time_gradient<=60){
507 printf(
"%.2f", time_gradient); cout <<
" seconds." <<
endl;
508 }
else if(time_gradient <=60*60){
509 printf(
"%.2f", time_gradient/60); cout <<
" minutes." <<
endl;
510 }
else if(time_gradient <= (60*60*24)){
511 printf(
"%.2f", time_gradient/(60*60)); cout <<
" hours." <<
endl;
513 printf(
"%.2f", time_gradient/(24*60*60)); cout <<
" days." <<
endl;
545 double Hprime, _Hprime;
546 double nllprime, _nllprime;
552 int _nalphaprime, _nprime, _nfevals;
554 bool _sprime, _divergent;
558 double H0, H, logu,
value, rn, alpha;
567 int is2=0;
int is3=0;
572 cout <<
"Initial chd=" << chd <<
endl;
573 cout <<
"Initial negative log density=" << nll <<
endl;
574 cout <<
"Initial gr in unbounded space= " << gr <<
endl;
575 cout <<
"Initial gr in rotated space= " << gr2 <<
endl;
576 cout <<
"Initial bounded parameters=" << z0 <<
endl;
577 cout <<
"Initial unbounded parameters=" << y0 <<
endl;
578 cout <<
"Initial rotated, unbounded parameters=" << x0 <<
endl;
581 for (
int is=1;is<=nmcmc;is++) {
587 _thetaprime=theta; _thetaminus=theta; _thetaplus=theta;
588 H0=-nll-0.5*
norm2(p);
594 epsvec(1)=
eps; epsbar(1)=
eps; Hbar(1)=0;
597 _nprime=0; _divergent=0; _nfevals=0;
600 thetaminus_end=theta; thetaplus_end=theta; thetaprime=theta;
601 rminus_end=p; rplus_end=p;
602 gr2minus_end=gr2; gr2plus_end=gr2; gr2prime=gr2;
603 nllprime=nll; grprime=gr;
607 v = 2 * (value < 0.5) - 1;
618 build_tree(nvar, gr, chd, eps, rplus_end, thetaplus_end, gr2, logu, v, j,
619 H0, _thetaprime, _thetaplus, _thetaminus, _rplus, _rminus,
620 _alphaprime, _nalphaprime, _sprime,
621 _nprime, _nfevals, _divergent, rng,
622 gr2plus_end, _grprime, _gr2prime, _nllprime, _Hprime, _parsaveprime);
626 thetaplus_end=_thetaplus; rplus_end=_rplus;
630 build_tree(nvar, gr, chd, eps, rminus_end, thetaminus_end, gr2, logu, v, j,
631 H0, _thetaprime, _thetaplus, _thetaminus, _rplus, _rminus,
632 _alphaprime, _nalphaprime, _sprime,
633 _nprime, _nfevals, _divergent, rng,
634 gr2minus_end, _grprime, _gr2prime, _nllprime, _Hprime, _parsaveprime);
635 thetaminus_end=_thetaminus; rminus_end=_rminus;
642 if (_sprime == 1 && rn <
double(_nprime)/
double(n)){
643 thetaprime=_thetaprime;
647 parsaveprime=_parsaveprime;
653 b=
stop_criterion(nvar, thetaminus_end, thetaplus_end, rminus_end, rplus_end);
657 if(j>=max_treedepth)
break;
664 nll=nllprime; H=Hprime;
665 gr2=gr2prime; theta=thetaprime;
666 parsave=parsaveprime;
668 for(
int i=1;i<nvar;i++) unbounded << ynew(i) <<
", ";
669 unbounded << ynew(nvar) <<
endl;
670 (*pofs_psave) << parsave;
673 if(_nalphaprime>0) alpha=double(_alphaprime)/double(_nalphaprime);
675 if(_divergent==1) ndivergent++;
681 bool slow=
slow_phase(is, warmup, adapt_init_buffer, adapt_term_buffer);
683 if( (adapt_mass || adapt_mass_dense) & slow){
684 if(is== adapt_init_buffer){
698 for(
int i=1; i<=nvar; i++) metric(i,i) = tmp(i);
699 if(verbose_adapt_mass==1){
700 cout <<
"Chain " << chain <<
": Iteration: " << is <<
": Estimated diagonal variances, min=" <<
min(tmp) <<
" and max=" <<
max(tmp) <<
endl;
705 if(verbose_adapt_mass==1){
707 cout <<
"Chain " << chain <<
708 ": Iteration " << is <<
": Estimated dense variances, min=" <<
min(tmp) <<
" and max=" <<
max(tmp) <<
endl;
729 if(!success && adapt_mass_dense){
731 cout <<
"Chain " << chain <<
": Choleski decomposition of dense mass matrix failed. Trying diagonal update instead." <<
endl;
736 if(!success && adapt_mass){
737 cout <<
"Chain " << chain <<
": Error updating diagonal mass matrix. Fix model, turn off adaptation, or increase adapt_window" <<
endl;
755 Hbar(is)=0; epsvec(is)=epsbar(is);
769 eps=
adapt_eps(is, iseps, eps, alpha, adapt_delta, mu, epsvec, epsbar, Hbar);
774 adaptation << alpha <<
"," << eps <<
"," << j <<
","
775 << _nfevals <<
"," << _divergent <<
"," << -H <<
"," << -nll <<
endl;
777 if(is ==warmup) time_warmup =
static_cast<double>(std::clock()-start) / CLOCKS_PER_SEC;
778 time_total =
static_cast<double>(std::clock()-start) / CLOCKS_PER_SEC;
780 if(use_duration==1 && time_total > duration){
782 cout <<
"Chain " << chain <<
":" << is <<
" samples generated after " << duration/60 <<
783 " minutes running." <<
endl;
788 if(adapt_mass_dense | adapt_mass){
789 ofstream metricsave(
"adapted_metric.txt", ios::trunc);
790 metricsave << metric;
795 cout <<
"Chain " << chain <<
": There were " << ndivergent <<
" divergent transitions after warmup" <<
endl;
797 cout <<
"Chain " << chain <<
": Final step size=" << eps <<
"; after " << warmup <<
" warmup iterations"<<
endl;
798 cout <<
"Chain " << chain <<
": Final acceptance ratio=";
799 printf(
"%.2f", alphasum /(nsamples-warmup));
800 if(useDA) cout <<
", and target=" << adapt_delta <<
endl;
else cout <<
endl;
static void restore_all_values(const dvector &x, const int &ii)
dvector rotate_pars(const dvector &m, const dvector &x)
static void set_active_random_effects(void)
void read_mle_hmc(int nvar, dvector &mle)
void nuts_mcmc_routine(int, int, double, int)
The function implements the MCMC algorithm NUTS, which is a self-tuning variant of Hamiltonian Monte ...
dvector diagonal(const dmatrix &matrix)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
Vector of double precision numbers.
bool stop_criterion(int nvar, dvector &thetaminus, dvector &thetaplus, dvector &rminus, dvector &rplus)
double sum(const d3_array &darray)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
int compute_next_window(int i, int warmup, int w1, int aws, int w3)
void print_mcmc_progress(int is, int nmcmc, int nwarmup, int chain, int refresh)
static dvariable reset(const dvar_vector &x)
static void restore_start_phase(void)
static adstring adprogram_name
dvector rotate_gradient(const dvector &x, const dmatrix &m)
void gradcalc(int nvar, const dvector &g)
int atoi(adstring &s)
Returns a integer converted from input s.
double find_reasonable_stepsize(int nvar, dvector y, dvector p, dmatrix &chd, bool verbose_adapt_mass, bool verbose_find_epsilon, int chain)
static int stddev_vscale(const dvar_vector &d, const dvar_vector &x)
bool calculate_chd_and_inverse(int nvar, const dmatrix &metric, dmatrix &chd, dmatrix &chdinv)
Calculate the Cholesky decomposition and its inverse given a mass matrix.
double randu(const random_number_generator &rng)
Uniform random number generator.
void fill_randn(long int &n)
Fill vector with random numbers.
Description not yet available.
prnstream & endl(prnstream &)
Description not yet available.
double get_hybrid_monte_carlo_value(int nvar, const independent_variables &y, dvector &g)
Written by Dave, commented by Cole starting 8/31/2016 Description not yet available.
Description not yet available.
static objective_function_value * pobjfun
Description not yet available.
static void xinit(const dvector &x)
static void set_inactive_random_effects(void)
Description not yet available.
void read_covariance_matrix(const dmatrix &S, int nvar, int &hbf, dvector &sscale)
void initialize(void)
Initialze all elements of dvector to zero.
double norm2(const d3_array &a)
Return sum of squared elements in a.
void read_empirical_covariance_matrix(int nvar, const dmatrix &S, const adstring &prog_name)
Reads the covariance matrix from a file, which is the program name prepended to the extension '...
int option_match(int argc, char *argv[], const char *string)
Checks if the program has been invoked with a particular command line argument ("string").
double adapt_eps(int ii, int iseps, double eps, double alpha, double &adapt_delta, double &mu, dvector &epsvec, dvector &epsbar, dvector &Hbar)
void print_mcmc_timing(double time_warmup, double time_total, int chain)
bool slow_phase(int is, int warmup, int w1, int w3)
static void set_YES_DERIVATIVES(void)
Enable accumulation of derivative information.
void read_hessian_matrix_and_scale1(int nvar, const dmatrix &_SS, double s, int mcmc2_flag)
dvector value(const df1_one_vector &v)
virtual void userfunction(void)=0
std::string get_filename(const char *f)
static int stddev_scale(const dvector &d, const dvector &x)
void add_sample_dense(const int nvar, int &is2, dvector &m, dmatrix &m2, const independent_variables &q)
Calculate running covariance using Welford's "online" algorithm.
void initialize(void)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
void build_tree(int nvar, dvector &gr, dmatrix &chd, double eps, dvector &p, dvector &y, dvector &gr2, double logu, int v, int j, double H0, dvector &_thetaprime, dvector &_thetaplus, dvector &_thetaminus, dvector &_rplus, dvector &_rminus, double &_alphaprime, int &_nalphaprime, bool &_sprime, int &_nprime, int &_nfevals, bool &_divergent, const random_number_generator &rng, dvector &gr2_end, dvector &_grprime, dvector &_gr2prime, double &_nllprime, double &_Hprime, independent_variables &_parsaveprime)
Fundamental data type for reverse mode automatic differentiation.
d3_array log(const d3_array &arr3)
Author: David Fournier Copyright (c) 2008-2012 Regents of the University of California.
void add_sample_diag(const int nvar, int &n, dvector &m, dvector &m2, const independent_variables &q)
Calculate running covariance using Welford's "online" algorithm.