Stan  1.0
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 <cstddef>
5 #include <stdexcept>
6 #include <map>
7 #include <vector>
8 #include <utility>
9 #include <string>
10 #include <sstream>
11 #include <iostream>
12 #include <locale>
13 
14 #include <boost/throw_exception.hpp>
15 
16 #include <stan/math/matrix.hpp>
17 #include <stan/io/var_context.hpp>
18 
19 namespace stan {
20 
21  namespace io {
22 
23  namespace {
24  size_t product(std::vector<size_t> dims) {
25  size_t y = 1U;
26  for (size_t i = 0; i < dims.size(); ++i)
27  y *= dims[i];
28  return y;
29  }
30  }
31 
40  class dump_writer {
41  private:
42  std::ostream& out_;
43 
44  // checks doesn't contain quote char
45  void write_name_equals(const std::string& name) {
46  for (size_t i = 0; i < name.size(); ++i)
47  if (name.at(i) == '"')
48  BOOST_THROW_EXCEPTION(
49  std::invalid_argument ("name can not contain quote char"));
50  out_ << '"' << name << '"' << " <- " << '\n';
51  }
52 
53 
54  // adds period at end of output if necessary for double
55  void write_val(const double& x) {
56  std::stringstream ss;
57  ss << x;
58  std::string s;
59  ss >> s;
60  for (std::string::iterator it = s.begin();
61  it < s.end();
62  ++it) {
63  if (*it == '.' || *it == 'e' || *it == 'E') {
64  out_ << s;
65  return;
66  }
67  }
68  out_ << s << ".";
69  }
70 
71  void write_val(const unsigned long long int& n) {
72  out_ << n;
73  }
74 
75  void write_val(const unsigned long int& n) {
76  out_ << n;
77  }
78 
79  void write_val(const unsigned int& n) {
80  out_ << n;
81  }
82 
83  void write_val(const unsigned short& n) {
84  out_ << n;
85  }
86 
87  void write_val(const long long& n) {
88  out_ << n;
89  }
90 
91  void write_val(const long& n) {
92  out_ << n;
93  }
94 
95  void write_val(const int& n) {
96  out_ << n;
97  }
98 
99  void write_val(const short& n) {
100  out_ << n;
101  }
102 
103  void write_val(const char& n) {
104  out_ << n;
105  }
106 
107 
108  template <typename T>
109  void write_list(T xs) {
110  out_ << "c(";
111  for (typename T::size_type i = 0; i < xs.size(); ++i) {
112  if (i > 0) out_ << ", ";
113  write_val(xs[i]);
114  }
115  out_ << ")";
116  }
117 
118  template <typename T>
119  void write_structure(std::vector<T> xs,
120  std::vector<size_t> dims) {
121  out_ << "structure(";
122  write_list(xs);
123  out_ << ',' << '\n';
124  out_ << ".Dim = ";
125  write_list(dims);
126  out_ << ")";
127  }
128 
129 
130  void dims(double x, std::vector<size_t> ds) {
131  // no op
132  }
133 
134  void dims(int x, std::vector<size_t> ds) {
135  // no op
136  }
137 
138  template <typename T>
139  void dims(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> m,
140  std::vector<size_t> ds) {
141  ds.push_back(m.rows());
142  ds.push_back(m.cols());
143  }
144 
145  template <typename T>
146  void dims(Eigen::Matrix<T,Eigen::Dynamic,1> v,
147  std::vector<size_t> ds) {
148  ds.push_back(v.size());
149  }
150 
151  template <typename T>
152  void dims(Eigen::Matrix<T,1,Eigen::Dynamic> rv,
153  std::vector<size_t> ds) {
154  ds.push_back(rv.size());
155  }
156 
157  template <typename T>
158  void dims(std::vector<T> x, std::vector<size_t> ds) {
159  ds.push_back(x.size());
160  if (x.size() > 0)
161  dims(x[0],ds);
162  }
163 
164  template <typename T>
165  std::vector<size_t> dims(T x) {
166  std::vector<size_t> ds;
167  dims(x,ds);
168  return ds;
169  }
170 
171  bool increment(const std::vector<size_t>& dims,
172  std::vector<size_t>& idx) {
173  for (size_t i = 0; i < dims.size(); ++i) {
174  ++idx[i];
175  if (idx[i] < dims[i]) return true;
176  idx[i] = 0;
177  }
178  return false;
179  }
180 
181  template <typename T>
182  void write_stan_val(const std::vector<T>& x,
183  const std::vector<size_t>& idx,
184  const size_t pos) {
185  size_t next_pos = pos + 1;
186  write_stan_val(x[idx[pos]],idx,next_pos);
187  }
188  void write_stan_val(const std::vector<double>& x,
189  const std::vector<size_t>& idx,
190  const size_t pos) {
191  write_val(x[idx[pos]]);
192  }
193  void write_stan_val(const std::vector<int>& x,
194  const std::vector<size_t>& idx,
195  const size_t pos) {
196  write_val(x[idx[pos]]);
197  }
198  void write_stan_val(const Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>& x,
199  const std::vector<size_t>& idx,
200  const size_t pos) {
201  size_t next_pos = pos + 1;
202  write_val(x(idx[pos],idx[next_pos]));
203  }
204  void write_stan_val(const Eigen::Matrix<double,1,Eigen::Dynamic>& x,
205  const std::vector<size_t>& idx,
206  const size_t pos) {
207  write_val(x[idx[pos]]);
208  }
209  void write_stan_val(const Eigen::Matrix<double,Eigen::Dynamic,1>& x,
210  const std::vector<size_t>& idx,
211  const size_t pos) {
212  write_val(x[idx[pos]]);
213  }
214 
215 
216  template <typename T>
217  void write_stan(const std::vector<T>& x) {
218  std::vector<size_t> dims = dims(x);
219  out_ << "structure(c(";
220  std::vector<size_t> idx(dims.size(),0U);
221  for (size_t count = 0; true; ++count) {
222  if (count > 0) out_ << ", ";
223  write_stan_val(x,idx);
224  if (!increment(dims,idx)) break;
225  }
226  out_ << "), .Dim = ";
227  write_list(dims);
228  out_ << ")";
229  }
230  void write_stan(const std::vector<double>& x) {
231  write_list(x);
232  }
233  void write_stan(const std::vector<int>& x) {
234  write_list(x);
235  }
236  void write_stan(double x) {
237  write_val(x);
238  }
239  void write_stan(int x) {
240  write_val(x);
241  }
242  void write_stan(const Eigen::Matrix<double,1,Eigen::Dynamic>& x) {
243  write_list(x);
244  }
245  void write_stan(const Eigen::Matrix<double,Eigen::Dynamic,1>& x) {
246  write_list(x);
247  }
248  void write_stan(const Eigen::Matrix<double,
249  Eigen::Dynamic,Eigen::Dynamic>& x) {
250  typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>::Index Index;
251  out_ << "structure(c(";
252  std::vector<double> vals;
253  for (Index m = 0; m < x.cols(); ++m) {
254  for (Index n = 0; n < x.rows(); ++n) {
255  if (m > 0 || n > 0) out_ << ", ";
256  write_val(x(m,n));
257  }
258  }
259  out_ << "), .Dim = c(";
260  out_ << x.rows() << ", " << x.cols();
261  out_ << "))";
262  }
263 
264  public:
265 
269  dump_writer() : out_(std::cout) { }
270 
277  dump_writer(std::ostream& out) : out_(out) { }
278 
283 
302  template <typename T>
303  void write(const std::string& name,
304  const T& x) {
305  write_name_equals(name);
306  write_stan(x);
307  }
308 
318  template <typename T>
319  void dump_structure(std::string name,
320  std::vector<size_t> dims,
321  std::vector<T> xs) {
322  if (xs.size() != product(dims))
323  BOOST_THROW_EXCEPTION(
324  std::invalid_argument("xs.size() != product(dims)"));
325  write_structure(xs,dims);
326  }
327 
336  template <typename T>
337  void dump_list(std::string name,
338  std::vector<T> xs) {
339  write_name_equals(name);
340  write_list(xs);
341  }
342 
351  template <typename T>
352  void dump_var(std::string name,
353  T x) {
354  write_name_equals(name);
355  write_val(x);
356  }
357 
358  };
359 
431  class dump_reader {
432  private:
433  std::string name_;
434  std::vector<int> stack_i_;
435  std::vector<double> stack_r_;
436  std::vector<size_t> dims_;
437  std::istream& in_;
438 
439  bool scan_single_char(char c_expected) {
440  int c = in_.peek();
441  if (c != c_expected)
442  return false;
443  char c_skip;
444  in_.get(c_skip);
445  return true;
446  }
447 
448  bool scan_optional_long() {
449  if (scan_single_char('l'))
450  return true;
451  else if (scan_single_char('L'))
452  return true;
453  else
454  return false;
455  }
456 
457  bool scan_char(char c_expected) {
458  char c;
459  in_ >> c;
460  if (c != c_expected) {
461  in_.putback(c);
462  return false;
463  }
464  return true;
465  }
466 
467  bool scan_name_unquoted() {
468  char c;
469  in_ >> c; //
470  if (!std::isalpha(c)) return false;
471  name_.push_back(c);
472  while (in_.get(c)) { // get turns off auto space skip
473  if (std::isalpha(c) || std::isdigit(c) || c == '_' || c == '.') {
474  name_.push_back(c);
475  } else {
476  in_.putback(c);
477  return true;
478  }
479  }
480  return true; // but hit eos
481  }
482 
483  bool scan_name() {
484  if (scan_char('"')) {
485  if (!scan_name_unquoted()) return false;
486  if (!scan_char('"')) return false;
487  } else if (scan_char('\'')) {
488  if (!scan_name_unquoted()) return false;
489  if (!scan_char('\'')) return false;
490  } else {
491  if (!scan_name_unquoted()) return false;
492  }
493  return true;
494  }
495 
496  bool scan_chars(std::string s) {
497  for (size_t i = 0; i < s.size(); ++i) {
498  char c;
499  if (!(in_ >> c)) {
500  for (size_t j = 1; j < i; ++j)
501  in_.putback(s[i-j]);
502  return false;
503  }
504  if (c != 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() {
515  std::string buf;
516  bool is_double = false;
517  char c;
518  while (in_.get(c)) {
519  if (std::isspace(c)) continue;
520  in_.putback(c);
521  break;
522  }
523  while (in_.get(c)) {
524  if (std::isdigit(c) || c == '-') {
525  buf.push_back(c);
526  } else if (c == '.'
527  || c == 'e'
528  || c == 'E') {
529  is_double = true;
530  buf.push_back(c);
531  }
532  else {
533  in_.putback(c);
534  break;
535  }
536  }
537  if (!is_double && stack_r_.size() == 0) {
538  int n;
539  if (!(std::stringstream(buf) >> n))
540  return false;
541  stack_i_.push_back(n);
542  scan_optional_long();
543  } else {
544  for (size_t j = 0; j < stack_i_.size(); ++j)
545  stack_r_.push_back(static_cast<double>(stack_i_[j]));
546  stack_i_.clear();
547  double x;
548  if (!(std::stringstream(buf) >> x))
549  return false;
550  stack_r_.push_back(x);
551  }
552  return true;
553  }
554 
555  void print_next_char() {
556  char c;
557  bool ok = in_.get(c);
558  if (ok) {
559  std::cout << "next char=" << c << std::endl;
560  in_.putback(c);
561  } else {
562  std::cout << "next char=<EOS>" << std::endl;
563  }
564  }
565 
566  bool scan_seq_value() {
567  if (!scan_char('(')) return false;
568  if (scan_char(')')) {
569  dims_.push_back(0U);
570  return true;
571  }
572  if (!scan_number()) return false;; // first entry
573  while (scan_char(',')) {
574  if (!scan_number()) return false;
575  }
576  dims_.push_back(stack_r_.size() + stack_i_.size());
577  return scan_char(')');
578  }
579 
580  bool scan_struct_value() {
581  if (!scan_char('(')) return false;
582  if (scan_char('c')) {
583  scan_seq_value();
584  } else {
585  size_t start;
586  in_ >> start;
587  if (!scan_char(':'))
588  return false;
589  size_t end;
590  in_ >> end;
591  if (start <= end) {
592  for (size_t i = start; i <= end; ++i)
593  stack_i_.push_back(i);
594  } else {
595  for (size_t i = start; i >= end; --i)
596  stack_i_.push_back(i);
597  }
598  }
599  dims_.clear();
600  if (!scan_char(',')) return false;
601  if (!scan_char('.')) return false;
602  if (!scan_chars("Dim")) return false;
603  if (!scan_char('=')) return false;
604  if (scan_char('c')) {
605  if (!scan_char('(')) return false;
606  size_t dim;
607  in_ >> dim;
608  scan_optional_long();
609  dims_.push_back(dim);
610  while (scan_char(',')) {
611  in_ >> dim;
612  scan_optional_long();
613  dims_.push_back(dim);
614  }
615  if (!scan_char(')')) return false;
616  } else {
617  size_t start;
618  in_ >> start;
619  if (!scan_char(':'))
620  return false;
621  size_t end;
622  in_ >> end;
623  if (start < end) {
624  for (size_t i = start; i <= end; ++i)
625  dims_.push_back(i);
626  } else {
627  for (size_t i = start; i >= end; --i)
628  dims_.push_back(i);
629  }
630  }
631  if (!scan_char(')')) return false;
632  return true;
633  }
634 
635 
636 
637  bool scan_value() {
638  if (scan_char('c'))
639  return scan_seq_value();
640  if (scan_chars("structure"))
641  return scan_struct_value();
642  if (!scan_number())
643  return false;
644  if (!scan_char(':'))
645  return true;
646  if (stack_i_.size() != 1)
647  return false;
648  if (!scan_number())
649  return false;
650  if (stack_i_.size() != 2)
651  return false;
652  int start = stack_i_[0];
653  int end = stack_i_[1];
654  stack_i_.clear();
655  if (start <= end) {
656  for (int i = start; i <= end; ++i)
657  stack_i_.push_back(i);
658  } else {
659  for (int i = start; i >= end; --i)
660  stack_i_.push_back(i);
661  }
662  dims_.push_back(stack_i_.size());
663  return true;
664  }
665 
669  void print() {
670  std::cout << "var name=|" << name_ << "|" << std::endl;
671  std:: cout << "dims=(";
672  for (size_t i = 0; i < dims_.size(); ++i) {
673  if (i > 0)
674  std::cout << ",";
675  std::cout << dims_[i];
676  }
677  std::cout << ")" << std::endl;
678  std::cout << "float stack:" << std::endl;
679  for (size_t i = 0; i < stack_r_.size(); ++i)
680  std::cout << " [" << i << "] " << stack_r_[i] << std::endl;
681  std::cout << "int stack" << std::endl;
682  for (size_t i = 0; i < stack_i_.size(); ++i)
683  std::cout << " [" << i << "] " << stack_i_[i] << std::endl;
684  }
685 
686 
687  public:
691  dump_reader() : in_(std::cin) { }
692 
698  dump_reader(std::istream& in) : in_(in) { }
699 
704 
705 
711  std::string name() {
712  return name_;
713  }
714 
721  std::vector<size_t> dims() {
722  return dims_;
723  }
724 
732  bool is_int() {
733  return stack_i_.size() > 0;
734  }
735 
742  std::vector<int> int_values() {
743  return stack_i_;
744  }
745 
753  std::vector<double> double_values() {
754  return stack_r_;
755  }
756 
764  bool next() {
765  stack_r_.clear();
766  stack_i_.clear();
767  dims_.clear();
768  name_.erase();
769  if (!scan_name()) // set name
770  return false;
771  if (!scan_char('<')) // set <-
772  return false;
773  if (!scan_char('-'))
774  return false;
775  if (!scan_value()) // set stack_r_, stack_i_, dims_
776  return false;
777  return true;
778  }
779 
780  };
781 
782 
783 
799  class dump : public stan::io::var_context {
800  private:
801  std::map<std::string,
802  std::pair<std::vector<double>,
803  std::vector<size_t> > > vars_r_;
804  std::map<std::string,
805  std::pair<std::vector<int>,
806  std::vector<size_t> > > vars_i_;
807  std::vector<double> const empty_vec_r_;
808  std::vector<int> const empty_vec_i_;
809  std::vector<size_t> const empty_vec_ui_;
819  bool contains_r_only(const std::string& name) const {
820  return vars_r_.find(name) != vars_r_.end();
821  }
822  public:
823 
831  dump(std::istream& in) {
832  dump_reader reader(in);
833  while (reader.next()) {
834  if (reader.is_int()) {
835  vars_i_[reader.name()]
836  = std::pair<std::vector<int>,
837  std::vector<size_t> >(reader.int_values(),
838  reader.dims());
839 
840  } else {
841  vars_r_[reader.name()]
842  = std::pair<std::vector<double>,
843  std::vector<size_t> >(reader.double_values(),
844  reader.dims());
845  }
846  }
847  }
848 
857  bool contains_r(const std::string& name) const {
858  return contains_r_only(name) || contains_i(name);
859  }
860 
869  bool contains_i(const std::string& name) const {
870  return vars_i_.find(name) != vars_i_.end();
871  }
872 
880  std::vector<double> vals_r(const std::string& name) const {
881  if (contains_r_only(name)) {
882  return (vars_r_.find(name)->second).first;
883  } else if (contains_i(name)) {
884  std::vector<int> vec_int = (vars_i_.find(name)->second).first;
885  std::vector<double> vec_r(vec_int.size());
886  for (size_t ii = 0; ii < vec_int.size(); ii++) {
887  vec_r[ii] = vec_int[ii];
888  }
889  return vec_r;
890  }
891  return empty_vec_r_;
892  }
893 
901  std::vector<size_t> dims_r(const std::string& name) const {
902  if (contains_r_only(name)) {
903  return (vars_r_.find(name)->second).second;
904  } else if (contains_i(name)) {
905  return (vars_i_.find(name)->second).second;
906  }
907  return empty_vec_ui_;
908  }
909 
917  std::vector<int> vals_i(const std::string& name) const {
918  if (contains_i(name)) {
919  return (vars_i_.find(name)->second).first;
920  }
921  return empty_vec_i_;
922  }
923 
931  std::vector<size_t> dims_i(const std::string& name) const {
932  if (contains_i(name)) {
933  return (vars_i_.find(name)->second).second;
934  }
935  return empty_vec_ui_;
936  }
937 
944  virtual void names_r(std::vector<std::string>& names) const {
945  names.resize(0);
946  for (std::map<std::string,
947  std::pair<std::vector<double>,
948  std::vector<size_t> > >
949  ::const_iterator it = vars_r_.begin();
950  it != vars_r_.end(); ++it)
951  names.push_back((*it).first);
952  }
953 
960  virtual void names_i(std::vector<std::string>& names) const {
961  names.resize(0);
962  for (std::map<std::string,
963  std::pair<std::vector<int>,
964  std::vector<size_t> > >
965  ::const_iterator it = vars_i_.begin();
966  it != vars_i_.end(); ++it)
967  names.push_back((*it).first);
968  }
969 
977  bool remove(const std::string& name) {
978  return (vars_i_.erase(name) > 0)
979  || (vars_r_.erase(name) > 0);
980  }
981 
982  };
983 
984  }
985 
986 }
987 #endif

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