1 #ifndef STAN__IO__DUMP_HPP
2 #define STAN__IO__DUMP_HPP
13 #include <boost/lexical_cast.hpp>
14 #include <boost/throw_exception.hpp>
26 size_t product(std::vector<size_t>
dims) {
28 for (
size_t i = 0; i < dims.size(); ++i)
47 void write_name_equals(
const std::string& name) {
48 for (
size_t i = 0; i < name.size(); ++i)
49 if (name.at(i) ==
'"')
50 BOOST_THROW_EXCEPTION(
51 std::invalid_argument (
"name can not contain quote char"));
52 out_ <<
'"' << name <<
'"' <<
" <- " <<
'\n';
57 void write_val(
const double& x) {
62 for (std::string::iterator it = s.begin();
65 if (*it ==
'.' || *it ==
'e' || *it ==
'E') {
73 void write_val(
const unsigned long long int& n) {
77 void write_val(
const unsigned long int& n) {
81 void write_val(
const unsigned int& n) {
85 void write_val(
const unsigned short& n) {
89 void write_val(
const long long& n) {
93 void write_val(
const long& n) {
97 void write_val(
const int& n) {
101 void write_val(
const short& n) {
105 void write_val(
const char& n) {
110 template <
typename T>
111 void write_list(T xs) {
114 for (idx_t i = 0; i < xs.size(); ++i) {
115 if (i > 0) out_ <<
", ";
121 template <
typename T>
122 void write_structure(std::vector<T> xs,
123 std::vector<size_t> dims) {
124 out_ <<
"structure(";
133 void dims(
double , std::vector<size_t> ) {
137 void dims(
int , std::vector<size_t> ) {
141 template <
typename T>
142 void dims(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> m,
143 std::vector<size_t> ds) {
144 ds.push_back(m.rows());
145 ds.push_back(m.cols());
148 template <
typename T>
149 void dims(Eigen::Matrix<T,Eigen::Dynamic,1> v,
150 std::vector<size_t> ds) {
151 ds.push_back(v.size());
154 template <
typename T>
155 void dims(Eigen::Matrix<T,1,Eigen::Dynamic> rv,
156 std::vector<size_t> ds) {
157 ds.push_back(rv.size());
160 template <
typename T>
161 void dims(std::vector<T> x, std::vector<size_t> ds) {
162 ds.push_back(x.size());
167 template <
typename T>
168 std::vector<size_t> dims(T x) {
169 std::vector<size_t> ds;
174 bool increment(
const std::vector<size_t>& dims,
175 std::vector<size_t>& idx) {
176 for (
size_t i = 0; i < dims.size(); ++i) {
178 if (idx[i] < dims[i])
return true;
184 template <
typename T>
185 void write_stan_val(
const std::vector<T>& x,
186 const std::vector<size_t>& idx,
188 size_t next_pos = pos + 1;
189 write_stan_val(x[idx[pos]],idx,next_pos);
191 void write_stan_val(
const std::vector<double>& x,
192 const std::vector<size_t>& idx,
194 write_val(x[idx[pos]]);
196 void write_stan_val(
const std::vector<int>& x,
197 const std::vector<size_t>& idx,
199 write_val(x[idx[pos]]);
201 void write_stan_val(
const Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>& x,
202 const std::vector<size_t>& idx,
204 size_t next_pos = pos + 1;
205 write_val(x(idx[pos],idx[next_pos]));
207 void write_stan_val(
const Eigen::Matrix<double,1,Eigen::Dynamic>& x,
208 const std::vector<size_t>& idx,
210 write_val(x[idx[pos]]);
212 void write_stan_val(
const Eigen::Matrix<double,Eigen::Dynamic,1>& x,
213 const std::vector<size_t>& idx,
215 write_val(x[idx[pos]]);
219 template <
typename T>
220 void write_stan(
const std::vector<T>& x) {
221 std::vector<size_t> dims = dims(x);
222 out_ <<
"structure(c(";
223 std::vector<size_t> idx(dims.size(),0U);
224 for (
size_t count = 0;
true; ++count) {
225 if (count > 0) out_ <<
", ";
226 write_stan_val(x,idx);
227 if (!increment(dims,idx))
break;
229 out_ <<
"), .Dim = ";
233 void write_stan(
const std::vector<double>& x) {
236 void write_stan(
const std::vector<int>& x) {
239 void write_stan(
double x) {
242 void write_stan(
int x) {
245 void write_stan(
const Eigen::Matrix<double,1,Eigen::Dynamic>& x) {
248 void write_stan(
const Eigen::Matrix<double,Eigen::Dynamic,1>& x) {
251 void write_stan(
const Eigen::Matrix<
double,
252 Eigen::Dynamic,Eigen::Dynamic>& x) {
253 typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>::Index Index;
254 out_ <<
"structure(c(";
255 std::vector<double> vals;
256 for (Index m = 0; m < x.cols(); ++m) {
257 for (Index n = 0; n < x.rows(); ++n) {
258 if (m > 0 || n > 0) out_ <<
", ";
262 out_ <<
"), .Dim = c(";
263 out_ << x.rows() <<
", " << x.cols();
305 template <
typename T>
308 write_name_equals(name);
321 template <
typename T>
323 std::vector<size_t> dims,
325 if (xs.size() != product(dims))
326 BOOST_THROW_EXCEPTION(
327 std::invalid_argument (
"xs.size() != product(dims)"));
328 write_structure(xs,dims);
339 template <
typename T>
342 write_name_equals(name);
354 template <
typename T>
357 write_name_equals(name);
438 std::vector<int> stack_i_;
439 std::vector<double> stack_r_;
440 std::vector<size_t> dims_;
443 bool scan_single_char(
char c_expected) {
445 if (in_.fail())
return false;
453 bool scan_optional_long() {
454 if (scan_single_char(
'l'))
456 else if (scan_single_char(
'L'))
462 bool scan_char(
char c_expected) {
465 if (in_.fail())
return false;
466 if (c != c_expected) {
473 bool scan_name_unquoted() {
476 if (in_.fail())
return false;
477 if (!std::isalpha(c))
return false;
480 if (std::isalpha(c) || std::isdigit(c) || c ==
'_' || c ==
'.') {
491 if (scan_char(
'"')) {
492 if (!scan_name_unquoted())
return false;
493 if (!scan_char(
'"'))
return false;
494 }
else if (scan_char(
'\'')) {
495 if (!scan_name_unquoted())
return false;
496 if (!scan_char(
'\''))
return false;
498 if (!scan_name_unquoted())
return false;
504 bool scan_chars(
const char *s,
bool case_sensitive =
true) {
505 for (
size_t i = 0; s[i]; ++i) {
508 for (
size_t j = 1; j < i; ++j)
513 if ((case_sensitive && c != s[i])
514 || (!case_sensitive && ::toupper(c) != ::toupper(s[i]))) {
516 for (
size_t j = 1; j < i; ++j)
524 bool scan_chars(std::string s,
bool case_sensitive =
true) {
525 for (
size_t i = 0; i < s.size(); ++i) {
528 for (
size_t j = 1; j < i; ++j)
533 if ((case_sensitive && c != s[i])
534 || (!case_sensitive && ::toupper(c) != ::toupper(s[i]))) {
536 for (
size_t j = 1; j < i; ++j)
548 if (std::isspace(c))
continue;
549 if (std::isdigit(c)) {
556 scan_optional_long();
559 d = boost::lexical_cast<
size_t>(buf_);
561 catch (
const boost::bad_lexical_cast &exc ) {
562 std::string msg =
"value " + buf_ +
" beyond array dimension range";
563 BOOST_THROW_EXCEPTION (std::invalid_argument (msg));
572 if (std::isspace(c))
continue;
573 if (std::isdigit(c)) {
586 n = boost::lexical_cast<
int>(buf_);
588 catch (
const boost::bad_lexical_cast &exc ) {
589 std::string msg =
"value " + buf_ +
" beyond int range";
590 BOOST_THROW_EXCEPTION (std::invalid_argument (msg));
595 double scan_double() {
598 x = boost::lexical_cast<
double>(buf_);
600 catch (
const boost::bad_lexical_cast &exc ) {
601 std::string msg =
"value " + buf_ +
" beyond numeric range";
602 BOOST_THROW_EXCEPTION (std::invalid_argument (msg));
610 void scan_number(
bool negate_val) {
612 if (scan_chars(
"Inf")) {
614 stack_r_.push_back(negate_val
615 ? -std::numeric_limits<double>::infinity()
616 : std::numeric_limits<double>::infinity());
619 if (scan_chars(
"NaN",
false)) {
620 stack_r_.push_back(std::numeric_limits<double>::quiet_NaN());
625 bool is_double =
false;
628 if (std::isdigit(c)) {
642 if (!is_double && stack_r_.size() == 0) {
644 stack_i_.push_back(negate_val ? -n : n);
645 scan_optional_long();
647 for (
size_t j = 0; j < stack_i_.size(); ++j)
648 stack_r_.push_back(static_cast<double>(stack_i_[j]));
650 double x = scan_double();
651 stack_r_.push_back(negate_val ? -x : x);
658 if (std::isspace(c))
continue;
662 bool negate_val = scan_char(
'-');
663 if (!negate_val) scan_char(
'+');
664 return scan_number(negate_val);
668 bool scan_seq_value() {
669 if (!scan_char(
'('))
return false;
670 if (scan_char(
')')) {
675 while (scan_char(
',')) {
678 dims_.push_back(stack_r_.size() + stack_i_.size());
679 return scan_char(
')');
682 bool scan_struct_value() {
683 if (!scan_char(
'('))
return false;
684 if (scan_char(
'c')) {
687 int start = scan_int();
690 int end = scan_int();
692 for (
int i = start; i <= end; ++i)
693 stack_i_.push_back(i);
695 for (
int i = start; i >= end; --i)
696 stack_i_.push_back(i);
700 if (!scan_char(
','))
return false;
701 if (!scan_char(
'.'))
return false;
702 if (!scan_chars(
"Dim"))
return false;
703 if (!scan_char(
'='))
return false;
704 if (scan_char(
'c')) {
705 if (!scan_char(
'('))
return false;
706 size_t dim = scan_dim();
707 dims_.push_back(dim);
708 while (scan_char(
',')) {
710 dims_.push_back(dim);
712 if (!scan_char(
')'))
return false;
715 size_t start = scan_dim();
718 size_t end = scan_dim();
720 for (
size_t i = start; i <= end; ++i)
723 for (
size_t i = start; i >= end; --i)
727 if (!scan_char(
')'))
return false;
733 return scan_seq_value();
734 if (scan_chars(
"structure"))
735 return scan_struct_value();
739 if (stack_i_.size() != 1)
742 if (stack_i_.size() != 2)
744 int start = stack_i_[0];
745 int end = stack_i_[1];
748 for (
int i = start; i <= end; ++i)
749 stack_i_.push_back(i);
751 for (
int i = start; i >= end; --i)
752 stack_i_.push_back(i);
754 dims_.push_back(stack_i_.size());
762 std::cout <<
"var name=|" << name_ <<
"|" << std::endl;
763 std:: cout <<
"dims=(";
764 for (
size_t i = 0; i < dims_.size(); ++i) {
767 std::cout << dims_[i];
769 std::cout <<
")" << std::endl;
770 std::cout <<
"float stack:" << std::endl;
771 for (
size_t i = 0; i < stack_r_.size(); ++i)
772 std::cout <<
" [" << i <<
"] " << stack_r_[i] << std::endl;
773 std::cout <<
"int stack" << std::endl;
774 for (
size_t i = 0; i < stack_i_.size(); ++i)
775 std::cout <<
" [" << i <<
"] " << stack_i_[i] << std::endl;
826 return stack_r_.size() == 0;
870 bool okSyntax = scan_value();
872 std::string msg =
"syntax error";
873 BOOST_THROW_EXCEPTION (std::invalid_argument (msg));
876 catch (
const std::invalid_argument &
e) {
877 std::string msg =
"data " + name_ +
" " + e.what();
878 BOOST_THROW_EXCEPTION (std::invalid_argument (msg));
904 std::map<std::string,
905 std::pair<std::vector<double>,
906 std::vector<size_t> > > vars_r_;
907 std::map<std::string,
908 std::pair<std::vector<int>,
909 std::vector<size_t> > > vars_i_;
910 std::vector<double>
const empty_vec_r_;
911 std::vector<int>
const empty_vec_i_;
912 std::vector<size_t>
const empty_vec_ui_;
922 bool contains_r_only(
const std::string& name)
const {
923 return vars_r_.find(name) != vars_r_.end();
936 while (reader.
next()) {
938 vars_i_[reader.
name()]
939 = std::pair<std::vector<int>,
944 vars_r_[reader.
name()]
945 = std::pair<std::vector<double>,
961 return contains_r_only(name) ||
contains_i(name);
973 return vars_i_.find(name) != vars_i_.end();
983 std::vector<double>
vals_r(
const std::string& name)
const {
984 if (contains_r_only(name)) {
985 return (vars_r_.find(name)->second).first;
987 std::vector<int> vec_int = (vars_i_.find(name)->second).first;
988 std::vector<double> vec_r(vec_int.size());
989 for (
size_t ii = 0; ii < vec_int.size(); ii++) {
990 vec_r[ii] = vec_int[ii];
1004 std::vector<size_t>
dims_r(
const std::string& name)
const {
1005 if (contains_r_only(name)) {
1006 return (vars_r_.find(name)->second).second;
1008 return (vars_i_.find(name)->second).second;
1010 return empty_vec_ui_;
1020 std::vector<int>
vals_i(
const std::string& name)
const {
1022 return (vars_i_.find(name)->second).first;
1024 return empty_vec_i_;
1034 std::vector<size_t>
dims_i(
const std::string& name)
const {
1036 return (vars_i_.find(name)->second).second;
1038 return empty_vec_ui_;
1047 virtual void names_r(std::vector<std::string>& names)
const {
1049 for (std::map<std::string,
1050 std::pair<std::vector<double>,
1051 std::vector<size_t> > >
1052 ::const_iterator it = vars_r_.begin();
1053 it != vars_r_.end(); ++it)
1054 names.push_back((*it).first);
1063 virtual void names_i(std::vector<std::string>& names)
const {
1065 for (std::map<std::string,
1066 std::pair<std::vector<int>,
1067 std::vector<size_t> > >
1068 ::const_iterator it = vars_i_.begin();
1069 it != vars_i_.end(); ++it)
1070 names.push_back((*it).first);
1080 bool remove(
const std::string& name) {
1081 return (vars_i_.erase(name) > 0)
1082 || (vars_r_.erase(name) > 0);
dump(std::istream &in)
Construct a dump object from the specified input stream.
dump_writer()
Construct a dump writer writing to standard output.
void write(const std::string &name, const T &x)
Write a variable with the specified name and value.
~dump_reader()
Destroy this reader.
void dump_structure(std::string, std::vector< size_t > dims, std::vector< T > xs)
Write a structure variable with the specified name, dimensions, and integer or double values...
~dump_writer()
Destroy this writer.
bool is_int()
Checks if the last item read is integer.
Writes data into the S-plus dump format.
virtual void names_r(std::vector< std::string > &names) const
Return a list of the names of the floating point variables in the dump.
bool contains_r(const std::string &name) const
Return true if this dump contains the specified variable name is defined.
std::vector< double > double_values()
Returns the floating point values from the last item if the last item read contained floating point v...
virtual void names_i(std::vector< std::string > &names) const
Return a list of the names of the integer variables in the dump.
void dump_list(std::string name, std::vector< T > xs)
Write a list variable with the specified name and integer or double values.
Primary template class for the metaprogram to compute the index type of a container.
A stream-based reader for integer, scalar, vector, matrix and array data types, with Jacobian calcula...
void dump_var(std::string name, T x)
Write a list variable with the specified name and integer or double values.
void dims(const T &x, std::vector< int > &result)
bool contains_i(const std::string &name) const
Return true if this dump contains an integer valued array with the specified name.
A var_reader reads array variables of integer and floating point type by name and dimension...
std::vector< size_t > dims_r(const std::string &name) const
Return the dimensions for the double variable with the specified name.
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...
std::vector< double > vals_r(const std::string &name) const
Return the double values for the variable with the specified name or null.
double e()
Return the base of the natural logarithm.
dump_writer(std::ostream &out)
Construct a dump writer writing to the specified output stream.
std::string name()
Return the name of the most recently read variable.
std::vector< size_t > dims()
Return the dimensions of the most recently read variable.
std::vector< int > vals_i(const std::string &name) const
Return the integer values for the variable with the specified name.
dump_reader()
Construct a reader for standard input.
Reads data from S-plus dump format.
Represents named arrays with dimensions.
bool next()
Read the next value from the input stream, returning true if successful and false if no further input...
dump_reader(std::istream &in)
Construct a reader for the specified input stream.
std::vector< size_t > dims_i(const std::string &name) const
Return the dimensions for the integer variable with the specified name.