1 #ifndef STAN_MCMC_COVAR_ADAPTATION_HPP
2 #define STAN_MCMC_COVAR_ADAPTATION_HPP
3 
4 #include <stan/math/prim.hpp>
5 #include <stan/mcmc/windowed_adaptation.hpp>
6 #include <vector>
7 
8 namespace stan {
9 
10 namespace mcmc {
11 
12 class covar_adaptation : public windowed_adaptation {
13  public:
covar_adaptation(int n)14   explicit covar_adaptation(int n)
15       : windowed_adaptation("covariance"), estimator_(n) {}
16 
learn_covariance(Eigen::MatrixXd & covar,const Eigen::VectorXd & q)17   bool learn_covariance(Eigen::MatrixXd& covar, const Eigen::VectorXd& q) {
18     if (adaptation_window())
19       estimator_.add_sample(q);
20 
21     if (end_adaptation_window()) {
22       compute_next_window();
23 
24       estimator_.sample_covariance(covar);
25 
26       double n = static_cast<double>(estimator_.num_samples());
27       covar = (n / (n + 5.0)) * covar
28               + 1e-3 * (5.0 / (n + 5.0))
29                     * Eigen::MatrixXd::Identity(covar.rows(), covar.cols());
30 
31       if (!covar.allFinite())
32         throw std::runtime_error(
33             "Numerical overflow in metric adaptation. "
34             "This occurs when the sampler encounters extreme values on the "
35             "unconstrained space; this may happen when the posterior density "
36             "function is too wide or improper. "
37             "There may be problems with your model specification.");
38 
39       estimator_.restart();
40 
41       ++adapt_window_counter_;
42       return true;
43     }
44 
45     ++adapt_window_counter_;
46     return false;
47   }
48 
49  protected:
50   stan::math::welford_covar_estimator estimator_;
51 };
52 
53 }  // namespace mcmc
54 
55 }  // namespace stan
56 
57 #endif
58