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())),
219 expr.
dx(i)/(value_type(1)+expr.
val()*expr.
val()),
243 expr.
dx(i)/
sqrt((expr.
val()-value_type(1)) *
244 (expr.
val()+value_type(1))),
246 (expr.
val()+value_type(1))))
258 expr.
dx(i)/(value_type(1)-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>
407 static const unsigned value = ExprLevel<T>::value;
410 template <
typename T,
typename 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))
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>
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;
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>
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>
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>
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;
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>
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>
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) {
1802 atomic_add(&(dst->fastAccessDx(i)), x.fastAccessDx(i));
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
#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)
KOKKOS_INLINE_FUNCTION value_type dx(int i) const
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 bool hasFastAccess() const
Sacado::Promote< base_expr_1, base_expr_2 >::type type
KOKKOS_INLINE_FUNCTION value_type val() const
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
KOKKOS_INLINE_FUNCTION value_type dx(int i) const
KOKKOS_INLINE_FUNCTION int size() const
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 T safe_sqrt(const T &x)
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
#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)
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
#define SACADO_FAD_DERIV_LOOP(I, SZ)
KOKKOS_INLINE_FUNCTION int size() const
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 const derived_type & derived() const
Return derived object.
KOKKOS_INLINE_FUNCTION value_type val() const
KOKKOS_INLINE_FUNCTION value_type dx(int i) const
Meta-function for determining nesting with an expression.
KOKKOS_INLINE_FUNCTION int size() const
#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
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 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 value_type fastAccessDx(int i) const
std::remove_cv< T2 >::type ExprT2
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
KOKKOS_INLINE_FUNCTION value_type val() const
static constexpr unsigned value
KOKKOS_INLINE_FUNCTION value_type fastAccessDx(int i) const
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