Stan  1.3
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
dump.hpp
Go to the documentation of this file.
1 #ifndef __STAN__IO__DUMP_HPP__
2 #define __STAN__IO__DUMP_HPP__
3 
4 #include <cctype>
5 #include <iostream>
6 #include <limits>
7 #include <map>
8 #include <sstream>
9 #include <string>
10 #include <vector>
11 #include <boost/throw_exception.hpp>
12 #include <stan/math/matrix.hpp>
13 #include <stan/io/var_context.hpp>
14 
15 namespace stan {
16 
17  namespace io {
18 
19  namespace {
20  size_t product(std::vector<size_t> dims) {
21  size_t y = 1U;
22  for (size_t i = 0; i < dims.size(); ++i)
23  y *= dims[i];
24  return y;
25  }
26  }
27 
36  class dump_writer {
37  private:
38  std::ostream& out_;
39 
40  // checks doesn't contain quote char
41  void write_name_equals(const std::string& name) {
42  for (size_t i = 0; i < name.size(); ++i)
43  if (name.at(i) == '"')
44  BOOST_THROW_EXCEPTION(
45  std::invalid_argument ("name can not contain quote char"));
46  out_ << '"' << name << '"' << " <- " << '\n';
47  }
48 
49 
50  // adds period at end of output if necessary for double
51  void write_val(const double& x) {
52  std::stringstream ss;
53  ss << x;
54  std::string s;
55  ss >> s;
56  for (std::string::iterator it = s.begin();
57  it < s.end();
58  ++it) {
59  if (*it == '.' || *it == 'e' || *it == 'E') {
60  out_ << s;
61  return;
62  }
63  }
64  out_ << s << ".";
65  }
66 
67  void write_val(const unsigned long long int& n) {
68  out_ << n;
69  }
70 
71  void write_val(const unsigned long int& n) {
72  out_ << n;
73  }
74 
75  void write_val(const unsigned int& n) {
76  out_ << n;
77  }
78 
79  void write_val(const unsigned short& n) {
80  out_ << n;
81  }
82 
83  void write_val(const long long& n) {
84  out_ << n;
85  }
86 
87  void write_val(const long& n) {
88  out_ << n;
89  }
90 
91  void write_val(const int& n) {
92  out_ << n;
93  }
94 
95  void write_val(const short& n) {
96  out_ << n;
97  }
98 
99  void write_val(const char& n) {
100  out_ << n;
101  }
102 
103 
104  template <typename T>
105  void write_list(T xs) {
106  out_ << "c(";
107  for (typename T::size_type i = 0; i < xs.size(); ++i) {
108  if (i > 0) out_ << ", ";
109  write_val(xs[i]);
110  }
111  out_ << ")";
112  }
113 
114  template <typename T>
115  void write_structure(std::vector<T> xs,
116  std::vector<size_t> dims) {
117  out_ << "structure(";
118  write_list(xs);
119  out_ << ',' << '\n';
120  out_ << ".Dim = ";
121  write_list(dims);
122  out_ << ")";
123  }
124 
125 
126  void dims(double /*x*/, std::vector<size_t> /*ds*/) {
127  // no op
128  }
129 
130  void dims(int /*x*/, std::vector<size_t> /*ds*/) {
131  // no op
132  }
133 
134  template <typename T>
135  void dims(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> m,
136  std::vector<size_t> ds) {
137  ds.push_back(m.rows());
138  ds.push_back(m.cols());
139  }
140 
141  template <typename T>
142  void dims(Eigen::Matrix<T,Eigen::Dynamic,1> v,
143  std::vector<size_t> ds) {
144  ds.push_back(v.size());
145  }
146 
147  template <typename T>
148  void dims(Eigen::Matrix<T,1,Eigen::Dynamic> rv,
149  std::vector<size_t> ds) {
150  ds.push_back(rv.size());
151  }
152 
153  template <typename T>
154  void dims(std::vector<T> x, std::vector<size_t> ds) {
155  ds.push_back(x.size());
156  if (x.size() > 0)
157  dims(x[0],ds);
158  }
159 
160  template <typename T>
161  std::vector<size_t> dims(T x) {
162  std::vector<size_t> ds;
163  dims(x,ds);
164  return ds;
165  }
166 
167  bool increment(const std::vector<size_t>& dims,
168  std::vector<size_t>& idx) {
169  for (size_t i = 0; i < dims.size(); ++i) {
170  ++idx[i];
171  if (idx[i] < dims[i]) return true;
172  idx[i] = 0;
173  }
174  return false;
175  }
176 
177  template <typename T>
178  void write_stan_val(const std::vector<T>& x,
179  const std::vector<size_t>& idx,
180  const size_t pos) {
181  size_t next_pos = pos + 1;
182  write_stan_val(x[idx[pos]],idx,next_pos);
183  }
184  void write_stan_val(const std::vector<double>& x,
185  const std::vector<size_t>& idx,
186  const size_t pos) {
187  write_val(x[idx[pos]]);
188  }
189  void write_stan_val(const std::vector<int>& x,
190  const std::vector<size_t>& idx,
191  const size_t pos) {
192  write_val(x[idx[pos]]);
193  }
194  void write_stan_val(const Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>& x,
195  const std::vector<size_t>& idx,
196  const size_t pos) {
197  size_t next_pos = pos + 1;
198  write_val(x(idx[pos],idx[next_pos]));
199  }
200  void write_stan_val(const Eigen::Matrix<double,1,Eigen::Dynamic>& x,
201  const std::vector<size_t>& idx,
202  const size_t pos) {
203  write_val(x[idx[pos]]);
204  }
205  void write_stan_val(const Eigen::Matrix<double,Eigen::Dynamic,1>& x,
206  const std::vector<size_t>& idx,
207  const size_t pos) {
208  write_val(x[idx[pos]]);
209  }
210 
211 
212  template <typename T>
213  void write_stan(const std::vector<T>& x) {
214  std::vector<size_t> dims = dims(x);
215  out_ << "structure(c(";
216  std::vector<size_t> idx(dims.size(),0U);
217  for (size_t count = 0; true; ++count) {
218  if (count > 0) out_ << ", ";
219  write_stan_val(x,idx);
220  if (!increment(dims,idx)) break;
221  }
222  out_ << "), .Dim = ";
223  write_list(dims);
224  out_ << ")";
225  }
226  void write_stan(const std::vector<double>& x) {
227  write_list(x);
228  }
229  void write_stan(const std::vector<int>& x) {
230  write_list(x);
231  }
232  void write_stan(double x) {
233  write_val(x);
234  }
235  void write_stan(int x) {
236  write_val(x);
237  }
238  void write_stan(const Eigen::Matrix<double,1,Eigen::Dynamic>& x) {
239  write_list(x);
240  }
241  void write_stan(const Eigen::Matrix<double,Eigen::Dynamic,1>& x) {
242  write_list(x);
243  }
244  void write_stan(const Eigen::Matrix<double,
245  Eigen::Dynamic,Eigen::Dynamic>& x) {
246  typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>::Index Index;
247  out_ << "structure(c(";
248  std::vector<double> vals;
249  for (Index m = 0; m < x.cols(); ++m) {
250  for (Index n = 0; n < x.rows(); ++n) {
251  if (m > 0 || n > 0) out_ << ", ";
252  write_val(x(m,n));
253  }
254  }
255  out_ << "), .Dim = c(";
256  out_ << x.rows() << ", " << x.cols();
257  out_ << "))";
258  }
259 
260  public:
261 
265  dump_writer() : out_(std::cout) { }
266 
273  dump_writer(std::ostream& out) : out_(out) { }
274 
279 
298  template <typename T>
299  void write(const std::string& name,
300  const T& x) {
301  write_name_equals(name);
302  write_stan(x);
303  }
304 
314  template <typename T>
315  void dump_structure(std::string /*name*/,
316  std::vector<size_t> dims,
317  std::vector<T> xs) {
318  if (xs.size() != product(dims))
319  BOOST_THROW_EXCEPTION(
320  std::invalid_argument("xs.size() != product(dims)"));
321  write_structure(xs,dims);
322  }
323 
332  template <typename T>
333  void dump_list(std::string name,
334  std::vector<T> xs) {
335  write_name_equals(name);
336  write_list(xs);
337  }
338 
347  template <typename T>
348  void dump_var(std::string name,
349  T x) {
350  write_name_equals(name);
351  write_val(x);
352  }
353 
354  };
355 
427  class dump_reader {
428  private:
429  std::string name_;
430  std::vector<int> stack_i_;
431  std::vector<double> stack_r_;
432  std::vector<size_t> dims_;
433  std::istream& in_;
434  // stan::io::buffered_stream in_;
435 
436  bool scan_single_char(char c_expected) {
437  int c = in_.peek();
438  if (c != c_expected)
439  return false;
440  char c_skip;
441  in_.get(c_skip);
442  return true;
443  }
444 
445  bool scan_optional_long() {
446  if (scan_single_char('l'))
447  return true;
448  else if (scan_single_char('L'))
449  return true;
450  else
451  return false;
452  }
453 
454  bool scan_char(char c_expected) {
455  char c;
456  in_ >> c;
457  if (c != c_expected) {
458  in_.putback(c);
459  return false;
460  }
461  return true;
462  }
463 
464  bool scan_name_unquoted() {
465  char c;
466  in_ >> c; //
467  if (!std::isalpha(c)) return false;
468  name_.push_back(c);
469  while (in_.get(c)) { // get turns off auto space skip
470  if (std::isalpha(c) || std::isdigit(c) || c == '_' || c == '.') {
471  name_.push_back(c);
472  } else {
473  in_.putback(c);
474  return true;
475  }
476  }
477  return true; // but hit eos
478  }
479 
480  bool scan_name() {
481  if (scan_char('"')) {
482  if (!scan_name_unquoted()) return false;
483  if (!scan_char('"')) return false;
484  } else if (scan_char('\'')) {
485  if (!scan_name_unquoted()) return false;
486  if (!scan_char('\'')) return false;
487  } else {
488  if (!scan_name_unquoted()) return false;
489  }
490  return true;
491  }
492 
493 
494  bool scan_chars(std::string s, bool case_sensitive = true) {
495  for (size_t i = 0; i < s.size(); ++i) {
496  char c;
497  if (!(in_ >> c)) {
498  for (size_t j = 1; j < i; ++j)
499  in_.putback(s[i-j]);
500  return false;
501  }
502  // all ASCII, so toupper is OK
503  if ((case_sensitive && c != s[i])
504  || (!case_sensitive && ::toupper(c) != ::toupper(s[i]))) {
505  in_.putback(c);
506  for (size_t j = 1; j < i; ++j)
507  in_.putback(s[i-j]);
508  return false;
509  }
510  }
511  return true;
512  }
513 
514  bool scan_number(bool negate_val) {
515 
516  // must take longest first!
517  if (scan_chars("Inf")) {
518  scan_chars("inity"); // read past if there
519  stack_r_.push_back(negate_val
520  ? -std::numeric_limits<double>::infinity()
521  : std::numeric_limits<double>::infinity());
522  return true;
523  }
524  if (scan_chars("NaN",false)) {
525  stack_r_.push_back(std::numeric_limits<double>::quiet_NaN());
526  return true;
527  }
528 
529  char c;
530  bool is_double = false;
531  std::string buf;
532  while (in_.get(c)) {
533  if (std::isdigit(c)) { // before pre-scan || c == '-' || c == '+') {
534  buf.push_back(c);
535  } else if (c == '.'
536  || c == 'e'
537  || c == 'E'
538  || c == '-'
539  || c == '+') {
540  is_double = true;
541  buf.push_back(c);
542  } else {
543  in_.putback(c);
544  break;
545  }
546  }
547  if (!is_double && stack_r_.size() == 0) {
548  int n;
549  if (!(std::stringstream(buf) >> n))
550  return false;
551  stack_i_.push_back(negate_val ? -n : n);
552  scan_optional_long();
553  } else {
554  for (size_t j = 0; j < stack_i_.size(); ++j)
555  stack_r_.push_back(negate_val
556  ? -static_cast<double>(stack_i_[j])
557  : static_cast<double>(stack_i_[j]));
558  stack_i_.clear();
559  double x;
560  if (!(std::stringstream(buf) >> x))
561  return false;
562  stack_r_.push_back(negate_val ? -x : x);
563  }
564  return true;
565  }
566 
567  bool scan_number() {
568  char c;
569  while (in_.get(c)) {
570  if (std::isspace(c)) continue;
571  in_.putback(c);
572  break;
573  }
574  bool negate_val = scan_char('-');
575  if (!negate_val) scan_char('+'); // flush leading +
576  return scan_number(negate_val);
577  }
578 
579 
580  bool scan_seq_value() {
581  if (!scan_char('(')) return false;
582  if (scan_char(')')) {
583  dims_.push_back(0U);
584  return true;
585  }
586  if (!scan_number()) return false;; // first entry
587  while (scan_char(',')) {
588  if (!scan_number()) return false;
589  }
590  dims_.push_back(stack_r_.size() + stack_i_.size());
591  return scan_char(')');
592  }
593 
594  bool scan_struct_value() {
595  if (!scan_char('(')) return false;
596  if (scan_char('c')) {
597  scan_seq_value();
598  } else {
599  size_t start;
600  in_ >> start;
601  if (!scan_char(':'))
602  return false;
603  size_t end;
604  in_ >> end;
605  if (start <= end) {
606  for (size_t i = start; i <= end; ++i)
607  stack_i_.push_back(i);
608  } else {
609  for (size_t i = start; i >= end; --i)
610  stack_i_.push_back(i);
611  }
612  }
613  dims_.clear();
614  if (!scan_char(',')) return false;
615  if (!scan_char('.')) return false;
616  if (!scan_chars("Dim")) return false;
617  if (!scan_char('=')) return false;
618  if (scan_char('c')) {
619  if (!scan_char('(')) return false;
620  size_t dim;
621  in_ >> dim;
622  scan_optional_long();
623  dims_.push_back(dim);
624  while (scan_char(',')) {
625  in_ >> dim;
626  scan_optional_long();
627  dims_.push_back(dim);
628  }
629  if (!scan_char(')')) return false;
630  } else {
631  size_t start;
632  in_ >> start;
633  if (!scan_char(':'))
634  return false;
635  size_t end;
636  in_ >> end;
637  if (start < end) {
638  for (size_t i = start; i <= end; ++i)
639  dims_.push_back(i);
640  } else {
641  for (size_t i = start; i >= end; --i)
642  dims_.push_back(i);
643  }
644  }
645  if (!scan_char(')')) return false;
646  return true;
647  }
648 
649 
650 
651  bool scan_value() {
652  if (scan_char('c'))
653  return scan_seq_value();
654  if (scan_chars("structure"))
655  return scan_struct_value();
656  if (!scan_number())
657  return false;
658  if (!scan_char(':'))
659  return true;
660  if (stack_i_.size() != 1)
661  return false;
662  if (!scan_number())
663  return false;
664  if (stack_i_.size() != 2)
665  return false;
666  int start = stack_i_[0];
667  int end = stack_i_[1];
668  stack_i_.clear();
669  if (start <= end) {
670  for (int i = start; i <= end; ++i)
671  stack_i_.push_back(i);
672  } else {
673  for (int i = start; i >= end; --i)
674  stack_i_.push_back(i);
675  }
676  dims_.push_back(stack_i_.size());
677  return true;
678  }
679 
683  void print() {
684  std::cout << "var name=|" << name_ << "|" << std::endl;
685  std:: cout << "dims=(";
686  for (size_t i = 0; i < dims_.size(); ++i) {
687  if (i > 0)
688  std::cout << ",";
689  std::cout << dims_[i];
690  }
691  std::cout << ")" << std::endl;
692  std::cout << "float stack:" << std::endl;
693  for (size_t i = 0; i < stack_r_.size(); ++i)
694  std::cout << " [" << i << "] " << stack_r_[i] << std::endl;
695  std::cout << "int stack" << std::endl;
696  for (size_t i = 0; i < stack_i_.size(); ++i)
697  std::cout << " [" << i << "] " << stack_i_[i] << std::endl;
698  }
699 
700 
701  public:
705  dump_reader() : in_(std::cin) { }
706 
712  dump_reader(std::istream& in) : in_(in) { }
713 
718 
719 
725  std::string name() {
726  return name_;
727  }
728 
735  std::vector<size_t> dims() {
736  return dims_;
737  }
738 
746  bool is_int() {
747  return stack_i_.size() > 0;
748  }
749 
756  std::vector<int> int_values() {
757  return stack_i_;
758  }
759 
767  std::vector<double> double_values() {
768  return stack_r_;
769  }
770 
778  bool next() {
779  stack_r_.clear();
780  stack_i_.clear();
781  dims_.clear();
782  name_.erase();
783  if (!scan_name()) // set name
784  return false;
785  if (!scan_char('<')) // set <-
786  return false;
787  if (!scan_char('-'))
788  return false;
789  if (!scan_value()) // set stack_r_, stack_i_, dims_
790  return false;
791  return true;
792  }
793 
794  };
795 
796 
797 
813  class dump : public stan::io::var_context {
814  private:
815  std::map<std::string,
816  std::pair<std::vector<double>,
817  std::vector<size_t> > > vars_r_;
818  std::map<std::string,
819  std::pair<std::vector<int>,
820  std::vector<size_t> > > vars_i_;
821  std::vector<double> const empty_vec_r_;
822  std::vector<int> const empty_vec_i_;
823  std::vector<size_t> const empty_vec_ui_;
833  bool contains_r_only(const std::string& name) const {
834  return vars_r_.find(name) != vars_r_.end();
835  }
836  public:
837 
845  dump(std::istream& in) {
846  dump_reader reader(in);
847  while (reader.next()) {
848  if (reader.is_int()) {
849  vars_i_[reader.name()]
850  = std::pair<std::vector<int>,
851  std::vector<size_t> >(reader.int_values(),
852  reader.dims());
853 
854  } else {
855  vars_r_[reader.name()]
856  = std::pair<std::vector<double>,
857  std::vector<size_t> >(reader.double_values(),
858  reader.dims());
859  }
860  }
861  }
862 
871  bool contains_r(const std::string& name) const {
872  return contains_r_only(name) || contains_i(name);
873  }
874 
883  bool contains_i(const std::string& name) const {
884  return vars_i_.find(name) != vars_i_.end();
885  }
886 
894  std::vector<double> vals_r(const std::string& name) const {
895  if (contains_r_only(name)) {
896  return (vars_r_.find(name)->second).first;
897  } else if (contains_i(name)) {
898  std::vector<int> vec_int = (vars_i_.find(name)->second).first;
899  std::vector<double> vec_r(vec_int.size());
900  for (size_t ii = 0; ii < vec_int.size(); ii++) {
901  vec_r[ii] = vec_int[ii];
902  }
903  return vec_r;
904  }
905  return empty_vec_r_;
906  }
907 
915  std::vector<size_t> dims_r(const std::string& name) const {
916  if (contains_r_only(name)) {
917  return (vars_r_.find(name)->second).second;
918  } else if (contains_i(name)) {
919  return (vars_i_.find(name)->second).second;
920  }
921  return empty_vec_ui_;
922  }
923 
931  std::vector<int> vals_i(const std::string& name) const {
932  if (contains_i(name)) {
933  return (vars_i_.find(name)->second).first;
934  }
935  return empty_vec_i_;
936  }
937 
945  std::vector<size_t> dims_i(const std::string& name) const {
946  if (contains_i(name)) {
947  return (vars_i_.find(name)->second).second;
948  }
949  return empty_vec_ui_;
950  }
951 
958  virtual void names_r(std::vector<std::string>& names) const {
959  names.resize(0);
960  for (std::map<std::string,
961  std::pair<std::vector<double>,
962  std::vector<size_t> > >
963  ::const_iterator it = vars_r_.begin();
964  it != vars_r_.end(); ++it)
965  names.push_back((*it).first);
966  }
967 
974  virtual void names_i(std::vector<std::string>& names) const {
975  names.resize(0);
976  for (std::map<std::string,
977  std::pair<std::vector<int>,
978  std::vector<size_t> > >
979  ::const_iterator it = vars_i_.begin();
980  it != vars_i_.end(); ++it)
981  names.push_back((*it).first);
982  }
983 
991  bool remove(const std::string& name) {
992  return (vars_i_.erase(name) > 0)
993  || (vars_r_.erase(name) > 0);
994  }
995 
996  };
997 
998  }
999 
1000 }
1001 #endif

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