Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
373  template <typename T> struct ScalarValue {
375  static const T& eval(const T& x) { return x; }
376  };
377 
379  template <typename T> struct MarkConstant {
381  static void eval(T& x) {}
382  };
383 
385  template <typename T> struct StringName {
386  static std::string eval() { return ""; }
387  };
388 
390  template <typename T> struct IsEqual {
392  static bool eval(const T& x, const T& y) { return x == y; }
393  };
394 
396  template <typename T> struct IsStaticallySized {
397  static const bool value = false;
398  };
399 
401 
404  template <typename T> struct IsStaticallySized<const T> {
405  static const bool value = IsStaticallySized<T>::value;
406  };
407 
409  template <typename T> struct StaticSize {
410  static const unsigned value = 0;
411  };
412 
414  template <typename T> struct IsFad {
415  static const bool value = false;
416  };
417 
419  template <typename T> struct IsFad< const T >
420  {
421  static const bool value = IsFad<T>::value;
422  };
423 
425  template <typename T>
426  struct RemoveConst {
427  typedef T type;
428  };
429 
431  template <typename T>
432  struct RemoveConst< const T > {
433  typedef T type;
434  };
435 
437 #define SACADO_BUILTIN_SPECIALIZATION(t,NAME) \
438  template <> struct ScalarType< t > { \
439  typedef t type; \
440  }; \
441  template <> struct ValueType< t > { \
442  typedef t type; \
443  }; \
444  template <> struct IsADType< t > { \
445  static const bool value = false; \
446  }; \
447  template <> struct IsScalarType< t > { \
448  static const bool value = true; \
449  }; \
450  template <> struct Value< t > { \
451  KOKKOS_INLINE_FUNCTION \
452  static const t& eval(const t& x) { return x; } \
453  }; \
454  template <> struct ScalarValue< t > { \
455  KOKKOS_INLINE_FUNCTION \
456  static const t& eval(const t& x) { return x; } \
457  }; \
458  template <> struct StringName< t > { \
459  static std::string eval() { return NAME; } \
460  }; \
461  template <> struct IsEqual< t > { \
462  KOKKOS_INLINE_FUNCTION \
463  static bool eval(const t& x, const t& y) { \
464  return x == y; } \
465  }; \
466  template <> struct IsStaticallySized< t > { \
467  static const bool value = true; \
468  };
469 
470 #define SACADO_BUILTIN_SPECIALIZATION_COMPLEX(t,NAME) \
471  template <> struct ScalarType< t > { \
472  typedef t type; \
473  }; \
474  template <> struct ValueType< t > { \
475  typedef t type; \
476  }; \
477  template <> struct IsADType< t > { \
478  static const bool value = false; \
479  }; \
480  template <> struct IsScalarType< t > { \
481  static const bool value = true; \
482  }; \
483  template <> struct Value< t > { \
484  static const t& eval(const t& x) { return x; } \
485  }; \
486  template <> struct ScalarValue< t > { \
487  static const t& eval(const t& x) { return x; } \
488  }; \
489  template <> struct StringName< t > { \
490  static std::string eval() { return NAME; } \
491  }; \
492  template <> struct IsEqual< t > { \
493  static bool eval(const t& x, const t& y) { \
494  return x == y; } \
495  }; \
496  template <> struct IsStaticallySized< t > { \
497  static const bool value = true; \
498  };
499 
500  SACADO_BUILTIN_SPECIALIZATION(char,"char")
501  SACADO_BUILTIN_SPECIALIZATION(float,"float")
502  SACADO_BUILTIN_SPECIALIZATION(double,"double")
504  SACADO_BUILTIN_SPECIALIZATION(unsigned int,"unsigned int")
505  SACADO_BUILTIN_SPECIALIZATION(long,"long")
506  SACADO_BUILTIN_SPECIALIZATION(unsigned long,"unsigned long")
507  SACADO_BUILTIN_SPECIALIZATION(bool,"bool")
508 #ifdef HAVE_SACADO_COMPLEX
509  SACADO_BUILTIN_SPECIALIZATION_COMPLEX(std::complex<double>,"std::complex<double>")
510  SACADO_BUILTIN_SPECIALIZATION_COMPLEX(std::complex<float>,"std::complex<float>")
511 #endif
512 
513 #undef SACADO_BUILTIN_SPECIALIZATION
514 #undef SACADO_BUILTIN_SPECIALIZATION_COMPLEX
515 
516 template< typename T , T v , bool NonZero = ( v != T(0) ) >
518 {
519  // Declaration of 'static const' causes an unresolved linker symbol in debug
520  // static const T value = v ;
521  enum { value = T(v) };
522  typedef T value_type ;
529 };
530 
531 template< typename T , T zero >
533 {
535  typedef T value_type ;
541  KOKKOS_INLINE_FUNCTION integral_nonzero& operator=(const T & v) { value = v; return *this; }
542 };
543 
544 } // namespace Sacado
545 
546 #endif // SACADO_TRAITS_HPP
Base template specification for marking constants.
static std::string eval()
#define SACADO_PROMOTE_SPECIALIZATION(type1, type2, type3)
Specialization of Promote to builtin types.
KOKKOS_INLINE_FUNCTION integral_nonzero & operator=(const integral_nonzero &v)
KOKKOS_INLINE_FUNCTION integral_nonzero()
Base template specification for ScalarValue.
Base template specification for ScalarType.
static KOKKOS_INLINE_FUNCTION bool eval(const T &x, const T &y)
Base template specification for whether a type is a Fad type.
Base template specification for string names of types.
KOKKOS_INLINE_FUNCTION integral_nonzero(const integral_nonzero &)
Base template specification for IsADType.
static KOKKOS_INLINE_FUNCTION void eval(T &x)
static const bool value
Base template specification for static size.
Base template specification for Value.
KOKKOS_INLINE_FUNCTION integral_nonzero(const T &)
Is a type an expression.
Base template specification for IsSimdType.
KOKKOS_INLINE_FUNCTION integral_nonzero & operator=(const integral_nonzero &)
const ScalarType< T >::type type
#define KOKKOS_INLINE_FUNCTION
#define T
Definition: Sacado_rad.hpp:573
static const bool value
KOKKOS_INLINE_FUNCTION integral_nonzero & operator=(const T &v)
Specialize this for a given type T to disable default Promote rules.
Determine whether a given type is a view.
Base template specification for testing equivalence.
Get the base Fad type from a view/expression.
KOKKOS_INLINE_FUNCTION integral_nonzero(const integral_nonzero &v)
#define SACADO_BUILTIN_SPECIALIZATION_COMPLEX(t, NAME)
Remove const from a type.
Do not initialize the derivative array.
static const bool value
const ValueType< T >::type type
integral_nonzero< T, v > type
#define SACADO_BUILTIN_SPECIALIZATION(t, NAME)
Specialization of above classes to builtin types.
DerivInit
Enum use to signal whether the derivative array should be initialized in AD object constructors...
static const bool value
static KOKKOS_INLINE_FUNCTION const T & eval(const T &x)
static const bool value
Initialize the derivative array.
KOKKOS_INLINE_FUNCTION integral_nonzero(const T &v)
Base template specification for IsScalarType.
expr expr expr bar false
static const unsigned value
KOKKOS_INLINE_FUNCTION integral_nonzero & operator=(const T &)
static const bool value
Base template specification for ValueType.
Base template specification for Promote.
static KOKKOS_INLINE_FUNCTION const T & eval(const T &x)
Base template specification for testing whether type is statically sized.
Get view type for any Fad type.