Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations 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 
5 #include <vector>
6 #include <boost/type_traits.hpp>
7 #include <boost/type_traits/is_arithmetic.hpp>
8 #include <boost/math/tools/promotion.hpp>
9 
10 #include <stan/agrad/fwd/fvar.hpp>
11 #include <stan/agrad/rev/var.hpp>
12 
16 
17 namespace stan {
18 
19  struct error_index {
20  enum { value =
21 #ifdef ERROR_INDEX
22 ERROR_INDEX
23 #else
24 1
25 #endif
26  };
27  };
28 
42  template <typename T>
43  struct is_constant {
48  enum { value = boost::is_convertible<T,double>::value };
49  };
50 
51 
56  template <typename T>
59  };
60 
61 
62  template <typename T>
63  struct is_constant_struct<std::vector<T> > {
65  };
66 
67  template <typename T, int R, int C>
68  struct is_constant_struct<Eigen::Matrix<T,R,C> > {
70  };
71 
72  template <typename T>
73  struct is_constant_struct<Eigen::Block<T> > {
75  };
76 
77 
78 
79 
80  // FIXME: use boost::type_traits::remove_all_extents to extend to array/ptr types
81 
82  template <typename T>
83  struct is_vector {
84  enum { value = 0 };
85  typedef T type;
86  };
87  template <typename T>
88  struct is_vector<const T> {
90  typedef T type;
91  };
92  template <typename T>
93  struct is_vector<std::vector<T> > {
94  enum { value = 1 };
95  typedef T type;
96  };
97 
98  template <typename T>
99  struct is_vector<Eigen::Matrix<T,Eigen::Dynamic,1> > {
100  enum { value = 1 };
101  typedef T type;
102  };
103  template <typename T>
104  struct is_vector<Eigen::Matrix<T,1,Eigen::Dynamic> > {
105  enum { value = 1 };
106  typedef T type;
107  };
108  template <typename T>
109  struct is_vector<Eigen::Block<T> > {
110  enum { value = 1 };
111  typedef T type;
112  };
113 
114 
115  namespace {
116  template <bool is_vec, typename T>
117  struct scalar_type_helper {
118  typedef T type;
119  };
120 
121  template <typename T>
122  struct scalar_type_helper<true, T> {
123  typedef typename
124  scalar_type_helper<is_vector<typename stan::math::value_type<T>::type>::value,
125  typename stan::math::value_type<T>::type>::type
126  type;
127  };
128  }
137  template <typename T>
138  struct scalar_type {
139  typedef typename scalar_type_helper<is_vector<T>::value, T>::type type;
140  };
141 
142  template <typename T>
143  inline T get(const T& x, size_t n) {
144  return x;
145  }
146  template <typename T>
147  inline T get(const std::vector<T>& x, size_t n) {
148  return x[n];
149  }
150  template <typename T, int R, int C>
151  inline T get(const Eigen::Matrix<T,R,C>& m, size_t n) {
152  return m(static_cast<int>(n));
153  }
154 
155 
156 
157  // length() should only be applied to primitive or std vector or Eigen vector
158  template <typename T>
159  size_t length(const T& /*x*/) {
160  return 1U;
161  }
162  template <typename T>
163  size_t length(const std::vector<T>& x) {
164  return x.size();
165  }
166  template <typename T, int R, int C>
167  size_t length(const Eigen::Matrix<T,R,C>& m) {
168  return m.size();
169  }
170 
171  template<typename T, bool is_vec>
172  struct size_of_helper {
173  static size_t size_of(const T& /*x*/) {
174  return 1U;
175  }
176  };
177 
178  template<typename T>
179  struct size_of_helper<T, true> {
180  static size_t size_of(const T& x) {
181  return x.size();
182  }
183  };
184 
185  template <typename T>
186  size_t size_of(const T& x) {
188  }
189 
190  template <typename T1, typename T2>
191  size_t max_size(const T1& x1, const T2& x2) {
192  size_t result = length(x1);
193  result = result > length(x2) ? result : length(x2);
194  return result;
195  }
196 
197  template <typename T1, typename T2, typename T3>
198  size_t max_size(const T1& x1, const T2& x2, const T3& x3) {
199  size_t result = length(x1);
200  result = result > length(x2) ? result : length(x2);
201  result = result > length(x3) ? result : length(x3);
202  return result;
203  }
204 
205  template <typename T1, typename T2, typename T3, typename T4>
206  size_t max_size(const T1& x1, const T2& x2, const T3& x3, const T4& x4) {
207  size_t result = length(x1);
208  result = result > length(x2) ? result : length(x2);
209  result = result > length(x3) ? result : length(x3);
210  result = result > length(x4) ? result : length(x4);
211  return result;
212  }
213 
214  // ****************** additions for new VV *************************
215  template <typename T>
216  struct scalar_type<Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> > {
217  typedef typename scalar_type<T>::type type;
218  };
219 
220  template <typename T>
221  struct scalar_type<T*> {
222  typedef typename scalar_type<T>::type type;
223  };
224 
225 
226  // handles scalar, eigen vec, eigen row vec, std vec
227  template <typename T>
228  struct is_vector_like {
230  };
231  template <typename T>
232  struct is_vector_like<T*> {
233  enum { value = true };
234  };
235  // handles const
236  template <typename T>
237  struct is_vector_like<const T> {
239  };
240  // handles eigen matrix
241  template <typename T>
242  struct is_vector_like<Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> > {
243  enum { value = true };
244  };
245 
246 
272  template <typename T,
273  bool is_array = stan::is_vector_like<T>::value,
274  bool throw_if_accessed = false>
275  class VectorView {
276  public:
277  typedef typename scalar_type<T>::type scalar_t;
278 
279  VectorView(scalar_t& c) : x_(&c) { }
280 
281  VectorView(std::vector<scalar_t>& v) : x_(&v[0]) { }
282 
283  template <int R, int C>
284  VectorView(Eigen::Matrix<scalar_t,R,C>& m) : x_(&m(0)) { }
285 
286  VectorView(scalar_t* x) : x_(x) { }
287 
289  if (throw_if_accessed)
290  throw std::out_of_range("VectorView: this cannot be accessed");
291  if (is_array)
292  return x_[i];
293  else
294  return x_[0];
295  }
296  private:
297  scalar_t* x_;
298  };
299 
304  template <typename T, bool is_array, bool throw_if_accessed>
305  class VectorView<const T, is_array, throw_if_accessed> {
306  public:
307  typedef typename scalar_type<T>::type scalar_t;
308 
309  VectorView(const scalar_t& c) : x_(&c) { }
310 
311  VectorView(const scalar_t* x) : x_(x) { }
312 
313  VectorView(const std::vector<scalar_t>& v) : x_(&v[0]) { }
314 
315  template <int R, int C>
316  VectorView(const Eigen::Matrix<scalar_t,R,C>& m) : x_(&m(0)) { }
317 
318  const scalar_t& operator[](int i) const {
319  if (throw_if_accessed)
320  throw std::out_of_range("VectorView: this cannot be accessed");
321  if (is_array)
322  return x_[i];
323  else
324  return x_[0];
325  }
326  private:
327  const scalar_t* x_;
328  };
329 
330  // simplify to hold value in common case where it's more efficient
331  template <>
332  class VectorView<const double, false, false> {
333  public:
334  VectorView(double x) : x_(x) { }
335  double operator[](int /* i */) const {
336  return x_;
337  }
338  private:
339  const double x_;
340  };
341 
342 
357  template<bool used, bool is_vec>
359  public:
360  DoubleVectorView(size_t /* n */) { }
361  double& operator[](size_t /* i */) {
362  throw std::runtime_error("used is false. this should never be called");
363  }
364  };
365 
366  template<>
367  class DoubleVectorView<true, false> {
368  private:
369  double x_;
370  public:
371  DoubleVectorView(size_t /* n */) : x_(0.0) { }
372  double& operator[](size_t /* i */) {
373  return x_;
374  }
375  };
376 
377  template<>
378  class DoubleVectorView<true, true> {
379  private:
380  std::vector<double> x_;
381  public:
382  DoubleVectorView(size_t n) : x_(n) { }
383  double& operator[](size_t i) {
384  return x_[i];
385  }
386  };
387 
392  template <typename T1,
393  typename T2 = double,
394  typename T3 = double,
395  typename T4 = double,
396  typename T5 = double,
397  typename T6 = double>
398  struct return_type {
399  typedef typename
400  boost::math::tools::promote_args<typename scalar_type<T1>::type,
401  typename scalar_type<T2>::type,
402  typename scalar_type<T3>::type,
403  typename scalar_type<T4>::type,
404  typename scalar_type<T5>::type,
407  };
408 
409 
410  template <typename T>
411  struct is_fvar {
412  enum { value = false };
413  };
414  template <typename T>
415  struct is_fvar<stan::agrad::fvar<T> > {
416  enum { value = true };
417  };
418 
419 
420  template <typename T>
421  struct is_var {
422  enum { value = false };
423  };
424  template <>
425  struct is_var<stan::agrad::var> {
426  enum { value = true };
427  };
428 
429 
430 
431  // FIXME: pull out scalar types
432 
437  template <typename T1,
438  typename T2 = double,
439  typename T3 = double,
440  typename T4 = double,
441  typename T5 = double,
442  typename T6 = double>
443  struct contains_fvar {
444  enum {
451  };
452  };
453 
454 
455  template <typename T1,
456  typename T2 = double,
457  typename T3 = double,
458  typename T4 = double,
459  typename T5 = double,
460  typename T6 = double>
462  enum {
465  || boost::is_arithmetic<typename scalar_type<T1>::type>::value)
466  && (is_var<typename scalar_type<T2>::type>::value
467  || boost::is_arithmetic<typename scalar_type<T2>::type>::value)
469  || boost::is_arithmetic<typename scalar_type<T3>::type>::value)
470  && (is_var<typename scalar_type<T4>::type>::value
471  || boost::is_arithmetic<typename scalar_type<T4>::type>::value)
473  || boost::is_arithmetic<typename scalar_type<T5>::type>::value)
474  && (is_var<typename scalar_type<T6>::type>::value
475  || boost::is_arithmetic<typename scalar_type<T6>::type>::value)
476  };
477  };
478 
479  namespace {
480  template <bool is_vec, typename T, typename T_container>
481  struct scalar_type_helper_pre {
482  typedef T_container type;
483  };
484 
485  template <typename T, typename T_container>
486  struct scalar_type_helper_pre<true, T, T_container> {
487  typedef typename
488  scalar_type_helper_pre<is_vector<typename stan::math::value_type<T>::type>::value,
491  type;
492  };
493  }
494 
501  template <typename T>
503  typedef typename
504  scalar_type_helper_pre<is_vector<typename stan::math::value_type<T>::type>::value,
507  };
508 
509 
510  template <typename T,
511  bool is_array
513  bool throw_if_accessed = false>
515  public:
517 
518  VectorViewMvt(matrix_t& m) : x_(&m) { }
519 
520  VectorViewMvt(std::vector<matrix_t>& vm) : x_(&vm[0]) { }
521 
523  if (throw_if_accessed)
524  throw std::out_of_range("VectorViewMvt: this cannot be accessed");
525  if (is_array)
526  return x_[i];
527  else
528  return x_[0];
529  }
530  private:
531  matrix_t* x_;
532  };
533 
538  template <typename T, bool is_array, bool throw_if_accessed>
539  class VectorViewMvt<const T, is_array, throw_if_accessed> {
540  public:
542 
543  VectorViewMvt(const matrix_t& m) : x_(&m) { }
544 
545  VectorViewMvt(const std::vector<matrix_t>& vm) : x_(&vm[0]) { }
546 
547  const matrix_t& operator[](int i) const {
548  if (throw_if_accessed)
549  throw std::out_of_range("VectorViewMvt: this cannot be accessed");
550  if (is_array)
551  return x_[i];
552  else
553  return x_[0];
554  }
555  private:
556  const matrix_t* x_;
557  };
558 
559  // length_mvt() should only be applied to std vector or Eigen matrix
560  template <typename T>
561  size_t length_mvt(const T& ) {
562  throw std::out_of_range("length_mvt passed to an unrecognized type.");
563  return 1U;
564  }
565  template <typename T, int R, int C>
566  size_t length_mvt(const Eigen::Matrix<T,R,C>& ) {
567  return 1U;
568  }
569  template <typename T, int R, int C>
570  size_t length_mvt(const std::vector<Eigen::Matrix<T,R,C> >& x) {
571  return x.size();
572  }
573 
574  template <typename T1, typename T2>
575  size_t max_size_mvt(const T1& x1, const T2& x2) {
576  size_t result = length_mvt(x1);
577  result = result > length_mvt(x2) ? result : length_mvt(x2);
578  return result;
579  }
580 
581  template <typename T1, typename T2, typename T3>
582  size_t max_size_mvt(const T1& x1, const T2& x2, const T3& x3) {
583  size_t result = length_mvt(x1);
584  result = result > length_mvt(x2) ? result : length_mvt(x2);
585  result = result > length_mvt(x3) ? result : length_mvt(x3);
586  return result;
587  }
588 
589  template <typename T1, typename T2, typename T3, typename T4>
590  size_t max_size_mvt(const T1& x1, const T2& x2, const T3& x3, const T4& x4) {
591  size_t result = length_mvt(x1);
592  result = result > length_mvt(x2) ? result : length_mvt(x2);
593  result = result > length_mvt(x3) ? result : length_mvt(x3);
594  result = result > length_mvt(x4) ? result : length_mvt(x4);
595  return result;
596  }
597 
598 }
599 #endif
600 
scalar_type< T >::type type
Definition: traits.hpp:222
Metaprogramming struct to detect whether a given type is constant in the mathematical sense (not the ...
Definition: traits.hpp:43
Metaprogram structure to determine the base scalar type of a template argument.
Definition: traits.hpp:138
scalar_t & operator[](int i)
Definition: traits.hpp:288
VectorView(scalar_t &c)
Definition: traits.hpp:279
size_t max_size_mvt(const T1 &x1, const T2 &x2)
Definition: traits.hpp:575
scalar_type< T >::type scalar_t
Definition: traits.hpp:277
double & operator[](size_t)
Definition: traits.hpp:361
static size_t size_of(const T &)
Definition: traits.hpp:173
scalar_type_helper_pre< is_vector< typename stan::math::value_type< T >::type >::value, typename stan::math::value_type< T >::type, T >::type type
Definition: traits.hpp:506
static size_t size_of(const T &x)
Definition: traits.hpp:180
VectorViewMvt(std::vector< matrix_t > &vm)
Definition: traits.hpp:520
size_t length(const T &)
Definition: traits.hpp:159
Metaprogram to calculate the base scalar return type resulting from promoting all the scalar types of...
Definition: traits.hpp:398
DoubleVectorView allocates double values to be used as intermediate values.
Definition: traits.hpp:358
scalar_type_helper< is_vector< T >::value, T >::type type
Definition: traits.hpp:139
VectorViewMvt(const std::vector< matrix_t > &vm)
Definition: traits.hpp:545
boost::math::tools::promote_args< typename scalar_type< T1 >::type, typename scalar_type< T2 >::type, typename scalar_type< T3 >::type, typename scalar_type< T4 >::type, typename scalar_type< T5 >::type, typename scalar_type< T6 >::type >::type type
Definition: traits.hpp:406
matrix_t & operator[](int i)
Definition: traits.hpp:522
VectorView(std::vector< scalar_t > &v)
Definition: traits.hpp:281
Metaprogram to determine if a type has a base scalar type that can be assigned to type double...
Definition: traits.hpp:57
size_t size_of(const T &x)
Definition: traits.hpp:186
VectorView(const std::vector< scalar_t > &v)
Definition: traits.hpp:313
size_t length_mvt(const T &)
Definition: traits.hpp:561
size_t max_size(const T1 &x1, const T2 &x2)
Definition: traits.hpp:191
VectorView(Eigen::Matrix< scalar_t, R, C > &m)
Definition: traits.hpp:284
Independent (input) and dependent (output) variables for gradients.
Definition: var.hpp:27
VectorViewMvt(matrix_t &m)
Definition: traits.hpp:518
DoubleVectorView(size_t)
Definition: traits.hpp:360
scalar_type_pre< T >::type matrix_t
Definition: traits.hpp:516
Metaprogram structure to determine the type of first container of the base scalar type of a template ...
Definition: traits.hpp:502
Metaprogram to calculate the base scalar return type resulting from promoting all the scalar types of...
Definition: traits.hpp:443
VectorView(scalar_t *x)
Definition: traits.hpp:286
VectorView is a template metaprogram that takes its argument and allows it to be used like a vector...
Definition: traits.hpp:275
VectorView(const Eigen::Matrix< scalar_t, R, C > &m)
Definition: traits.hpp:316
Primary template class for metaprogram to compute the type of values stored in a container.
Definition: value_type.hpp:21

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