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