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  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
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)
ValueType< T >::type value_type
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.
static KOKKOS_INLINE_FUNCTION const value_type & eval(const T &x)
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
ScalarType< T >::type scalar_type
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 KOKKOS_INLINE_FUNCTION const scalar_type & eval(const T &x)
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.