1 #ifndef __STAN__MCMC__HMC_BASE_H__
2 #define __STAN__MCMC__HMC_BASE_H__
6 #include <boost/random/normal_distribution.hpp>
7 #include <boost/random/mersenne_twister.hpp>
8 #include <boost/random/variate_generator.hpp>
9 #include <boost/random/uniform_01.hpp>
21 template <
class BaseRNG = boost::mt19937>
40 boost::variate_generator<BaseRNG&,
47 std::vector<double>
_x;
49 std::vector<double>
_g;
58 std::vector<double> x = this->
_x;
60 for (
size_t i = 0; i < m.size(); ++i)
62 std::vector<double> g = this->
_g;
63 double lastlogp = this->
_logp;
64 double logp =
leapfrog(this->_model, this->_z, x, m, g, this->_epsilon);
65 double H = logp - lastlogp;
66 int direction = H >
log(0.5) ? 1 : -1;
70 for (
size_t i = 0; i < m.size(); ++i)
72 logp =
leapfrog(this->_model, this->_z, x, m, g, this->_epsilon);
74 if ((direction == 1) && !(H >
log(0.5)))
76 else if ((direction == -1) && !(H <
log(0.5)))
79 this->_epsilon = ( (direction == 1)
80 ? 2.0 * this->_epsilon
81 : 0.5 * this->_epsilon );
83 if (this->_epsilon > 1e300)
84 throw std::runtime_error(
"Posterior is improper. Please check your model.");
85 if (this->_epsilon == 0)
86 throw std::runtime_error(
"No acceptably small step size could be found. Perhaps the posterior is not continuous?");
117 double epsilon_pm = 0.0,
118 bool epsilon_adapt =
true,
119 double delta = 0.651,
121 BaseRNG rand_int = BaseRNG(std::time(0)),
122 const std::vector<double>* params_r = 0,
123 const std::vector<int>* params_i = 0)
132 _da(gamma,
std::vector<double>(1, 0.0)),
136 _x(model.num_params_r()),
137 _z(model.num_params_i()),
138 _g(model.num_params_r())
143 throw std::invalid_argument(
"hmc_base ctor: double params must match in size");
148 throw std::invalid_argument(
"hmc_base ctor: int params must match in size");
169 const std::vector<int>& z) {
170 if (x.size() != this->_x.size())
171 throw std::invalid_argument(
"hmc_base::set_params double params must match in size");
172 if (z.size() != this->_z.size())
173 throw std::invalid_argument(
"hmc_base::set_params int params must match in size");
176 this->_logp = this->_model.
grad_log_prob(this->_x,this->_z,this->_g);
191 if (x.size() != this->_model.num_params_r())
192 throw std::invalid_argument(
"x.size() must match num model params.");
194 this->_logp = this->_model.
grad_log_prob(this->_x,this->_z,this->_g);
210 if (z.size() != this->_model.num_params_i())
211 throw std::invalid_argument(
"z.size() must match num params");
213 this->_logp = this->_model.
grad_log_prob(this->_x,this->_z,this->_g);
217 return this->_epsilon_pm != 0;
231 std::vector<double> result;
232 this->_da.
xbar(result);
233 this->_epsilon =
exp(result[0]);
242 params.assign(1, this->_epsilon);
Implements Nesterov's dual average algorithm.
void setx0(const std::vector< double > &x0)
Set the point towards which each iterate is shrunk.
void xbar(std::vector< double > &xbar)
Get the exponentially weighted moving average of all previous iterates.
An abstract base class for adaptive samplers.
bool adapting()
Return whether or not parameter adaptation is on.
virtual void adapt_off()
Turn off parameter adaption.
boost::uniform_01< BaseRNG & > _rand_uniform_01
void set_params_r(const std::vector< double > &x)
Sets the model real parameters to the specified values and update gradients and log probability to ma...
stan::model::prob_grad & _model
void adaptation_init(double epsilon_scale)
boost::variate_generator< BaseRNG &, boost::normal_distribution<> > _rand_unit_norm
hmc_base(stan::model::prob_grad &model, double epsilon=-1, double epsilon_pm=0.0, bool epsilon_adapt=true, double delta=0.651, double gamma=0.05, BaseRNG rand_int=BaseRNG(std::time(0)), const std::vector< double > *params_r=0, const std::vector< int > *params_i=0)
Construct a base HMC sampler.
virtual void adapt_off()
Turn off parameter adaptation.
virtual void get_parameters(std::vector< double > ¶ms)
Write the step size into position 1 of the specified vector.
void set_params_i(const std::vector< int > &z)
Sets the model integer parameters to the specified values and update gradients and log probability to...
virtual void find_reasonable_parameters()
Search for a roughly reasonable (within a factor of 2) setting of the step size epsilon.
virtual void set_params(const std::vector< double > &x, const std::vector< int > &z)
Sets the model real and integer parameters to the specified values.
The prob_grad class represents densities with fixed numbers of discrete and scalar parameters and the...
virtual void init(std::vector< double > ¶ms_r, std::vector< int > ¶ms_i)
virtual size_t num_params_r()
virtual size_t num_params_i()
virtual double grad_log_prob(std::vector< double > ¶ms_r, std::vector< int > ¶ms_i, std::vector< double > &gradient, std::ostream *output_stream=0)=0
Reimplementing boost functionality.
var log(const var &a)
Return the natural log of the specified variable (cmath).
var exp(const var &a)
Return the exponentiation of the specified variable (cmath).
double epsilon()
Return minimum positive number representable.
double leapfrog(stan::model::prob_grad &model, std::vector< int > z, std::vector< double > &x, std::vector< double > &m, std::vector< double > &g, double epsilon, std::ostream *error_msgs=0, std::ostream *output_msgs=0)
Computes the log probability for a single leapfrog step in Hamiltonian Monte Carlo.
Probability, optimization and sampling library.
Template specification of functions in std for Stan.