Stan  1.0
probability, sampling & optimization
chains.hpp
Go to the documentation of this file.
1 #ifndef __STAN__MCMC__CHAINS_HPP__
2 #define __STAN__MCMC__CHAINS_HPP__
3 
4 #include <algorithm>
5 #include <cmath>
6 #include <iostream>
7 #include <map>
8 #include <stdexcept>
9 #include <string>
10 #include <sstream>
11 #include <utility>
12 #include <vector>
13 #include <fstream>
14 #include <cstdlib>
15 
16 #include <boost/accumulators/accumulators.hpp>
17 #include <boost/accumulators/statistics/stats.hpp>
18 #include <boost/accumulators/statistics/mean.hpp>
19 // #include <boost/accumulators/statistics/moment.hpp>
20 #include <boost/accumulators/statistics/tail_quantile.hpp>
21 #include <boost/accumulators/statistics/variance.hpp>
22 #include <boost/accumulators/statistics/covariance.hpp>
23 #include <boost/accumulators/statistics/variates/covariate.hpp>
24 
25 
26 #include <boost/random/uniform_int_distribution.hpp>
27 #include <boost/random/additive_combine.hpp>
28 
29 #include <stan/math/matrix.hpp>
32 
33 namespace stan {
34 
35  namespace mcmc {
36 
37  const std::vector<std::string>&
38  test_match_return_names(const std::vector<std::string>& names,
39  const std::vector<std::vector<size_t> >& dimss) {
40  if (names.size() == dimss.size())
41  return names;
42  std::stringstream msg;
43  msg << "names and dimss mismatch in size"
44  << " names.size()=" << names.size()
45  << " dimss.size()=" << dimss.size();
46  throw std::invalid_argument(msg.str());
47  }
48 
49  void validate_prob(double p) {
50  // test this way so NaN fails
51  if (p >= 0.0 && p <= 1.0)
52  return;
53  std::stringstream msg;
54  msg << "require probabilities to be finite between 0 and 1 inclusive."
55  << " found p=" << p;
56  throw std::invalid_argument(msg.str());
57  }
58 
70  void validate_dims_idxs(const std::vector<size_t>& dims,
71  const std::vector<size_t>& idxs) {
72  if (idxs.size() != dims.size()) {
73  std::stringstream msg;
74  msg << "index vector and dims vector must be same size."
75  << "; idxs.size()=" << idxs.size()
76  << "; dims.size()=" << dims.size();
77  throw std::invalid_argument(msg.str());
78  }
79  for (size_t i = 0; i < idxs.size(); ++i) {
80  if (idxs[i] >= dims[i]) {
81  std::stringstream msg;
82  msg << "indexes must be within bounds."
83  << "; idxs[" << i << "]=" << idxs[i]
84  << "; dims[" << i << "]=" << dims[i];
85  throw std::out_of_range(msg.str());
86  }
87  }
88  }
89 
103  size_t get_offset(const std::vector<size_t>& dims,
104  const std::vector<size_t>& idxs) {
105  validate_dims_idxs(dims,idxs);
106  if (idxs.size() == 0)
107  return 0;
108  if (idxs.size() == 1)
109  return idxs[0];
110  size_t pos(0);
111  // OK, stop at 1
112  for (size_t i = idxs.size(); --i != 0; ) {
113  pos += idxs[i];
114  pos *= dims[i-1];
115  }
116  return pos + idxs[0];
117  }
118 
150  void
151  increment_indexes(const std::vector<size_t>& dims,
152  std::vector<size_t>& idxs) {
153  validate_dims_idxs(dims,idxs);
154  for (size_t i = 0; i < dims.size(); ++i) {
155  ++idxs[i];
156  if (idxs[i] < dims[i])
157  return;
158  idxs[i] = 0;
159  }
160  }
161 
172  template <class RNG>
173  void permutation(std::vector<size_t>& x,
174  size_t n,
175  RNG& rng) {
176  x.resize(n);
177  for (size_t i = 0; i < n; ++i)
178  x[i] = i;
179  if (x.size() < 2) return;
180  for (int i = x.size(); --i != 0; ) {
181  boost::random::uniform_int_distribution<size_t> uid(0,i);
182  size_t j = uid(rng);
183  size_t temp = x[i];
184  x[i] = x[j];
185  x[j] = temp;
186  }
187  }
188 
189 
202  template <typename T>
203  void permute(const std::vector<size_t>& pi,
204  const std::vector<T>& x_from,
205  std::vector<T>& x_to) {
206  size_t N = pi.size();
207  if (N != x_from.size()) {
208  std::stringstream msg;
209  msg << "Require permutation to be same size as source vector."
210  << "; found pi.size()=" << pi.size()
211  << "; x_from.size()=" << x_from.size();
212  }
213  x_to.resize(N);
214  for (size_t i = 0; i < N; ++i)
215  x_to[i] = x_from[pi[i]];
216  }
217 
218 
233  template <typename RNG = boost::random::ecuyer1988>
234  class chains {
235  private:
236 
237  size_t _warmup;
238  const std::vector<std::string> _names;
239  const std::vector<std::vector<size_t> > _dimss;
240  const size_t _num_params; // total
241  const std::vector<size_t> _starts;
242  const std::map<std::string,size_t> _name_to_index;
243  // [chain,param,sample]
244  std::vector<std::vector<std::vector<double > > > _samples;
245  std::vector<size_t> _permutation;
246  RNG _rng; // defaults to time-based init
247 
248  static size_t calc_num_params(const std::vector<size_t>& dims) {
249  size_t num_params = 1;
250  for (size_t i = 0; i < dims.size(); ++i)
251  num_params *= dims[i];
252  return num_params;
253  }
254 
255  static size_t
256  calc_total_num_params(const std::vector<std::vector<size_t> >& dimss) {
257  int num_params = 0;
258  for (size_t i = 0; i < dimss.size(); ++i)
259  num_params += calc_num_params(dimss[i]);
260  return num_params;
261  }
262 
263  static std::vector<size_t>
264  calc_starts(const std::vector<std::vector<size_t> >& dimss) {
265  std::vector<size_t> starts(dimss.size());
266  starts[0] = 0;
267  for (size_t i = 1; i < dimss.size(); ++i)
268  starts[i] = starts[i - 1] + calc_num_params(dimss[i - 1]);
269  return starts;
270  }
271 
272  static std::map<std::string,size_t>
273  calc_name_to_index(const std::vector<std::string> names) {
274  std::map<std::string,size_t> name_to_index;
275  for (size_t i = 0; i < names.size(); ++i)
276  name_to_index[names[i]] = i;
277  return name_to_index;
278  }
279 
280  inline void validate_param_name_idx(size_t j) {
281  if (j < num_param_names())
282  return;
283  std::stringstream msg;
284  msg << "parameter name index must be less than number of params"
285  << "; found j=" << j;
286  throw std::out_of_range(msg.str());
287  }
288 
289  inline void validate_param_idx(size_t n) {
290  if (n < num_params())
291  return;
292  std::stringstream msg;
293  msg << "parameter index must be less than number of params"
294  << "; found n=" << n;
295  throw std::out_of_range(msg.str());
296  }
297 
298  inline void validate_chain_idx(size_t k) {
299  if (k >= num_chains()) {
300  std::stringstream msg;
301  msg << "chain must be less than number of chains."
302  << "; num chains=" << num_chains()
303  << "; chain=" << k;
304  throw std::out_of_range(msg.str());
305  }
306  }
307 
308  // k = chain idx, m = iteration
309  void validate_iteration(size_t k,
310  size_t m) {
311  validate_chain_idx(k);
312  if (m >= _samples[k][0].size()) {
313  std::stringstream msg;
314  msg << "require sample index below number of samples"
315  << "; sample index m=" << m
316  << "; chain index k=" << k
317  << "; num samples in chain" << k << "="
318  << _samples[k][0].size();
319  throw std::out_of_range(msg.str());
320  }
321  }
322 
323  void resize_permutation(size_t K) {
324  if (_permutation.size() != K)
325  permutation(_permutation,K,_rng);
326  }
327 
328  public:
329 
351  chains(const size_t num_chains,
352  const std::vector<std::string>& names,
353  const std::vector<std::vector<size_t> >& dimss)
354  : _warmup(0),
355  // function call tests dimensionality match & returns names
356  _names(names), // test_match_return_names(names,dimss)),
357  _dimss(dimss),
358  _num_params(calc_total_num_params(dimss)),
359  _starts(calc_starts(dimss)), // copy
360  _name_to_index(calc_name_to_index(names)), // copy
361  _samples(num_chains,std::vector<std::vector<double> >(_num_params))
362  { }
363 
371  inline size_t num_chains() {
372  return _samples.size();
373  }
374 
385  inline size_t num_params() {
386  return _num_params;
387  }
388 
396  inline size_t num_param_names() {
397  return _names.size();
398  }
399 
407  const std::vector<std::string>& param_names() {
408  return _names;
409  }
410 
421  const std::string& param_name(size_t j) {
422  validate_param_name_idx(j);
423  return _names[j];
424  }
425 
433  const std::vector<std::vector<size_t> >& param_dimss() {
434  return _dimss;
435  }
436 
449  const std::vector<size_t>& param_dims(size_t j) {
450  validate_param_name_idx(j);
451  return _dimss[j];
452  }
453 
462  const std::vector<size_t>& param_starts() {
463  return _starts;
464  }
465 
477  size_t param_start(size_t j) {
478  validate_param_name_idx(j);
479  return _starts[j];
480  }
481 
490  const std::vector<size_t> param_sizes() {
491  std::vector<size_t> s(num_param_names());
492  for (unsigned int j = 0; j < num_param_names(); ++j)
493  s[j] = param_size(j); // could optimize tests in param_sizes() out
494  return s;
495  }
496 
508  size_t param_size(size_t j) {
509  validate_param_name_idx(j);
510  if (j + 1 < _starts.size())
511  return _starts[j+1] - _starts[j];
512  return num_params() - _starts[j];
513  }
514 
526  size_t param_name_to_index(const std::string& name) {
527  std::map<std::string,size_t>::const_iterator it
528  = _name_to_index.find(name);
529  if (it == _name_to_index.end()) {
530  std::stringstream ss;
531  ss << "unknown parameter name=" << name;
532  throw std::out_of_range(ss.str());
533  }
534  return it->second;
535  }
536 
537 
552  size_t get_total_param_index(size_t j, // param id
553  const std::vector<size_t>& idxs) {
554  return get_offset(param_dims(j),idxs)
555  + param_start(j);
556  }
557 
558 
568  void set_warmup(size_t warmup_iterations) {
569  _warmup = warmup_iterations;
570  }
571 
572 
580  inline size_t warmup() {
581  return _warmup;
582  }
583 
584 
595  void add(size_t chain,
596  std::vector<double> theta) {
597  validate_chain_idx(chain);
598  if (theta.size() != _num_params) {
599  std::stringstream msg;
600  msg << "parameter vector size must match num params"
601  << "; num params=" << _num_params
602  << "; theta.size()=" << theta.size();
603  throw std::invalid_argument(msg.str());
604  }
605  for (size_t i = 0; i < theta.size(); ++i)
606  _samples[chain][i].push_back(theta[i]); // _samples very non-local
607  }
608 
609 
610 
611 
612 
622  size_t num_warmup_samples(size_t k) {
623  return std::min<size_t>(num_samples(k), warmup());
624  }
625 
634  size_t total = 0;
635  for (size_t k = 0; k < num_chains(); ++k)
636  total += num_warmup_samples(k);
637  return total;
638  }
639 
649  size_t num_kept_samples(size_t k) {
650  if (num_samples(k) > warmup())
651  return num_samples(k) - warmup();
652  return 0U;
653  }
654 
655 
664  size_t num_kept_samples() {
665  size_t total = 0;
666  for (size_t k = 0; k < num_chains(); ++k)
667  total += num_kept_samples(k);
668  return total;
669  }
670 
679  size_t num_samples() {
680  size_t M = 0;
681  for (size_t k = 0; k < num_chains(); ++k)
682  M += num_samples(k);
683  return M;
684  }
685 
697  size_t num_samples(size_t k) {
698  validate_chain_idx(k);
699  return _samples[k][0].size();
700  }
701 
702 
716  void
717  get_samples(size_t n,
718  std::vector<double>& samples) {
719  validate_param_idx(n);
720  samples.resize(0);
721  samples.reserve(num_samples());
722  for (size_t k = 0; k < num_chains(); ++k)
723  samples.insert(samples.end(),
724  _samples[k][n].begin(),
725  _samples[k][n].end());
726  }
727 
743  void get_samples(size_t k,
744  size_t n,
745  std::vector<double>& samples) {
746  validate_chain_idx(k);
747  validate_param_idx(n);
748  samples.resize(0);
749  samples.reserve(num_samples(k));
750  samples.insert(samples.end(),
751  _samples[k][n].begin(),
752  _samples[k][n].end());
753  }
754 
755 
770  void
772  std::vector<double>& samples) {
773  validate_param_idx(n);
774  size_t M = num_kept_samples();
775  samples.resize(M);
776  resize_permutation(M);
777  // const std::vector<size_t>& permutation = _permutation;
778  size_t pos = 0;
779  for (size_t k = 0; k < num_chains(); ++k) {
780  // const std::vector<double>& samples_k_n = _samples[k][n];
781  for (size_t m = warmup(); m < num_samples(k); ++m) {
782  samples[_permutation[pos]] = _samples[k][n][m]; // _samples_k_n[m];
783  ++pos;
784  }
785  }
786  }
787 
798  template <typename F>
799  void
801  size_t n,
802  F& f) {
803  using std::vector;
804  for (vector<double>::const_iterator it = _samples[k][n].begin() + warmup();
805  it != _samples[k][n].end();
806  ++it)
807  f(*it);
808  }
809 
820  template <typename F>
821  void
823  F& f) {
824  for (size_t k = 0; k < num_chains(); ++k)
825  apply_kept_samples(k,n,f);
826  }
827 
843  void
845  size_t n,
846  std::vector<double>& samples) {
847  validate_param_idx(n);
848  samples.resize(0);
849  samples.reserve(num_kept_samples(k));
850  samples.insert(samples.end(),
851  _samples[k][n].begin() + warmup(),
852  _samples[k][n].end());
853  }
854 
855 
856 
870  void
872  std::vector<double>& samples) {
873  validate_param_idx(n);
874  samples.resize(0);
875  samples.reserve(num_warmup_samples());
876  for (size_t k = 0; k < num_chains(); ++k) {
877  if (num_warmup_samples(k) < warmup())
878  samples.insert(samples.end(),
879  _samples[k][n].begin(),
880  _samples[k][n].end());
881  else
882  samples.insert(samples.end(),
883  _samples[k][n].begin(),
884  _samples[k][n].begin() + warmup());
885  }
886  }
887 
903  void
905  size_t n,
906  std::vector<double>& samples) {
907  validate_param_idx(n);
908  samples.resize(0);
909  samples.reserve(num_warmup_samples(k));
910  if (num_warmup_samples(k) < warmup())
911  samples.insert(samples.end(),
912  _samples[k][n].begin(),
913  _samples[k][n].end());
914  else
915  samples.insert(samples.end(),
916  _samples[k][n].begin(),
917  _samples[k][n].begin() + warmup());
918  }
919 
920 
932  double mean(size_t k,
933  size_t n) {
934  using boost::accumulators::accumulator_set;
935  using boost::accumulators::stats;
937  validate_chain_idx(k);
938  validate_param_idx(n);
939  accumulator_set<double, stats<mean> > acc;
940  apply_kept_samples(k,n,acc);
941  return boost::accumulators::mean(acc);
942  }
943 
952  double mean(size_t n) {
953  using boost::accumulators::accumulator_set;
954  using boost::accumulators::stats;
956  validate_param_idx(n);
957  accumulator_set<double, stats<mean> > acc;
958  apply_kept_samples(n,acc);
959  return boost::accumulators::mean(acc);
960  }
961 
975  double sd(size_t k,
976  size_t n) {
977  validate_chain_idx(k);
978  validate_param_idx(n);
979  using boost::accumulators::accumulator_set;
980  using boost::accumulators::stats;
982  accumulator_set<double, stats<variance> > acc;
983  apply_kept_samples(k,n,acc);
984  double M = num_kept_samples(k);
985  return std::sqrt((M / (M-1)) * boost::accumulators::variance(acc));
986  }
987 
1000  double sd(size_t n) {
1001  validate_param_idx(n);
1002  using boost::accumulators::accumulator_set;
1003  using boost::accumulators::stats;
1005  accumulator_set<double, stats<variance> > acc;
1006  apply_kept_samples(n,acc);
1007  double M = num_kept_samples();
1008  return std::sqrt((M / (M-1)) * boost::accumulators::variance(acc));
1009  }
1010 
1022  double variance(size_t k,
1023  size_t n) {
1024  validate_chain_idx(k);
1025  validate_param_idx(n);
1026  using boost::accumulators::accumulator_set;
1027  using boost::accumulators::stats;
1029  accumulator_set<double, stats<variance> > acc;
1030  apply_kept_samples(k,n,acc);
1031  double M = num_kept_samples(k);
1032  return (M / (M-1)) *boost::accumulators::variance(acc);
1033  }
1034 
1045  double variance(size_t n) {
1046  validate_param_idx(n);
1047  using boost::accumulators::accumulator_set;
1048  using boost::accumulators::stats;
1050  accumulator_set<double, stats<variance> > acc;
1051  apply_kept_samples(n,acc);
1052  double M = num_kept_samples(n);
1053  return (M / (M-1)) *boost::accumulators::variance(acc);
1054  }
1055 
1068  double covariance(size_t k,
1069  size_t n1,
1070  size_t n2) {
1071  validate_chain_idx(k);
1072  validate_param_idx(n1);
1073  validate_param_idx(n2);
1074  using boost::accumulators::accumulator_set;
1075  using boost::accumulators::stats;
1077  using boost::accumulators::tag::covariance;
1078  using boost::accumulators::tag::covariate1;
1079 
1080  accumulator_set<double, stats<covariance<double, covariate1> > > acc;
1081  std::vector<double> samples1, samples2;
1082  this->get_kept_samples(k, n1, samples1);
1083  this->get_kept_samples(k, n2, samples2);
1084  for (size_t kk = 0; kk < this->num_kept_samples(k); kk++) {
1085  acc(samples1[kk], boost::accumulators::covariate1 = samples2[kk]);
1086  }
1087  double M = num_kept_samples(k);
1088  return (M / (M-1)) * boost::accumulators::covariance(acc);
1089  }
1090 
1102  double covariance(size_t n1, size_t n2) {
1103  validate_param_idx(n1);
1104  validate_param_idx(n2);
1105  using boost::accumulators::accumulator_set;
1106  using boost::accumulators::stats;
1108  using boost::accumulators::tag::covariance;
1109  using boost::accumulators::tag::covariate1;
1110 
1111  accumulator_set<double, stats<covariance<double, covariate1> > > acc;
1112  for (size_t chain = 0; chain < this->num_chains(); chain++) {
1113  std::vector<double> samples1, samples2;
1114  this->get_kept_samples(chain, n1, samples1);
1115  this->get_kept_samples(chain, n2, samples2);
1116  for (size_t kk = 0; kk < this->num_kept_samples(chain); kk++) {
1117  acc(samples1[kk], boost::accumulators::covariate1 = samples2[kk]);
1118  }
1119  }
1120  double M = this->num_kept_samples();
1121  return (M / (M-1)) * boost::accumulators::covariance(acc);
1122  }
1123 
1124 
1137  double correlation(size_t k,
1138  size_t n1,
1139  size_t n2) {
1140  double cov = covariance(k, n1, n2);
1141  double sd1 = sd(k, n1);
1142  double sd2 = sd(k, n2);
1143 
1144  return cov / sd1 / sd2;
1145  }
1146 
1158  double correlation(size_t n1, size_t n2) {
1159  double cov = covariance(n1, n2);
1160  double sd1 = sd(n1);
1161  double sd2 = sd(n2);
1162 
1163  return cov / sd1 / sd2;
1164  }
1165 
1166 
1180  double quantile(size_t k,
1181  size_t n,
1182  double prob) {
1183  validate_chain_idx(k);
1184  validate_param_idx(n);
1185  using boost::accumulators::accumulator_set;
1186  using boost::accumulators::left;
1187  using boost::accumulators::quantile_probability;
1188  using boost::accumulators::right;
1189  using boost::accumulators::stats;
1190  using boost::accumulators::tag::tail;
1191  using boost::accumulators::tag::tail_quantile;
1192  double size = num_kept_samples(k);
1193  if (prob < 0.5) {
1194  std::size_t cs(2 + prob * size); // 2+ for interpolation
1195  accumulator_set<double, stats<tail_quantile<left> > >
1196  acc(tail<left>::cache_size = cs);
1197  apply_kept_samples(k,n,acc);
1198  return boost::accumulators::quantile(acc, quantile_probability = prob);
1199  } else {
1200  std::size_t cs(2 + (1.0 - prob) * size);
1201  accumulator_set<double, stats<tail_quantile<right> > >
1202  acc(tail<right>::cache_size = cs);
1203  apply_kept_samples(k,n,acc);
1204  return boost::accumulators::quantile(acc, quantile_probability = prob);
1205  }
1206  }
1207 
1219  double quantile(size_t n,
1220  double prob) {
1221  validate_param_idx(n);
1222  using boost::accumulators::accumulator_set;
1223  using boost::accumulators::left;
1224  using boost::accumulators::quantile_probability;
1225  using boost::accumulators::right;
1226  using boost::accumulators::stats;
1227  using boost::accumulators::tag::tail;
1228  using boost::accumulators::tag::tail_quantile;
1229  double size = num_kept_samples();
1230  if (prob < 0.5) {
1231  std::size_t cs(2 + prob * size); // 2+ for interpolation
1232  accumulator_set<double, stats<tail_quantile<left> > >
1233  acc(tail<left>::cache_size = cs);
1234  apply_kept_samples(n,acc);
1235  return boost::accumulators::quantile(acc, quantile_probability = prob);
1236  } else {
1237  std::size_t cs(2 + (1.0 - prob) * size);
1238  accumulator_set<double, stats<tail_quantile<right> > >
1239  acc(tail<right>::cache_size = cs);
1240  apply_kept_samples(n,acc);
1241  return boost::accumulators::quantile(acc, quantile_probability = prob);
1242  }
1243  }
1244 
1260  void quantiles(size_t k,
1261  size_t n,
1262  const std::vector<double>& probs,
1263  std::vector<double>& quantiles) {
1264  validate_chain_idx(k);
1265  validate_param_idx(n);
1266  for (size_t i = 0; i < probs.size(); ++i)
1267  validate_prob(probs[i]);
1268  quantiles.resize(probs.size());
1269 
1270  using boost::accumulators::accumulator_set;
1271  using boost::accumulators::quantile;
1272  using boost::accumulators::quantile_probability;
1273  using boost::accumulators::right;
1274  using boost::accumulators::stats;
1275  using boost::accumulators::tag::tail;
1276  using boost::accumulators::tag::tail_quantile;
1277  // keeps all (more efficient to have two for (min,0.5) and (0.5,max))
1278  accumulator_set<double, stats<tail_quantile<right> > >
1279  acc(tail<right>::cache_size = num_kept_samples(k));
1280  apply_kept_samples(k,n,acc);
1281 
1282  for (size_t i = 0; i < probs.size(); ++i)
1283  quantiles[i] = quantile(acc, quantile_probability = probs[i]);
1284  }
1285 
1299  void quantiles(size_t n,
1300  const std::vector<double>& probs,
1301  std::vector<double>& quantiles) {
1302  validate_param_idx(n);
1303  for (size_t i = 0; i < probs.size(); ++i)
1304  validate_prob(probs[i]);
1305  quantiles.resize(probs.size());
1306 
1307  using boost::accumulators::accumulator_set;
1308  using boost::accumulators::quantile;
1309  using boost::accumulators::quantile_probability;
1310  using boost::accumulators::right;
1311  using boost::accumulators::stats;
1312  using boost::accumulators::tag::tail;
1313  using boost::accumulators::tag::tail_quantile;
1314  accumulator_set<double, stats<tail_quantile<right> > >
1315  acc(tail<right>::cache_size = num_kept_samples());
1316  apply_kept_samples(n,acc);
1317  for (size_t i = 0; i < probs.size(); ++i)
1318  quantiles[i] = quantile(acc, quantile_probability = probs[i]);
1319  }
1320 
1339  std::pair<double,double>
1341  size_t n,
1342  double prob) {
1343  // validate k,n in calls to quantile
1344  validate_prob(prob);
1345  double low_prob = (1.0 - prob) / 2.0;
1346  double high_prob = 1.0 - low_prob;
1347  double low_quantile = quantile(k,n,low_prob);
1348  double high_quantile = quantile(k,n,high_prob);
1349  return std::pair<double,double>(low_quantile,high_quantile);
1350  }
1351 
1368  std::pair<double,double>
1370  double prob) {
1371  // validate n in calls to quantile
1372  validate_prob(prob);
1373  double low_prob = (1.0 - prob) / 2.0;
1374  double high_prob = 1.0 - low_prob;
1375  double low_quantile = quantile(n,low_prob);
1376  double high_quantile = quantile(n,high_prob);
1377  return std::pair<double,double>(low_quantile,high_quantile);
1378  }
1379 
1388  void autocorrelation(const size_t k, const size_t n,
1389  std::vector<double>& ac) {
1390  std::vector<double> samples;
1391  get_kept_samples(k,n,samples);
1393  ac);
1394  }
1395 
1404  void autocovariance(const size_t k, const size_t n,
1405  std::vector<double>& acov) {
1406  std::vector<double> samples;
1407  get_kept_samples(k,n,samples);
1409  acov);
1410  }
1411 
1425  // FIXME: reimplement using autocorrelation.
1426  double effective_sample_size(size_t n) {
1427  validate_param_idx(n);
1428  size_t m = this->num_chains();
1429  // need to generalize to each jagged samples per chain
1430  size_t n_samples = this->num_kept_samples(0U);
1431  for (size_t chain = 1; chain < m; chain++) {
1432  n_samples = std::min(n_samples, this->num_kept_samples(chain));
1433  }
1434 
1435  using std::vector;
1436  vector< vector<double> > acov;
1437  for (size_t chain = 0; chain < m; chain++) {
1438  vector<double> acov_chain;
1439  autocovariance(chain, n, acov_chain);
1440  acov.push_back(acov_chain);
1441  }
1442 
1443  vector<double> chain_mean;
1444  vector<double> chain_var;
1445  for (size_t chain = 0; chain < m; chain++) {
1446  double n_kept_samples = num_kept_samples(chain);
1447  chain_mean.push_back(this->mean(chain,n));
1448  chain_var.push_back(acov[chain][0]*n_kept_samples/(n_kept_samples-1));
1449  }
1450  double mean_var = stan::math::mean(chain_var);
1451  double var_plus = mean_var*(n_samples-1)/n_samples;
1452  if (m > 1) var_plus += stan::math::variance(chain_mean);
1453  vector<double> rho_hat_t;
1454  double rho_hat = 0;
1455  for (size_t t = 1; (t < n_samples && rho_hat >= 0); t++) {
1456  vector<double> acov_t(m);
1457  for (size_t chain = 0; chain < m; chain++) {
1458  acov_t[chain] = acov[chain][t];
1459  }
1460  rho_hat = 1 - (mean_var - stan::math::mean(acov_t)) / var_plus;
1461  if (rho_hat >= 0)
1462  rho_hat_t.push_back(rho_hat);
1463  }
1464 
1465  double ess = m*n_samples;
1466  if (rho_hat_t.size() > 0) {
1467  ess /= 1 + 2 * stan::math::sum(rho_hat_t);
1468  }
1469  return ess;
1470  }
1471 
1484  size_t n_chains = this->num_chains();
1485  size_t n_samples = this->num_kept_samples(0U);
1486  for (size_t chain = 1; chain < n_chains; chain++) {
1487  n_samples = std::min(n_samples, this->num_kept_samples(chain));
1488  }
1489  if (n_samples % 2 == 1)
1490  n_samples--;
1491 
1492  std::vector<double> split_chain_mean;
1493  std::vector<double> split_chain_var;
1494 
1495  for (size_t chain = 0; chain < n_chains; chain++) {
1496  std::vector<double> samples(n_samples);
1497  this->get_kept_samples(chain, n, samples);
1498 
1499  std::vector<double> split_chain(n_samples/2);
1500  split_chain.assign(samples.begin(),
1501  samples.begin()+n_samples/2);
1502  split_chain_mean.push_back(stan::math::mean(split_chain));
1503  split_chain_var.push_back(stan::math::variance(split_chain));
1504 
1505  split_chain.assign(samples.end()-n_samples/2,
1506  samples.end());
1507  split_chain_mean.push_back(stan::math::mean(split_chain));
1508  split_chain_var.push_back(stan::math::variance(split_chain));
1509  }
1510 
1511  double var_between = n_samples/2 * stan::math::variance(split_chain_mean);
1512  double var_within = stan::math::mean(split_chain_var);
1513 
1514  // rewrote [(n-1)*W/n + B/n]/W as (n-1+ B/W)/n
1515  return sqrt((var_between/var_within + n_samples/2 -1)/(n_samples/2));
1516  }
1517 
1518  };
1519 
1520 
1521  namespace {
1529  std::string read_header(std::fstream& file) {
1530  std::string header = "";
1531  // strip comments
1532  while (file.peek() == '#') {
1533  file.ignore(10000, '\n');
1534  }
1535  std::getline(file, header, '\n');
1536  return header;
1537  }
1538 
1546  void
1547  tokenize(const std::string& line, const char delimiter,
1548  std::vector<std::string>& tokens) {
1549  tokens.clear();
1550  std::stringstream stream(line);
1551  std::string token;
1552  while (std::getline(stream,token,delimiter)) {
1553  tokens.push_back(token);
1554  }
1555  }
1556 
1564  void
1565  get_names(const std::vector<std::string>& tokens,
1566  const size_t skip,
1567  std::vector<std::string>& names) {
1568  names.clear();
1569  for (size_t i = 0; i < tokens.size(); i++) {
1570  std::stringstream token(tokens[i]);
1571  std::string name;
1572  std::getline(token,name,'.');
1573  if (names.size() == 0 || names.back()!=name) {
1574  names.push_back(name);
1575  }
1576  }
1577  names.erase(names.begin(), names.begin()+skip);
1578  }
1579 
1587  void
1588  get_dimss(const std::vector<std::string>& tokens,
1589  const size_t skip,
1590  std::vector<std::vector<size_t> >& dimss) {
1591  dimss.clear();
1592  std::string last_name;
1593  std::vector<std::string> split;
1594  for (int i = tokens.size()-1; i >= 0; --i) {
1595  tokenize(tokens[i], '.', split);
1596 
1597  std::vector<size_t> dims;
1598  if (split.size() == 1) {
1599  dims.push_back(1);
1600  dimss.insert(dimss.begin(), dims);
1601  } else if (split.front() != last_name) {
1602  for (size_t j = 1; j < split.size(); j++) {
1603  dims.push_back((size_t)atol(split[j].c_str()));
1604  }
1605  dimss.insert(dimss.begin(), dims);
1606  }
1607  last_name = split.front();
1608  }
1609  dimss.erase(dimss.begin(), dimss.begin()+skip);
1610  }
1611 
1620  void
1621  read_values(std::fstream& file, const size_t num_values,
1622  std::vector<std::vector<double> >& thetas) {
1623  thetas.clear();
1624  read_header(file); // ignore header
1625  std::vector<double> theta;
1626  std::string line;
1627  std::vector<std::string> tokens;
1628  while (file.peek() != std::istream::traits_type::eof()) {
1629  while (file.peek() == '#') { // ignore comments
1630  file.ignore(10000, '\n');
1631  }
1632  std::getline(file, line, '\n');
1633  tokenize(line, ',', tokens);
1634  theta.clear();
1635  for (size_t i = tokens.size()-num_values; i < tokens.size(); i++) {
1636  theta.push_back(atof(tokens[i].c_str()));
1637  }
1638  if (theta.size() > 0) {
1639  thetas.push_back(theta);
1640  }
1641  }
1642  }
1643 
1651  void
1652  read_values(std::fstream& file,
1653  std::vector<std::vector<double> >& thetas) {
1654  thetas.clear();
1655  std::string header = read_header(file);
1656  int num_values = 1;
1657  for (const char* header_ptr = header.c_str();
1658  *header_ptr != '\n' && *header_ptr != 0; header_ptr++)
1659  num_values += *header_ptr == ',';
1660 
1661  std::vector<double> theta;
1662  std::string line;
1663  std::vector<std::string> tokens;
1664  while (file.peek() != std::istream::traits_type::eof()) {
1665  while (file.peek() == '#') { // ignore comments
1666  file.ignore(10000, '\n');
1667  }
1668  std::getline(file, line, '\n');
1669  tokenize(line, ',', tokens);
1670  theta.clear();
1671  for (size_t i = tokens.size()-num_values; i < tokens.size(); i++) {
1672  theta.push_back(atof(tokens[i].c_str()));
1673  }
1674  if (theta.size() > 0) {
1675  thetas.push_back(theta);
1676  }
1677  }
1678  }
1679 
1688  void
1689  reorder_values(std::vector<std::vector<double> >& thetas,
1690  const std::vector<size_t>& from,
1691  const std::vector<size_t>& to) {
1692  std::vector<double> temp(from.size());
1693  for (size_t ii = 0; ii < thetas.size(); ii++) {
1694  for (size_t jj = 0; jj < from.size(); jj++) {
1695  temp[jj] = thetas[ii][from[jj]];
1696  }
1697  for (size_t jj = 0; jj < to.size(); jj++) {
1698  thetas[ii][to[jj]] = temp[jj];
1699  }
1700  }
1701  }
1702 
1711  void
1712  get_reordering(const std::vector<std::vector<size_t> >& dimss,
1713  std::vector<size_t>& from,
1714  std::vector<size_t>& to) {
1715  from.clear();
1716  to.clear();
1717 
1718  size_t offset = 0;
1719  for (size_t ii = 0; ii < dimss.size(); ii++) {
1720  size_t curr_size = dimss[ii][0];
1721  if (dimss[ii].size() > 1) {
1722  for (size_t jj = 1; jj < dimss[ii].size(); jj++)
1723  curr_size *= dimss[ii][jj];
1724 
1725  std::vector<size_t> idxs;
1726  for (size_t jj = 0; jj < dimss[ii].size(); jj++) {
1727  idxs.push_back(0);
1728  }
1729  size_t from_index = 0;
1730  for (size_t to_index = 0; to_index < curr_size; to_index++) {
1731  from_index = 0;
1732  size_t offset_temp = 1;
1733  for (size_t kk = idxs.size(); kk > 0; --kk) {
1734  from_index += idxs[kk-1] * offset_temp;
1735  offset_temp *= dimss[ii][kk-1];
1736  }
1737  if (from_index != to_index) {
1738  from.push_back(offset+from_index);
1739  to.push_back(offset+to_index);
1740  }
1741  increment_indexes(dimss[ii], idxs);
1742  }
1743  }
1744  offset += curr_size;
1745  }
1746  }
1747  }
1748 
1758  void
1759  read_variables(const std::string filename, const size_t skip,
1760  std::vector<std::string>& names,
1761  std::vector<std::vector<size_t> >& dimss) {
1762  names.clear();
1763  dimss.clear();
1764  std::fstream csv_output_file(filename.c_str(), std::fstream::in);
1765  if (!csv_output_file.is_open()) {
1766  throw std::runtime_error("Could not open " + filename);
1767  }
1768  std::string header = read_header(csv_output_file);
1769  csv_output_file.close();
1770 
1771  std::vector<std::string> tokens;
1772  tokenize(header, ',', tokens);
1773  get_names(tokens, skip, names);
1774  get_dimss(tokens, skip, dimss);
1775  }
1776 
1787  template <typename RNG>
1789  const size_t chain,
1790  const std::string filename,
1791  const size_t skip) {
1792  std::fstream csv_output_file(filename.c_str(), std::fstream::in);
1793  if (!csv_output_file.is_open()) {
1794  throw std::runtime_error("Could not open " + filename);
1795  }
1796  std::vector<std::vector<double> > thetas;
1797  read_values(csv_output_file, chains.num_params(), thetas);
1798  csv_output_file.close();
1799 
1800  std::vector<size_t> from, to;
1801  get_reordering(chains.param_dimss(), from, to);
1802  reorder_values(thetas, from, to);
1803  for (size_t i = 0; i < thetas.size(); i++) {
1804  chains.add(chain, thetas[i]);
1805  }
1806  return thetas.size();
1807  }
1808 
1809  }
1810 }
1811 
1812 
1813 #endif
1814 
1815 
1816 /*
1817 
1818 
1819 pair<double,double> smallest_interval(size_t n,
1820  double prob);
1821 
1822 double potential_scale_reduction(size_t n)
1823 
1824 double mcmc_error_mean(size_t n);
1825 
1826 void print(ostream&);
1827 
1828 ostream& operator<<(ostream&, const chains&);
1829 */
An mcmc::chains object stores parameter names and dimensionalities along with samples from multiple c...
Definition: chains.hpp:234
void get_samples(size_t n, std::vector< double > &samples)
Write into the specified vector the warmup and kept samples for the scalar parameter with the specifi...
Definition: chains.hpp:717
void get_warmup_samples(size_t k, size_t n, std::vector< double > &samples)
Write into the specified vector the warmup samples for the parameter with the specified index in the ...
Definition: chains.hpp:904
void get_warmup_samples(size_t n, std::vector< double > &samples)
Write into the specified vector the warmup samples for the scalar parameter with the specified index.
Definition: chains.hpp:871
size_t param_size(size_t j)
Return the size of the named parameter with the specified index.
Definition: chains.hpp:508
void apply_kept_samples(size_t n, F &f)
Apply the specified functor to each kept sample for the specified parameter across all chains.
Definition: chains.hpp:822
double mean(size_t k, size_t n)
Return the sample mean of the kept samples in the specified chain for the specified parameter.
Definition: chains.hpp:932
size_t num_params()
Return the total number of parameters.
Definition: chains.hpp:385
void get_samples(size_t k, size_t n, std::vector< double > &samples)
Write into the specified vector the warmup and kept samples for the scalar parameter with the specifi...
Definition: chains.hpp:743
void apply_kept_samples(size_t k, size_t n, F &f)
Apply the specified functor to each kept sample for the specified parameter in the specified chain.
Definition: chains.hpp:800
double covariance(size_t k, size_t n1, size_t n2)
Return the covariance of the kept samples in the specified chain for the specified parameters.
Definition: chains.hpp:1068
double sd(size_t k, size_t n)
Return the sample standard deviation of the kept samples in the specified chain for the specified par...
Definition: chains.hpp:975
const std::vector< size_t > & param_dims(size_t j)
Return the dimensions of the parameter name with the specified index.
Definition: chains.hpp:449
void quantiles(size_t k, size_t n, const std::vector< double > &probs, std::vector< double > &quantiles)
Write the specified sample quantiles into the specified vector for the kept samples for the specified...
Definition: chains.hpp:1260
double correlation(size_t n1, size_t n2)
Return the correlation of the kept samples for the specified parameters.
Definition: chains.hpp:1158
void set_warmup(size_t warmup_iterations)
Set the warmup cutoff to the specified number of iterations.
Definition: chains.hpp:568
size_t param_start(size_t j)
Return the starting position of the named parameter with the specified index in the underlying sequen...
Definition: chains.hpp:477
size_t num_warmup_samples(size_t k)
Return the number of warmup samples in the specified chain.
Definition: chains.hpp:622
const std::vector< size_t > param_sizes()
Return a copy of the sequence of named parameter sizes.
Definition: chains.hpp:490
size_t num_param_names()
Return the total number of parameter names.
Definition: chains.hpp:396
size_t param_name_to_index(const std::string &name)
Return the named parameter index for the specified parameter name.
Definition: chains.hpp:526
double variance(size_t n)
Return the variance of the kept samples in all chains for the specified parameter.
Definition: chains.hpp:1045
const std::vector< std::vector< size_t > > & param_dimss()
Return the sequence of named parameter dimensions.
Definition: chains.hpp:433
void autocovariance(const size_t k, const size_t n, std::vector< double > &acov)
Returns the autocovariance for the specified parameter in the kept samples of the chain specified.
Definition: chains.hpp:1404
void add(size_t chain, std::vector< double > theta)
Add the specified sample to the end of the specified chain.
Definition: chains.hpp:595
double mean(size_t n)
Return the sample mean of the kept samples in all chains for the specified parameter.
Definition: chains.hpp:952
double quantile(size_t k, size_t n, double prob)
Return the specified sample quantile for kept samples for the specified parameter in the specified ch...
Definition: chains.hpp:1180
size_t num_samples(size_t k)
Return the number of samples including warmup and kept samples in the specified chain.
Definition: chains.hpp:697
const std::string & param_name(size_t j)
Return the name of the parameter with the specified index.
Definition: chains.hpp:421
double correlation(size_t k, size_t n1, size_t n2)
Return the correlation of the kept samples in the specified chain for the specified parameters.
Definition: chains.hpp:1137
double covariance(size_t n1, size_t n2)
Return the covariance of the kept samples for the specified parameters.
Definition: chains.hpp:1102
size_t get_total_param_index(size_t j, const std::vector< size_t > &idxs)
Return the index in the underlying sequence of scalar parameters for the parameter with the specified...
Definition: chains.hpp:552
size_t num_chains()
Return the number of chains.
Definition: chains.hpp:371
void get_kept_samples_permuted(size_t n, std::vector< double > &samples)
Write into the specified vector the kept samples for the scalar parameter with the specified index.
Definition: chains.hpp:771
size_t num_warmup_samples()
Return the total number of warmup samples across chains.
Definition: chains.hpp:633
double effective_sample_size(size_t n)
Returns the effective sample size for the specified parameter across all kept samples.
Definition: chains.hpp:1426
double sd(size_t n)
Return the sample standard deviation of the kept samples in all chains for the specified parameter.
Definition: chains.hpp:1000
const std::vector< size_t > & param_starts()
Return the sequence of starting indexes for the named parameters in the underlying sequence of scalar...
Definition: chains.hpp:462
double split_potential_scale_reduction(size_t n)
Return the split potential scale reduction (split R hat) for the specified parameter.
Definition: chains.hpp:1483
chains(const size_t num_chains, const std::vector< std::string > &names, const std::vector< std::vector< size_t > > &dimss)
Construct a chains object with the specified number of Markov chains, and the specified parameter nam...
Definition: chains.hpp:351
std::pair< double, double > central_interval(size_t n, double prob)
Return the specified central interval for the specified parameter in the kept samples of all chains.
Definition: chains.hpp:1369
size_t num_samples()
Return the total number of samples across chains including warmup and kept samples.
Definition: chains.hpp:679
const std::vector< std::string > & param_names()
Return the sequence of parameter names.
Definition: chains.hpp:407
size_t warmup()
Return the warmup iteration cutoff.
Definition: chains.hpp:580
double quantile(size_t n, double prob)
Return the specified sample quantile for kept samples for the specified parameter across all chains.
Definition: chains.hpp:1219
double variance(size_t k, size_t n)
Return the variance of the kept samples in the specified chain for the specified parameter.
Definition: chains.hpp:1022
void quantiles(size_t n, const std::vector< double > &probs, std::vector< double > &quantiles)
Write the specified sample quantiles into the specified vector for the kept samples for the specified...
Definition: chains.hpp:1299
size_t num_kept_samples(size_t k)
Return the number of samples in the specified chain not including warmup samples.
Definition: chains.hpp:649
size_t num_kept_samples()
Return the total number of samples in all chains not including warmup samples.
Definition: chains.hpp:664
void get_kept_samples(size_t k, size_t n, std::vector< double > &samples)
Write into the specified vector the kept samples for the scalar parameter with the specified index in...
Definition: chains.hpp:844
void autocorrelation(const size_t k, const size_t n, std::vector< double > &ac)
Returns the autocorrelations for the specified parameter in the kept samples of the chain specified.
Definition: chains.hpp:1388
std::pair< double, double > central_interval(size_t k, size_t n, double prob)
Return the specified sample central interval for the specified parameter in the kept samples in the s...
Definition: chains.hpp:1340
vector_types push_back(DOUBLE_T)
var sqrt(const var &a)
Return the square root of the specified variable (cmath).
Definition: agrad.hpp:1761
T sum(const std::vector< T > &xs)
Return the sum of the values in the specified standard vector.
Definition: matrix.hpp:1131
boost::math::tools::promote_args< T >::type mean(const std::vector< T > &v)
Returns the sample mean (i.e., average) of the coefficients in the specified standard vector.
Definition: matrix.hpp:1020
int min(const std::vector< int > &x)
Returns the minimum coefficient in the specified column vector.
Definition: matrix.hpp:917
double pi()
Return the value of pi.
boost::math::tools::promote_args< T >::type variance(const std::vector< T > &v)
Returns the sample variance (divide by length - 1) of the coefficients in the specified standard vect...
Definition: matrix.hpp:1053
void increment_indexes(const std::vector< size_t > &dims, std::vector< size_t > &idxs)
Increments the specified indexes to refer to the next value in an array given by the specified dimens...
Definition: chains.hpp:151
const std::vector< std::string > & test_match_return_names(const std::vector< std::string > &names, const std::vector< std::vector< size_t > > &dimss)
Definition: chains.hpp:38
void read_variables(const std::string filename, const size_t skip, std::vector< std::string > &names, std::vector< std::vector< size_t > > &dimss)
Reads variable names and dims from a csv output file.
Definition: chains.hpp:1759
void permute(const std::vector< size_t > &pi, const std::vector< T > &x_from, std::vector< T > &x_to)
Write the specified permutation of the first vector into the second vector.
Definition: chains.hpp:203
size_t get_offset(const std::vector< size_t > &dims, const std::vector< size_t > &idxs)
Return the offset in last-index major indexing for the specified indexes given the specified number o...
Definition: chains.hpp:103
size_t add_chain(stan::mcmc::chains< RNG > &chains, const size_t chain, const std::string filename, const size_t skip)
Adds a chain from a csv file.
Definition: chains.hpp:1788
void permutation(std::vector< size_t > &x, size_t n, RNG &rng)
Write a permutation into the specified vector of the specified size using the specified Boost random ...
Definition: chains.hpp:173
void validate_dims_idxs(const std::vector< size_t > &dims, const std::vector< size_t > &idxs)
Validate the specified indexes with respect to the specified dimensions.
Definition: chains.hpp:70
void validate_prob(double p)
Definition: chains.hpp:49
void autocovariance(const std::vector< T > &y, std::vector< T > &acov, Eigen::FFT< T > &fft)
Write autocovariance estimates for every lag for the specified input sequence into the specified resu...
void autocorrelation(const std::vector< T > &y, std::vector< T > &ac, Eigen::FFT< T > &fft)
Write autocorrelation estimates for every lag for the specified input sequence into the specified res...
Probability, optimization and sampling library.
Definition: agrad.cpp:6
Template specification of functions in std for Stan.
Definition: agrad.hpp:2306

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