Stan  1.3
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
traits.hpp
Go to the documentation of this file.
1 #ifndef __STAN__META__TRAITS_HPP__
2 #define __STAN__META__TRAITS_HPP__
3 
4 #include <vector>
5 #include <boost/type_traits.hpp>
6 #include <boost/math/tools/promotion.hpp>
7 #include <stan/math/matrix.hpp>
8 
9 namespace stan {
10 
24  template <typename T>
25  struct is_constant {
30  enum { value = boost::is_convertible<T,double>::value };
31  };
32 
33 
38  template <typename T>
41  };
42 
43 
44  template <typename T>
45  struct is_constant_struct<std::vector<T> > {
47  };
48 
49  template <typename T, int R, int C>
50  struct is_constant_struct<Eigen::Matrix<T,R,C> > {
52  };
53 
54  template <typename T>
55  struct is_constant_struct<Eigen::Block<T> > {
57  };
58 
59 
60 
61 
62  // FIXME: use boost::type_traits::remove_all_extents to extend to array/ptr types
63 
64  template <typename T>
65  struct is_vector {
66  enum { value = 0 };
67  typedef T type;
68  };
69  template <typename T>
70  struct is_vector<const T> {
72  typedef T type;
73  };
74  template <typename T>
75  struct is_vector<std::vector<T> > {
76  enum { value = 1 };
77  typedef T type;
78  };
79 
80  template <typename T>
81  struct is_vector<Eigen::Matrix<T,Eigen::Dynamic,1> > {
82  enum { value = 1 };
83  typedef T type;
84  };
85  template <typename T>
86  struct is_vector<Eigen::Matrix<T,1,Eigen::Dynamic> > {
87  enum { value = 1 };
88  typedef T type;
89  };
90 
91  namespace {
92  template <bool is_vec, typename T>
93  struct scalar_type_helper {
94  typedef T type;
95  };
96 
97  template <typename T>
98  struct scalar_type_helper<true, T> {
99  typedef typename scalar_type_helper<is_vector<typename T::value_type>::value, typename T::value_type>::type type;
100  };
101  }
110  template <typename T>
111  struct scalar_type {
112  typedef typename scalar_type_helper<is_vector<T>::value, T>::type type;
113  };
114 
115  template <typename T>
116  inline T get(const T& x, size_t n) {
117  return x;
118  }
119  template <typename T>
120  inline T get(const std::vector<T>& x, size_t n) {
121  return x[n];
122  }
123  template <typename T, int R, int C>
124  inline T get(const Eigen::Matrix<T,R,C>& m, size_t n) {
125  return m(static_cast<int>(n));
126  }
127 
128 
129 
130  // length() should only be applied to primitive or std vector or Eigen vector
131  template <typename T>
132  size_t length(const T& /*x*/) {
133  return 1U;
134  }
135  template <typename T>
136  size_t length(const std::vector<T>& x) {
137  return x.size();
138  }
139  template <typename T, int R, int C>
140  size_t length(const Eigen::Matrix<T,R,C>& m) {
141  return m.size();
142  }
143 
144  template<typename T, bool is_vec>
145  struct size_of_helper {
146  static size_t size_of(const T& /*x*/) {
147  return 1U;
148  }
149  };
150 
151  template<typename T>
152  struct size_of_helper<T, true> {
153  static size_t size_of(const T& x) {
154  return x.size();
155  }
156  };
157 
158  template <typename T>
159  size_t size_of(const T& x) {
161  }
162 
163  template <typename T1, typename T2>
164  size_t max_size(const T1& x1, const T2& x2) {
165  size_t result = length(x1);
166  result = result > length(x2) ? result : length(x2);
167  return result;
168  }
169 
170  template <typename T1, typename T2, typename T3>
171  size_t max_size(const T1& x1, const T2& x2, const T3& x3) {
172  size_t result = length(x1);
173  result = result > length(x2) ? result : length(x2);
174  result = result > length(x3) ? result : length(x3);
175  return result;
176  }
177 
178  template <typename T1, typename T2, typename T3, typename T4>
179  size_t max_size(const T1& x1, const T2& x2, const T3& x3, const T4& x4) {
180  size_t result = length(x1);
181  result = result > length(x2) ? result : length(x2);
182  result = result > length(x3) ? result : length(x3);
183  result = result > length(x4) ? result : length(x4);
184  return result;
185  }
186 
187  // ****************** additions for new VV *************************
188  template <typename T>
189  struct scalar_type<Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> > {
190  typedef typename scalar_type<T>::type type;
191  };
192 
193  template <typename T>
194  struct scalar_type<T*> {
195  typedef typename scalar_type<T>::type type;
196  };
197 
198 
199  // handles scalar, eigen vec, eigen row vec, std vec
200  template <typename T>
201  struct is_vector_like {
203  };
204  template <typename T>
205  struct is_vector_like<T*> {
206  enum { value = true };
207  };
208  // handles const
209  template <typename T>
210  struct is_vector_like<const T> {
212  };
213  // handles eigen matrix
214  template <typename T>
215  struct is_vector_like<Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> > {
216  enum { value = true };
217  };
218 
219 
220  template <typename T,
221  bool is_array = stan::is_vector_like<T>::value>
222  class VectorView {
223  public:
224  typedef typename scalar_type<T>::type scalar_t;
225 
226  VectorView(scalar_t& c) : x_(&c) { }
227 
228  VectorView(std::vector<scalar_t>& v) : x_(&v[0]) { }
229 
230  template <int R, int C>
231  VectorView(Eigen::Matrix<scalar_t,R,C>& m) : x_(&m(0)) { }
232 
233  VectorView(scalar_t* x) : x_(x) { }
234 
236  if (is_array) return x_[i];
237  else return x_[0];
238  }
239  private:
240  scalar_t* x_;
241  };
242 
243  template <typename T, bool is_array>
244  class VectorView<const T, is_array> {
245  public:
246  typedef typename scalar_type<T>::type scalar_t;
247 
248  VectorView(const scalar_t& c) : x_(&c) { }
249 
250  VectorView(const scalar_t* x) : x_(x) { }
251 
252  VectorView(const std::vector<scalar_t>& v) : x_(&v[0]) { }
253 
254  template <int R, int C>
255  VectorView(const Eigen::Matrix<scalar_t,R,C>& m) : x_(&m(0)) { }
256 
257  const scalar_t operator[](int i) const {
258  if (is_array) return x_[i];
259  else return x_[0];
260  }
261  private:
262  const scalar_t* x_;
263  };
264 
265  // simplify to hold value in common case where it's more efficient
266  template <>
267  class VectorView<const double, false> {
268  public:
269  VectorView(double x) : x_(x) { }
270  double operator[](int /* i */) const {
271  return x_;
272  }
273  private:
274  const double x_;
275  };
276 
277  template<bool used, bool is_vec>
279  public:
280  DoubleVectorView(size_t /* n */) { }
281  double& operator[](size_t /* i */) {
282  throw std::runtime_error("used is false. this should never be called");
283  }
284  };
285 
286  template<>
287  class DoubleVectorView<true, false> {
288  private:
289  double x_;
290  public:
291  DoubleVectorView(size_t /* n */) : x_(0.0) { }
292  double& operator[](size_t /* i */) {
293  return x_;
294  }
295  };
296 
297  template<>
298  class DoubleVectorView<true, true> {
299  private:
300  std::vector<double> x_;
301  public:
302  DoubleVectorView(size_t n) : x_(n) { }
303  double& operator[](size_t i) {
304  return x_[i];
305  }
306  };
307 
312  template <typename T1,
313  typename T2 = double,
314  typename T3 = double,
315  typename T4 = double,
316  typename T5 = double,
317  typename T6 = double>
318  struct return_type {
319  typedef typename
320  boost::math::tools::promote_args<typename scalar_type<T1>::type,
321  typename scalar_type<T2>::type,
322  typename scalar_type<T3>::type,
323  typename scalar_type<T4>::type,
324  typename scalar_type<T5>::type,
327  };
328 
329 
330 
331 }
332 
333 #endif

     [ Stan Home Page ] © 2011–2013, Stan Development Team.