1 #ifndef __STAN__MCMC__ADAPTIVE_CDHMC_H__
2 #define __STAN__MCMC__ADAPTIVE_CDHMC_H__
7 #include <boost/random/normal_distribution.hpp>
8 #include <boost/random/mersenne_twister.hpp>
9 #include <boost/random/variate_generator.hpp>
10 #include <boost/random/uniform_01.hpp>
45 std::vector<double> _x;
49 std::vector<double> _g;
62 boost::mt19937 _rand_int;
63 boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > _rand_unit_norm;
64 boost::uniform_01<boost::mt19937&> _rand_uniform_01;
69 inline static double da_gamma() {
return 0.05; }
82 _L = lround(_epsilonL /
epsilon);
109 double delta = 0.651,
111 unsigned int random_seed =
static_cast<unsigned int>(std::time(0)))
114 _x(model.num_params_r()),
115 _z(model.num_params_i()),
116 _g(model.num_params_r()),
121 _rand_int(random_seed),
122 _rand_unit_norm(_rand_int,
123 boost::normal_distribution<>()),
124 _rand_uniform_01(_rand_int),
126 _da(da_gamma(),
std::vector<double>(1, 0)) {
132 _da.
setx0(std::vector<double>(1,
log(_epsilon)));
152 const std::vector<int>& z) {
153 if (x.size() != _x.size())
154 throw std::invalid_argument(
"adaptive_cdhmc::set_params: double params must match in size");
155 if (z.size() != _z.size())
156 throw std::invalid_argument(
"adaptive_cdhmc::set_params: int params must match in size");
175 throw std::invalid_argument(
"x.size() must match the number of parameters of the model.");
193 throw std::invalid_argument(
"z.size() must match the number of parameters of the model.");
204 std::vector<double> x = _x;
206 for (
size_t i = 0; i < m.size(); ++i)
207 m[i] = _rand_unit_norm();
208 std::vector<double> g = _g;
209 double lastlogp = _logp;
210 double logp =
leapfrog(_model, _z, x, m, g, _epsilon);
211 double H = logp - lastlogp;
212 int direction = H >
log(0.5) ? 1 : -1;
218 for (
size_t i = 0; i < m.size(); ++i)
219 m[i] = _rand_unit_norm();
220 logp =
leapfrog(_model, _z, x, m, g, _epsilon);
224 if ((direction == 1) && (H <
log(0.5)))
226 else if ((direction == -1) && (H >
log(0.5)))
229 _epsilon = direction == 1 ? 2 * _epsilon : 0.5 * _epsilon;
241 std::vector<double> probs;
253 for (
size_t i = 0; i < m.size(); ++i)
254 m[i] = _rand_unit_norm();
257 std::vector<double> g_new(_g);
258 std::vector<double> x_new(_x);
259 double logp_new = -1e100;
260 for (
unsigned int l = 0; l < _L; ++l)
261 logp_new =
leapfrog(_model, _z, x_new, m, g_new, _epsilon);
265 double dH = H_new - H;
266 if (_rand_uniform_01() <
exp(dH)) {
274 if (adapt_stat != adapt_stat)
277 double adapt_g = adapt_stat - _delta;
278 std::vector<double> gvec(1, -adapt_g);
279 std::vector<double> result;
283 std::vector<double> result;
286 double avg_eta = 1.0 /
n_steps();
302 std::vector<double> result;
313 params.assign(1, _epsilon);
Implements Nesterov's dual average algorithm.
void setx0(const std::vector< double > &x0)
Set the point towards which each iterate is shrunk.
void update(const std::vector< double > &g, std::vector< double > &xk)
Produces the next iterate xk given the current gradient g.
void xbar(std::vector< double > &xbar)
Get the exponentially weighted moving average of all previous iterates.
Adaptive "constant distance" Hamiltonian Monte Carlo (CDHMC) sampler.
adaptive_cdhmc(stan::model::prob_grad &model, double epsilonL, double delta=0.651, double epsilon=-1, unsigned int random_seed=static_cast< unsigned int >(std::time(0)))
Constructs an adaptive "constant distance" Hamiltonian Monte Carlo (CDHMC) sampler for the specified ...
virtual sample next_impl()
Returns the next sample.
void set_epsilon(double epsilon)
Set the step size epsilon.
virtual ~adaptive_cdhmc()
Destructor.
virtual void find_reasonable_parameters()
Searches for a roughly reasonable (within a factor of 2) setting of the step size epsilon.
void set_params_r(const std::vector< double > &x)
Sets the model's real parameters to the specified values and update gradients and log probability to ...
virtual void get_parameters(std::vector< double > ¶ms)
Returns the value of epsilon.
virtual void adapt_off()
Turn off parameter adaptation.
virtual void set_params(const std::vector< double > &x, const std::vector< int > &z)
Sets the model's real and integer parameters to the specified values.
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...
An abstract base class for adaptive samplers.
bool adapting()
Return whether or not parameter adaptation is on.
int n_steps()
Return the number of iterations for this sampler.
void update_mean_stat(double avg_eta, double adapt_stat)
Updates the mean statistic given the specified adaptation statistic and weighting.
void nfevals_plus_eq(int n)
Add the specified number of evaluations to the number of function evaluations.
virtual void adapt_off()
Turn off parameter adaption.
Representation of a MCMC sample.
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 log_prob_star(size_t idx, int val, std::vector< double > ¶ms_r, std::vector< int > ¶ms_i, std::ostream *output_stream=0)
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
int param_range_i_lower(size_t idx)
int param_range_i_upper(size_t idx)
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.
int min(const std::vector< int > &x)
Returns the minimum coefficient in the specified column vector.
double dot_self(const Eigen::Matrix< double, R, C > &v)
Returns the dot product of the specified vector with itself.
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.
int sample_unnorm_log(std::vector< double > probs, boost::uniform_01< boost::mt19937 & > &rand_uniform_01)
Probability, optimization and sampling library.
Template specification of functions in std for Stan.