Stan  1.1
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 
55  // FIXME: use boost::type_traits::remove_all_extents to extend to array/ptr types
56 
57  template <typename T>
58  struct is_vector {
59  enum { value = 0 };
60  typedef T type;
61  };
62  template <typename T>
63  struct is_vector<const T> {
65  typedef T type;
66  };
67  template <typename T>
68  struct is_vector<std::vector<T> > {
69  enum { value = 1 };
70  typedef T type;
71  };
72 
73  template <typename T>
74  struct is_vector<Eigen::Matrix<T,Eigen::Dynamic,1> > {
75  enum { value = 1 };
76  typedef T type;
77  };
78  template <typename T>
79  struct is_vector<Eigen::Matrix<T,1,Eigen::Dynamic> > {
80  enum { value = 1 };
81  typedef T type;
82  };
83 
84  namespace {
85  template <bool is_vec, typename T>
86  struct scalar_type_helper {
87  typedef T type;
88  };
89 
90  template <typename T>
91  struct scalar_type_helper<true, T> {
92  typedef typename scalar_type_helper<is_vector<typename T::value_type>::value, typename T::value_type>::type type;
93  };
94  }
103  template <typename T>
104  struct scalar_type {
105  typedef typename scalar_type_helper<is_vector<T>::value, T>::type type;
106  };
107 
108  template <typename T>
109  inline T get(const T& x, size_t n) {
110  return x;
111  }
112  template <typename T>
113  inline T get(const std::vector<T>& x, size_t n) {
114  return x[n];
115  }
116  template <typename T, int R, int C>
117  inline T get(const Eigen::Matrix<T,R,C>& m, size_t n) {
118  return m(static_cast<int>(n));
119  }
120 
121 
122 
123  // length() should only be applied to primitive or std vector or Eigen vector
124  template <typename T>
125  size_t length(const T& /*x*/) {
126  return 1U;
127  }
128  template <typename T>
129  size_t length(const std::vector<T>& x) {
130  return x.size();
131  }
132  template <typename T, int R, int C>
133  size_t length(const Eigen::Matrix<T,R,C>& m) {
134  return m.size();
135  }
136 
137  template<typename T, bool is_vec>
138  struct size_of_helper {
139  static size_t size_of(const T& /*x*/) {
140  return 1U;
141  }
142  };
143 
144  template<typename T>
145  struct size_of_helper<T, true> {
146  static size_t size_of(const T& x) {
147  return x.size();
148  }
149  };
150 
151  template <typename T>
152  size_t size_of(const T& x) {
154  }
155 
156  template <typename T1, typename T2>
157  size_t max_size(const T1& x1, const T2& x2) {
158  size_t result = length(x1);
159  result = result > length(x2) ? result : length(x2);
160  return result;
161  }
162 
163  template <typename T1, typename T2, typename T3>
164  size_t max_size(const T1& x1, const T2& x2, const T3& x3) {
165  size_t result = length(x1);
166  result = result > length(x2) ? result : length(x2);
167  result = result > length(x3) ? result : length(x3);
168  return result;
169  }
170 
171  template <typename T1, typename T2, typename T3, typename T4>
172  size_t max_size(const T1& x1, const T2& x2, const T3& x3, const T4& x4) {
173  size_t result = length(x1);
174  result = result > length(x2) ? result : length(x2);
175  result = result > length(x3) ? result : length(x3);
176  result = result > length(x4) ? result : length(x4);
177  return result;
178  }
179 
180  // ****************** additions for new VV *************************
181  template <typename T>
182  struct scalar_type<Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> > {
183  typedef typename scalar_type<T>::type type;
184  };
185 
186  template <typename T>
187  struct scalar_type<T*> {
188  typedef typename scalar_type<T>::type type;
189  };
190 
191 
192  // handles scalar, eigen vec, eigen row vec, std vec
193  template <typename T>
194  struct is_vector_like {
196  };
197  template <typename T>
198  struct is_vector_like<T*> {
199  enum { value = true };
200  };
201  // handles const
202  template <typename T>
203  struct is_vector_like<const T> {
205  };
206  // handles eigen matrix
207  template <typename T>
208  struct is_vector_like<Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> > {
209  enum { value = true };
210  };
211 
212 
213  template <typename T,
214  bool is_array = stan::is_vector_like<T>::value>
215  class VectorView {
216  public:
217  typedef typename scalar_type<T>::type scalar_t;
218 
219  VectorView(scalar_t& c) : x_(&c) { }
220 
221  VectorView(std::vector<scalar_t>& v) : x_(&v[0]) { }
222 
223  template <int R, int C>
224  VectorView(Eigen::Matrix<scalar_t,R,C>& m) : x_(&m(0)) { }
225 
226  VectorView(scalar_t* x) : x_(x) { }
227 
229  if (is_array) return x_[i];
230  else return x_[0];
231  }
232  private:
233  scalar_t* x_;
234  };
235 
236  template <typename T, bool is_array>
237  class VectorView<const T, is_array> {
238  public:
239  typedef typename scalar_type<T>::type scalar_t;
240 
241  VectorView(const scalar_t& c) : x_(&c) { }
242 
243  VectorView(const scalar_t* x) : x_(x) { }
244 
245  VectorView(const std::vector<scalar_t>& v) : x_(&v[0]) { }
246 
247  template <int R, int C>
248  VectorView(const Eigen::Matrix<scalar_t,R,C>& m) : x_(&m(0)) { }
249 
250  const scalar_t operator[](int i) const {
251  if (is_array) return x_[i];
252  else return x_[0];
253  }
254  private:
255  const scalar_t* x_;
256  };
257 
258  // simplify to hold value in common case where it's more efficient
259  template <>
260  class VectorView<const double, false> {
261  public:
262  VectorView(double x) : x_(x) { }
263  double operator[](int /* i */) const {
264  return x_;
265  }
266  private:
267  const double x_;
268  };
269 
270  template<bool used, bool is_vec>
272  public:
273  DoubleVectorView(size_t /* n */) { }
274  double& operator[](size_t /* i */) {
275  throw std::runtime_error("used is false. this should never be called");
276  }
277  };
278 
279  template<>
280  class DoubleVectorView<true, false> {
281  private:
282  double x_;
283  public:
284  DoubleVectorView(size_t /* n */) : x_(0.0) { }
285  double& operator[](size_t /* i */) {
286  return x_;
287  }
288  };
289 
290  template<>
291  class DoubleVectorView<true, true> {
292  private:
293  std::vector<double> x_;
294  public:
295  DoubleVectorView(size_t n) : x_(n) { }
296  double& operator[](size_t i) {
297  return x_[i];
298  }
299  };
300 
305  template <typename T1,
306  typename T2 = double,
307  typename T3 = double,
308  typename T4 = double,
309  typename T5 = double,
310  typename T6 = double>
311  struct return_type {
312  typedef typename
313  boost::math::tools::promote_args<typename scalar_type<T1>::type,
314  typename scalar_type<T2>::type,
315  typename scalar_type<T3>::type,
316  typename scalar_type<T4>::type,
317  typename scalar_type<T5>::type,
320  };
321 
322 
323 
324 }
325 
326 #endif

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