array_var_context.hpp
Go to the documentation of this file.
1 #ifndef STAN_IO_ARRAY_VAR_CONTEXT_HPP
2 #define STAN_IO_ARRAY_VAR_CONTEXT_HPP
3 
5 #include <boost/throw_exception.hpp>
6 #include <map>
7 #include <sstream>
8 #include <string>
9 #include <vector>
10 #include <utility>
11 
12 namespace stan {
13 
14  namespace io {
15 
16  template<typename T>
17  T product(std::vector<T> dims) {
18  T y = 1;
19  for (size_t i = 0; i < dims.size(); ++i)
20  y *= dims[i];
21  return y;
22  }
23 
24  /**
25  * An array_var_context object represents a named arrays
26  * with dimensions constructed from an array, a vector
27  * of names, and a vector of all dimensions for each element.
28  */
29  class array_var_context : public var_context {
30  private:
31  std::map<std::string,
32  std::pair<std::vector<double>,
33  std::vector<size_t> > > vars_r_;
34  std::map<std::string,
35  std::pair<std::vector<int>,
36  std::vector<size_t> > > vars_i_;
37  std::vector<double> const empty_vec_r_;
38  std::vector<int> const empty_vec_i_;
39  std::vector<size_t> const empty_vec_ui_;
40 
41  bool contains_r_only(const std::string& name) const {
42  return vars_r_.find(name) != vars_r_.end();
43  }
44 
45  /**
46  * Check (1) if the vecotr size of dimensions is no smaller
47  * than the name vecotr size; (2) if the size of the input
48  * array is large enough for what is needed.
49  */
50  template <typename T>
51  void validate(const std::vector<std::string>& names,
52  const std::vector<T>& array,
53  const std::vector<std::vector<size_t> >& dims) {
54  size_t total = 0;
55  size_t num_par = names.size();
56  if (num_par > dims.size()) {
57  std::stringstream msg;
58  msg << "size of vector of dimensions (found " << dims.size() << ") "
59  << "should be no smaller than number of parameters (found "
60  << num_par << ").";
61  BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
62  }
63  for (size_t i = 0; i < num_par; i++)
64  total += stan::io::product(dims[i]);
65  size_t array_len = array.size();
66  if (total > array_len) {
67  std::stringstream msg;
68  msg << "array is not long enough for all elements: " << array_len
69  << " is found, but "
70  << total << " is needed.";
71  BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
72  }
73  }
74 
75  void add_r(const std::vector<std::string>& names,
76  const std::vector<double>& values,
77  const std::vector<std::vector<size_t> >& dims) {
78  validate(names, values, dims);
79  size_t start = 0;
80  size_t end = 0;
81  for (size_t i = 0; i < names.size(); i++) {
82  end += product(dims[i]);
83  std::vector<double> v(values.begin() + start, values.begin() + end);
84  vars_r_[names[i]]
85  = std::pair<std::vector<double>,
86  std::vector<size_t> >(v, dims[i]);
87  start = end;
88  }
89  }
90  void add_i(const std::vector<std::string>& names,
91  const std::vector<int>& values,
92  const std::vector<std::vector<size_t> >& dims) {
93  validate(names, values, dims);
94  size_t start = 0;
95  size_t end = 0;
96  for (size_t i = 0; i < names.size(); i++) {
97  end += product(dims[i]);
98  std::vector<int> v(values.begin() + start, values.begin() + end);
99  vars_i_[names[i]]
100  = std::pair<std::vector<int>,
101  std::vector<size_t> >(v, dims[i]);
102  start = end;
103  }
104  }
105 
106  public:
107  /**
108  * Construct an array_var_context from only real value arrays.
109  *
110  * @param names_r names for each element
111  * @param values_r a vector of double values for all elements
112  * @param dim_r a vector of dimensions
113  */
114  array_var_context(const std::vector<std::string>& names_r,
115  const std::vector<double>& values_r,
116  const std::vector<std::vector<size_t> >& dim_r) {
117  add_r(names_r, values_r, dim_r);
118  }
119 
120  /**
121  * Construct an array_var_context from only integer value arrays.
122  *
123  * @param names_i names for each element
124  * @param values_i a vector of integer values for all elements
125  * @param dim_i a vector of dimensions
126  */
127  array_var_context(const std::vector<std::string>& names_i,
128  const std::vector<int>& values_i,
129  const std::vector<std::vector<size_t> >& dim_i) {
130  add_i(names_i, values_i, dim_i);
131  }
132 
133  /**
134  * Construct an array_var_context from arrays of both double
135  * and integer separately
136  *
137  */
138  array_var_context(const std::vector<std::string>& names_r,
139  const std::vector<double>& values_r,
140  const std::vector<std::vector<size_t> >& dim_r,
141  const std::vector<std::string>& names_i,
142  const std::vector<int>& values_i,
143  const std::vector<std::vector<size_t> >& dim_i) {
144  add_i(names_i, values_i, dim_i);
145  add_r(names_r, values_r, dim_r);
146  }
147 
148  /**
149  * Return <code>true</code> if this dump contains the specified
150  * variable name is defined. This method returns <code>true</code>
151  * even if the values are all integers.
152  *
153  * @param name Variable name to test.
154  * @return <code>true</code> if the variable exists.
155  */
156  bool contains_r(const std::string& name) const {
157  return contains_r_only(name) || contains_i(name);
158  }
159 
160  /**
161  * Return <code>true</code> if this dump contains an integer
162  * valued array with the specified name.
163  *
164  * @param name Variable name to test.
165  * @return <code>true</code> if the variable name has an integer
166  * array value.
167  */
168  bool contains_i(const std::string& name) const {
169  return vars_i_.find(name) != vars_i_.end();
170  }
171 
172  /**
173  * Return the double values for the variable with the specified
174  * name or null.
175  *
176  * @param name Name of variable.
177  * @return Values of variable.
178  */
179  std::vector<double> vals_r(const std::string& name) const {
180  if (contains_r_only(name)) {
181  return (vars_r_.find(name)->second).first;
182  } else if (contains_i(name)) {
183  std::vector<int> vec_int = (vars_i_.find(name)->second).first;
184  std::vector<double> vec_r(vec_int.size());
185  for (size_t ii = 0; ii < vec_int.size(); ii++) {
186  vec_r[ii] = vec_int[ii];
187  }
188  return vec_r;
189  }
190  return empty_vec_r_;
191  }
192 
193  /**
194  * Return the dimensions for the double variable with the specified
195  * name.
196  *
197  * @param name Name of variable.
198  * @return Dimensions of variable.
199  */
200  std::vector<size_t> dims_r(const std::string& name) const {
201  if (contains_r_only(name)) {
202  return (vars_r_.find(name)->second).second;
203  } else if (contains_i(name)) {
204  return (vars_i_.find(name)->second).second;
205  }
206  return empty_vec_ui_;
207  }
208 
209  /**
210  * Return the integer values for the variable with the specified
211  * name.
212  *
213  * @param name Name of variable.
214  * @return Values.
215  */
216  std::vector<int> vals_i(const std::string& name) const {
217  if (contains_i(name)) {
218  return (vars_i_.find(name)->second).first;
219  }
220  return empty_vec_i_;
221  }
222 
223  /**
224  * Return the dimensions for the integer variable with the specified
225  * name.
226  *
227  * @param name Name of variable.
228  * @return Dimensions of variable.
229  */
230  std::vector<size_t> dims_i(const std::string& name) const {
231  if (contains_i(name)) {
232  return (vars_i_.find(name)->second).second;
233  }
234  return empty_vec_ui_;
235  }
236 
237  /**
238  * Return a list of the names of the floating point variables in
239  * the dump.
240  *
241  * @param names Vector to store the list of names in.
242  */
243  virtual void names_r(std::vector<std::string>& names) const {
244  names.resize(0);
245  for (std::map<std::string,
246  std::pair<std::vector<double>,
247  std::vector<size_t> > >
248  ::const_iterator it = vars_r_.begin();
249  it != vars_r_.end(); ++it)
250  names.push_back((*it).first);
251  }
252 
253  /**
254  * Return a list of the names of the integer variables in
255  * the dump.
256  *
257  * @param names Vector to store the list of names in.
258  */
259  virtual void names_i(std::vector<std::string>& names) const {
260  names.resize(0);
261  for (std::map<std::string,
262  std::pair<std::vector<int>,
263  std::vector<size_t> > >
264  ::const_iterator it = vars_i_.begin();
265  it != vars_i_.end(); ++it)
266  names.push_back((*it).first);
267  }
268 
269  /**
270  * Remove variable from the object.
271  *
272  * @param name Name of the variable to remove.
273  * @return If variable is removed returns <code>true</code>, else
274  * returns <code>false</code>.
275  */
276  bool remove(const std::string& name) {
277  return (vars_i_.erase(name) > 0)
278  || (vars_r_.erase(name) > 0);
279  }
280  };
281  }
282 }
283 #endif
const XML_Char * name
Definition: expat.h:151
std::vector< int > vals_i(const std::string &name) const
set< int >::iterator it
std::map< std::string, std::pair< std::vector< int >, std::vector< size_t > > > vars_i_
std::vector< size_t > dims_i(const std::string &name) const
virtual void names_i(std::vector< std::string > &names) const
std::vector< int > const empty_vec_i_
array_var_context(const std::vector< std::string > &names_r, const std::vector< double > &values_r, const std::vector< std::vector< size_t > > &dim_r, const std::vector< std::string > &names_i, const std::vector< int > &values_i, const std::vector< std::vector< size_t > > &dim_i)
void add_r(const std::vector< std::string > &names, const std::vector< double > &values, const std::vector< std::vector< size_t > > &dims)
std::vector< size_t > dims_r(const std::string &name) const
bool contains_i(const std::string &name) const
std::map< std::string, std::pair< std::vector< double >, std::vector< size_t > > > vars_r_
std::vector< size_t > const empty_vec_ui_
array_var_context(const std::vector< std::string > &names_i, const std::vector< int > &values_i, const std::vector< std::vector< size_t > > &dim_i)
virtual void names_r(std::vector< std::string > &names) const
bool contains_r_only(const std::string &name) const
std::vector< double > const empty_vec_r_
void invalid_argument(const char *function, const char *name, const T &y, const char *msg1, const char *msg2)
bool contains_r(const std::string &name) const
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
T product(std::vector< T > dims)
std::vector< double > vals_r(const std::string &name) const
double T
Definition: Xdiff_gwt.C:5
array_var_context(const std::vector< std::string > &names_r, const std::vector< double > &values_r, const std::vector< std::vector< size_t > > &dim_r)
void validate(const std::vector< std::string > &names, const std::vector< T > &array, const std::vector< std::vector< size_t > > &dims)
void add_i(const std::vector< std::string > &names, const std::vector< int > &values, const std::vector< std::vector< size_t > > &dims)