1 #ifndef __STAN__MCMC__CHAINS_HPP__
2 #define __STAN__MCMC__CHAINS_HPP__
16 #include <boost/accumulators/accumulators.hpp>
17 #include <boost/accumulators/statistics/stats.hpp>
18 #include <boost/accumulators/statistics/mean.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>
26 #include <boost/random/uniform_int_distribution.hpp>
27 #include <boost/random/additive_combine.hpp>
37 const std::vector<std::string>&
39 const std::vector<std::vector<size_t> >& dimss) {
40 if (names.size() == dimss.size())
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());
51 if (p >= 0.0 && p <= 1.0)
53 std::stringstream msg;
54 msg <<
"require probabilities to be finite between 0 and 1 inclusive."
56 throw std::invalid_argument(msg.str());
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());
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());
104 const std::vector<size_t>& idxs) {
106 if (idxs.size() == 0)
108 if (idxs.size() == 1)
112 for (
size_t i = idxs.size(); --i != 0; ) {
116 return pos + idxs[0];
152 std::vector<size_t>& idxs) {
154 for (
size_t i = 0; i < dims.size(); ++i) {
156 if (idxs[i] < dims[i])
177 for (
size_t i = 0; i < n; ++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);
202 template <
typename T>
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();
214 for (
size_t i = 0; i < N; ++i)
215 x_to[i] = x_from[pi[i]];
233 template <
typename RNG = boost::random::ecuyer1988>
238 const std::vector<std::string> _names;
239 const std::vector<std::vector<size_t> > _dimss;
240 const size_t _num_params;
241 const std::vector<size_t> _starts;
242 const std::map<std::string,size_t> _name_to_index;
244 std::vector<std::vector<std::vector<double > > > _samples;
245 std::vector<size_t> _permutation;
248 static size_t calc_num_params(
const std::vector<size_t>& dims) {
250 for (
size_t i = 0; i < dims.size(); ++i)
251 num_params *= dims[i];
256 calc_total_num_params(
const std::vector<std::vector<size_t> >& dimss) {
258 for (
size_t i = 0; i < dimss.size(); ++i)
259 num_params += calc_num_params(dimss[i]);
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());
267 for (
size_t i = 1; i < dimss.size(); ++i)
268 starts[i] = starts[i - 1] + calc_num_params(dimss[i - 1]);
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;
280 inline void validate_param_name_idx(
size_t j) {
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());
289 inline void validate_param_idx(
size_t n) {
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());
298 inline void validate_chain_idx(
size_t k) {
300 std::stringstream msg;
301 msg <<
"chain must be less than number of chains."
304 throw std::out_of_range(msg.str());
309 void validate_iteration(
size_t k,
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());
323 void resize_permutation(
size_t K) {
324 if (_permutation.size() != K)
352 const std::vector<std::string>& names,
353 const std::vector<std::vector<size_t> >& dimss)
358 _num_params(calc_total_num_params(dimss)),
359 _starts(calc_starts(dimss)),
360 _name_to_index(calc_name_to_index(names)),
361 _samples(num_chains,std::vector<std::vector<double> >(_num_params))
372 return _samples.size();
397 return _names.size();
422 validate_param_name_idx(j);
450 validate_param_name_idx(j);
478 validate_param_name_idx(j);
509 validate_param_name_idx(j);
510 if (j + 1 < _starts.size())
511 return _starts[j+1] - _starts[j];
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());
553 const std::vector<size_t>& idxs) {
569 _warmup = warmup_iterations;
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());
605 for (
size_t i = 0; i < theta.size(); ++i)
698 validate_chain_idx(k);
699 return _samples[k][0].size();
718 std::vector<double>& samples) {
719 validate_param_idx(n);
723 samples.insert(samples.end(),
724 _samples[k][n].begin(),
725 _samples[k][n].end());
745 std::vector<double>& samples) {
746 validate_chain_idx(k);
747 validate_param_idx(n);
750 samples.insert(samples.end(),
751 _samples[k][n].begin(),
752 _samples[k][n].end());
772 std::vector<double>& samples) {
773 validate_param_idx(n);
776 resize_permutation(M);
782 samples[_permutation[pos]] = _samples[k][n][m];
798 template <
typename F>
804 for (vector<double>::const_iterator it = _samples[k][n].begin() +
warmup();
805 it != _samples[k][n].end();
820 template <
typename F>
846 std::vector<double>& samples) {
847 validate_param_idx(n);
850 samples.insert(samples.end(),
851 _samples[k][n].begin() +
warmup(),
852 _samples[k][n].end());
872 std::vector<double>& samples) {
873 validate_param_idx(n);
878 samples.insert(samples.end(),
879 _samples[k][n].begin(),
880 _samples[k][n].end());
882 samples.insert(samples.end(),
883 _samples[k][n].begin(),
884 _samples[k][n].begin() +
warmup());
906 std::vector<double>& samples) {
907 validate_param_idx(n);
911 samples.insert(samples.end(),
912 _samples[k][n].begin(),
913 _samples[k][n].end());
915 samples.insert(samples.end(),
916 _samples[k][n].begin(),
917 _samples[k][n].begin() +
warmup());
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;
953 using boost::accumulators::accumulator_set;
954 using boost::accumulators::stats;
956 validate_param_idx(n);
957 accumulator_set<double, stats<mean> > acc;
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;
1001 validate_param_idx(n);
1002 using boost::accumulators::accumulator_set;
1003 using boost::accumulators::stats;
1005 accumulator_set<double, stats<variance> > acc;
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;
1046 validate_param_idx(n);
1047 using boost::accumulators::accumulator_set;
1048 using boost::accumulators::stats;
1050 accumulator_set<double, stats<variance> > acc;
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;
1080 accumulator_set<double, stats<covariance<double, covariate1> > > acc;
1081 std::vector<double> samples1, samples2;
1085 acc(samples1[kk], boost::accumulators::covariate1 = samples2[kk]);
1088 return (M / (M-1)) * boost::accumulators::covariance(acc);
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;
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;
1117 acc(samples1[kk], boost::accumulators::covariate1 = samples2[kk]);
1121 return (M / (M-1)) * boost::accumulators::covariance(acc);
1141 double sd1 =
sd(k, n1);
1142 double sd2 =
sd(k, n2);
1144 return cov / sd1 / sd2;
1160 double sd1 =
sd(n1);
1161 double sd2 =
sd(n2);
1163 return cov / sd1 / sd2;
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;
1194 std::size_t cs(2 + prob * size);
1195 accumulator_set<double, stats<tail_quantile<left> > >
1196 acc(tail<left>::cache_size = cs);
1198 return boost::accumulators::quantile(acc, quantile_probability = prob);
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);
1204 return boost::accumulators::quantile(acc, quantile_probability = 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;
1231 std::size_t cs(2 + prob * size);
1232 accumulator_set<double, stats<tail_quantile<left> > >
1233 acc(tail<left>::cache_size = cs);
1235 return boost::accumulators::quantile(acc, quantile_probability = prob);
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);
1241 return boost::accumulators::quantile(acc, quantile_probability = prob);
1262 const std::vector<double>& probs,
1264 validate_chain_idx(k);
1265 validate_param_idx(n);
1266 for (
size_t i = 0; i < probs.size(); ++i)
1268 quantiles.resize(probs.size());
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;
1278 accumulator_set<double, stats<tail_quantile<right> > >
1282 for (
size_t i = 0; i < probs.size(); ++i)
1283 quantiles[i] =
quantile(acc, quantile_probability = probs[i]);
1300 const std::vector<double>& probs,
1302 validate_param_idx(n);
1303 for (
size_t i = 0; i < probs.size(); ++i)
1305 quantiles.resize(probs.size());
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> > >
1317 for (
size_t i = 0; i < probs.size(); ++i)
1318 quantiles[i] =
quantile(acc, quantile_probability = probs[i]);
1339 std::pair<double,double>
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);
1368 std::pair<double,double>
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);
1389 std::vector<double>& ac) {
1390 std::vector<double> samples;
1405 std::vector<double>& acov) {
1406 std::vector<double> samples;
1427 validate_param_idx(n);
1431 for (
size_t chain = 1; chain < m; chain++) {
1436 vector< vector<double> > acov;
1437 for (
size_t chain = 0; chain < m; chain++) {
1438 vector<double> acov_chain;
1440 acov.push_back(acov_chain);
1443 vector<double> chain_mean;
1444 vector<double> chain_var;
1445 for (
size_t chain = 0; chain < m; 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));
1451 double var_plus = mean_var*(n_samples-1)/n_samples;
1453 vector<double> rho_hat_t;
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];
1462 rho_hat_t.push_back(rho_hat);
1465 double ess = m*n_samples;
1466 if (rho_hat_t.size() > 0) {
1486 for (
size_t chain = 1; chain < n_chains; chain++) {
1489 if (n_samples % 2 == 1)
1492 std::vector<double> split_chain_mean;
1493 std::vector<double> split_chain_var;
1495 for (
size_t chain = 0; chain < n_chains; chain++) {
1496 std::vector<double> samples(n_samples);
1499 std::vector<double> split_chain(n_samples/2);
1500 split_chain.assign(samples.begin(),
1501 samples.begin()+n_samples/2);
1505 split_chain.assign(samples.end()-n_samples/2,
1515 return sqrt((var_between/var_within + n_samples/2 -1)/(n_samples/2));
1529 std::string read_header(std::fstream& file) {
1530 std::string header =
"";
1532 while (file.peek() ==
'#') {
1533 file.ignore(10000,
'\n');
1535 std::getline(file, header,
'\n');
1547 tokenize(
const std::string& line,
const char delimiter,
1548 std::vector<std::string>& tokens) {
1550 std::stringstream stream(line);
1552 while (std::getline(stream,token,delimiter)) {
1553 tokens.push_back(token);
1565 get_names(
const std::vector<std::string>& tokens,
1567 std::vector<std::string>& names) {
1569 for (
size_t i = 0; i < tokens.size(); i++) {
1570 std::stringstream token(tokens[i]);
1572 std::getline(token,name,
'.');
1573 if (names.size() == 0 || names.back()!=name) {
1574 names.push_back(name);
1577 names.erase(names.begin(), names.begin()+skip);
1588 get_dimss(
const std::vector<std::string>& tokens,
1590 std::vector<std::vector<size_t> >& dimss) {
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);
1597 std::vector<size_t> dims;
1598 if (split.size() == 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()));
1605 dimss.insert(dimss.begin(), dims);
1607 last_name = split.front();
1609 dimss.erase(dimss.begin(), dimss.begin()+skip);
1621 read_values(std::fstream& file,
const size_t num_values,
1622 std::vector<std::vector<double> >& thetas) {
1625 std::vector<double> theta;
1627 std::vector<std::string> tokens;
1628 while (file.peek() != std::istream::traits_type::eof()) {
1629 while (file.peek() ==
'#') {
1630 file.ignore(10000,
'\n');
1632 std::getline(file, line,
'\n');
1633 tokenize(line,
',', tokens);
1635 for (
size_t i = tokens.size()-num_values; i < tokens.size(); i++) {
1636 theta.push_back(atof(tokens[i].c_str()));
1638 if (theta.size() > 0) {
1639 thetas.push_back(theta);
1652 read_values(std::fstream& file,
1653 std::vector<std::vector<double> >& thetas) {
1655 std::string header = read_header(file);
1657 for (
const char* header_ptr = header.c_str();
1658 *header_ptr !=
'\n' && *header_ptr != 0; header_ptr++)
1659 num_values += *header_ptr ==
',';
1661 std::vector<double> theta;
1663 std::vector<std::string> tokens;
1664 while (file.peek() != std::istream::traits_type::eof()) {
1665 while (file.peek() ==
'#') {
1666 file.ignore(10000,
'\n');
1668 std::getline(file, line,
'\n');
1669 tokenize(line,
',', tokens);
1671 for (
size_t i = tokens.size()-num_values; i < tokens.size(); i++) {
1672 theta.push_back(atof(tokens[i].c_str()));
1674 if (theta.size() > 0) {
1675 thetas.push_back(theta);
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]];
1697 for (
size_t jj = 0; jj < to.size(); jj++) {
1698 thetas[ii][to[jj]] = temp[jj];
1712 get_reordering(
const std::vector<std::vector<size_t> >& dimss,
1713 std::vector<size_t>& from,
1714 std::vector<size_t>& to) {
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];
1725 std::vector<size_t> idxs;
1726 for (
size_t jj = 0; jj < dimss[ii].size(); jj++) {
1729 size_t from_index = 0;
1730 for (
size_t to_index = 0; to_index < curr_size; to_index++) {
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];
1737 if (from_index != to_index) {
1738 from.push_back(offset+from_index);
1739 to.push_back(offset+to_index);
1744 offset += curr_size;
1760 std::vector<std::string>& names,
1761 std::vector<std::vector<size_t> >& dimss) {
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);
1768 std::string header = read_header(csv_output_file);
1769 csv_output_file.close();
1771 std::vector<std::string> tokens;
1772 tokenize(header,
',', tokens);
1773 get_names(tokens, skip, names);
1774 get_dimss(tokens, skip, dimss);
1787 template <
typename RNG>
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);
1796 std::vector<std::vector<double> > thetas;
1797 read_values(csv_output_file, chains.
num_params(), thetas);
1798 csv_output_file.close();
1800 std::vector<size_t> from, to;
1802 reorder_values(thetas, from, to);
1803 for (
size_t i = 0; i < thetas.size(); i++) {
1804 chains.
add(chain, thetas[i]);
1806 return thetas.size();