Sacado Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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"
58#include <string>
59
60#ifdef HAVE_SACADO_COMPLEX
61#include <complex>
62#endif
63
64namespace Sacado {
65
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> {
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>
399 typename ScalarType<T>::type scalarValue(const T& x) {
400 return ScalarValue<T>::eval(x);
401 }
402
404 template <typename T> struct MarkConstant {
406 static void eval(T& x) {}
407 };
408
410 template <typename T> struct StringName {
411 static std::string eval() { return ""; }
412 };
413
415 template <typename T> struct IsEqual {
417 static bool eval(const T& x, const T& y) { return x == y; }
418 };
419
421 template <typename T> struct IsStaticallySized {
422 static const bool value = false;
423 };
424
426
429 template <typename T> struct IsStaticallySized<const T> {
431 };
432
434 template <typename T> struct StaticSize {
435 static const unsigned value = 0;
436 };
437
439 template <typename T> struct IsFad {
440 static const bool value = false;
441 };
442
444 template <typename T> struct IsFad< const T >
445 {
446 static const bool value = IsFad<T>::value;
447 };
448
450 template <typename T>
451 struct RemoveConst {
452 typedef T type;
453 };
454
456 template <typename T>
457 struct RemoveConst< const T > {
458 typedef T type;
459 };
460
462#define SACADO_BUILTIN_SPECIALIZATION(t,NAME) \
463 template <> struct ScalarType< t > { \
464 typedef t type; \
465 }; \
466 template <> struct ValueType< t > { \
467 typedef t type; \
468 }; \
469 template <> struct IsADType< t > { \
470 static const bool value = false; \
471 }; \
472 template <> struct IsScalarType< t > { \
473 static const bool value = true; \
474 }; \
475 template <> struct Value< t > { \
476 SACADO_INLINE_FUNCTION \
477 static const t& eval(const t& x) { return x; } \
478 }; \
479 template <> struct ScalarValue< t > { \
480 SACADO_INLINE_FUNCTION \
481 static const t& eval(const t& x) { return x; } \
482 }; \
483 template <> struct StringName< t > { \
484 static std::string eval() { return NAME; } \
485 }; \
486 template <> struct IsEqual< t > { \
487 SACADO_INLINE_FUNCTION \
488 static bool eval(const t& x, const t& y) { \
489 return x == y; } \
490 }; \
491 template <> struct IsStaticallySized< t > { \
492 static const bool value = true; \
493 };
494
495#define SACADO_BUILTIN_SPECIALIZATION_COMPLEX(t,NAME) \
496 template <> struct ScalarType< t > { \
497 typedef t type; \
498 }; \
499 template <> struct ValueType< t > { \
500 typedef t type; \
501 }; \
502 template <> struct IsADType< t > { \
503 static const bool value = false; \
504 }; \
505 template <> struct IsScalarType< t > { \
506 static const bool value = true; \
507 }; \
508 template <> struct Value< t > { \
509 static const t& eval(const t& x) { return x; } \
510 }; \
511 template <> struct ScalarValue< t > { \
512 static const t& eval(const t& x) { return x; } \
513 }; \
514 template <> struct StringName< t > { \
515 static std::string eval() { return NAME; } \
516 }; \
517 template <> struct IsEqual< t > { \
518 static bool eval(const t& x, const t& y) { \
519 return x == y; } \
520 }; \
521 template <> struct IsStaticallySized< t > { \
522 static const bool value = true; \
523 };
524
526 SACADO_BUILTIN_SPECIALIZATION(float,"float")
527 SACADO_BUILTIN_SPECIALIZATION(double,"double")
529 SACADO_BUILTIN_SPECIALIZATION(unsigned int,"unsigned int")
531 SACADO_BUILTIN_SPECIALIZATION(unsigned long,"unsigned long")
533#ifdef HAVE_SACADO_COMPLEX
534 SACADO_BUILTIN_SPECIALIZATION_COMPLEX(std::complex<double>,"std::complex<double>")
535 SACADO_BUILTIN_SPECIALIZATION_COMPLEX(std::complex<float>,"std::complex<float>")
536#endif
537
538#undef SACADO_BUILTIN_SPECIALIZATION
539#undef SACADO_BUILTIN_SPECIALIZATION_COMPLEX
540
541template< typename T , T v , bool NonZero = ( v != T(0) ) >
543{
544 // Declaration of 'static const' causes an unresolved linker symbol in debug
545 // static const T value = v ;
546 enum { value = T(v) };
547 typedef T value_type ;
554};
555
556template< typename T , T zero >
568
569} // namespace Sacado
570
571#endif // SACADO_TRAITS_HPP
#define SACADO_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
const double y
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.
SACADO_INLINE_FUNCTION ScalarType< T >::type scalarValue(const T &x)
A simple template function for invoking ScalarValue<>
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 SACADO_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 SACADO_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 SACADO_INLINE_FUNCTION const scalar_type & eval(const T &x)
Base template specification for ScalarValue.
static SACADO_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 SACADO_INLINE_FUNCTION const value_type & eval(const T &x)
ValueType< T >::type value_type
Base template specification for Value.
static SACADO_INLINE_FUNCTION const T & eval(const T &x)
Get view type for any Fad type.
SACADO_INLINE_FUNCTION integral_nonzero(const T &v)
SACADO_INLINE_FUNCTION integral_nonzero(const integral_nonzero &v)
SACADO_INLINE_FUNCTION integral_nonzero & operator=(const integral_nonzero &v)
SACADO_INLINE_FUNCTION integral_nonzero & operator=(const T &v)
SACADO_INLINE_FUNCTION integral_nonzero & operator=(const integral_nonzero &)
SACADO_INLINE_FUNCTION integral_nonzero(const integral_nonzero &)
SACADO_INLINE_FUNCTION integral_nonzero(const T &)
SACADO_INLINE_FUNCTION integral_nonzero()
SACADO_INLINE_FUNCTION integral_nonzero & operator=(const T &)
integral_nonzero< T, v > type