1 #ifndef STAN_IO_DUMP_HPP
2 #define STAN_IO_DUMP_HPP
4 #include <boost/lexical_cast.hpp>
5 #include <boost/throw_exception.hpp>
6 #include <boost/type_traits/is_floating_point.hpp>
7 #include <boost/type_traits/is_integral.hpp>
8 #include <boost/type_traits/is_arithmetic.hpp>
9 #include <boost/utility/enable_if.hpp>
13 #include <stan/math/prim/scal/meta/index_type.hpp>
14 #include <stan/math/prim/arr/meta/index_type.hpp>
15 #include <stan/math/prim/mat/meta/index_type.hpp>
106 std::vector<int> stack_i_;
107 std::vector<double> stack_r_;
108 std::vector<size_t> dims_;
111 bool scan_single_char(
char c_expected) {
113 if (in_.fail())
return false;
121 bool scan_optional_long() {
122 if (scan_single_char(
'l'))
124 else if (scan_single_char(
'L'))
130 bool scan_char(
char c_expected) {
133 if (in_.fail())
return false;
134 if (c != c_expected) {
141 bool scan_name_unquoted() {
144 if (in_.fail())
return false;
145 if (!std::isalpha(c))
return false;
148 if (std::isalpha(c) || std::isdigit(c) || c ==
'_' || c ==
'.') {
159 if (scan_char(
'"')) {
160 if (!scan_name_unquoted())
return false;
161 if (!scan_char(
'"'))
return false;
162 }
else if (scan_char(
'\'')) {
163 if (!scan_name_unquoted())
return false;
164 if (!scan_char(
'\''))
return false;
166 if (!scan_name_unquoted())
return false;
172 bool scan_chars(
const char *s,
bool case_sensitive =
true) {
173 for (
size_t i = 0; s[i]; ++i) {
176 for (
size_t j = 1; j < i; ++j)
181 if ((case_sensitive && c != s[i])
182 || (!case_sensitive && ::toupper(c) != ::toupper(s[i]))) {
184 for (
size_t j = 1; j < i; ++j)
192 bool scan_chars(std::string s,
bool case_sensitive =
true) {
193 for (
size_t i = 0; i < s.size(); ++i) {
196 for (
size_t j = 1; j < i; ++j)
201 if ((case_sensitive && c != s[i])
202 || (!case_sensitive && ::toupper(c) != ::toupper(s[i]))) {
204 for (
size_t j = 1; j < i; ++j)
216 if (std::isspace(c))
continue;
217 if (std::isdigit(c)) {
224 scan_optional_long();
227 d = boost::lexical_cast<
size_t>(buf_);
229 catch (
const boost::bad_lexical_cast &exc ) {
230 std::string msg =
"value " + buf_ +
" beyond array dimension range";
231 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
240 if (std::isspace(c))
continue;
241 if (std::isdigit(c)) {
254 n = boost::lexical_cast<
int>(buf_);
256 catch (
const boost::bad_lexical_cast &exc ) {
257 std::string msg =
"value " + buf_ +
" beyond int range";
258 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
263 double scan_double() {
266 x = boost::lexical_cast<
double>(buf_);
270 catch (
const boost::bad_lexical_cast &exc ) {
271 std::string msg =
"value " + buf_ +
" beyond numeric range";
272 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
280 void scan_number(
bool negate_val) {
282 if (scan_chars(
"Inf")) {
284 stack_r_.push_back(negate_val
285 ? -std::numeric_limits<double>::infinity()
286 : std::numeric_limits<double>::infinity());
289 if (scan_chars(
"NaN",
false)) {
290 stack_r_.push_back(std::numeric_limits<double>::quiet_NaN());
295 bool is_double =
false;
298 if (std::isdigit(c)) {
312 if (!is_double && stack_r_.size() == 0) {
314 stack_i_.push_back(negate_val ? -n : n);
315 scan_optional_long();
317 for (
size_t j = 0; j < stack_i_.size(); ++j)
318 stack_r_.push_back(static_cast<double>(stack_i_[j]));
320 double x = scan_double();
321 stack_r_.push_back(negate_val ? -x : x);
328 if (std::isspace(c))
continue;
332 bool negate_val = scan_char(
'-');
333 if (!negate_val) scan_char(
'+');
334 return scan_number(negate_val);
338 bool scan_seq_value() {
339 if (!scan_char(
'('))
return false;
340 if (scan_char(
')')) {
345 while (scan_char(
',')) {
348 dims_.push_back(stack_r_.size() + stack_i_.size());
349 return scan_char(
')');
352 bool scan_struct_value() {
353 if (!scan_char(
'('))
return false;
354 if (scan_char(
'c')) {
357 int start = scan_int();
360 int end = scan_int();
362 for (
int i = start; i <= end; ++i)
363 stack_i_.push_back(i);
365 for (
int i = start; i >= end; --i)
366 stack_i_.push_back(i);
370 if (!scan_char(
','))
return false;
371 if (!scan_char(
'.'))
return false;
372 if (!scan_chars(
"Dim"))
return false;
373 if (!scan_char(
'='))
return false;
374 if (scan_char(
'c')) {
375 if (!scan_char(
'('))
return false;
376 size_t dim = scan_dim();
377 dims_.push_back(dim);
378 while (scan_char(
',')) {
380 dims_.push_back(dim);
382 if (!scan_char(
')'))
return false;
384 size_t start = scan_dim();
387 size_t end = scan_dim();
389 for (
size_t i = start; i <= end; ++i)
392 for (
size_t i = start; i >= end; --i)
396 if (!scan_char(
')'))
return false;
402 return scan_seq_value();
403 if (scan_chars(
"structure"))
404 return scan_struct_value();
408 if (stack_i_.size() != 1)
411 if (stack_i_.size() != 2)
413 int start = stack_i_[0];
414 int end = stack_i_[1];
417 for (
int i = start; i <= end; ++i)
418 stack_i_.push_back(i);
420 for (
int i = start; i >= end; --i)
421 stack_i_.push_back(i);
423 dims_.push_back(stack_i_.size());
470 return stack_r_.size() == 0;
514 bool okSyntax = scan_value();
516 std::string msg =
"syntax error";
517 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
520 catch (
const std::invalid_argument &e) {
521 std::string msg =
"data " + name_ +
" " + e.what();
522 BOOST_THROW_EXCEPTION(std::invalid_argument(msg));
547 std::map<std::string,
548 std::pair<std::vector<double>,
549 std::vector<size_t> > > vars_r_;
550 std::map<std::string,
551 std::pair<std::vector<int>,
552 std::vector<size_t> > > vars_i_;
553 std::vector<double>
const empty_vec_r_;
554 std::vector<int>
const empty_vec_i_;
555 std::vector<size_t>
const empty_vec_ui_;
565 bool contains_r_only(
const std::string& name)
const {
566 return vars_r_.find(name) != vars_r_.end();
577 explicit dump(std::istream& in) {
579 while (reader.
next()) {
581 vars_i_[reader.
name()]
582 = std::pair<std::vector<int>,
587 vars_r_[reader.
name()]
588 = std::pair<std::vector<double>,
604 return contains_r_only(name) ||
contains_i(name);
616 return vars_i_.find(name) != vars_i_.end();
626 std::vector<double>
vals_r(
const std::string& name)
const {
627 if (contains_r_only(name)) {
628 return (vars_r_.find(name)->second).first;
630 std::vector<int> vec_int = (vars_i_.find(name)->second).first;
631 std::vector<double> vec_r(vec_int.size());
632 for (
size_t ii = 0; ii < vec_int.size(); ii++) {
633 vec_r[ii] = vec_int[ii];
647 std::vector<size_t>
dims_r(
const std::string& name)
const {
648 if (contains_r_only(name)) {
649 return (vars_r_.find(name)->second).second;
651 return (vars_i_.find(name)->second).second;
653 return empty_vec_ui_;
663 std::vector<int>
vals_i(
const std::string& name)
const {
665 return (vars_i_.find(name)->second).first;
677 std::vector<size_t>
dims_i(
const std::string& name)
const {
679 return (vars_i_.find(name)->second).second;
681 return empty_vec_ui_;
690 virtual void names_r(std::vector<std::string>& names)
const {
692 for (std::map<std::string,
693 std::pair<std::vector<double>,
694 std::vector<size_t> > >
695 ::const_iterator it = vars_r_.begin();
696 it != vars_r_.end(); ++it)
697 names.push_back((*it).first);
706 virtual void names_i(std::vector<std::string>& names)
const {
708 for (std::map<std::string,
709 std::pair<std::vector<int>,
710 std::vector<size_t> > >
711 ::const_iterator it = vars_i_.begin();
712 it != vars_i_.end(); ++it)
713 names.push_back((*it).first);
723 bool remove(
const std::string& name) {
724 return (vars_i_.erase(name) > 0)
725 || (vars_r_.erase(name) > 0);
dump(std::istream &in)
Construct a dump object from the specified input stream.
~dump_reader()
Destroy this reader.
bool is_int()
Checks if the last item read is integer.
Probability, optimization and sampling library.
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.
A stream-based reader for integer, scalar, vector, matrix and array data types, with Jacobian calcula...
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.
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< 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.
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.
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.