Stan  1.3
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
print.cpp
Go to the documentation of this file.
1 #include <algorithm>
2 #include <iostream>
3 #include <iomanip>
4 #include <ios>
5 #include <stan/mcmc/chains.hpp>
6 
7 
8 int calculate_size(const Eigen::VectorXd& x,
9  const std::string& name,
10  const int digits,
11  std::ios_base::fmtflags& format) {
12  using std::max;
13  using std::ceil;
14  using std::log10;
15 
16  double padding = 0;
17  if (digits > 0)
18  padding = digits + 1;
19 
20  double fixed_size = 0.0;
21  if (x.maxCoeff() > 0)
22  fixed_size = ceil(log10(x.maxCoeff()+0.001)) + padding;
23  if (x.minCoeff() < 0)
24  fixed_size = max(fixed_size, ceil(log10(-x.minCoeff()+0.01))+(padding+1));
25  format = std::ios_base::fixed;
26  if (fixed_size < 7) {
27  return max(fixed_size,
28  max(name.length(), std::string("-0.0").length())+0.0);
29  }
30 
31  double scientific_size = 0;
32  scientific_size += 4.0; // "-0.0" has four digits
33  scientific_size += 1.0; // e
34  double exponent_size = 0;
35  if (x.maxCoeff() > 0)
36  exponent_size = ceil(log10(log10(x.maxCoeff())));
37  if (x.minCoeff() < 0)
38  exponent_size = max(exponent_size,
39  ceil(log10(log10(-x.minCoeff()))));
40  scientific_size += fmin(exponent_size, 3);
41  format = std::ios_base::scientific;
42  return scientific_size;
43 }
44 
45 Eigen::VectorXi calculate_sizes(const Eigen::MatrixXd& values,
46  const Eigen::Matrix<std::string, Eigen::Dynamic, 1>& headers,
47  const Eigen::VectorXi& digits,
48  Eigen::Matrix<std::ios_base::fmtflags, Eigen::Dynamic, 1>& formats) {
49  int n = values.cols();
50  Eigen::VectorXi column_lengths(n);
51  formats.resize(n);
52  for (int i = 0; i < n; i++) {
53  column_lengths(i) = calculate_size(values.col(i), headers(i), digits(i), formats(i)) + 1;
54  }
55  return column_lengths;
56 }
57 
58 void print_usage() {
59 
60  std::cout << "USAGE: print <filename 1> [<filename 2> ... <filename N>]"
61  << std::endl
62  << std::endl;
63 
64  std::cout << "OPTIONS:" << std::endl << std::endl;
65  std::cout << " --autocorr=<chain_index>\tAppend the autocorrelations for the given chain"
66  << std::endl
67  << std::endl;
68 
69 }
70 
71 
81 int main(int argc, const char* argv[]) {
82  if (argc == 1) {
83  print_usage();
84  return 0;
85  }
86 
87  std::vector<std::string> filenames;
88  for (int i = 1; i < argc; i++) {
89 
90  if (std::string(argv[i]).find("--autocorr=") != std::string::npos)
91  continue;
92 
93  filenames.push_back(argv[i]);
94 
95  if (std::string("--help") == std::string(argv[i])) {
96  print_usage();
97  return 0;
98 
99  }
100  }
101 
102  Eigen::VectorXi thin(filenames.size());
103 
104  std::ifstream ifstream;
105  ifstream.open(filenames[0].c_str());
107  stan::mcmc::chains<> chains(stan_csv);
108  ifstream.close();
109  thin(0) = stan_csv.metadata.thin;
110 
111 
112  for (int chain = 1; chain < filenames.size(); chain++) {
113  ifstream.open(filenames[chain].c_str());
114  stan_csv = stan::io::stan_csv_reader::parse(ifstream);
115  chains.add(stan_csv);
116  ifstream.close();
117  thin(chain) = stan_csv.metadata.thin;
118  }
119 
120  // print
121  const int skip = 3;
122  std::string model_name = ""; // FIXME: put in model name
123  int max_name_length = 0;
124  for (int i = skip; i < chains.num_params(); i++)
125  if (chains.param_name(i).length() > max_name_length)
126  max_name_length = chains.param_name(i).length();
127  for (int i = 0; i < 2; i++)
128  if (chains.param_name(i).length() > max_name_length)
129  max_name_length = chains.param_name(i).length();
130 
131 
132  Eigen::MatrixXd values(chains.num_params(),10);
133  values.setZero();
134  Eigen::VectorXd probs(5);
135  probs << 0.025, 0.25, 0.5, 0.75, 0.975;
136 
137  for (int i = 0; i < chains.num_params(); i++) {
138  double sd = chains.sd(i);
139  double n_eff = chains.effective_sample_size(i);
140  values(i,0) = chains.mean(i);
141  values(i,1) = sd / sqrt(n_eff);
142  values(i,2) = sd;
143  Eigen::VectorXd quantiles = chains.quantiles(i,probs);
144  for (int j = 0; j < 5; j++)
145  values(i,3+j) = quantiles(j);
146  values(i,8) = n_eff;
147  values(i,9) = chains.split_potential_scale_reduction(i);
148  }
149 
150  int n = 10;
151  Eigen::Matrix<std::string, Eigen::Dynamic, 1> headers(n);
152  headers <<
153  "mean", "se_mean", "sd",
154  "2.5%", "25%", "50%", "75%", "97.5%",
155  "n_eff", "Rhat";
156  Eigen::VectorXi digits(n);
157  digits.setConstant(1);
158  digits(8) = 0;
159 
160  Eigen::VectorXi column_lengths(n);
161  Eigen::Matrix<std::ios_base::fmtflags, Eigen::Dynamic, 1> formats(n);
162  column_lengths = calculate_sizes(values, headers, digits, formats);
163 
164  std::cout << "Inference for Stan model: " << model_name << std::endl
165  << chains.num_chains() << " chains: each with iter=(" << chains.num_kept_samples(0);
166  for (int chain = 1; chain < chains.num_chains(); chain++)
167  std::cout << "," << chains.num_kept_samples(chain);
168  std::cout << ")";
169  std::cout << "; warmup=(" << chains.warmup(0);
170  for (int chain = 1; chain < chains.num_chains(); chain++)
171  std::cout << "," << chains.warmup(chain);
172  std::cout << ")";
173  std::cout << "; thin=(" << thin(0);
174  for (int chain = 1; chain < chains.num_chains(); chain++)
175  std::cout << "," << thin(chain);
176  std::cout << ")";
177  std::cout << "; " << chains.num_samples() << " iterations saved."
178  << std::endl << std::endl;
179 
180  using std::setprecision;
181  using std::setw;
182 
183  // header
184  std::cout << std::setw(max_name_length+1) << "";
185  for (int i = 0; i < n; i++) {
186  std::cout << setw(column_lengths(i)) << headers(i);
187  }
188  std::cout << std::endl;
189  // each row
190  for (int i = skip; i < chains.num_params(); i++) {
191  std::cout << setw(max_name_length+1) << std::left << chains.param_name(i);
192  std::cout << std::right;
193  for (int j = 0; j < n; j++) {
194  std::cout.setf(formats(j), std::ios::floatfield);
195  std::cout << setprecision(digits(j)) << setw(column_lengths(j)) << values(i,j);
196  }
197  std::cout << std::endl;
198  }
199  // lp__, treedepth__
200  for (int i = 0; i < 2; i++) {
201  std::cout << setw(max_name_length+1) << std::left << chains.param_name(i);
202  std::cout << std::right;
203  for (int j = 0; j < n; j++) {
204  std::cout.setf(formats(j), std::ios::floatfield);
205  std::cout << setprecision(digits(j)) << setw(column_lengths(j)) << values(i,j);
206  }
207  std::cout << std::endl;
208  }
209 
210  std::cout << std::endl;
211  std::cout << "Samples were drawn using " << stan_csv.adaptation.sampler << "." << std::endl
212  << "For each parameter, n_eff is a crude measure of effective sample size," << std::endl
213  << "and Rhat is the potential scale reduction factor on split chains (at " << std::endl
214  << "convergence, Rhat=1)." << std::endl
215  << std::endl;
216 
217  for (int k = 1; k < argc; k++) {
218 
219  if (std::string(argv[k]).find("--autocorr=") != std::string::npos) {
220 
221  const int c = atoi(std::string(argv[k]).substr(11).c_str());
222 
223  if (c < 0 || c >= chains.num_chains()) {
224  std::cout << "Bad chain index " << c << ", aborting autocorrelation display." << std::endl;
225  break;
226  }
227 
228  Eigen::MatrixXd autocorr(chains.num_params(), chains.num_samples(c));
229 
230  for (int i = 0; i < chains.num_params(); i++) {
231  autocorr.row(i) = chains.autocorrelation(c, i);
232  }
233 
234  // Format and print header
235  std::cout << "Displaying the autocorrelations for chain " << c << ":" << std::endl;
236  std::cout << std::endl;
237 
238  const int n_autocorr = autocorr.row(0).size();
239 
240  int lag_width = 1;
241  int number = n_autocorr;
242  while ( number != 0) { number /= 10; lag_width++; }
243 
244  std::cout << setw(lag_width > 4 ? lag_width : 4) << "Lag";
245  for (int i = 0; i < chains.num_params(); ++i) {
246  std::cout << setw(max_name_length + 1) << std::right << chains.param_name(i);
247  }
248  std::cout << std::endl;
249 
250  // Print body
251  for (int n = 0; n < n_autocorr; ++n) {
252  std::cout << setw(lag_width) << std::right << n;
253  for (int i = 0; i < chains.num_params(); ++i) {
254  std::cout << setw(max_name_length + 1) << std::right << autocorr(i, n);
255  }
256  std::cout << std::endl;
257  }
258 
259  }
260 
261  }
262 
263  return 0;
264 
265 }
266 
267 
268 

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