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