31 #ifndef SACADO_FAD_EXP_OPS_HPP
32 #define SACADO_FAD_EXP_OPS_HPP
34 #include <type_traits>
42 #if defined(HAVE_SACADO_KOKKOSCORE)
43 #include "Kokkos_Atomic.hpp"
44 #include "impl/Kokkos_Error.hpp"
47 #define FAD_UNARYOP_MACRO(OPNAME,OP,USING,VALUE,DX,FASTACCESSDX) \
52 template <typename T, typename ExprSpec> \
55 template <typename T> \
56 class OP< T,ExprSpecDefault > : \
57 public Expr< OP<T,ExprSpecDefault> > { \
60 typedef typename std::remove_cv<T>::type ExprT; \
61 typedef typename ExprT::value_type value_type; \
62 typedef typename ExprT::scalar_type scalar_type; \
64 typedef ExprSpecDefault expr_spec_type; \
66 KOKKOS_INLINE_FUNCTION \
67 OP(const T& expr_) : expr(expr_) {} \
69 KOKKOS_INLINE_FUNCTION \
70 int size() const { return expr.size(); } \
72 KOKKOS_INLINE_FUNCTION \
73 bool hasFastAccess() const { \
74 return expr.hasFastAccess(); \
77 KOKKOS_INLINE_FUNCTION \
78 value_type val() const { \
83 KOKKOS_INLINE_FUNCTION \
84 value_type dx(int i) const { \
89 KOKKOS_INLINE_FUNCTION \
90 value_type fastAccessDx(int i) const { \
92 return FASTACCESSDX; \
100 template <typename T> \
101 KOKKOS_INLINE_FUNCTION \
102 OP< typename Expr<T>::derived_type, \
103 typename T::expr_spec_type > \
104 OPNAME (const Expr<T>& expr) \
106 typedef OP< typename Expr<T>::derived_type, \
107 typename T::expr_spec_type > expr_t; \
109 return expr_t(expr.derived()); \
112 template <typename T, typename E> \
113 struct ExprLevel< OP< T,E > > { \
114 static const unsigned value = ExprLevel<T>::value; \
117 template <typename T, typename E> \
118 struct IsFadExpr< OP< T,E > > { \
119 static const unsigned value = true; \
125 template <typename T, typename E> \
126 struct IsExpr< Fad::Exp::OP< T,E > > { \
127 static const bool value = true; \
130 template <typename T, typename E> \
131 struct BaseExprType< Fad::Exp::OP< T,E > > { \
132 typedef typename BaseExprType<T>::type type; \
135 template <typename T, typename E> \
136 struct IsSimdType< Fad::Exp::OP< T,E > > { \
137 static const bool value = \
138 IsSimdType< typename Fad::Exp::OP< T,E >::scalar_type >::value; \
148 expr.fastAccessDx(i))
154 -expr.fastAccessDx(i))
159 exp(expr.val())*expr.dx(i),
160 exp(expr.val())*expr.fastAccessDx(i))
165 expr.dx(i)/expr.val(),
166 expr.fastAccessDx(i)/expr.val())
171 expr.dx(i)/(
log(value_type(10))*expr.val()),
172 expr.fastAccessDx(i) / (
log(value_type(10))*expr.val()))
177 expr.
dx(i)/(value_type(2)* sqrt(expr.val())),
181 using std::cos; using std::
sin;,
183 -expr.
dx(i)* sin(expr.val()),
187 using std::cos; using std::sin;,
189 expr.
dx(i)* cos(expr.val()),
196 (value_type(1)+ tan(expr.val())* tan(expr.val())),
198 (value_type(1)+ tan(expr.val())* tan(expr.val())))
201 using std::acos; using std::sqrt;,
203 -expr.
dx(i)/ sqrt(value_type(1)-expr.val()*expr.val()),
205 sqrt(value_type(1)-expr.val()*expr.val()))
208 using std::asin; using std::sqrt;,
210 expr.
dx(i)/ sqrt(value_type(1)-expr.val()*expr.val()),
212 sqrt(value_type(1)-expr.val()*expr.val()))
217 expr.
dx(i)/(value_type(1)+expr.val()*expr.val()),
218 expr.
fastAccessDx(i)/(value_type(1)+expr.val()*expr.val()))
221 using std::cosh; using std::
sinh;,
223 expr.
dx(i)* sinh(expr.val()),
227 using std::cosh; using std::sinh;,
229 expr.
dx(i)* cosh(expr.val()),
233 using std::tanh; using std::cosh;,
235 expr.
dx(i)/( cosh(expr.val())* cosh(expr.val())),
237 ( cosh(expr.val())* cosh(expr.val())))
240 using std::acosh; using std::sqrt;,
242 expr.
dx(i)/ sqrt((expr.val()-value_type(1)) *
243 (expr.val()+value_type(1))),
245 (expr.val()+value_type(1))))
248 using std::asinh; using std::sqrt;,
250 expr.
dx(i)/ sqrt(value_type(1)+expr.val()*expr.val()),
252 expr.val()*expr.val()))
257 expr.
dx(i)/(value_type(1)-expr.val()*expr.val()),
259 expr.val()*expr.val()))
276 expr.
dx(i)/(value_type(3)*cbrt(expr.val()*expr.val())),
277 expr.
fastAccessDx(i)/(value_type(3)*cbrt(expr.val()*expr.val())))
279 #undef FAD_UNARYOP_MACRO
281 #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) \
286 template <typename T1, typename T2, \
287 bool is_const_T1, bool is_const_T2, \
288 typename ExprSpec > \
291 template <typename T1, typename T2> \
292 class OP< T1, T2, false, false, ExprSpecDefault > : \
293 public Expr< OP< T1, T2, false, false, ExprSpecDefault > > { \
296 typedef typename std::remove_cv<T1>::type ExprT1; \
297 typedef typename std::remove_cv<T2>::type ExprT2; \
298 typedef typename ExprT1::value_type value_type_1; \
299 typedef typename ExprT2::value_type value_type_2; \
300 typedef typename Sacado::Promote<value_type_1, \
301 value_type_2>::type value_type; \
303 typedef typename ExprT1::scalar_type scalar_type_1; \
304 typedef typename ExprT2::scalar_type scalar_type_2; \
305 typedef typename Sacado::Promote<scalar_type_1, \
306 scalar_type_2>::type scalar_type; \
308 typedef ExprSpecDefault expr_spec_type; \
310 KOKKOS_INLINE_FUNCTION \
311 OP(const T1& expr1_, const T2& expr2_) : \
312 expr1(expr1_), expr2(expr2_) {} \
314 KOKKOS_INLINE_FUNCTION \
316 const int sz1 = expr1.size(), sz2 = expr2.size(); \
317 return sz1 > sz2 ? sz1 : sz2; \
320 KOKKOS_INLINE_FUNCTION \
321 bool hasFastAccess() const { \
322 return expr1.hasFastAccess() && expr2.hasFastAccess(); \
325 KOKKOS_INLINE_FUNCTION \
326 value_type val() const { \
331 KOKKOS_INLINE_FUNCTION \
332 value_type dx(int i) const { \
334 const int sz1 = expr1.size(), sz2 = expr2.size(); \
335 if (sz1 > 0 && sz2 > 0) \
343 KOKKOS_INLINE_FUNCTION \
344 value_type fastAccessDx(int i) const { \
346 return FASTACCESSDX; \
356 template <typename T1, typename T2> \
357 class OP< T1, T2, false, true, ExprSpecDefault > \
358 : public Expr< OP< T1, T2, false, true, ExprSpecDefault > > { \
361 typedef typename std::remove_cv<T1>::type ExprT1; \
363 typedef typename ExprT1::value_type value_type; \
364 typedef typename ExprT1::scalar_type scalar_type; \
366 typedef ExprSpecDefault expr_spec_type; \
368 KOKKOS_INLINE_FUNCTION \
369 OP(const T1& expr1_, const ConstT& c_) : \
370 expr1(expr1_), c(c_) {} \
372 KOKKOS_INLINE_FUNCTION \
374 return expr1.size(); \
377 KOKKOS_INLINE_FUNCTION \
378 bool hasFastAccess() const { \
379 return expr1.hasFastAccess(); \
382 KOKKOS_INLINE_FUNCTION \
383 value_type val() const { \
385 return VAL_CONST_DX_2; \
388 KOKKOS_INLINE_FUNCTION \
389 value_type dx(int i) const { \
394 KOKKOS_INLINE_FUNCTION \
395 value_type fastAccessDx(int i) const { \
397 return CONST_FASTACCESSDX_2; \
406 template <typename T1, typename T2> \
407 class OP< T1, T2, true, false, ExprSpecDefault > \
408 : public Expr< OP< T1, T2, true, false, ExprSpecDefault > > { \
411 typedef typename std::remove_cv<T2>::type ExprT2; \
413 typedef typename ExprT2::value_type value_type; \
414 typedef typename ExprT2::scalar_type scalar_type; \
416 typedef ExprSpecDefault expr_spec_type; \
418 KOKKOS_INLINE_FUNCTION \
419 OP(const ConstT& c_, const T2& expr2_) : \
420 c(c_), expr2(expr2_) {} \
422 KOKKOS_INLINE_FUNCTION \
424 return expr2.size(); \
427 KOKKOS_INLINE_FUNCTION \
428 bool hasFastAccess() const { \
429 return expr2.hasFastAccess(); \
432 KOKKOS_INLINE_FUNCTION \
433 value_type val() const { \
435 return VAL_CONST_DX_1; \
438 KOKKOS_INLINE_FUNCTION \
439 value_type dx(int i) const { \
444 KOKKOS_INLINE_FUNCTION \
445 value_type fastAccessDx(int i) const { \
447 return CONST_FASTACCESSDX_1; \
456 template <typename T1, typename T2> \
457 KOKKOS_INLINE_FUNCTION \
458 SACADO_FAD_EXP_OP_ENABLE_EXPR_EXPR(OP) \
459 OPNAME (const T1& expr1, const T2& expr2) \
461 typedef OP< typename Expr<T1>::derived_type, \
462 typename Expr<T2>::derived_type, \
463 false, false, typename T1::expr_spec_type > expr_t; \
465 return expr_t(expr1.derived(), expr2.derived()); \
468 template <typename T> \
469 KOKKOS_INLINE_FUNCTION \
470 OP< typename T::value_type, typename Expr<T>::derived_type, \
471 true, false, typename T::expr_spec_type > \
472 OPNAME (const typename T::value_type& c, \
473 const Expr<T>& expr) \
475 typedef typename T::value_type ConstT; \
476 typedef OP< ConstT, typename Expr<T>::derived_type, \
477 true, false, typename T::expr_spec_type > expr_t; \
479 return expr_t(c, expr.derived()); \
482 template <typename T> \
483 KOKKOS_INLINE_FUNCTION \
484 OP< typename Expr<T>::derived_type, typename T::value_type, \
485 false, true, typename T::expr_spec_type > \
486 OPNAME (const Expr<T>& expr, \
487 const typename T::value_type& c) \
489 typedef typename T::value_type ConstT; \
490 typedef OP< typename Expr<T>::derived_type, ConstT, \
491 false, true, typename T::expr_spec_type > expr_t; \
493 return expr_t(expr.derived(), c); \
496 template <typename T> \
497 KOKKOS_INLINE_FUNCTION \
498 SACADO_FAD_EXP_OP_ENABLE_SCALAR_EXPR(OP) \
499 OPNAME (const typename T::scalar_type& c, \
500 const Expr<T>& expr) \
502 typedef typename T::scalar_type ConstT; \
503 typedef OP< ConstT, typename Expr<T>::derived_type, \
504 true, false, typename T::expr_spec_type > expr_t; \
506 return expr_t(c, expr.derived()); \
509 template <typename T> \
510 KOKKOS_INLINE_FUNCTION \
511 SACADO_FAD_EXP_OP_ENABLE_EXPR_SCALAR(OP) \
512 OPNAME (const Expr<T>& expr, \
513 const typename T::scalar_type& c) \
515 typedef typename T::scalar_type ConstT; \
516 typedef OP< typename Expr<T>::derived_type, ConstT, \
517 false, true, typename T::expr_spec_type > expr_t; \
519 return expr_t(expr.derived(), c); \
522 template <typename T1, typename T2, bool c1, bool c2, typename E> \
523 struct ExprLevel< OP< T1, T2, c1, c2, E > > { \
524 static constexpr unsigned value_1 = ExprLevel<T1>::value; \
525 static constexpr unsigned value_2 = ExprLevel<T2>::value; \
526 static constexpr unsigned value = \
527 value_1 >= value_2 ? value_1 : value_2; \
530 template <typename T1, typename T2, bool c1, bool c2, typename E> \
531 struct IsFadExpr< OP< T1, T2, c1, c2, E > > { \
532 static constexpr unsigned value = true; \
538 template <typename T1, typename T2, bool c1, bool c2, typename E> \
539 struct IsExpr< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
540 static constexpr bool value = true; \
543 template <typename T1, typename T2, bool c1, bool c2, typename E> \
544 struct BaseExprType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
545 typedef typename BaseExprType<T1>::type base_expr_1; \
546 typedef typename BaseExprType<T2>::type base_expr_2; \
547 typedef typename Sacado::Promote<base_expr_1, \
548 base_expr_2>::type type; \
551 template <typename T1, typename T2, bool c1, bool c2, typename E> \
552 struct IsSimdType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
553 static const bool value = \
554 IsSimdType< typename Fad::Exp::OP< T1, T2, c1, c2, E >::value_type >::value; \
563 expr1.val() + expr2.val(),
564 expr1.dx(i) + expr2.dx(i),
567 expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
572 expr2.fastAccessDx(i),
573 expr1.fastAccessDx(i))
577 expr1.val() - expr2.val(),
578 expr1.dx(i) - expr2.dx(i),
581 expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
586 -expr2.fastAccessDx(i),
587 expr1.fastAccessDx(i))
591 expr1.val() * expr2.val(),
592 expr1.val()*expr2.dx(i) + expr1.dx(i)*expr2.val(),
593 expr1.val()*expr2.dx(i),
594 expr1.dx(i)*expr2.val(),
595 expr1.val()*expr2.fastAccessDx(i) +
596 expr1.fastAccessDx(i)*expr2.val(),
601 c*expr2.fastAccessDx(i),
602 expr1.fastAccessDx(i)*
c)
606 expr1.val() / expr2.val(),
607 (expr1.dx(i)*expr2.val() - expr2.dx(i)*expr1.val()) /
608 (expr2.val()*expr2.val()),
609 -expr2.dx(i)*expr1.val() / (expr2.val()*expr2.val()),
610 expr1.dx(i)/expr2.val(),
611 (expr1.fastAccessDx(i)*expr2.val() -
612 expr2.fastAccessDx(i)*expr1.val()) /
613 (expr2.val()*expr2.val()),
616 -expr2.dx(i)*
c / (expr2.val()*expr2.val()),
618 -expr2.fastAccessDx(i)*
c / (expr2.val()*expr2.val()),
619 expr1.fastAccessDx(i)/
c)
623 atan2(expr1.val(), expr2.val()),
624 (expr2.val()*expr1.dx(i) - expr1.val()*expr2.dx(i))/
625 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
626 -expr1.val()*expr2.dx(i)/
627 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
628 expr2.val()*expr1.dx(i)/
629 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
630 (expr2.val()*expr1.fastAccessDx(i) - expr1.val()*expr2.fastAccessDx(i))/
631 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
634 (-
c*expr2.dx(i)) / (
c*
c + expr2.val()*expr2.val()),
635 (
c*expr1.dx(i))/ (expr1.val()*expr1.val() +
c*
c),
636 (-
c*expr2.fastAccessDx(i))/ (
c*
c + expr2.val()*expr2.val()),
637 (
c*expr1.fastAccessDx(i))/ (expr1.val()*expr1.val() +
c*
c))
655 if_then_else( expr1.val() >= expr2.val(), expr1.val(), expr2.val() ),
657 if_then_else( expr1.val() >= expr2.val(), value_type(0.0), expr2.
dx(i) ),
658 if_then_else( expr1.val() >= expr2.val(), expr1.
dx(i), value_type(0.0) ),
661 if_then_else( expr1.val() >= c, expr1.val(), value_type(c) ),
669 if_then_else( expr1.val() <= expr2.val(), expr1.val(), expr2.val() ),
671 if_then_else( expr1.val() <= expr2.val(), value_type(0.0), expr2.
dx(i) ),
672 if_then_else( expr1.val() <= expr2.val(), expr1.
dx(i), value_type(0.0) ),
674 if_then_else( c <= expr2.val(), value_type(c), expr2.val() ),
675 if_then_else( expr1.val() <= c, expr1.val(), value_type(c) ),
690 template <
typename T1,
typename T2,
691 bool is_const_T1,
bool is_const_T2,
692 typename ExprSpec,
bool is_simd >
698 template <
typename T1,
typename T2>
699 class PowerOp< T1, T2, false, false, ExprSpecDefault, true > :
700 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault, true > > {
703 typedef typename std::remove_cv<T1>::type ExprT1;
704 typedef typename std::remove_cv<T2>::type ExprT2;
705 typedef typename ExprT1::value_type value_type_1;
706 typedef typename ExprT2::value_type value_type_2;
708 value_type_2>::type value_type;
710 typedef typename ExprT1::scalar_type scalar_type_1;
711 typedef typename ExprT2::scalar_type scalar_type_2;
713 scalar_type_2>::type scalar_type;
715 typedef ExprSpecDefault expr_spec_type;
718 PowerOp(
const T1& expr1_,
const T2& expr2_) :
719 expr1(expr1_), expr2(expr2_) {}
723 const int sz1 = expr1.size(), sz2 = expr2.size();
724 return sz1 > sz2 ? sz1 : sz2;
728 bool hasFastAccess()
const {
729 return expr1.hasFastAccess() && expr2.hasFastAccess();
733 value_type
val()
const {
735 return pow(expr1.val(), expr2.val());
739 value_type
dx(
int i)
const {
741 const int sz1 = expr1.size(), sz2 = expr2.size();
742 if (sz1 > 0 && sz2 > 0)
743 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())) );
747 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())) );
749 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())) );
755 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())) );
765 template <
typename T1,
typename T2>
766 class PowerOp< T1, T2, false, true, ExprSpecDefault, true >
767 :
public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault, true > > {
770 typedef typename std::remove_cv<T1>::type ExprT1;
772 typedef typename ExprT1::value_type value_type;
773 typedef typename ExprT1::scalar_type scalar_type;
775 typedef ExprSpecDefault expr_spec_type;
778 PowerOp(
const T1& expr1_,
const ConstT& c_) :
779 expr1(expr1_),
c(c_) {}
787 bool hasFastAccess()
const {
788 return expr1.hasFastAccess();
792 value_type
val()
const {
794 return pow(expr1.val(),
c);
798 value_type
dx(
int i)
const {
802 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)) );
810 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)) );
819 template <
typename T1,
typename T2>
820 class PowerOp< T1, T2, true, false, ExprSpecDefault, true >
821 :
public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault, true > > {
824 typedef typename std::remove_cv<T2>::type ExprT2;
826 typedef typename ExprT2::value_type value_type;
827 typedef typename ExprT2::scalar_type scalar_type;
829 typedef ExprSpecDefault expr_spec_type;
832 PowerOp(
const ConstT& c_,
const T2& expr2_) :
833 c(c_), expr2(expr2_) {}
841 bool hasFastAccess()
const {
842 return expr2.hasFastAccess();
846 value_type
val()
const {
848 return pow(c, expr2.val());
852 value_type
dx(
int i)
const {
854 return if_then_else( c == scalar_type(0.0), value_type(0.0), value_type(expr2.dx(i)*
log(c)*
pow(c,expr2.val())) );
860 return if_then_else( c == scalar_type(0.0), value_type(0.0), value_type(expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val())) );
873 template <
typename T1,
typename T2>
874 class PowerOp< T1, T2, false, false, ExprSpecDefault, false > :
875 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault, false > > {
878 typedef typename std::remove_cv<T1>::type ExprT1;
879 typedef typename std::remove_cv<T2>::type ExprT2;
880 typedef typename ExprT1::value_type value_type_1;
881 typedef typename ExprT2::value_type value_type_2;
883 value_type_2>::type value_type;
885 typedef typename ExprT1::scalar_type scalar_type_1;
886 typedef typename ExprT2::scalar_type scalar_type_2;
888 scalar_type_2>::type scalar_type;
890 typedef ExprSpecDefault expr_spec_type;
893 PowerOp(
const T1& expr1_,
const T2& expr2_) :
894 expr1(expr1_), expr2(expr2_) {}
898 const int sz1 = expr1.size(), sz2 = expr2.size();
899 return sz1 > sz2 ? sz1 : sz2;
903 bool hasFastAccess()
const {
904 return expr1.hasFastAccess() && expr2.hasFastAccess();
908 value_type
val()
const {
910 return pow(expr1.val(), expr2.val());
914 value_type
dx(
int i)
const {
916 const int sz1 = expr1.size(), sz2 = expr2.size();
917 if (sz1 > 0 && sz2 > 0)
918 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()));
922 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()));
924 return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type(expr2.dx(i)*
log(expr1.val())*
pow(expr1.val(),expr2.val()));
930 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()));
940 template <
typename T1,
typename T2>
941 class PowerOp< T1, T2, false, true, ExprSpecDefault, false >
942 :
public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault, false > > {
945 typedef typename std::remove_cv<T1>::type ExprT1;
947 typedef typename ExprT1::value_type value_type;
948 typedef typename ExprT1::scalar_type scalar_type;
950 typedef ExprSpecDefault expr_spec_type;
953 PowerOp(
const T1& expr1_,
const ConstT& c_) :
954 expr1(expr1_),
c(c_) {}
962 bool hasFastAccess()
const {
963 return expr1.hasFastAccess();
967 value_type
val()
const {
969 return pow(expr1.val(),
c);
973 value_type
dx(
int i)
const {
977 return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type(c*expr1.dx(i)/expr1.val()*
pow(expr1.val(),
c));
985 return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type(c*expr1.fastAccessDx(i)/expr1.val()*
pow(expr1.val(),
c));
994 template <
typename T1,
typename T2>
995 class PowerOp< T1, T2, true, false, ExprSpecDefault, false >
996 :
public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault, false > > {
999 typedef typename std::remove_cv<T2>::type ExprT2;
1001 typedef typename ExprT2::value_type value_type;
1002 typedef typename ExprT2::scalar_type scalar_type;
1004 typedef ExprSpecDefault expr_spec_type;
1007 PowerOp(
const ConstT& c_,
const T2& expr2_) :
1008 c(c_), expr2(expr2_) {}
1012 return expr2.size();
1016 bool hasFastAccess()
const {
1017 return expr2.hasFastAccess();
1021 value_type
val()
const {
1023 return pow(c, expr2.val());
1027 value_type
dx(
int i)
const {
1029 return c == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.dx(i)*
log(c)*
pow(c,expr2.val()));
1035 return c == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val()));
1044 template <
typename T1,
typename T2>
1047 pow (
const T1& expr1,
const T2& expr2)
1049 typedef PowerOp< typename Expr<T1>::derived_type,
1050 typename Expr<T2>::derived_type,
1051 false,
false,
typename T1::expr_spec_type > expr_t;
1053 return expr_t(expr1.derived(), expr2.derived());
1056 template <
typename T>
1058 PowerOp< typename T::value_type, typename Expr<T>::derived_type,
1059 true,
false,
typename T::expr_spec_type >
1060 pow (
const typename T::value_type& c,
1061 const Expr<T>& expr)
1063 typedef typename T::value_type ConstT;
1064 typedef PowerOp< ConstT, typename Expr<T>::derived_type,
1065 true,
false,
typename T::expr_spec_type > expr_t;
1067 return expr_t(c, expr.derived());
1070 template <
typename T>
1072 PowerOp< typename Expr<T>::derived_type,
typename T::value_type,
1073 false,
true,
typename T::expr_spec_type >
1074 pow (
const Expr<T>& expr,
1075 const typename T::value_type& c)
1077 typedef typename T::value_type ConstT;
1078 typedef PowerOp< typename Expr<T>::derived_type, ConstT,
1079 false,
true,
typename T::expr_spec_type > expr_t;
1081 return expr_t(expr.derived(),
c);
1084 template <
typename T>
1087 pow (
const typename T::scalar_type& c,
1088 const Expr<T>& expr)
1090 typedef typename T::scalar_type ConstT;
1091 typedef PowerOp< ConstT, typename Expr<T>::derived_type,
1092 true,
false,
typename T::expr_spec_type > expr_t;
1094 return expr_t(c, expr.derived());
1097 template <
typename T>
1100 pow (
const Expr<T>& expr,
1101 const typename T::scalar_type& c)
1103 typedef typename T::scalar_type ConstT;
1104 typedef PowerOp< typename Expr<T>::derived_type, ConstT,
1105 false,
true,
typename T::expr_spec_type > expr_t;
1107 return expr_t(expr.derived(),
c);
1110 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1111 struct ExprLevel< PowerOp< T1, T2, c1, c2, E > > {
1112 static constexpr
unsigned value_1 = ExprLevel<T1>::value;
1113 static constexpr
unsigned value_2 = ExprLevel<T2>::value;
1114 static constexpr
unsigned value =
1115 value_1 >= value_2 ? value_1 : value_2;
1118 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1119 struct IsFadExpr< PowerOp< T1, T2, c1, c2, E > > {
1120 static constexpr
unsigned value =
true;
1126 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1127 struct IsExpr< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1128 static constexpr
bool value =
true;
1131 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1132 struct BaseExprType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1133 typedef typename BaseExprType<T1>::type base_expr_1;
1134 typedef typename BaseExprType<T2>::type base_expr_2;
1136 base_expr_2>::type type;
1139 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1140 struct IsSimdType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1141 static const bool value =
1142 IsSimdType< typename Fad::Exp::PowerOp< T1, T2, c1, c2, E >::value_type >::value;
1155 template <
typename CondT,
typename T1,
typename T2,
1156 bool is_const_T1,
bool is_const_T2,
1160 template <
typename CondT,
typename T1,
typename T2>
1162 public Expr< IfThenElseOp< CondT, T1, T2, false, false, ExprSpecDefault > > {
1166 typedef typename std::remove_cv<T1>::type
ExprT1;
1167 typedef typename std::remove_cv<T2>::type
ExprT2;
1182 cond(cond_), expr1(expr1_), expr2(expr2_) {}
1186 int sz1 = expr1.size(), sz2 = expr2.size();
1187 return sz1 > sz2 ? sz1 : sz2;
1192 return expr1.hasFastAccess() && expr2.hasFastAccess();
1201 value_type
dx(
int i)
const {
1207 return if_then_else( cond, expr1.fastAccessDx(i), expr2.fastAccessDx(i) );
1218 template <
typename CondT,
typename T1,
typename T2>
1220 public Expr< IfThenElseOp< CondT, T1, T2, false, true, ExprSpecDefault > > {
1224 typedef typename std::remove_cv<T1>::type
ExprT1;
1233 cond(cond_), expr1(expr1_),
c(c_) {}
1237 return expr1.size();
1242 return expr1.hasFastAccess();
1251 value_type
dx(
int i)
const {
1252 return if_then_else( cond, expr1.dx(i), value_type(0.0) );
1257 return if_then_else( cond, expr1.fastAccessDx(i), value_type(0.0) );
1267 template <
typename CondT,
typename T1,
typename T2>
1269 public Expr< IfThenElseOp< CondT, T1, T2, true, false, ExprSpecDefault > > {
1273 typedef typename std::remove_cv<T2>::type
ExprT2;
1282 cond(cond_),
c(c_), expr2(expr2_) {}
1286 return expr2.size();
1291 return expr2.hasFastAccess();
1300 value_type
dx(
int i)
const {
1301 return if_then_else( cond, value_type(0.0), expr2.dx(i) );
1306 return if_then_else( cond, value_type(0.0), expr2.fastAccessDx(i) );
1316 template <
typename CondT,
typename T1,
typename T2>
1324 typename T1::expr_spec_type >
1330 false,
false,
typename T1::expr_spec_type > expr_t;
1332 return expr_t(cond, expr1.derived(), expr2.derived());
1335 template <
typename CondT,
typename T>
1337 IfThenElseOp< CondT, typename T::value_type, typename Expr<T>::derived_type,
1338 true,
false,
typename T::expr_spec_type >
1342 typedef typename T::value_type ConstT;
1344 true,
false,
typename T::expr_spec_type > expr_t;
1346 return expr_t(cond, c, expr.
derived());
1349 template <
typename CondT,
typename T>
1351 IfThenElseOp< CondT, typename Expr<T>::derived_type,
typename T::value_type,
1352 false,
true,
typename T::expr_spec_type >
1354 const typename T::value_type&
c)
1356 typedef typename T::value_type ConstT;
1358 false,
true,
typename T::expr_spec_type > expr_t;
1360 return expr_t(cond, expr.
derived(),
c);
1363 template <
typename CondT,
typename T>
1367 typename T::scalar_type >,
1368 IfThenElseOp< CondT,
typename T::scalar_type,
1370 true,
false,
typename T::expr_spec_type >
1375 typedef typename T::scalar_type ConstT;
1377 true,
false,
typename T::expr_spec_type > expr_t;
1379 return expr_t(cond, c, expr.
derived());
1382 template <
typename CondT,
typename T>
1386 typename T::scalar_type >,
1387 IfThenElseOp< CondT, typename Expr<T>::derived_type,
1388 typename T::scalar_type,
1389 false,
true,
typename T::expr_spec_type >
1394 typedef typename T::scalar_type ConstT;
1396 false,
true,
typename T::expr_spec_type > expr_t;
1398 return expr_t(cond, expr.
derived(),
c);
1401 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1407 value_1 >= value_2 ? value_1 : value_2;
1410 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1419 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1421 struct IsExpr< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
1425 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1427 struct BaseExprType< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
1435 #undef FAD_BINARYOP_MACRO
1442 template <
typename T1,
typename T2 = T1>
1444 typedef decltype( std::declval<T1>() == std::declval<T2>() )
type;
1450 #define FAD_RELOP_MACRO(OP) \
1451 namespace Sacado { \
1454 template <typename T1, typename T2> \
1455 KOKKOS_INLINE_FUNCTION \
1456 typename mpl::enable_if_c< \
1457 IsFadExpr<T1>::value && IsFadExpr<T2>::value && \
1458 ExprLevel<T1>::value == ExprLevel<T2>::value, \
1459 typename ConditionalReturnType<typename T1::value_type, \
1460 typename T2::value_type>::type \
1462 operator OP (const T1& expr1, const T2& expr2) \
1464 return expr1.derived().val() OP expr2.derived().val(); \
1467 template <typename T2> \
1468 KOKKOS_INLINE_FUNCTION \
1469 typename ConditionalReturnType<typename T2::value_type>::type \
1470 operator OP (const typename T2::value_type& a, \
1471 const Expr<T2>& expr2) \
1473 return a OP expr2.derived().val(); \
1476 template <typename T1> \
1477 KOKKOS_INLINE_FUNCTION \
1478 typename ConditionalReturnType<typename T1::value_type>::type \
1479 operator OP (const Expr<T1>& expr1, \
1480 const typename T1::value_type& b) \
1482 return expr1.derived().val() OP b; \
1499 #undef FAD_RELOP_MACRO
1506 template <
typename ExprT>
1510 return ! expr.
derived().val();
1524 template <
typename T>
1528 bool is_zero = (x.val() == 0.0);
1529 for (
int i=0; i<x.size(); i++)
1530 is_zero = is_zero && (x.dx(i) == 0.0);
1539 #define FAD_BOOL_MACRO(OP) \
1540 namespace Sacado { \
1543 template <typename T1, typename T2> \
1544 KOKKOS_INLINE_FUNCTION \
1546 operator OP (const Expr<T1>& expr1, \
1547 const Expr<T2>& expr2) \
1549 return toBool(expr1) OP toBool(expr2); \
1552 template <typename T2> \
1553 KOKKOS_INLINE_FUNCTION \
1555 operator OP (const typename Expr<T2>::value_type& a, \
1556 const Expr<T2>& expr2) \
1558 return a OP toBool(expr2); \
1561 template <typename T1> \
1562 KOKKOS_INLINE_FUNCTION \
1564 operator OP (const Expr<T1>& expr1, \
1565 const typename Expr<T1>::value_type& b) \
1567 return toBool(expr1) OP b; \
1576 #undef FAD_BOOL_MACRO
1585 template <
typename T>
1586 std::ostream& operator << (std::ostream& os, const Expr<T>& xx) {
1588 os << x.val() <<
" [";
1590 for (
int i=0; i< x.size(); i++) {
1591 os <<
" " << x.dx(i);
1603 #if defined(HAVE_SACADO_KOKKOSCORE)
1613 template <
typename S>
1615 void atomic_add(GeneralFad<S>* dst,
const GeneralFad<S>& x) {
1616 using Kokkos::atomic_add;
1618 const int xsz = x.size();
1619 const int sz = dst->size();
1625 "Sacado error: Fad resize within atomic_add() not supported!");
1627 if (xsz != sz && sz > 0 && xsz > 0)
1629 "Sacado error: Fad assignment of incompatiable sizes!");
1632 if (sz > 0 && xsz > 0) {
1637 atomic_add(&(dst->val()), x.val());
1645 #endif // HAVE_SACADO_KOKKOSCORE
1647 #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)
decltype(std::declval< T1 >()==std::declval< T2 >()) typedef type
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