Stan  1.3
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
util.hpp
Go to the documentation of this file.
1 #ifndef __STAN__MCMC__UTIL_HPP__
2 #define __STAN__MCMC__UTIL_HPP__
3 
4 #include <cstddef>
5 #include <stdexcept>
6 #include <fstream>
7 
8 #include <boost/random/uniform_01.hpp>
9 #include <boost/random/mersenne_twister.hpp>
10 #include <boost/exception/diagnostic_information.hpp>
11 #include <boost/exception_ptr.hpp>
12 
13 #include <stan/model/prob_grad.hpp>
15 
16 namespace stan {
17 
18  namespace mcmc {
19 
20  void write_error_msgs(std::ostream* error_msgs,
21  const std::domain_error& e) {
22  if (!error_msgs) return;
23  *error_msgs << std::endl
24  << "Informational Message: The parameter state is about to be Metropolis"
25  << " rejected due to the following underlying, non-fatal (really)"
26  << " issue (and please ignore that what comes next might say 'error'): "
27  << e.what()
28  << std::endl
29  << "If the problem persists across multiple draws, you might have"
30  << " a problem with an initial state or a gradient somewhere."
31  << std::endl
32  << " If the problem does not persist, the resulting samples will still"
33  << " be drawn from the posterior."
34  << std::endl;
35  }
36 
37 
59  std::vector<int> z,
60  std::vector<double>& x, std::vector<double>& m,
61  std::vector<double>& g, double epsilon,
62  std::ostream* error_msgs = 0,
63  std::ostream* output_msgs = 0) {
64  stan::math::scaled_add(m, g, 0.5 * epsilon);
65  stan::math::scaled_add(x, m, epsilon);
66  double logp;
67  try {
68  logp = model.grad_log_prob(x, z, g, output_msgs);
69  } catch (std::domain_error e) {
70  write_error_msgs(error_msgs,e);
71  logp = -std::numeric_limits<double>::infinity();
72  }
73  stan::math::scaled_add(m, g, 0.5 * epsilon);
74  return logp;
75  }
76 
77  // Returns the new log probability of x and m
78  // Catches domain errors and sets logp as -inf.
79  // Uses a different step size for each variable in x and m.
81  std::vector<int> z,
82  const std::vector<double>& step_sizes,
83  std::vector<double>& x, std::vector<double>& m,
84  std::vector<double>& g, double epsilon,
85  std::ostream* error_msgs = 0,
86  std::ostream* output_msgs = 0) {
87  for (size_t i = 0; i < m.size(); i++)
88  m[i] += 0.5 * epsilon * step_sizes[i] * g[i];
89  for (size_t i = 0; i < x.size(); i++)
90  x[i] += epsilon * step_sizes[i] * m[i];
91  double logp;
92  try {
93  logp = model.grad_log_prob(x, z, g, output_msgs);
94  } catch (std::domain_error e) {
95  write_error_msgs(error_msgs,e);
96  logp = -std::numeric_limits<double>::infinity();
97  }
98  for (size_t i = 0; i < m.size(); i++)
99  m[i] += 0.5 * epsilon * step_sizes[i] * g[i];
100  return logp;
101  }
102 
103  // Uses a nondiagonal mass matrix to conduct leapfrog
105  std::vector<int> z,
106  const Eigen::MatrixXd& _cov_L,
107  std::vector<double>& x, std::vector<double>& m,
108  std::vector<double>& g, double epsilon,
109  std::ostream* error_msgs = 0,
110  std::ostream* output_msgs = 0) {
111  Eigen::Map<Eigen::VectorXd> x_mat(&x[0],x.size());
112  Eigen::Map<Eigen::VectorXd> m_mat(&m[0],m.size());
113  Eigen::Map<Eigen::VectorXd> g_mat(&g[0],g.size());
114  m_mat += (0.5 * epsilon) * (_cov_L.transpose().triangularView<Eigen::Upper>() * g_mat);
115  x_mat += epsilon * (_cov_L.triangularView<Eigen::Lower>() * m_mat);
116  double logp;
117  try {
118  logp = model.grad_log_prob(x, z, g, output_msgs);
119  } catch (std::domain_error e) {
120  write_error_msgs(error_msgs,e);
121  logp = -std::numeric_limits<double>::infinity();
122  }
123  m_mat += (0.5 * epsilon) * (_cov_L.transpose().triangularView<Eigen::Upper>() * g_mat);
124  return logp;
125  }
126 
127 
128  void read_cov(std::string& cov_file,
129  Eigen::MatrixXd& cov_L)
130  {
131  std::fstream cov_stream(cov_file.c_str());
132  for(int i = 0; i < cov_L.rows(); i++){
133  for(int j=0; j< cov_L.cols(); j++){
134  cov_stream >> cov_L(i,j);
135  }
136  }
137  //cov_stream.read((char *)_cov_L.data(), sizeof(Eigen::MatrixXd::Scalar)*_cov_L.size());
138  // stan::io::dump data_var_context(mass_stream);
139  cov_stream.close();
140  cov_L = cov_L.selfadjointView<Eigen::Upper>().llt().matrixL();
141 
142  }
143 
144 
145 
146  // this is for eventual gibbs sampler for discrete
147  int sample_unnorm_log(std::vector<double> probs,
148  boost::uniform_01<boost::mt19937&>& rand_uniform_01) {
149  // linearize and scale, but don't norm
150  double mx = stan::math::max(probs);
151  for (size_t k = 0; k < probs.size(); ++k)
152  probs[k] = exp(probs[k] - mx);
153 
154  // norm by scaling uniform sample
155  double sum_probs = stan::math::sum(probs);
156  // handles overrun due to arithmetic imprecision
157  double sample_0_sum = std::max(rand_uniform_01() * sum_probs, sum_probs);
158  int k = 0;
159  double cum_unnorm_prob = probs[0];
160  while (cum_unnorm_prob < sample_0_sum)
161  cum_unnorm_prob += probs[++k];
162  return k;
163  }
164 
165 
166  }
167 
168 }
169 
170 #endif

     [ Stan Home Page ] © 2011–2013, Stan Development Team.