1 #ifndef STAN_IO_DUMP_HPP 2 #define STAN_IO_DUMP_HPP 6 #include <stan/math/prim/mat.hpp> 7 #include <boost/lexical_cast.hpp> 8 #include <boost/throw_exception.hpp> 9 #include <boost/type_traits/is_floating_point.hpp> 10 #include <boost/type_traits/is_integral.hpp> 11 #include <boost/type_traits/is_arithmetic.hpp> 12 #include <boost/utility/enable_if.hpp> 120 std::vector<int> stack_i_;
121 std::vector<double> stack_r_;
122 std::vector<size_t> dims_;
125 bool scan_single_char(
char c_expected) {
127 if (in_.fail())
return false;
135 bool scan_optional_long() {
136 if (scan_single_char(
'l'))
138 else if (scan_single_char(
'L'))
144 bool scan_char(
char c_expected) {
147 if (in_.fail())
return false;
148 if (c != c_expected) {
155 bool scan_name_unquoted() {
158 if (in_.fail())
return false;
159 if (!std::isalpha(c))
return false;
162 if (std::isalpha(c) || std::isdigit(c) || c ==
'_' || c ==
'.') {
173 if (scan_char(
'"')) {
174 if (!scan_name_unquoted())
return false;
175 if (!scan_char(
'"'))
return false;
176 }
else if (scan_char(
'\'')) {
177 if (!scan_name_unquoted())
return false;
178 if (!scan_char(
'\''))
return false;
180 if (!scan_name_unquoted())
return false;
186 bool scan_chars(
const char *s,
bool case_sensitive =
true) {
187 for (
size_t i = 0; s[i]; ++i) {
190 for (
size_t j = 1; j < i; ++j)
195 if ((case_sensitive && c != s[i])
196 || (!case_sensitive && ::toupper(c) != ::toupper(s[i]))) {
198 for (
size_t j = 1; j < i; ++j)
206 bool scan_chars(std::string s,
bool case_sensitive =
true) {
207 for (
size_t i = 0; i < s.size(); ++i) {
210 for (
size_t j = 1; j < i; ++j)
215 if ((case_sensitive && c != s[i])
216 || (!case_sensitive && ::toupper(c) != ::toupper(s[i]))) {
218 for (
size_t j = 1; j < i; ++j)
230 if (std::isspace(c))
continue;
231 if (std::isdigit(c)) {
238 scan_optional_long();
241 d = boost::lexical_cast<
size_t>(buf_);
243 catch (
const boost::bad_lexical_cast &exc ) {
244 std::string msg =
"value " + buf_ +
" beyond array dimension range";
245 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
254 if (std::isspace(c))
continue;
255 if (std::isdigit(c)) {
268 n = boost::lexical_cast<
int>(buf_);
270 catch (
const boost::bad_lexical_cast &exc ) {
271 std::string msg =
"value " + buf_ +
" beyond int range";
272 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
277 double scan_double() {
280 x = boost::lexical_cast<
double>(buf_);
284 catch (
const boost::bad_lexical_cast &exc ) {
285 std::string msg =
"value " + buf_ +
" beyond numeric range";
286 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
294 void scan_number(
bool negate_val) {
296 if (scan_chars(
"Inf")) {
298 stack_r_.push_back(negate_val
299 ? -std::numeric_limits<double>::infinity()
300 : std::numeric_limits<double>::infinity());
303 if (scan_chars(
"NaN",
false)) {
304 stack_r_.push_back(std::numeric_limits<double>::quiet_NaN());
309 bool is_double =
false;
312 if (std::isdigit(c)) {
326 if (!is_double && stack_r_.size() == 0) {
328 stack_i_.push_back(negate_val ? -n : n);
329 scan_optional_long();
331 for (
size_t j = 0; j < stack_i_.size(); ++j)
332 stack_r_.push_back(static_cast<double>(stack_i_[j]));
334 double x = scan_double();
335 stack_r_.push_back(negate_val ? -x : x);
342 if (std::isspace(c))
continue;
346 bool negate_val = scan_char(
'-');
347 if (!negate_val) scan_char(
'+');
348 return scan_number(negate_val);
351 bool scan_zero_integers() {
352 if (!scan_char(
'('))
return false;
353 if (scan_char(
')')) {
358 if (s < 0)
return false;
359 for (
int i = 0; i < s; ++i) {
360 stack_i_.push_back(0);
362 if (!scan_char(
')'))
return false;
367 bool scan_zero_doubles() {
368 if (!scan_char(
'('))
return false;
369 if (scan_char(
')')) {
374 if (s < 0)
return false;
375 for (
int i = 0; i < s; ++i) {
376 stack_r_.push_back(0);
378 if (!scan_char(
')'))
return false;
384 bool scan_seq_value() {
385 if (!scan_char(
'('))
return false;
386 if (scan_char(
')')) {
391 while (scan_char(
',')) {
394 dims_.push_back(stack_r_.size() + stack_i_.size());
395 return scan_char(
')');
398 bool scan_struct_value() {
399 if (!scan_char(
'('))
return false;
400 if (scan_chars(
"integer")) {
401 scan_zero_integers();
402 }
else if (scan_chars(
"double")) {
404 }
else if (scan_char(
'c')) {
407 int start = scan_int();
410 int end = scan_int();
412 for (
int i = start; i <= end; ++i)
413 stack_i_.push_back(i);
415 for (
int i = start; i >= end; --i)
416 stack_i_.push_back(i);
420 if (!scan_char(
','))
return false;
421 if (!scan_char(
'.'))
return false;
422 if (!scan_chars(
"Dim"))
return false;
423 if (!scan_char(
'='))
return false;
424 if (scan_char(
'c')) {
425 if (!scan_char(
'('))
return false;
426 size_t dim = scan_dim();
427 dims_.push_back(dim);
428 while (scan_char(
',')) {
430 dims_.push_back(dim);
432 if (!scan_char(
')'))
return false;
434 size_t start = scan_dim();
437 size_t end = scan_dim();
439 for (
size_t i = start; i <= end; ++i)
442 for (
size_t i = start; i >= end; --i)
446 if (!scan_char(
')'))
return false;
452 return scan_seq_value();
453 if (scan_chars(
"integer"))
454 return scan_zero_integers();
455 if (scan_chars(
"double"))
456 return scan_zero_doubles();
457 if (scan_chars(
"structure"))
458 return scan_struct_value();
462 if (stack_i_.size() != 1)
465 if (stack_i_.size() != 2)
467 int start = stack_i_[0];
468 int end = stack_i_[1];
471 for (
int i = start; i <= end; ++i)
472 stack_i_.push_back(i);
474 for (
int i = start; i >= end; --i)
475 stack_i_.push_back(i);
477 dims_.push_back(stack_i_.size());
524 return stack_r_.size() == 0;
568 bool okSyntax = scan_value();
570 std::string msg =
"syntax error";
571 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
574 catch (
const std::invalid_argument &e) {
575 std::string msg =
"data " + name_ +
" " + e.what();
576 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
601 std::map<std::string,
602 std::pair<std::vector<double>,
603 std::vector<size_t> > > vars_r_;
604 std::map<std::string,
605 std::pair<std::vector<int>,
606 std::vector<size_t> > > vars_i_;
607 std::vector<double>
const empty_vec_r_;
608 std::vector<int>
const empty_vec_i_;
609 std::vector<size_t>
const empty_vec_ui_;
619 bool contains_r_only(
const std::string&
name)
const {
620 return vars_r_.find(name) != vars_r_.end();
631 explicit dump(std::istream& in) {
633 while (reader.
next()) {
635 vars_i_[reader.
name()]
636 = std::pair<std::vector<int>,
641 vars_r_[reader.
name()]
642 = std::pair<std::vector<double>,
658 return contains_r_only(name) || contains_i(name);
670 return vars_i_.find(name) != vars_i_.end();
680 std::vector<double>
vals_r(
const std::string& name)
const {
681 if (contains_r_only(name)) {
682 return (vars_r_.find(name)->second).first;
683 }
else if (contains_i(name)) {
684 std::vector<int> vec_int = (vars_i_.find(name)->second).first;
685 std::vector<double> vec_r(vec_int.size());
686 for (
size_t ii = 0; ii < vec_int.size(); ii++) {
687 vec_r[ii] = vec_int[ii];
701 std::vector<size_t>
dims_r(
const std::string& name)
const {
702 if (contains_r_only(name)) {
703 return (vars_r_.find(name)->second).second;
704 }
else if (contains_i(name)) {
705 return (vars_i_.find(name)->second).second;
707 return empty_vec_ui_;
717 std::vector<int>
vals_i(
const std::string& name)
const {
718 if (contains_i(name)) {
719 return (vars_i_.find(name)->second).first;
731 std::vector<size_t>
dims_i(
const std::string& name)
const {
732 if (contains_i(name)) {
733 return (vars_i_.find(name)->second).second;
735 return empty_vec_ui_;
744 virtual void names_r(std::vector<std::string>& names)
const {
746 for (std::map<std::string,
747 std::pair<std::vector<double>,
748 std::vector<size_t> > >
749 ::const_iterator it = vars_r_.begin();
750 it != vars_r_.end(); ++it)
751 names.push_back((*it).first);
760 virtual void names_i(std::vector<std::string>& names)
const {
762 for (std::map<std::string,
763 std::pair<std::vector<int>,
764 std::vector<size_t> > >
765 ::const_iterator it = vars_i_.begin();
766 it != vars_i_.end(); ++it)
767 names.push_back((*it).first);
777 bool remove(
const std::string&
name) {
778 return (vars_i_.erase(name) > 0)
779 || (vars_r_.erase(name) > 0);
dump(std::istream &in)
Construct a dump object from the specified input stream.
bool contains_r(const std::string &name) const
Return true if this dump contains the specified variable name is defined.
~dump_reader()
Destroy this reader.
std::vector< size_t > dims_i(const std::string &name) const
Return the dimensions for the integer variable with the specified name.
bool is_int()
Checks if the last item read is integer.
Probability, optimization and sampling library.
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_r(std::vector< std::string > &names) const
Return a list of the names of the floating point variables in the dump.
A stream-based reader for integer, scalar, vector, matrix and array data types, with Jacobian calcula...
A var_reader reads array variables of integer and floating point type by name and dimension...
void validate_zero_buf(const B &buf)
Throw an bad-cast exception if the specified buffer contains a digit other than 0 before an e or E...
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...
virtual void names_i(std::vector< std::string > &names) const
Return a list of the names of the integer variables in the dump.
std::vector< int > vals_i(const std::string &name) const
Return the integer values for the variable with the specified name.
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.
bool contains_i(const std::string &name) const
Return true if this dump contains an integer valued array with the specified name.
std::vector< double > vals_r(const std::string &name) const
Return the double values for the variable with the specified name or null.
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.