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 explicit 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()),
237 expr.
dx(i)*(value_type(1)-tanh(expr.val())*tanh(expr.val())),
238 expr.
fastAccessDx(i)*(value_type(1)-tanh(expr.val())*tanh(expr.val())))
241 using std::acosh; using std::sqrt;,
243 expr.
dx(i)/ sqrt((expr.val()-value_type(1)) *
244 (expr.val()+value_type(1))),
246 (expr.val()+value_type(1))))
249 using std::asinh; using std::sqrt;,
251 expr.
dx(i)/ sqrt(value_type(1)+expr.val()*expr.val()),
253 expr.val()*expr.val()))
258 expr.
dx(i)/(value_type(1)-expr.val()*expr.val()),
260 expr.val()*expr.val()))
277 expr.
dx(i)/(value_type(3)*cbrt(expr.val()*expr.val())),
288 template <
typename T,
typename ExprSpec,
bool is_simd>
294 template <
typename T>
296 public Expr< SafeSqrtOp<T,ExprSpecDefault> > {
299 typedef typename std::remove_cv<T>::type ExprT;
300 typedef typename ExprT::value_type value_type;
301 typedef typename ExprT::scalar_type scalar_type;
303 typedef ExprSpecDefault expr_spec_type;
306 explicit SafeSqrtOp(
const T& expr_) : expr(expr_) {}
309 int size()
const {
return expr.size(); }
312 bool hasFastAccess()
const {
313 return expr.hasFastAccess();
317 value_type
val()
const {
319 return sqrt(expr.val());
323 value_type
dx(
int i)
const {
326 expr.val() == value_type(0.0), value_type(0.0),
327 value_type(expr.dx(i)/(value_type(2)*
sqrt(expr.val()))));
334 expr.val() == value_type(0.0), value_type(0.0),
335 value_type(expr.fastAccessDx(i)/(value_type(2)*
sqrt(expr.val()))));
346 template <
typename T>
348 public Expr< SafeSqrtOp<T,ExprSpecDefault> > {
351 typedef typename std::remove_cv<T>::type ExprT;
352 typedef typename ExprT::value_type value_type;
353 typedef typename ExprT::scalar_type scalar_type;
355 typedef ExprSpecDefault expr_spec_type;
358 explicit SafeSqrtOp(
const T& expr_) : expr(expr_) {}
361 int size()
const {
return expr.size(); }
364 bool hasFastAccess()
const {
365 return expr.hasFastAccess();
369 value_type
val()
const {
371 return sqrt(expr.val());
375 value_type
dx(
int i)
const {
377 return expr.val() == value_type(0.0) ? value_type(0.0) :
378 value_type(expr.dx(i)/(value_type(2)*
sqrt(expr.val())));
384 return expr.val() == value_type(0.0) ? value_type(0.0) :
385 value_type(expr.fastAccessDx(i)/(value_type(2)*
sqrt(expr.val())));
393 template <
typename T>
395 SafeSqrtOp< typename Expr<T>::derived_type,
396 typename T::expr_spec_type >
399 typedef SafeSqrtOp< typename Expr<T>::derived_type,
400 typename T::expr_spec_type > expr_t;
402 return expr_t(expr.derived());
405 template <
typename T,
typename E>
406 struct ExprLevel< SafeSqrtOp< T,E > > {
407 static const unsigned value = ExprLevel<T>::value;
410 template <
typename T,
typename E>
411 struct IsFadExpr< SafeSqrtOp< T,E > > {
412 static const unsigned value =
true;
418 template <
typename T,
typename E>
420 static const bool value =
true;
423 template <
typename T,
typename E>
425 typedef typename BaseExprType<T>::type type;
428 template <
typename T,
typename E>
430 static const bool value =
431 IsSimdType< typename Fad::Exp::SafeSqrtOp< T,E >::scalar_type >::value;
436 #undef FAD_UNARYOP_MACRO
438 #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) \
443 template <typename T1, typename T2, \
444 bool is_const_T1, bool is_const_T2, \
445 typename ExprSpec > \
448 template <typename T1, typename T2> \
449 class OP< T1, T2, false, false, ExprSpecDefault > : \
450 public Expr< OP< T1, T2, false, false, ExprSpecDefault > > { \
453 typedef typename std::remove_cv<T1>::type ExprT1; \
454 typedef typename std::remove_cv<T2>::type ExprT2; \
455 typedef typename ExprT1::value_type value_type_1; \
456 typedef typename ExprT2::value_type value_type_2; \
457 typedef typename Sacado::Promote<value_type_1, \
458 value_type_2>::type value_type; \
460 typedef typename ExprT1::scalar_type scalar_type_1; \
461 typedef typename ExprT2::scalar_type scalar_type_2; \
462 typedef typename Sacado::Promote<scalar_type_1, \
463 scalar_type_2>::type scalar_type; \
465 typedef ExprSpecDefault expr_spec_type; \
467 KOKKOS_INLINE_FUNCTION \
468 OP(const T1& expr1_, const T2& expr2_) : \
469 expr1(expr1_), expr2(expr2_) {} \
471 KOKKOS_INLINE_FUNCTION \
473 const int sz1 = expr1.size(), sz2 = expr2.size(); \
474 return sz1 > sz2 ? sz1 : sz2; \
477 KOKKOS_INLINE_FUNCTION \
478 bool hasFastAccess() const { \
479 return expr1.hasFastAccess() && expr2.hasFastAccess(); \
482 KOKKOS_INLINE_FUNCTION \
483 value_type val() const { \
488 KOKKOS_INLINE_FUNCTION \
489 value_type dx(int i) const { \
491 const int sz1 = expr1.size(), sz2 = expr2.size(); \
492 if (sz1 > 0 && sz2 > 0) \
500 KOKKOS_INLINE_FUNCTION \
501 value_type fastAccessDx(int i) const { \
503 return FASTACCESSDX; \
513 template <typename T1, typename T2> \
514 class OP< T1, T2, false, true, ExprSpecDefault > \
515 : public Expr< OP< T1, T2, false, true, ExprSpecDefault > > { \
518 typedef typename std::remove_cv<T1>::type ExprT1; \
520 typedef typename ExprT1::value_type value_type; \
521 typedef typename ExprT1::scalar_type scalar_type; \
523 typedef ExprSpecDefault expr_spec_type; \
525 KOKKOS_INLINE_FUNCTION \
526 OP(const T1& expr1_, const ConstT& c_) : \
527 expr1(expr1_), c(c_) {} \
529 KOKKOS_INLINE_FUNCTION \
531 return expr1.size(); \
534 KOKKOS_INLINE_FUNCTION \
535 bool hasFastAccess() const { \
536 return expr1.hasFastAccess(); \
539 KOKKOS_INLINE_FUNCTION \
540 value_type val() const { \
542 return VAL_CONST_DX_2; \
545 KOKKOS_INLINE_FUNCTION \
546 value_type dx(int i) const { \
551 KOKKOS_INLINE_FUNCTION \
552 value_type fastAccessDx(int i) const { \
554 return CONST_FASTACCESSDX_2; \
563 template <typename T1, typename T2> \
564 class OP< T1, T2, true, false, ExprSpecDefault > \
565 : public Expr< OP< T1, T2, true, false, ExprSpecDefault > > { \
568 typedef typename std::remove_cv<T2>::type ExprT2; \
570 typedef typename ExprT2::value_type value_type; \
571 typedef typename ExprT2::scalar_type scalar_type; \
573 typedef ExprSpecDefault expr_spec_type; \
575 KOKKOS_INLINE_FUNCTION \
576 OP(const ConstT& c_, const T2& expr2_) : \
577 c(c_), expr2(expr2_) {} \
579 KOKKOS_INLINE_FUNCTION \
581 return expr2.size(); \
584 KOKKOS_INLINE_FUNCTION \
585 bool hasFastAccess() const { \
586 return expr2.hasFastAccess(); \
589 KOKKOS_INLINE_FUNCTION \
590 value_type val() const { \
592 return VAL_CONST_DX_1; \
595 KOKKOS_INLINE_FUNCTION \
596 value_type dx(int i) const { \
601 KOKKOS_INLINE_FUNCTION \
602 value_type fastAccessDx(int i) const { \
604 return CONST_FASTACCESSDX_1; \
613 template <typename T1, typename T2> \
614 KOKKOS_INLINE_FUNCTION \
615 SACADO_FAD_EXP_OP_ENABLE_EXPR_EXPR(OP) \
616 OPNAME (const T1& expr1, const T2& expr2) \
618 typedef OP< typename Expr<T1>::derived_type, \
619 typename Expr<T2>::derived_type, \
620 false, false, typename T1::expr_spec_type > expr_t; \
622 return expr_t(expr1.derived(), expr2.derived()); \
625 template <typename T> \
626 KOKKOS_INLINE_FUNCTION \
627 OP< typename T::value_type, typename Expr<T>::derived_type, \
628 true, false, typename T::expr_spec_type > \
629 OPNAME (const typename T::value_type& c, \
630 const Expr<T>& expr) \
632 typedef typename T::value_type ConstT; \
633 typedef OP< ConstT, typename Expr<T>::derived_type, \
634 true, false, typename T::expr_spec_type > expr_t; \
636 return expr_t(c, expr.derived()); \
639 template <typename T> \
640 KOKKOS_INLINE_FUNCTION \
641 OP< typename Expr<T>::derived_type, typename T::value_type, \
642 false, true, typename T::expr_spec_type > \
643 OPNAME (const Expr<T>& expr, \
644 const typename T::value_type& c) \
646 typedef typename T::value_type ConstT; \
647 typedef OP< typename Expr<T>::derived_type, ConstT, \
648 false, true, typename T::expr_spec_type > expr_t; \
650 return expr_t(expr.derived(), c); \
653 template <typename T> \
654 KOKKOS_INLINE_FUNCTION \
655 SACADO_FAD_EXP_OP_ENABLE_SCALAR_EXPR(OP) \
656 OPNAME (const typename T::scalar_type& c, \
657 const Expr<T>& expr) \
659 typedef typename T::scalar_type ConstT; \
660 typedef OP< ConstT, typename Expr<T>::derived_type, \
661 true, false, typename T::expr_spec_type > expr_t; \
663 return expr_t(c, expr.derived()); \
666 template <typename T> \
667 KOKKOS_INLINE_FUNCTION \
668 SACADO_FAD_EXP_OP_ENABLE_EXPR_SCALAR(OP) \
669 OPNAME (const Expr<T>& expr, \
670 const typename T::scalar_type& c) \
672 typedef typename T::scalar_type ConstT; \
673 typedef OP< typename Expr<T>::derived_type, ConstT, \
674 false, true, typename T::expr_spec_type > expr_t; \
676 return expr_t(expr.derived(), c); \
679 template <typename T1, typename T2, bool c1, bool c2, typename E> \
680 struct ExprLevel< OP< T1, T2, c1, c2, E > > { \
681 static constexpr unsigned value_1 = ExprLevel<T1>::value; \
682 static constexpr unsigned value_2 = ExprLevel<T2>::value; \
683 static constexpr unsigned value = \
684 value_1 >= value_2 ? value_1 : value_2; \
687 template <typename T1, typename T2, bool c1, bool c2, typename E> \
688 struct IsFadExpr< OP< T1, T2, c1, c2, E > > { \
689 static constexpr unsigned value = true; \
695 template <typename T1, typename T2, bool c1, bool c2, typename E> \
696 struct IsExpr< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
697 static constexpr bool value = true; \
700 template <typename T1, typename T2, bool c1, bool c2, typename E> \
701 struct BaseExprType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
702 typedef typename BaseExprType<T1>::type base_expr_1; \
703 typedef typename BaseExprType<T2>::type base_expr_2; \
704 typedef typename Sacado::Promote<base_expr_1, \
705 base_expr_2>::type type; \
708 template <typename T1, typename T2, bool c1, bool c2, typename E> \
709 struct IsSimdType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
710 static const bool value = \
711 IsSimdType< typename Fad::Exp::OP< T1, T2, c1, c2, E >::value_type >::value; \
720 expr1.val() + expr2.val(),
721 expr1.dx(i) + expr2.dx(i),
724 expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
729 expr2.fastAccessDx(i),
730 expr1.fastAccessDx(i))
734 expr1.val() - expr2.val(),
735 expr1.dx(i) - expr2.dx(i),
738 expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
743 -expr2.fastAccessDx(i),
744 expr1.fastAccessDx(i))
748 expr1.val() * expr2.val(),
749 expr1.val()*expr2.dx(i) + expr1.dx(i)*expr2.val(),
750 expr1.val()*expr2.dx(i),
751 expr1.dx(i)*expr2.val(),
752 expr1.val()*expr2.fastAccessDx(i) +
753 expr1.fastAccessDx(i)*expr2.val(),
758 c*expr2.fastAccessDx(i),
759 expr1.fastAccessDx(i)*
c)
763 expr1.val() / expr2.val(),
764 (expr1.dx(i)*expr2.val() - expr2.dx(i)*expr1.val()) /
765 (expr2.val()*expr2.val()),
766 -expr2.dx(i)*expr1.val() / (expr2.val()*expr2.val()),
767 expr1.dx(i)/expr2.val(),
768 (expr1.fastAccessDx(i)*expr2.val() -
769 expr2.fastAccessDx(i)*expr1.val()) /
770 (expr2.val()*expr2.val()),
773 -expr2.dx(i)*
c / (expr2.val()*expr2.val()),
775 -expr2.fastAccessDx(i)*
c / (expr2.val()*expr2.val()),
776 expr1.fastAccessDx(i)/
c)
780 atan2(expr1.val(), expr2.val()),
781 (expr2.val()*expr1.dx(i) - expr1.val()*expr2.dx(i))/
782 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
783 -expr1.val()*expr2.dx(i)/
784 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
785 expr2.val()*expr1.dx(i)/
786 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
787 (expr2.val()*expr1.fastAccessDx(i) - expr1.val()*expr2.fastAccessDx(i))/
788 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
791 (-
c*expr2.dx(i)) / (
c*
c + expr2.val()*expr2.val()),
792 (
c*expr1.dx(i))/ (expr1.val()*expr1.val() +
c*
c),
793 (-
c*expr2.fastAccessDx(i))/ (
c*
c + expr2.val()*expr2.val()),
794 (
c*expr1.fastAccessDx(i))/ (expr1.val()*expr1.val() +
c*
c))
814 if_then_else( expr1.val() >= expr2.val(), value_type(0.0), expr2.
dx(i) ),
815 if_then_else( expr1.val() >= expr2.val(), expr1.
dx(i), value_type(0.0) ),
818 if_then_else( expr1.val() >= c, expr1.val(), value_type(c) ),
826 if_then_else( expr1.val() <= expr2.val(), expr1.val(), expr2.val() ),
828 if_then_else( expr1.val() <= expr2.val(), value_type(0.0), expr2.
dx(i) ),
829 if_then_else( expr1.val() <= expr2.val(), expr1.
dx(i), value_type(0.0) ),
831 if_then_else( c <= expr2.val(), value_type(c), expr2.val() ),
832 if_then_else( expr1.val() <= c, expr1.val(), value_type(c) ),
847 template <
typename T1,
typename T2,
848 bool is_const_T1,
bool is_const_T2,
849 typename ExprSpec,
bool is_simd >
855 template <
typename T1,
typename T2>
856 class PowerOp< T1, T2, false, false, ExprSpecDefault, true > :
857 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault, true > > {
860 typedef typename std::remove_cv<T1>::type ExprT1;
861 typedef typename std::remove_cv<T2>::type ExprT2;
862 typedef typename ExprT1::value_type value_type_1;
863 typedef typename ExprT2::value_type value_type_2;
865 value_type_2>::type value_type;
867 typedef typename ExprT1::scalar_type scalar_type_1;
868 typedef typename ExprT2::scalar_type scalar_type_2;
870 scalar_type_2>::type scalar_type;
872 typedef ExprSpecDefault expr_spec_type;
875 PowerOp(
const T1& expr1_,
const T2& expr2_) :
876 expr1(expr1_), expr2(expr2_) {}
880 const int sz1 = expr1.size(), sz2 = expr2.size();
881 return sz1 > sz2 ? sz1 : sz2;
885 bool hasFastAccess()
const {
886 return expr1.hasFastAccess() && expr2.hasFastAccess();
890 value_type
val()
const {
892 return pow(expr1.val(), expr2.val());
896 value_type
dx(
int i)
const {
898 const int sz1 = expr1.size(), sz2 = expr2.size();
899 if (sz1 > 0 && sz2 > 0)
900 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())) );
904 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())) );
906 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())) );
912 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())) );
922 template <
typename T1,
typename T2>
923 class PowerOp< T1, T2, false, true, ExprSpecDefault, true >
924 :
public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault, true > > {
927 typedef typename std::remove_cv<T1>::type ExprT1;
929 typedef typename ExprT1::value_type value_type;
930 typedef typename ExprT1::scalar_type scalar_type;
932 typedef ExprSpecDefault expr_spec_type;
935 PowerOp(
const T1& expr1_,
const ConstT& c_) :
936 expr1(expr1_),
c(c_) {}
944 bool hasFastAccess()
const {
945 return expr1.hasFastAccess();
949 value_type
val()
const {
951 return pow(expr1.val(),
c);
955 value_type
dx(
int i)
const {
959 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)) );
967 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)) );
976 template <
typename T1,
typename T2>
977 class PowerOp< T1, T2, true, false, ExprSpecDefault, true >
978 :
public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault, true > > {
981 typedef typename std::remove_cv<T2>::type ExprT2;
983 typedef typename ExprT2::value_type value_type;
984 typedef typename ExprT2::scalar_type scalar_type;
986 typedef ExprSpecDefault expr_spec_type;
989 PowerOp(
const ConstT& c_,
const T2& expr2_) :
990 c(c_), expr2(expr2_) {}
998 bool hasFastAccess()
const {
999 return expr2.hasFastAccess();
1003 value_type
val()
const {
1005 return pow(c, expr2.val());
1009 value_type
dx(
int i)
const {
1011 return if_then_else( c == scalar_type(0.0), value_type(0.0), value_type(expr2.dx(i)*
log(c)*
pow(c,expr2.val())) );
1017 return if_then_else( c == scalar_type(0.0), value_type(0.0), value_type(expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val())) );
1030 template <
typename T1,
typename T2>
1031 class PowerOp< T1, T2, false, false, ExprSpecDefault, false > :
1032 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault, false > > {
1035 typedef typename std::remove_cv<T1>::type ExprT1;
1036 typedef typename std::remove_cv<T2>::type ExprT2;
1037 typedef typename ExprT1::value_type value_type_1;
1038 typedef typename ExprT2::value_type value_type_2;
1040 value_type_2>::type value_type;
1042 typedef typename ExprT1::scalar_type scalar_type_1;
1043 typedef typename ExprT2::scalar_type scalar_type_2;
1045 scalar_type_2>::type scalar_type;
1047 typedef ExprSpecDefault expr_spec_type;
1050 PowerOp(
const T1& expr1_,
const T2& expr2_) :
1051 expr1(expr1_), expr2(expr2_) {}
1055 const int sz1 = expr1.size(), sz2 = expr2.size();
1056 return sz1 > sz2 ? sz1 : sz2;
1060 bool hasFastAccess()
const {
1061 return expr1.hasFastAccess() && expr2.hasFastAccess();
1065 value_type
val()
const {
1067 return pow(expr1.val(), expr2.val());
1071 value_type
dx(
int i)
const {
1073 const int sz1 = expr1.size(), sz2 = expr2.size();
1074 if (sz1 > 0 && sz2 > 0)
1075 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()));
1079 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()));
1081 return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type(expr2.dx(i)*
log(expr1.val())*
pow(expr1.val(),expr2.val()));
1087 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()));
1097 template <
typename T1,
typename T2>
1098 class PowerOp< T1, T2, false, true, ExprSpecDefault, false >
1099 :
public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault, false > > {
1102 typedef typename std::remove_cv<T1>::type ExprT1;
1104 typedef typename ExprT1::value_type value_type;
1105 typedef typename ExprT1::scalar_type scalar_type;
1107 typedef ExprSpecDefault expr_spec_type;
1110 PowerOp(
const T1& expr1_,
const ConstT& c_) :
1111 expr1(expr1_),
c(c_) {}
1115 return expr1.size();
1119 bool hasFastAccess()
const {
1120 return expr1.hasFastAccess();
1124 value_type
val()
const {
1126 return pow(expr1.val(),
c);
1130 value_type
dx(
int i)
const {
1134 return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type(c*expr1.dx(i)/expr1.val()*
pow(expr1.val(),
c));
1142 return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type(c*expr1.fastAccessDx(i)/expr1.val()*
pow(expr1.val(),
c));
1151 template <
typename T1,
typename T2>
1152 class PowerOp< T1, T2, true, false, ExprSpecDefault, false >
1153 :
public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault, false > > {
1156 typedef typename std::remove_cv<T2>::type ExprT2;
1158 typedef typename ExprT2::value_type value_type;
1159 typedef typename ExprT2::scalar_type scalar_type;
1161 typedef ExprSpecDefault expr_spec_type;
1164 PowerOp(
const ConstT& c_,
const T2& expr2_) :
1165 c(c_), expr2(expr2_) {}
1169 return expr2.size();
1173 bool hasFastAccess()
const {
1174 return expr2.hasFastAccess();
1178 value_type
val()
const {
1180 return pow(c, expr2.val());
1184 value_type
dx(
int i)
const {
1186 return c == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.dx(i)*
log(c)*
pow(c,expr2.val()));
1192 return c == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val()));
1201 template <
typename T1,
typename T2>
1204 pow (
const T1& expr1,
const T2& expr2)
1206 typedef PowerOp< typename Expr<T1>::derived_type,
1207 typename Expr<T2>::derived_type,
1208 false,
false,
typename T1::expr_spec_type > expr_t;
1210 return expr_t(expr1.derived(), expr2.derived());
1213 template <
typename T>
1215 PowerOp< typename T::value_type, typename Expr<T>::derived_type,
1216 true,
false,
typename T::expr_spec_type >
1217 pow (
const typename T::value_type& c,
1218 const Expr<T>& expr)
1220 typedef typename T::value_type ConstT;
1221 typedef PowerOp< ConstT, typename Expr<T>::derived_type,
1222 true,
false,
typename T::expr_spec_type > expr_t;
1224 return expr_t(c, expr.derived());
1227 template <
typename T>
1229 PowerOp< typename Expr<T>::derived_type,
typename T::value_type,
1230 false,
true,
typename T::expr_spec_type >
1231 pow (
const Expr<T>& expr,
1232 const typename T::value_type& c)
1234 typedef typename T::value_type ConstT;
1235 typedef PowerOp< typename Expr<T>::derived_type, ConstT,
1236 false,
true,
typename T::expr_spec_type > expr_t;
1238 return expr_t(expr.derived(),
c);
1241 template <
typename T>
1244 pow (
const typename T::scalar_type& c,
1245 const Expr<T>& expr)
1247 typedef typename T::scalar_type ConstT;
1248 typedef PowerOp< ConstT, typename Expr<T>::derived_type,
1249 true,
false,
typename T::expr_spec_type > expr_t;
1251 return expr_t(c, expr.derived());
1254 template <
typename T>
1257 pow (
const Expr<T>& expr,
1258 const typename T::scalar_type& c)
1260 typedef typename T::scalar_type ConstT;
1261 typedef PowerOp< typename Expr<T>::derived_type, ConstT,
1262 false,
true,
typename T::expr_spec_type > expr_t;
1264 return expr_t(expr.derived(),
c);
1267 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1268 struct ExprLevel< PowerOp< T1, T2, c1, c2, E > > {
1269 static constexpr
unsigned value_1 = ExprLevel<T1>::value;
1270 static constexpr
unsigned value_2 = ExprLevel<T2>::value;
1271 static constexpr
unsigned value =
1272 value_1 >= value_2 ? value_1 : value_2;
1275 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1276 struct IsFadExpr< PowerOp< T1, T2, c1, c2, E > > {
1277 static constexpr
unsigned value =
true;
1283 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1284 struct IsExpr< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1285 static constexpr
bool value =
true;
1288 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1289 struct BaseExprType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1290 typedef typename BaseExprType<T1>::type base_expr_1;
1291 typedef typename BaseExprType<T2>::type base_expr_2;
1293 base_expr_2>::type type;
1296 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1297 struct IsSimdType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1298 static const bool value =
1299 IsSimdType< typename Fad::Exp::PowerOp< T1, T2, c1, c2, E >::value_type >::value;
1312 template <
typename CondT,
typename T1,
typename T2,
1313 bool is_const_T1,
bool is_const_T2,
1317 template <
typename CondT,
typename T1,
typename T2>
1319 public Expr< IfThenElseOp< CondT, T1, T2, false, false, ExprSpecDefault > > {
1323 typedef typename std::remove_cv<T1>::type
ExprT1;
1324 typedef typename std::remove_cv<T2>::type
ExprT2;
1339 cond(cond_), expr1(expr1_), expr2(expr2_) {}
1343 int sz1 = expr1.size(), sz2 = expr2.size();
1344 return sz1 > sz2 ? sz1 : sz2;
1349 return expr1.hasFastAccess() && expr2.hasFastAccess();
1364 return if_then_else( cond, expr1.fastAccessDx(i), expr2.fastAccessDx(i) );
1375 template <
typename CondT,
typename T1,
typename T2>
1377 public Expr< IfThenElseOp< CondT, T1, T2, false, true, ExprSpecDefault > > {
1381 typedef typename std::remove_cv<T1>::type
ExprT1;
1390 cond(cond_), expr1(expr1_),
c(c_) {}
1394 return expr1.size();
1399 return expr1.hasFastAccess();
1424 template <
typename CondT,
typename T1,
typename T2>
1426 public Expr< IfThenElseOp< CondT, T1, T2, true, false, ExprSpecDefault > > {
1430 typedef typename std::remove_cv<T2>::type
ExprT2;
1439 cond(cond_),
c(c_), expr2(expr2_) {}
1443 return expr2.size();
1448 return expr2.hasFastAccess();
1473 template <
typename CondT,
typename T1,
typename T2>
1481 typename T1::expr_spec_type >
1487 false,
false,
typename T1::expr_spec_type > expr_t;
1489 return expr_t(cond, expr1.derived(), expr2.derived());
1492 template <
typename CondT,
typename T>
1494 IfThenElseOp< CondT, typename T::value_type, typename Expr<T>::derived_type,
1495 true,
false,
typename T::expr_spec_type >
1499 typedef typename T::value_type ConstT;
1501 true,
false,
typename T::expr_spec_type > expr_t;
1503 return expr_t(cond, c, expr.
derived());
1506 template <
typename CondT,
typename T>
1508 IfThenElseOp< CondT, typename Expr<T>::derived_type,
typename T::value_type,
1509 false,
true,
typename T::expr_spec_type >
1511 const typename T::value_type&
c)
1513 typedef typename T::value_type ConstT;
1515 false,
true,
typename T::expr_spec_type > expr_t;
1517 return expr_t(cond, expr.
derived(),
c);
1520 template <
typename CondT,
typename T>
1524 typename T::scalar_type >,
1525 IfThenElseOp< CondT,
typename T::scalar_type,
1527 true,
false,
typename T::expr_spec_type >
1532 typedef typename T::scalar_type ConstT;
1534 true,
false,
typename T::expr_spec_type > expr_t;
1536 return expr_t(cond, c, expr.
derived());
1539 template <
typename CondT,
typename T>
1543 typename T::scalar_type >,
1544 IfThenElseOp< CondT, typename Expr<T>::derived_type,
1545 typename T::scalar_type,
1546 false,
true,
typename T::expr_spec_type >
1551 typedef typename T::scalar_type ConstT;
1553 false,
true,
typename T::expr_spec_type > expr_t;
1555 return expr_t(cond, expr.
derived(),
c);
1558 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1564 value_1 >= value_2 ? value_1 : value_2;
1567 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1576 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1578 struct IsExpr< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
1582 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1584 struct BaseExprType< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
1592 #undef FAD_BINARYOP_MACRO
1605 template <
typename T1,
typename T2 =
T1,
1609 template <
typename T1,
typename T2>
1611 typedef decltype( std::declval<T1>() == std::declval<T2>() ) type;
1618 #define FAD_RELOP_MACRO(OP) \
1619 namespace Sacado { \
1622 template <typename T1, typename T2> \
1623 KOKKOS_INLINE_FUNCTION \
1624 typename mpl::enable_if_c< \
1625 IsFadExpr<T1>::value && IsFadExpr<T2>::value && \
1626 ExprLevel<T1>::value == ExprLevel<T2>::value, \
1627 typename Impl::ConditionalReturnType<typename T1::value_type, \
1628 typename T2::value_type>::type \
1630 operator OP (const T1& expr1, const T2& expr2) \
1632 return expr1.derived().val() OP expr2.derived().val(); \
1635 template <typename T2> \
1636 KOKKOS_INLINE_FUNCTION \
1637 typename Impl::ConditionalReturnType<typename T2::value_type>::type \
1638 operator OP (const typename T2::value_type& a, \
1639 const Expr<T2>& expr2) \
1641 return a OP expr2.derived().val(); \
1644 template <typename T1> \
1645 KOKKOS_INLINE_FUNCTION \
1646 typename Impl::ConditionalReturnType<typename T1::value_type>::type \
1647 operator OP (const Expr<T1>& expr1, \
1648 const typename T1::value_type& b) \
1650 return expr1.derived().val() OP b; \
1667 #undef FAD_RELOP_MACRO
1674 template <
typename ExprT>
1678 return ! expr.
derived().val();
1692 template <
typename T>
1696 bool is_zero = (x.val() == 0.0);
1697 for (
int i=0; i<x.size(); i++)
1698 is_zero = is_zero && (x.dx(i) == 0.0);
1707 #define FAD_BOOL_MACRO(OP) \
1708 namespace Sacado { \
1711 template <typename T1, typename T2> \
1712 KOKKOS_INLINE_FUNCTION \
1714 operator OP (const Expr<T1>& expr1, \
1715 const Expr<T2>& expr2) \
1717 return toBool(expr1) OP toBool(expr2); \
1720 template <typename T2> \
1721 KOKKOS_INLINE_FUNCTION \
1723 operator OP (const typename Expr<T2>::value_type& a, \
1724 const Expr<T2>& expr2) \
1726 return a OP toBool(expr2); \
1729 template <typename T1> \
1730 KOKKOS_INLINE_FUNCTION \
1732 operator OP (const Expr<T1>& expr1, \
1733 const typename Expr<T1>::value_type& b) \
1735 return toBool(expr1) OP b; \
1744 #undef FAD_BOOL_MACRO
1753 template <
typename T>
1754 std::ostream& operator << (std::ostream& os, const Expr<T>& xx) {
1756 os << x.val() <<
" [";
1758 for (
int i=0; i< x.size(); i++) {
1759 os <<
" " << x.dx(i);
1771 #if defined(HAVE_SACADO_KOKKOSCORE)
1781 template <
typename S>
1783 void atomic_add(GeneralFad<S>* dst,
const GeneralFad<S>& x) {
1784 using Kokkos::atomic_add;
1786 const int xsz = x.size();
1787 const int sz = dst->size();
1793 "Sacado error: Fad resize within atomic_add() not supported!");
1795 if (xsz != sz && sz > 0 && xsz > 0)
1797 "Sacado error: Fad assignment of incompatiable sizes!");
1800 if (sz > 0 && xsz > 0) {
1805 atomic_add(&(dst->
val()), x.val());
1813 #endif // HAVE_SACADO_KOKKOSCORE
1815 #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
#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
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
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
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
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
#define KOKKOS_INLINE_FUNCTION
KOKKOS_INLINE_FUNCTION int size() const
KOKKOS_INLINE_FUNCTION T safe_sqrt(const T &x)
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()
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 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
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