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> 102 std::vector<int> stack_i_;
103 std::vector<double> stack_r_;
104 std::vector<size_t> dims_;
107 bool scan_single_char(
char c_expected) {
109 if (in_.fail())
return false;
117 bool scan_optional_long() {
118 if (scan_single_char(
'l'))
120 else if (scan_single_char(
'L'))
126 bool scan_char(
char c_expected) {
129 if (in_.fail())
return false;
130 if (c != c_expected) {
137 bool scan_name_unquoted() {
140 if (in_.fail())
return false;
141 if (!std::isalpha(c))
return false;
144 if (std::isalpha(c) || std::isdigit(c) || c ==
'_' || c ==
'.') {
155 if (scan_char(
'"')) {
156 if (!scan_name_unquoted())
return false;
157 if (!scan_char(
'"'))
return false;
158 }
else if (scan_char(
'\'')) {
159 if (!scan_name_unquoted())
return false;
160 if (!scan_char(
'\''))
return false;
162 if (!scan_name_unquoted())
return false;
168 bool scan_chars(
const char *s,
bool case_sensitive =
true) {
169 for (
size_t i = 0; s[i]; ++i) {
172 for (
size_t j = 1; j < i; ++j)
177 if ((case_sensitive && c != s[i])
178 || (!case_sensitive && ::toupper(c) != ::toupper(s[i]))) {
180 for (
size_t j = 1; j < i; ++j)
188 bool scan_chars(std::string s,
bool case_sensitive =
true) {
189 for (
size_t i = 0; i < s.size(); ++i) {
192 for (
size_t j = 1; j < i; ++j)
197 if ((case_sensitive && c != s[i])
198 || (!case_sensitive && ::toupper(c) != ::toupper(s[i]))) {
200 for (
size_t j = 1; j < i; ++j)
212 if (std::isspace(c))
continue;
213 if (std::isdigit(c)) {
220 scan_optional_long();
223 d = boost::lexical_cast<
size_t>(buf_);
225 catch (
const boost::bad_lexical_cast &exc ) {
226 std::string msg =
"value " + buf_ +
" beyond array dimension range";
227 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
236 if (std::isspace(c))
continue;
237 if (std::isdigit(c)) {
250 n = boost::lexical_cast<
int>(buf_);
252 catch (
const boost::bad_lexical_cast &exc ) {
253 std::string msg =
"value " + buf_ +
" beyond int range";
254 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
259 double scan_double() {
262 x = boost::lexical_cast<
double>(buf_);
266 catch (
const boost::bad_lexical_cast &exc ) {
267 std::string msg =
"value " + buf_ +
" beyond numeric range";
268 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
276 void scan_number(
bool negate_val) {
278 if (scan_chars(
"Inf")) {
280 stack_r_.push_back(negate_val
281 ? -std::numeric_limits<double>::infinity()
282 : std::numeric_limits<double>::infinity());
285 if (scan_chars(
"NaN",
false)) {
286 stack_r_.push_back(std::numeric_limits<double>::quiet_NaN());
291 bool is_double =
false;
294 if (std::isdigit(c)) {
308 if (!is_double && stack_r_.size() == 0) {
310 stack_i_.push_back(negate_val ? -n : n);
311 scan_optional_long();
313 for (
size_t j = 0; j < stack_i_.size(); ++j)
314 stack_r_.push_back(static_cast<double>(stack_i_[j]));
316 double x = scan_double();
317 stack_r_.push_back(negate_val ? -x : x);
324 if (std::isspace(c))
continue;
328 bool negate_val = scan_char(
'-');
329 if (!negate_val) scan_char(
'+');
330 return scan_number(negate_val);
334 bool scan_seq_value() {
335 if (!scan_char(
'('))
return false;
336 if (scan_char(
')')) {
341 while (scan_char(
',')) {
344 dims_.push_back(stack_r_.size() + stack_i_.size());
345 return scan_char(
')');
348 bool scan_struct_value() {
349 if (!scan_char(
'('))
return false;
350 if (scan_char(
'c')) {
353 int start = scan_int();
356 int end = scan_int();
358 for (
int i = start; i <= end; ++i)
359 stack_i_.push_back(i);
361 for (
int i = start; i >= end; --i)
362 stack_i_.push_back(i);
366 if (!scan_char(
','))
return false;
367 if (!scan_char(
'.'))
return false;
368 if (!scan_chars(
"Dim"))
return false;
369 if (!scan_char(
'='))
return false;
370 if (scan_char(
'c')) {
371 if (!scan_char(
'('))
return false;
372 size_t dim = scan_dim();
373 dims_.push_back(dim);
374 while (scan_char(
',')) {
376 dims_.push_back(dim);
378 if (!scan_char(
')'))
return false;
380 size_t start = scan_dim();
383 size_t end = scan_dim();
385 for (
size_t i = start; i <= end; ++i)
388 for (
size_t i = start; i >= end; --i)
392 if (!scan_char(
')'))
return false;
398 return scan_seq_value();
399 if (scan_chars(
"structure"))
400 return scan_struct_value();
404 if (stack_i_.size() != 1)
407 if (stack_i_.size() != 2)
409 int start = stack_i_[0];
410 int end = stack_i_[1];
413 for (
int i = start; i <= end; ++i)
414 stack_i_.push_back(i);
416 for (
int i = start; i >= end; --i)
417 stack_i_.push_back(i);
419 dims_.push_back(stack_i_.size());
466 return stack_r_.size() == 0;
510 bool okSyntax = scan_value();
512 std::string msg =
"syntax error";
513 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
516 catch (
const std::invalid_argument &e) {
517 std::string msg =
"data " + name_ +
" " + e.what();
518 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
543 std::map<std::string,
544 std::pair<std::vector<double>,
545 std::vector<size_t> > > vars_r_;
546 std::map<std::string,
547 std::pair<std::vector<int>,
548 std::vector<size_t> > > vars_i_;
549 std::vector<double>
const empty_vec_r_;
550 std::vector<int>
const empty_vec_i_;
551 std::vector<size_t>
const empty_vec_ui_;
561 bool contains_r_only(
const std::string&
name)
const {
562 return vars_r_.find(name) != vars_r_.end();
573 explicit dump(std::istream& in) {
575 while (reader.
next()) {
577 vars_i_[reader.
name()]
578 = std::pair<std::vector<int>,
583 vars_r_[reader.
name()]
584 = std::pair<std::vector<double>,
600 return contains_r_only(name) || contains_i(name);
612 return vars_i_.find(name) != vars_i_.end();
622 std::vector<double>
vals_r(
const std::string& name)
const {
623 if (contains_r_only(name)) {
624 return (vars_r_.find(name)->second).first;
625 }
else if (contains_i(name)) {
626 std::vector<int> vec_int = (vars_i_.find(name)->second).first;
627 std::vector<double> vec_r(vec_int.size());
628 for (
size_t ii = 0; ii < vec_int.size(); ii++) {
629 vec_r[ii] = vec_int[ii];
643 std::vector<size_t>
dims_r(
const std::string& name)
const {
644 if (contains_r_only(name)) {
645 return (vars_r_.find(name)->second).second;
646 }
else if (contains_i(name)) {
647 return (vars_i_.find(name)->second).second;
649 return empty_vec_ui_;
659 std::vector<int>
vals_i(
const std::string& name)
const {
660 if (contains_i(name)) {
661 return (vars_i_.find(name)->second).first;
673 std::vector<size_t>
dims_i(
const std::string& name)
const {
674 if (contains_i(name)) {
675 return (vars_i_.find(name)->second).second;
677 return empty_vec_ui_;
686 virtual void names_r(std::vector<std::string>& names)
const {
688 for (std::map<std::string,
689 std::pair<std::vector<double>,
690 std::vector<size_t> > >
691 ::const_iterator it = vars_r_.begin();
692 it != vars_r_.end(); ++it)
693 names.push_back((*it).first);
702 virtual void names_i(std::vector<std::string>& names)
const {
704 for (std::map<std::string,
705 std::pair<std::vector<int>,
706 std::vector<size_t> > >
707 ::const_iterator it = vars_i_.begin();
708 it != vars_i_.end(); ++it)
709 names.push_back((*it).first);
719 bool remove(
const std::string&
name) {
720 return (vars_i_.erase(name) > 0)
721 || (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.