Sacado Package Browser (Single Doxygen Collection)  Version of the Day
Sacado_Traits.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Sacado Package
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25 // (etphipp@sandia.gov).
26 //
27 // ***********************************************************************
28 //
29 // The forward-mode AD classes in Sacado are a derivative work of the
30 // expression template classes in the Fad package by Nicolas Di Cesare.
31 // The following banner is included in the original Fad source code:
32 //
33 // ************ DO NOT REMOVE THIS BANNER ****************
34 //
35 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
36 // http://www.ann.jussieu.fr/~dicesare
37 //
38 // CEMRACS 98 : C++ courses,
39 // templates : new C++ techniques
40 // for scientific computing
41 //
42 //********************************************************
43 //
44 // NumericalTraits class to illustrate TRAITS
45 //
46 //********************************************************
47 // @HEADER
48 
49 #ifndef SACADO_TRAITS_HPP
50 #define SACADO_TRAITS_HPP
51 
52 #include "Sacado_ConfigDefs.h"
53 #include "Sacado_dummy_arg.hpp"
54 #include "Sacado_mpl_enable_if.hpp"
57 #include "Sacado_mpl_is_same.hpp"
58 #include <string>
59 
60 #ifdef HAVE_SACADO_COMPLEX
61 #include <complex>
62 #endif
63 
64 namespace Sacado {
65 
70  enum DerivInit {
73  };
74 
76  template <typename T>
77  struct IsExpr {
78  static const bool value = false;
79  };
80 
82  template <typename T>
83  struct IsView {
84  static const bool value = false;
85  };
86 
88  template <typename T>
89  struct BaseExprType {
90  typedef T type;
91  };
92 
94  template <typename T,unsigned,unsigned> struct ViewFadType {};
95 
97  template <typename T> struct OverrideDefaultPromote {
98  static const bool value = false;
99  };
100 
102 
106  template <typename A, typename B, typename Enabled = void> struct Promote {};
107 
109  template <typename A>
110  struct Promote< A, A,
111  typename mpl::enable_if_c< !OverrideDefaultPromote<A>::value >::type > {
112  typedef typename BaseExprType<A>::type type;
113  };
114 
116  template <typename A, typename B>
117  struct Promote< A, B,
118  typename mpl::enable_if_c< mpl::is_convertible<A,B>::value &&
119  !mpl::is_convertible<B,A>::value &&
120  !OverrideDefaultPromote<A>::value &&
121  !OverrideDefaultPromote<B>::value
122  >::type > {
123  typedef typename BaseExprType<B>::type type;
124  };
125 
127  template <typename A, typename B>
128  struct Promote< A, B,
129  typename mpl::enable_if_c< mpl::is_convertible<B,A>::value &&
130  !mpl::is_convertible<A,B>::value &&
131  !OverrideDefaultPromote<A>::value &&
132  !OverrideDefaultPromote<B>::value
133  >::type > {
134  typedef typename BaseExprType<A>::type type;
135  };
136 
141  template <typename A, typename B>
142  struct Promote< A, B,
143  typename mpl::enable_if_c< mpl::is_convertible<A,B>::value &&
144  mpl::is_convertible<B,A>::value &&
145  !mpl::is_same<A,B>::value &&
146  ( IsExpr<A>::value ||
147  IsExpr<B>::value ) >::type >
148  {
152  };
153 
159  template <typename A, typename B>
160  struct Promote< A, B,
161  typename mpl::enable_if_c< !mpl::is_convertible<A,B>::value &&
162  !mpl::is_convertible<B,A>::value &&
163  IsExpr<A>::value &&
164  mpl::is_convertible< B, typename BaseExprType< typename A::value_type >::type >::value
165  >::type >
166  {
167  typedef typename BaseExprType<A>::type type;
168  };
169 
175  template <typename A, typename B>
176  struct Promote< A, B,
177  typename mpl::enable_if_c< !mpl::is_convertible<A,B>::value &&
178  !mpl::is_convertible<B,A>::value &&
179  IsExpr<B>::value &&
180  mpl::is_convertible< A, typename BaseExprType< typename B::value_type >::type >::value
181  >::type >
182  {
183  typedef typename BaseExprType<B>::type type;
184  };
185 
191  template <typename A, typename B>
192  struct Promote< A, B,
193  typename mpl::enable_if_c< !mpl::is_convertible<A,B>::value &&
194  !mpl::is_convertible<B,A>::value &&
195  IsExpr<A>::value &&
196  IsExpr<B>::value &&
197  mpl::is_same< typename BaseExprType< typename A::value_type >::type,
198  typename BaseExprType< typename B::value_type >::type >::value
199  >::type >
200  {
204  };
205 
207 #define SACADO_PROMOTE_SPECIALIZATION(type1,type2,type3) \
208  template <> struct Promote< type1, type2, void > { \
209  typedef type3 type; \
210  }; \
211  template <> struct Promote< type2, type1, void > { \
212  typedef type3 type; \
213  };
214 
215  SACADO_PROMOTE_SPECIALIZATION(double,float,double)
216  SACADO_PROMOTE_SPECIALIZATION(double,long,double)
217  SACADO_PROMOTE_SPECIALIZATION(double,int,double)
218  SACADO_PROMOTE_SPECIALIZATION(float,long,float)
219  SACADO_PROMOTE_SPECIALIZATION(float,int,float)
220 #ifdef HAVE_SACADO_COMPLEX
221  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,std::complex<float>,std::complex<double>)
222  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,double,std::complex<double>)
223  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,float,std::complex<double>)
224  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,long,std::complex<double>)
225  SACADO_PROMOTE_SPECIALIZATION(std::complex<double>,int,std::complex<double>)
226  SACADO_PROMOTE_SPECIALIZATION(std::complex<float>,float,std::complex<float>)
227  SACADO_PROMOTE_SPECIALIZATION(std::complex<float>,long,std::complex<float>)
228  SACADO_PROMOTE_SPECIALIZATION(std::complex<float>,int,std::complex<float>)
229 #endif // HAVE_SACADO_COMPLEX
230 
231 #undef SACADO_PROMOTE_SPECIALIZATION
232 
233  // Macros for building proper Promote specialization for AD types
234 
235 #define SACADO_AD_PROMOTE_SPEC(NS, AD) /* */
236 
237 #define SACADO_AD_PROMOTE_SPEC2(NS, AD) /* */
238 
239 #define SACADO_FAD_PROMOTE_SPEC(NS, FAD) /* */
240 
241 #define SACADO_SFAD_PROMOTE_SPEC(NS, FAD) /* */
242 
243 #define SACADO_EXPR_PROMOTE_SPEC(NS) /* */
244 
245 #define SACADO_VFAD_PROMOTE_SPEC(NS) /* */
246 
247 #define SACADO_RAD_PROMOTE_SPEC(NS) \
248  namespace NS { \
249  template <typename> class ADvar; \
250  template <typename> class ADvari; \
251  } \
252  template <typename T> \
253  struct OverrideDefaultPromote< NS :: ADvari <T>& > { \
254  static const bool value = true; \
255  }; \
256  template <typename T> \
257  struct Promote< NS :: ADvar <T>, \
258  NS :: ADvari <T>& > { \
259  typedef NS :: ADvar <T> type; \
260  }; \
261  template <typename T> \
262  struct Promote< NS :: ADvari <T>&, \
263  NS :: ADvar <T> > { \
264  typedef NS :: ADvar <T> type; \
265  }; \
266  template <typename T> \
267  struct Promote< NS :: ADvari <T>&, \
268  typename NS :: ADvari <T>::value_type > { \
269  typedef NS :: ADvar <T> type; \
270  }; \
271  template <typename T> \
272  struct Promote< typename NS :: ADvari <T>::value_type, \
273  NS :: ADvari <T>& > { \
274  typedef NS :: ADvar <T> type; \
275  }; \
276  template <typename T> \
277  struct Promote< NS :: ADvari <T>&, \
278  typename dummy< typename NS :: ADvari <T>::value_type, \
279  typename NS :: ADvari <T>::scalar_type \
280  >::type > { \
281  typedef NS :: ADvar <T> type; \
282  }; \
283  template <typename T> \
284  struct Promote< typename dummy< typename NS :: ADvari <T>::value_type, \
285  typename NS :: ADvari <T>::scalar_type \
286  >::type, \
287  NS :: ADvari <T>& > { \
288  typedef NS :: ADvar <T> type; \
289  };
290 
291  //
292  // We define defaults for all of the traits to make Sacado easier to use.
293  // The default choices are based on what appears to be the "safest" choice
294  // for any scalar type. They may not work in all cases, in which case a
295  // specialization should be provided.
296  //
297 
299 
303  template <typename T> struct ScalarType {
304  typedef T type;
305  };
306 
308 
311  template <typename T> struct ScalarType<const T> {
312  typedef const typename ScalarType<T>::type type;
313  };
314 
316 
320  template <typename T> struct ValueType {
321  typedef T type;
322  };
323 
325 
328  template <typename T> struct ValueType<const T> {
329  typedef const typename ValueType<T>::type type;
330  };
331 
333 
337  template <typename T> struct IsADType {
338  static const bool value = false;
339  };
340 
342 
346  template <typename T> struct IsScalarType {
347  static const bool value = false;
348  };
349 
351 
355  template <typename T> struct IsSimdType {
356  static const bool value = false;
357  };
358 
360 
363  template <typename T> struct Value {
365  static const T& eval(const T& x) { return x; }
366  };
367 
369  template <typename T> struct Value<const T> {
370  typedef typename ValueType<T>::type value_type;
372  static const value_type& eval(const T& x) {
373  return Value<T>::eval(x);
374  }
375  };
376 
378 
382  template <typename T> struct ScalarValue {
384  static const T& eval(const T& x) { return x; }
385  };
386 
388  template <typename T> struct ScalarValue<const T> {
391  static const scalar_type& eval(const T& x) {
392  return ScalarValue<T>::eval(x);
393  }
394  };
395 
397  template <typename T> struct MarkConstant {
399  static void eval(T& x) {}
400  };
401 
403  template <typename T> struct StringName {
404  static std::string eval() { return ""; }
405  };
406 
408  template <typename T> struct IsEqual {
410  static bool eval(const T& x, const T& y) { return x == y; }
411  };
412 
414  template <typename T> struct IsStaticallySized {
415  static const bool value = false;
416  };
417 
419 
422  template <typename T> struct IsStaticallySized<const T> {
423  static const bool value = IsStaticallySized<T>::value;
424  };
425 
427  template <typename T> struct StaticSize {
428  static const unsigned value = 0;
429  };
430 
432  template <typename T> struct IsFad {
433  static const bool value = false;
434  };
435 
437  template <typename T> struct IsFad< const T >
438  {
439  static const bool value = IsFad<T>::value;
440  };
441 
443  template <typename T>
444  struct RemoveConst {
445  typedef T type;
446  };
447 
449  template <typename T>
450  struct RemoveConst< const T > {
451  typedef T type;
452  };
453 
455 #define SACADO_BUILTIN_SPECIALIZATION(t,NAME) \
456  template <> struct ScalarType< t > { \
457  typedef t type; \
458  }; \
459  template <> struct ValueType< t > { \
460  typedef t type; \
461  }; \
462  template <> struct IsADType< t > { \
463  static const bool value = false; \
464  }; \
465  template <> struct IsScalarType< t > { \
466  static const bool value = true; \
467  }; \
468  template <> struct Value< t > { \
469  KOKKOS_INLINE_FUNCTION \
470  static const t& eval(const t& x) { return x; } \
471  }; \
472  template <> struct ScalarValue< t > { \
473  KOKKOS_INLINE_FUNCTION \
474  static const t& eval(const t& x) { return x; } \
475  }; \
476  template <> struct StringName< t > { \
477  static std::string eval() { return NAME; } \
478  }; \
479  template <> struct IsEqual< t > { \
480  KOKKOS_INLINE_FUNCTION \
481  static bool eval(const t& x, const t& y) { \
482  return x == y; } \
483  }; \
484  template <> struct IsStaticallySized< t > { \
485  static const bool value = true; \
486  };
487 
488 #define SACADO_BUILTIN_SPECIALIZATION_COMPLEX(t,NAME) \
489  template <> struct ScalarType< t > { \
490  typedef t type; \
491  }; \
492  template <> struct ValueType< t > { \
493  typedef t type; \
494  }; \
495  template <> struct IsADType< t > { \
496  static const bool value = false; \
497  }; \
498  template <> struct IsScalarType< t > { \
499  static const bool value = true; \
500  }; \
501  template <> struct Value< t > { \
502  static const t& eval(const t& x) { return x; } \
503  }; \
504  template <> struct ScalarValue< t > { \
505  static const t& eval(const t& x) { return x; } \
506  }; \
507  template <> struct StringName< t > { \
508  static std::string eval() { return NAME; } \
509  }; \
510  template <> struct IsEqual< t > { \
511  static bool eval(const t& x, const t& y) { \
512  return x == y; } \
513  }; \
514  template <> struct IsStaticallySized< t > { \
515  static const bool value = true; \
516  };
517 
518  SACADO_BUILTIN_SPECIALIZATION(char,"char")
519  SACADO_BUILTIN_SPECIALIZATION(float,"float")
520  SACADO_BUILTIN_SPECIALIZATION(double,"double")
522  SACADO_BUILTIN_SPECIALIZATION(unsigned int,"unsigned int")
523  SACADO_BUILTIN_SPECIALIZATION(long,"long")
524  SACADO_BUILTIN_SPECIALIZATION(unsigned long,"unsigned long")
525  SACADO_BUILTIN_SPECIALIZATION(bool,"bool")
526 #ifdef HAVE_SACADO_COMPLEX
527  SACADO_BUILTIN_SPECIALIZATION_COMPLEX(std::complex<double>,"std::complex<double>")
528  SACADO_BUILTIN_SPECIALIZATION_COMPLEX(std::complex<float>,"std::complex<float>")
529 #endif
530 
531 #undef SACADO_BUILTIN_SPECIALIZATION
532 #undef SACADO_BUILTIN_SPECIALIZATION_COMPLEX
533 
534 template< typename T , T v , bool NonZero = ( v != T(0) ) >
536 {
537  // Declaration of 'static const' causes an unresolved linker symbol in debug
538  // static const T value = v ;
539  enum { value = T(v) };
540  typedef T value_type ;
547 };
548 
549 template< typename T , T zero >
551 {
553  typedef T value_type ;
559  KOKKOS_INLINE_FUNCTION integral_nonzero& operator=(const T & v) { value = v; return *this; }
560 };
561 
562 } // namespace Sacado
563 
564 #endif // SACADO_TRAITS_HPP
#define KOKKOS_INLINE_FUNCTION
expr expr expr bar false
#define SACADO_BUILTIN_SPECIALIZATION_COMPLEX(t, NAME)
#define SACADO_BUILTIN_SPECIALIZATION(t, NAME)
Specialization of above classes to builtin types.
#define SACADO_PROMOTE_SPECIALIZATION(type1, type2, type3)
Specialization of Promote to builtin types.
#define T
Definition: Sacado_rad.hpp:573
DerivInit
Enum use to signal whether the derivative array should be initialized in AD object constructors.
@ InitDerivArray
Initialize the derivative array.
@ NoInitDerivArray
Do not initialize the derivative array.
Get the base Fad type from a view/expression.
Base template specification for IsADType.
static const bool value
Base template specification for testing equivalence.
static KOKKOS_INLINE_FUNCTION bool eval(const T &x, const T &y)
Is a type an expression.
static const bool value
Base template specification for whether a type is a Fad type.
static const bool value
Base template specification for IsScalarType.
static const bool value
Base template specification for IsSimdType.
static const bool value
Base template specification for testing whether type is statically sized.
Determine whether a given type is a view.
static const bool value
Base template specification for marking constants.
static KOKKOS_INLINE_FUNCTION void eval(T &x)
Specialize this for a given type T to disable default Promote rules.
Base template specification for Promote.
Remove const from a type.
const ScalarType< T >::type type
Base template specification for ScalarType.
ScalarType< T >::type scalar_type
static KOKKOS_INLINE_FUNCTION const scalar_type & eval(const T &x)
Base template specification for ScalarValue.
static KOKKOS_INLINE_FUNCTION const T & eval(const T &x)
Base template specification for static size.
static const unsigned value
Base template specification for string names of types.
static std::string eval()
const ValueType< T >::type type
Base template specification for ValueType.
static KOKKOS_INLINE_FUNCTION const value_type & eval(const T &x)
ValueType< T >::type value_type
Base template specification for Value.
static KOKKOS_INLINE_FUNCTION const T & eval(const T &x)
Get view type for any Fad type.
KOKKOS_INLINE_FUNCTION integral_nonzero & operator=(const integral_nonzero &v)
KOKKOS_INLINE_FUNCTION integral_nonzero(const T &v)
KOKKOS_INLINE_FUNCTION integral_nonzero & operator=(const T &v)
KOKKOS_INLINE_FUNCTION integral_nonzero(const integral_nonzero &v)
KOKKOS_INLINE_FUNCTION integral_nonzero & operator=(const T &)
KOKKOS_INLINE_FUNCTION integral_nonzero(const T &)
KOKKOS_INLINE_FUNCTION integral_nonzero(const integral_nonzero &)
KOKKOS_INLINE_FUNCTION integral_nonzero & operator=(const integral_nonzero &)
KOKKOS_INLINE_FUNCTION integral_nonzero()
integral_nonzero< T, v > type