31 #ifndef SACADO_FAD_EXP_OPS_HPP
32 #define SACADO_FAD_EXP_OPS_HPP
34 #include <type_traits>
44 #if defined(HAVE_SACADO_KOKKOSCORE)
45 #include "Kokkos_Atomic.hpp"
46 #include "impl/Kokkos_Error.hpp"
49 #define FAD_UNARYOP_MACRO(OPNAME,OP,USING,VALUE,DX,FASTACCESSDX) \
54 template <typename T, typename ExprSpec> \
57 template <typename T> \
58 class OP< T,ExprSpecDefault > : \
59 public Expr< OP<T,ExprSpecDefault> > { \
62 typedef typename std::remove_cv<T>::type ExprT; \
63 typedef typename ExprT::value_type value_type; \
64 typedef typename ExprT::scalar_type scalar_type; \
66 typedef ExprSpecDefault expr_spec_type; \
68 KOKKOS_INLINE_FUNCTION \
69 OP(const T& expr_) : expr(expr_) {} \
71 KOKKOS_INLINE_FUNCTION \
72 int size() const { return expr.size(); } \
74 KOKKOS_INLINE_FUNCTION \
75 bool hasFastAccess() const { \
76 return expr.hasFastAccess(); \
79 KOKKOS_INLINE_FUNCTION \
80 value_type val() const { \
85 KOKKOS_INLINE_FUNCTION \
86 value_type dx(int i) const { \
91 KOKKOS_INLINE_FUNCTION \
92 value_type fastAccessDx(int i) const { \
94 return FASTACCESSDX; \
102 template <typename T> \
103 KOKKOS_INLINE_FUNCTION \
104 OP< typename Expr<T>::derived_type, \
105 typename T::expr_spec_type > \
106 OPNAME (const Expr<T>& expr) \
108 typedef OP< typename Expr<T>::derived_type, \
109 typename T::expr_spec_type > expr_t; \
111 return expr_t(expr.derived()); \
114 template <typename T, typename E> \
115 struct ExprLevel< OP< T,E > > { \
116 static const unsigned value = ExprLevel<T>::value; \
119 template <typename T, typename E> \
120 struct IsFadExpr< OP< T,E > > { \
121 static const unsigned value = true; \
127 template <typename T, typename E> \
128 struct IsExpr< Fad::Exp::OP< T,E > > { \
129 static const bool value = true; \
132 template <typename T, typename E> \
133 struct BaseExprType< Fad::Exp::OP< T,E > > { \
134 typedef typename BaseExprType<T>::type type; \
137 template <typename T, typename E> \
138 struct IsSimdType< Fad::Exp::OP< T,E > > { \
139 static const bool value = \
140 IsSimdType< typename Fad::Exp::OP< T,E >::scalar_type >::value; \
150 expr.fastAccessDx(i))
156 -expr.fastAccessDx(i))
161 exp(expr.val())*expr.dx(i),
162 exp(expr.val())*expr.fastAccessDx(i))
167 expr.dx(i)/expr.val(),
168 expr.fastAccessDx(i)/expr.val())
173 expr.dx(i)/(
log(value_type(10))*expr.val()),
174 expr.fastAccessDx(i) / (
log(value_type(10))*expr.val()))
179 expr.
dx(i)/(value_type(2)* sqrt(expr.val())),
183 using std::cos; using std::
sin;,
185 -expr.
dx(i)* sin(expr.val()),
189 using std::cos; using std::sin;,
191 expr.
dx(i)* cos(expr.val()),
198 (value_type(1)+ tan(expr.val())* tan(expr.val())),
200 (value_type(1)+ tan(expr.val())* tan(expr.val())))
203 using std::acos; using std::sqrt;,
205 -expr.
dx(i)/ sqrt(value_type(1)-expr.val()*expr.val()),
207 sqrt(value_type(1)-expr.val()*expr.val()))
210 using std::asin; using std::sqrt;,
212 expr.
dx(i)/ sqrt(value_type(1)-expr.val()*expr.val()),
214 sqrt(value_type(1)-expr.val()*expr.val()))
219 expr.
dx(i)/(value_type(1)+expr.val()*expr.val()),
220 expr.
fastAccessDx(i)/(value_type(1)+expr.val()*expr.val()))
223 using std::cosh; using std::
sinh;,
225 expr.
dx(i)* sinh(expr.val()),
229 using std::cosh; using std::sinh;,
231 expr.
dx(i)* cosh(expr.val()),
235 using std::tanh; using std::cosh;,
237 expr.
dx(i)/( cosh(expr.val())* cosh(expr.val())),
239 ( cosh(expr.val())* cosh(expr.val())))
242 using std::acosh; using std::sqrt;,
244 expr.
dx(i)/ sqrt((expr.val()-value_type(1)) *
245 (expr.val()+value_type(1))),
247 (expr.val()+value_type(1))))
250 using std::asinh; using std::sqrt;,
252 expr.
dx(i)/ sqrt(value_type(1)+expr.val()*expr.val()),
254 expr.val()*expr.val()))
259 expr.
dx(i)/(value_type(1)-expr.val()*expr.val()),
261 expr.val()*expr.val()))
278 expr.
dx(i)/(value_type(3)*cbrt(expr.val()*expr.val())),
279 expr.
fastAccessDx(i)/(value_type(3)*cbrt(expr.val()*expr.val())))
281 #undef FAD_UNARYOP_MACRO
283 #define FAD_BINARYOP_MACRO(OPNAME,OP,USING,VALUE,DX,CDX1,CDX2,FASTACCESSDX,VAL_CONST_DX_1,VAL_CONST_DX_2,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
288 template <typename T1, typename T2, \
289 bool is_const_T1, bool is_const_T2, \
290 typename ExprSpec > \
293 template <typename T1, typename T2> \
294 class OP< T1, T2, false, false, ExprSpecDefault > : \
295 public Expr< OP< T1, T2, false, false, ExprSpecDefault > > { \
298 typedef typename std::remove_cv<T1>::type ExprT1; \
299 typedef typename std::remove_cv<T2>::type ExprT2; \
300 typedef typename ExprT1::value_type value_type_1; \
301 typedef typename ExprT2::value_type value_type_2; \
302 typedef typename Sacado::Promote<value_type_1, \
303 value_type_2>::type value_type; \
305 typedef typename ExprT1::scalar_type scalar_type_1; \
306 typedef typename ExprT2::scalar_type scalar_type_2; \
307 typedef typename Sacado::Promote<scalar_type_1, \
308 scalar_type_2>::type scalar_type; \
310 typedef ExprSpecDefault expr_spec_type; \
312 KOKKOS_INLINE_FUNCTION \
313 OP(const T1& expr1_, const T2& expr2_) : \
314 expr1(expr1_), expr2(expr2_) {} \
316 KOKKOS_INLINE_FUNCTION \
318 const int sz1 = expr1.size(), sz2 = expr2.size(); \
319 return sz1 > sz2 ? sz1 : sz2; \
322 KOKKOS_INLINE_FUNCTION \
323 bool hasFastAccess() const { \
324 return expr1.hasFastAccess() && expr2.hasFastAccess(); \
327 KOKKOS_INLINE_FUNCTION \
328 value_type val() const { \
333 KOKKOS_INLINE_FUNCTION \
334 value_type dx(int i) const { \
336 const int sz1 = expr1.size(), sz2 = expr2.size(); \
337 if (sz1 > 0 && sz2 > 0) \
345 KOKKOS_INLINE_FUNCTION \
346 value_type fastAccessDx(int i) const { \
348 return FASTACCESSDX; \
358 template <typename T1, typename T2> \
359 class OP< T1, T2, false, true, ExprSpecDefault > \
360 : public Expr< OP< T1, T2, false, true, ExprSpecDefault > > { \
363 typedef typename std::remove_cv<T1>::type ExprT1; \
365 typedef typename ExprT1::value_type value_type; \
366 typedef typename ExprT1::scalar_type scalar_type; \
368 typedef ExprSpecDefault expr_spec_type; \
370 KOKKOS_INLINE_FUNCTION \
371 OP(const T1& expr1_, const ConstT& c_) : \
372 expr1(expr1_), c(c_) {} \
374 KOKKOS_INLINE_FUNCTION \
376 return expr1.size(); \
379 KOKKOS_INLINE_FUNCTION \
380 bool hasFastAccess() const { \
381 return expr1.hasFastAccess(); \
384 KOKKOS_INLINE_FUNCTION \
385 value_type val() const { \
387 return VAL_CONST_DX_2; \
390 KOKKOS_INLINE_FUNCTION \
391 value_type dx(int i) const { \
396 KOKKOS_INLINE_FUNCTION \
397 value_type fastAccessDx(int i) const { \
399 return CONST_FASTACCESSDX_2; \
408 template <typename T1, typename T2> \
409 class OP< T1, T2, true, false, ExprSpecDefault > \
410 : public Expr< OP< T1, T2, true, false, ExprSpecDefault > > { \
413 typedef typename std::remove_cv<T2>::type ExprT2; \
415 typedef typename ExprT2::value_type value_type; \
416 typedef typename ExprT2::scalar_type scalar_type; \
418 typedef ExprSpecDefault expr_spec_type; \
420 KOKKOS_INLINE_FUNCTION \
421 OP(const ConstT& c_, const T2& expr2_) : \
422 c(c_), expr2(expr2_) {} \
424 KOKKOS_INLINE_FUNCTION \
426 return expr2.size(); \
429 KOKKOS_INLINE_FUNCTION \
430 bool hasFastAccess() const { \
431 return expr2.hasFastAccess(); \
434 KOKKOS_INLINE_FUNCTION \
435 value_type val() const { \
437 return VAL_CONST_DX_1; \
440 KOKKOS_INLINE_FUNCTION \
441 value_type dx(int i) const { \
446 KOKKOS_INLINE_FUNCTION \
447 value_type fastAccessDx(int i) const { \
449 return CONST_FASTACCESSDX_1; \
458 template <typename T1, typename T2> \
459 KOKKOS_INLINE_FUNCTION \
460 SACADO_FAD_EXP_OP_ENABLE_EXPR_EXPR(OP) \
461 OPNAME (const T1& expr1, const T2& expr2) \
463 typedef OP< typename Expr<T1>::derived_type, \
464 typename Expr<T2>::derived_type, \
465 false, false, typename T1::expr_spec_type > expr_t; \
467 return expr_t(expr1.derived(), expr2.derived()); \
470 template <typename T> \
471 KOKKOS_INLINE_FUNCTION \
472 OP< typename T::value_type, typename Expr<T>::derived_type, \
473 true, false, typename T::expr_spec_type > \
474 OPNAME (const typename T::value_type& c, \
475 const Expr<T>& expr) \
477 typedef typename T::value_type ConstT; \
478 typedef OP< ConstT, typename Expr<T>::derived_type, \
479 true, false, typename T::expr_spec_type > expr_t; \
481 return expr_t(c, expr.derived()); \
484 template <typename T> \
485 KOKKOS_INLINE_FUNCTION \
486 OP< typename Expr<T>::derived_type, typename T::value_type, \
487 false, true, typename T::expr_spec_type > \
488 OPNAME (const Expr<T>& expr, \
489 const typename T::value_type& c) \
491 typedef typename T::value_type ConstT; \
492 typedef OP< typename Expr<T>::derived_type, ConstT, \
493 false, true, typename T::expr_spec_type > expr_t; \
495 return expr_t(expr.derived(), c); \
498 template <typename T> \
499 KOKKOS_INLINE_FUNCTION \
500 SACADO_FAD_EXP_OP_ENABLE_SCALAR_EXPR(OP) \
501 OPNAME (const typename T::scalar_type& c, \
502 const Expr<T>& expr) \
504 typedef typename T::scalar_type ConstT; \
505 typedef OP< ConstT, typename Expr<T>::derived_type, \
506 true, false, typename T::expr_spec_type > expr_t; \
508 return expr_t(c, expr.derived()); \
511 template <typename T> \
512 KOKKOS_INLINE_FUNCTION \
513 SACADO_FAD_EXP_OP_ENABLE_EXPR_SCALAR(OP) \
514 OPNAME (const Expr<T>& expr, \
515 const typename T::scalar_type& c) \
517 typedef typename T::scalar_type ConstT; \
518 typedef OP< typename Expr<T>::derived_type, ConstT, \
519 false, true, typename T::expr_spec_type > expr_t; \
521 return expr_t(expr.derived(), c); \
524 template <typename T1, typename T2, bool c1, bool c2, typename E> \
525 struct ExprLevel< OP< T1, T2, c1, c2, E > > { \
526 static constexpr unsigned value_1 = ExprLevel<T1>::value; \
527 static constexpr unsigned value_2 = ExprLevel<T2>::value; \
528 static constexpr unsigned value = \
529 value_1 >= value_2 ? value_1 : value_2; \
532 template <typename T1, typename T2, bool c1, bool c2, typename E> \
533 struct IsFadExpr< OP< T1, T2, c1, c2, E > > { \
534 static constexpr unsigned value = true; \
540 template <typename T1, typename T2, bool c1, bool c2, typename E> \
541 struct IsExpr< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
542 static constexpr bool value = true; \
545 template <typename T1, typename T2, bool c1, bool c2, typename E> \
546 struct BaseExprType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
547 typedef typename BaseExprType<T1>::type base_expr_1; \
548 typedef typename BaseExprType<T2>::type base_expr_2; \
549 typedef typename Sacado::Promote<base_expr_1, \
550 base_expr_2>::type type; \
553 template <typename T1, typename T2, bool c1, bool c2, typename E> \
554 struct IsSimdType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
555 static const bool value = \
556 IsSimdType< typename Fad::Exp::OP< T1, T2, c1, c2, E >::value_type >::value; \
565 expr1.val() + expr2.val(),
566 expr1.dx(i) + expr2.dx(i),
569 expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
574 expr2.fastAccessDx(i),
575 expr1.fastAccessDx(i))
579 expr1.val() - expr2.val(),
580 expr1.dx(i) - expr2.dx(i),
583 expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
588 -expr2.fastAccessDx(i),
589 expr1.fastAccessDx(i))
593 expr1.val() * expr2.val(),
594 expr1.val()*expr2.dx(i) + expr1.dx(i)*expr2.val(),
595 expr1.val()*expr2.dx(i),
596 expr1.dx(i)*expr2.val(),
597 expr1.val()*expr2.fastAccessDx(i) +
598 expr1.fastAccessDx(i)*expr2.val(),
603 c*expr2.fastAccessDx(i),
604 expr1.fastAccessDx(i)*
c)
608 expr1.val() / expr2.val(),
609 (expr1.dx(i)*expr2.val() - expr2.dx(i)*expr1.val()) /
610 (expr2.val()*expr2.val()),
611 -expr2.dx(i)*expr1.val() / (expr2.val()*expr2.val()),
612 expr1.dx(i)/expr2.val(),
613 (expr1.fastAccessDx(i)*expr2.val() -
614 expr2.fastAccessDx(i)*expr1.val()) /
615 (expr2.val()*expr2.val()),
618 -expr2.dx(i)*
c / (expr2.val()*expr2.val()),
620 -expr2.fastAccessDx(i)*
c / (expr2.val()*expr2.val()),
621 expr1.fastAccessDx(i)/
c)
625 atan2(expr1.val(), expr2.val()),
626 (expr2.val()*expr1.dx(i) - expr1.val()*expr2.dx(i))/
627 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
628 -expr1.val()*expr2.dx(i)/
629 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
630 expr2.val()*expr1.dx(i)/
631 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
632 (expr2.val()*expr1.fastAccessDx(i) - expr1.val()*expr2.fastAccessDx(i))/
633 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
636 (-
c*expr2.dx(i)) / (
c*
c + expr2.val()*expr2.val()),
637 (
c*expr1.dx(i))/ (expr1.val()*expr1.val() +
c*
c),
638 (-
c*expr2.fastAccessDx(i))/ (
c*
c + expr2.val()*expr2.val()),
639 (
c*expr1.fastAccessDx(i))/ (expr1.val()*expr1.val() +
c*
c))
657 if_then_else( expr1.val() >= expr2.val(), expr1.val(), expr2.val() ),
659 if_then_else( expr1.val() >= expr2.val(), value_type(0.0), expr2.
dx(i) ),
660 if_then_else( expr1.val() >= expr2.val(), expr1.
dx(i), value_type(0.0) ),
663 if_then_else( expr1.val() >= c, expr1.val(), value_type(c) ),
671 if_then_else( expr1.val() <= expr2.val(), expr1.val(), expr2.val() ),
673 if_then_else( expr1.val() <= expr2.val(), value_type(0.0), expr2.
dx(i) ),
674 if_then_else( expr1.val() <= expr2.val(), expr1.
dx(i), value_type(0.0) ),
676 if_then_else( c <= expr2.val(), value_type(c), expr2.val() ),
677 if_then_else( expr1.val() <= c, expr1.val(), value_type(c) ),
692 template <
typename T1,
typename T2,
693 bool is_const_T1,
bool is_const_T2,
694 typename ExprSpec,
bool is_simd >
700 template <
typename T1,
typename T2>
701 class PowerOp< T1, T2, false, false, ExprSpecDefault, true > :
702 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault, true > > {
705 typedef typename std::remove_cv<T1>::type ExprT1;
706 typedef typename std::remove_cv<T2>::type ExprT2;
707 typedef typename ExprT1::value_type value_type_1;
708 typedef typename ExprT2::value_type value_type_2;
710 value_type_2>::type value_type;
712 typedef typename ExprT1::scalar_type scalar_type_1;
713 typedef typename ExprT2::scalar_type scalar_type_2;
715 scalar_type_2>::type scalar_type;
717 typedef ExprSpecDefault expr_spec_type;
720 PowerOp(
const T1& expr1_,
const T2& expr2_) :
721 expr1(expr1_), expr2(expr2_) {}
725 const int sz1 = expr1.size(), sz2 = expr2.size();
726 return sz1 > sz2 ? sz1 : sz2;
730 bool hasFastAccess()
const {
731 return expr1.hasFastAccess() && expr2.hasFastAccess();
735 value_type
val()
const {
737 return pow(expr1.val(), expr2.val());
741 value_type
dx(
int i)
const {
743 const int sz1 = expr1.size(), sz2 = expr2.size();
744 if (sz1 > 0 && sz2 > 0)
745 return if_then_else( expr1.val() == value_type(0.0), value_type(0.0), value_type((expr2.dx(i)*
log(expr1.val())+expr2.val()*expr1.dx(i)/expr1.val())*
pow(expr1.val(),expr2.val())) );
749 return if_then_else(expr1.val() == value_type(0.0), value_type(0.0), value_type(expr2.val()*expr1.dx(i)/expr1.val()*
pow(expr1.val(),expr2.val())) );
751 return if_then_else( expr1.val() == value_type(0.0), value_type(0.0), value_type(expr2.dx(i)*
log(expr1.val())*
pow(expr1.val(),expr2.val())) );
757 return if_then_else( expr1.val() == value_type(0.0), value_type(0.0), value_type((expr2.fastAccessDx(i)*
log(expr1.val())+expr2.val()*expr1.fastAccessDx(i)/expr1.val())*
pow(expr1.val(),expr2.val())) );
767 template <
typename T1,
typename T2>
768 class PowerOp< T1, T2, false, true, ExprSpecDefault, true >
769 :
public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault, true > > {
772 typedef typename std::remove_cv<T1>::type ExprT1;
774 typedef typename ExprT1::value_type value_type;
775 typedef typename ExprT1::scalar_type scalar_type;
777 typedef ExprSpecDefault expr_spec_type;
780 PowerOp(
const T1& expr1_,
const ConstT& c_) :
781 expr1(expr1_),
c(c_) {}
789 bool hasFastAccess()
const {
790 return expr1.hasFastAccess();
794 value_type
val()
const {
796 return pow(expr1.val(),
c);
800 value_type
dx(
int i)
const {
804 return if_then_else( expr1.val() == value_type(0.0), value_type(0.0), value_type(c*expr1.dx(i)/expr1.val()*
pow(expr1.val(),
c)) );
812 return if_then_else( expr1.val() == value_type(0.0), value_type(0.0), value_type(c*expr1.fastAccessDx(i)/expr1.val()*
pow(expr1.val(),
c)) );
821 template <
typename T1,
typename T2>
822 class PowerOp< T1, T2, true, false, ExprSpecDefault, true >
823 :
public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault, true > > {
826 typedef typename std::remove_cv<T2>::type ExprT2;
828 typedef typename ExprT2::value_type value_type;
829 typedef typename ExprT2::scalar_type scalar_type;
831 typedef ExprSpecDefault expr_spec_type;
834 PowerOp(
const ConstT& c_,
const T2& expr2_) :
835 c(c_), expr2(expr2_) {}
843 bool hasFastAccess()
const {
844 return expr2.hasFastAccess();
848 value_type
val()
const {
850 return pow(c, expr2.val());
854 value_type
dx(
int i)
const {
856 return if_then_else( c == scalar_type(0.0), value_type(0.0), value_type(expr2.dx(i)*
log(c)*
pow(c,expr2.val())) );
862 return if_then_else( c == scalar_type(0.0), value_type(0.0), value_type(expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val())) );
875 template <
typename T1,
typename T2>
876 class PowerOp< T1, T2, false, false, ExprSpecDefault, false > :
877 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault, false > > {
880 typedef typename std::remove_cv<T1>::type ExprT1;
881 typedef typename std::remove_cv<T2>::type ExprT2;
882 typedef typename ExprT1::value_type value_type_1;
883 typedef typename ExprT2::value_type value_type_2;
885 value_type_2>::type value_type;
887 typedef typename ExprT1::scalar_type scalar_type_1;
888 typedef typename ExprT2::scalar_type scalar_type_2;
890 scalar_type_2>::type scalar_type;
892 typedef ExprSpecDefault expr_spec_type;
895 PowerOp(
const T1& expr1_,
const T2& expr2_) :
896 expr1(expr1_), expr2(expr2_) {}
900 const int sz1 = expr1.size(), sz2 = expr2.size();
901 return sz1 > sz2 ? sz1 : sz2;
905 bool hasFastAccess()
const {
906 return expr1.hasFastAccess() && expr2.hasFastAccess();
910 value_type
val()
const {
912 return pow(expr1.val(), expr2.val());
916 value_type
dx(
int i)
const {
918 const int sz1 = expr1.size(), sz2 = expr2.size();
919 if (sz1 > 0 && sz2 > 0)
920 return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type((expr2.dx(i)*
log(expr1.val())+expr2.val()*expr1.dx(i)/expr1.val())*
pow(expr1.val(),expr2.val()));
924 return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type(expr2.val()*expr1.dx(i)/expr1.val()*
pow(expr1.val(),expr2.val()));
926 return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type(expr2.dx(i)*
log(expr1.val())*
pow(expr1.val(),expr2.val()));
932 return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type((expr2.fastAccessDx(i)*
log(expr1.val())+expr2.val()*expr1.fastAccessDx(i)/expr1.val())*
pow(expr1.val(),expr2.val()));
942 template <
typename T1,
typename T2>
943 class PowerOp< T1, T2, false, true, ExprSpecDefault, false >
944 :
public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault, false > > {
947 typedef typename std::remove_cv<T1>::type ExprT1;
949 typedef typename ExprT1::value_type value_type;
950 typedef typename ExprT1::scalar_type scalar_type;
952 typedef ExprSpecDefault expr_spec_type;
955 PowerOp(
const T1& expr1_,
const ConstT& c_) :
956 expr1(expr1_),
c(c_) {}
964 bool hasFastAccess()
const {
965 return expr1.hasFastAccess();
969 value_type
val()
const {
971 return pow(expr1.val(),
c);
975 value_type
dx(
int i)
const {
979 return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type(c*expr1.dx(i)/expr1.val()*
pow(expr1.val(),
c));
987 return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type(c*expr1.fastAccessDx(i)/expr1.val()*
pow(expr1.val(),
c));
996 template <
typename T1,
typename T2>
997 class PowerOp< T1, T2, true, false, ExprSpecDefault, false >
998 :
public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault, false > > {
1001 typedef typename std::remove_cv<T2>::type ExprT2;
1003 typedef typename ExprT2::value_type value_type;
1004 typedef typename ExprT2::scalar_type scalar_type;
1006 typedef ExprSpecDefault expr_spec_type;
1009 PowerOp(
const ConstT& c_,
const T2& expr2_) :
1010 c(c_), expr2(expr2_) {}
1014 return expr2.size();
1018 bool hasFastAccess()
const {
1019 return expr2.hasFastAccess();
1023 value_type
val()
const {
1025 return pow(c, expr2.val());
1029 value_type
dx(
int i)
const {
1031 return c == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.dx(i)*
log(c)*
pow(c,expr2.val()));
1037 return c == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val()));
1046 template <
typename T1,
typename T2>
1049 pow (
const T1& expr1,
const T2& expr2)
1051 typedef PowerOp< typename Expr<T1>::derived_type,
1052 typename Expr<T2>::derived_type,
1053 false,
false,
typename T1::expr_spec_type > expr_t;
1055 return expr_t(expr1.derived(), expr2.derived());
1058 template <
typename T>
1060 PowerOp< typename T::value_type, typename Expr<T>::derived_type,
1061 true,
false,
typename T::expr_spec_type >
1062 pow (
const typename T::value_type& c,
1063 const Expr<T>& expr)
1065 typedef typename T::value_type ConstT;
1066 typedef PowerOp< ConstT, typename Expr<T>::derived_type,
1067 true,
false,
typename T::expr_spec_type > expr_t;
1069 return expr_t(c, expr.derived());
1072 template <
typename T>
1074 PowerOp< typename Expr<T>::derived_type,
typename T::value_type,
1075 false,
true,
typename T::expr_spec_type >
1076 pow (
const Expr<T>& expr,
1077 const typename T::value_type& c)
1079 typedef typename T::value_type ConstT;
1080 typedef PowerOp< typename Expr<T>::derived_type, ConstT,
1081 false,
true,
typename T::expr_spec_type > expr_t;
1083 return expr_t(expr.derived(),
c);
1086 template <
typename T>
1089 pow (
const typename T::scalar_type& c,
1090 const Expr<T>& expr)
1092 typedef typename T::scalar_type ConstT;
1093 typedef PowerOp< ConstT, typename Expr<T>::derived_type,
1094 true,
false,
typename T::expr_spec_type > expr_t;
1096 return expr_t(c, expr.derived());
1099 template <
typename T>
1102 pow (
const Expr<T>& expr,
1103 const typename T::scalar_type& c)
1105 typedef typename T::scalar_type ConstT;
1106 typedef PowerOp< typename Expr<T>::derived_type, ConstT,
1107 false,
true,
typename T::expr_spec_type > expr_t;
1109 return expr_t(expr.derived(),
c);
1112 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1113 struct ExprLevel< PowerOp< T1, T2, c1, c2, E > > {
1114 static constexpr
unsigned value_1 = ExprLevel<T1>::value;
1115 static constexpr
unsigned value_2 = ExprLevel<T2>::value;
1116 static constexpr
unsigned value =
1117 value_1 >= value_2 ? value_1 : value_2;
1120 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1121 struct IsFadExpr< PowerOp< T1, T2, c1, c2, E > > {
1122 static constexpr
unsigned value =
true;
1128 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1129 struct IsExpr< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1130 static constexpr
bool value =
true;
1133 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1134 struct BaseExprType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1135 typedef typename BaseExprType<T1>::type base_expr_1;
1136 typedef typename BaseExprType<T2>::type base_expr_2;
1138 base_expr_2>::type type;
1141 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1142 struct IsSimdType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1143 static const bool value =
1144 IsSimdType< typename Fad::Exp::PowerOp< T1, T2, c1, c2, E >::value_type >::value;
1157 template <
typename CondT,
typename T1,
typename T2,
1158 bool is_const_T1,
bool is_const_T2,
1162 template <
typename CondT,
typename T1,
typename T2>
1164 public Expr< IfThenElseOp< CondT, T1, T2, false, false, ExprSpecDefault > > {
1168 typedef typename std::remove_cv<T1>::type
ExprT1;
1169 typedef typename std::remove_cv<T2>::type
ExprT2;
1184 cond(cond_), expr1(expr1_), expr2(expr2_) {}
1188 int sz1 = expr1.size(), sz2 = expr2.size();
1189 return sz1 > sz2 ? sz1 : sz2;
1194 return expr1.hasFastAccess() && expr2.hasFastAccess();
1203 value_type
dx(
int i)
const {
1209 return if_then_else( cond, expr1.fastAccessDx(i), expr2.fastAccessDx(i) );
1220 template <
typename CondT,
typename T1,
typename T2>
1222 public Expr< IfThenElseOp< CondT, T1, T2, false, true, ExprSpecDefault > > {
1226 typedef typename std::remove_cv<T1>::type
ExprT1;
1235 cond(cond_), expr1(expr1_),
c(c_) {}
1239 return expr1.size();
1244 return expr1.hasFastAccess();
1253 value_type
dx(
int i)
const {
1254 return if_then_else( cond, expr1.dx(i), value_type(0.0) );
1259 return if_then_else( cond, expr1.fastAccessDx(i), value_type(0.0) );
1269 template <
typename CondT,
typename T1,
typename T2>
1271 public Expr< IfThenElseOp< CondT, T1, T2, true, false, ExprSpecDefault > > {
1275 typedef typename std::remove_cv<T2>::type
ExprT2;
1284 cond(cond_),
c(c_), expr2(expr2_) {}
1288 return expr2.size();
1293 return expr2.hasFastAccess();
1302 value_type
dx(
int i)
const {
1303 return if_then_else( cond, value_type(0.0), expr2.dx(i) );
1308 return if_then_else( cond, value_type(0.0), expr2.fastAccessDx(i) );
1318 template <
typename CondT,
typename T1,
typename T2>
1326 typename T1::expr_spec_type >
1332 false,
false,
typename T1::expr_spec_type > expr_t;
1334 return expr_t(cond, expr1.derived(), expr2.derived());
1337 template <
typename CondT,
typename T>
1339 IfThenElseOp< CondT, typename T::value_type, typename Expr<T>::derived_type,
1340 true,
false,
typename T::expr_spec_type >
1344 typedef typename T::value_type ConstT;
1346 true,
false,
typename T::expr_spec_type > expr_t;
1348 return expr_t(cond, c, expr.
derived());
1351 template <
typename CondT,
typename T>
1353 IfThenElseOp< CondT, typename Expr<T>::derived_type,
typename T::value_type,
1354 false,
true,
typename T::expr_spec_type >
1356 const typename T::value_type&
c)
1358 typedef typename T::value_type ConstT;
1360 false,
true,
typename T::expr_spec_type > expr_t;
1362 return expr_t(cond, expr.
derived(),
c);
1365 template <
typename CondT,
typename T>
1369 typename T::scalar_type >,
1370 IfThenElseOp< CondT,
typename T::scalar_type,
1372 true,
false,
typename T::expr_spec_type >
1377 typedef typename T::scalar_type ConstT;
1379 true,
false,
typename T::expr_spec_type > expr_t;
1381 return expr_t(cond, c, expr.
derived());
1384 template <
typename CondT,
typename T>
1388 typename T::scalar_type >,
1389 IfThenElseOp< CondT, typename Expr<T>::derived_type,
1390 typename T::scalar_type,
1391 false,
true,
typename T::expr_spec_type >
1396 typedef typename T::scalar_type ConstT;
1398 false,
true,
typename T::expr_spec_type > expr_t;
1400 return expr_t(cond, expr.
derived(),
c);
1403 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1409 value_1 >= value_2 ? value_1 : value_2;
1412 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1421 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1423 struct IsExpr< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
1427 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1429 struct BaseExprType< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
1437 #undef FAD_BINARYOP_MACRO
1450 template <
typename T1,
typename T2 =
T1,
1454 template <
typename T1,
typename T2>
1456 typedef decltype( std::declval<T1>() == std::declval<T2>() ) type;
1463 #define FAD_RELOP_MACRO(OP) \
1464 namespace Sacado { \
1467 template <typename T1, typename T2> \
1468 KOKKOS_INLINE_FUNCTION \
1469 typename mpl::enable_if_c< \
1470 IsFadExpr<T1>::value && IsFadExpr<T2>::value && \
1471 ExprLevel<T1>::value == ExprLevel<T2>::value, \
1472 typename Impl::ConditionalReturnType<typename T1::value_type, \
1473 typename T2::value_type>::type \
1475 operator OP (const T1& expr1, const T2& expr2) \
1477 return expr1.derived().val() OP expr2.derived().val(); \
1480 template <typename T2> \
1481 KOKKOS_INLINE_FUNCTION \
1482 typename Impl::ConditionalReturnType<typename T2::value_type>::type \
1483 operator OP (const typename T2::value_type& a, \
1484 const Expr<T2>& expr2) \
1486 return a OP expr2.derived().val(); \
1489 template <typename T1> \
1490 KOKKOS_INLINE_FUNCTION \
1491 typename Impl::ConditionalReturnType<typename T1::value_type>::type \
1492 operator OP (const Expr<T1>& expr1, \
1493 const typename T1::value_type& b) \
1495 return expr1.derived().val() OP b; \
1512 #undef FAD_RELOP_MACRO
1519 template <
typename ExprT>
1523 return ! expr.
derived().val();
1537 template <
typename T>
1541 bool is_zero = (x.val() == 0.0);
1542 for (
int i=0; i<x.size(); i++)
1543 is_zero = is_zero && (x.dx(i) == 0.0);
1552 #define FAD_BOOL_MACRO(OP) \
1553 namespace Sacado { \
1556 template <typename T1, typename T2> \
1557 KOKKOS_INLINE_FUNCTION \
1559 operator OP (const Expr<T1>& expr1, \
1560 const Expr<T2>& expr2) \
1562 return toBool(expr1) OP toBool(expr2); \
1565 template <typename T2> \
1566 KOKKOS_INLINE_FUNCTION \
1568 operator OP (const typename Expr<T2>::value_type& a, \
1569 const Expr<T2>& expr2) \
1571 return a OP toBool(expr2); \
1574 template <typename T1> \
1575 KOKKOS_INLINE_FUNCTION \
1577 operator OP (const Expr<T1>& expr1, \
1578 const typename Expr<T1>::value_type& b) \
1580 return toBool(expr1) OP b; \
1589 #undef FAD_BOOL_MACRO
1598 template <
typename T>
1599 std::ostream& operator << (std::ostream& os, const Expr<T>& xx) {
1601 os << x.val() <<
" [";
1603 for (
int i=0; i< x.size(); i++) {
1604 os <<
" " << x.dx(i);
1616 #if defined(HAVE_SACADO_KOKKOSCORE)
1626 template <
typename S>
1628 void atomic_add(GeneralFad<S>* dst,
const GeneralFad<S>& x) {
1629 using Kokkos::atomic_add;
1631 const int xsz = x.size();
1632 const int sz = dst->size();
1638 "Sacado error: Fad resize within atomic_add() not supported!");
1640 if (xsz != sz && sz > 0 && xsz > 0)
1642 "Sacado error: Fad assignment of incompatiable sizes!");
1645 if (sz > 0 && xsz > 0) {
1650 atomic_add(&(dst->val()), x.val());
1658 #endif // HAVE_SACADO_KOKKOSCORE
1660 #endif // SACADO_FAD_OPS_HPP
Wrapper for a generic expression template.
std::remove_cv< T1 >::type ExprT1
KOKKOS_INLINE_FUNCTION value_type dx(int i) const
#define FAD_BOOL_MACRO(OP)
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
expr expr expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
#define FAD_UNARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, FASTACCESSDX)
static constexpr bool value
#define SACADO_FAD_EXP_OP_ENABLE_EXPR_EXPR(OP)
KOKKOS_INLINE_FUNCTION bool toBool(const Expr< T > &xx)
#define SACADO_FAD_THREAD_SINGLE
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MinOp
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
expr expr expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 expr1 expr1 c *expr2 expr1 c *expr2 expr1 c *expr2 expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 Atan2Op
ExprT2::scalar_type scalar_type
KOKKOS_INLINE_FUNCTION const derived_type & derived() const
Return derived object.
Sacado::Promote< base_expr_1, base_expr_2 >::type type
Determine whether a given type is an expression.
KOKKOS_INLINE_FUNCTION mpl::enable_if_c< IsFadExpr< T1 >::value &&IsFadExpr< T2 >::value &&ExprLevel< T1 >::value==ExprLevel< T2 >::value, IfThenElseOp< CondT, typename Expr< T1 >::derived_type, typename Expr< T2 >::derived_type, false, false, typename T1::expr_spec_type > >::type if_then_else(const CondT &cond, const T1 &expr1, const T2 &expr2)
KOKKOS_INLINE_FUNCTION IfThenElseOp(const CondT &cond_, const T1 &expr1_, const ConstT &c_)
Wrapper for a generic expression template.
BaseExprType< T1 >::type base_expr_1
KOKKOS_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
ExprT1::scalar_type scalar_type
expr expr expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 expr1 expr1 c *expr2 expr1 c *expr2 expr1 c *expr2 expr1 DivisionOp
KOKKOS_INLINE_FUNCTION mpl::enable_if_c< ExprLevel< Expr< T1 > >::value==ExprLevel< Expr< T2 > >::value, Expr< PowerOp< Expr< T1 >, Expr< T2 > > > >::type pow(const Expr< T1 > &expr1, const Expr< T2 > &expr2)
ExprT1::value_type value_type_1
ExprT1::scalar_type scalar_type_1
ExprT2::value_type value_type
ExprT2::value_type value_type_2
#define KOKKOS_INLINE_FUNCTION
KOKKOS_INLINE_FUNCTION int size() const
KOKKOS_INLINE_FUNCTION value_type val() const
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 c
KOKKOS_INLINE_FUNCTION value_type fastAccessDx(int i) const
#define FAD_BINARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, CDX1, CDX2, FASTACCESSDX, VAL_CONST_DX_1, VAL_CONST_DX_2, CONST_DX_1, CONST_DX_2, CONST_FASTACCESSDX_1, CONST_FASTACCESSDX_2)
#define SACADO_FAD_EXP_OP_ENABLE_SCALAR_EXPR(OP)
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
#define SACADO_FAD_DERIV_LOOP(I, SZ)
Get the base Fad type from a view/expression.
std::remove_cv< T2 >::type ExprT2
ExprT1::value_type value_type
T derived_type
Typename of derived object, returned by derived()
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
Meta-function for determining nesting with an expression.
#define FAD_RELOP_MACRO(OP)
atan2(expr1.val(), expr2.val())
KOKKOS_INLINE_FUNCTION IfThenElseOp(const CondT &cond_, const T1 &expr1_, const T2 &expr2_)
#define SACADO_FAD_EXP_OP_ENABLE_EXPR_SCALAR(OP)
ExprSpecDefault expr_spec_type
KOKKOS_INLINE_FUNCTION int size() const
KOKKOS_INLINE_FUNCTION value_type dx(int i) const
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
Sacado::Promote< scalar_type_1, scalar_type_2 >::type scalar_type
std::remove_cv< T1 >::type ExprT1
if_then_else(expr.val() >=0, expr.dx(i), value_type(-expr.dx(i)))
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
ExprSpecDefault expr_spec_type
KOKKOS_INLINE_FUNCTION value_type fastAccessDx(int i) const
KOKKOS_INLINE_FUNCTION IfThenElseOp(const CondT &cond_, const ConstT &c_, const T2 &expr2_)
ExprSpecDefault expr_spec_type
BaseExprType< T2 >::type base_expr_2
Sacado::Promote< value_type_1, value_type_2 >::type value_type
KOKKOS_INLINE_FUNCTION value_type fastAccessDx(int i) const
KOKKOS_INLINE_FUNCTION int size() const
expr expr expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 SubtractionOp
KOKKOS_INLINE_FUNCTION value_type val() const
KOKKOS_INLINE_FUNCTION value_type dx(int i) const
std::remove_cv< T2 >::type ExprT2
KOKKOS_INLINE_FUNCTION value_type val() const
static constexpr unsigned value
ExprT2::scalar_type scalar_type_2
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 PowerOp