31 #ifndef SACADO_FAD_EXP_OPS_HPP
32 #define SACADO_FAD_EXP_OPS_HPP
34 #include <type_traits>
44 #if defined(HAVE_SACADO_KOKKOS)
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 SACADO_INLINE_FUNCTION \
69 explicit OP(const T& expr_) : expr(expr_) {} \
71 SACADO_INLINE_FUNCTION \
72 int size() const { return expr.size(); } \
74 SACADO_INLINE_FUNCTION \
75 bool hasFastAccess() const { \
76 return expr.hasFastAccess(); \
79 SACADO_INLINE_FUNCTION \
80 value_type val() const { \
85 SACADO_INLINE_FUNCTION \
86 value_type dx(int i) const { \
91 SACADO_INLINE_FUNCTION \
92 value_type fastAccessDx(int i) const { \
94 return FASTACCESSDX; \
102 template <typename T> \
103 SACADO_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; \
143 template <typename T, typename E> \
144 struct ValueType< Fad::Exp::OP< T,E > > { \
145 typedef typename Fad::Exp::OP< T,E >::value_type type; \
148 template <typename T, typename E> \
149 struct ScalarType< Fad::Exp::OP< T,E > > { \
150 typedef typename Fad::Exp::OP< T,E >::scalar_type type; \
160 expr.fastAccessDx(
i))
166 -expr.fastAccessDx(
i))
171 exp(expr.val())*expr.dx(
i),
172 exp(expr.val())*expr.fastAccessDx(
i))
177 expr.dx(
i)/expr.val(),
178 expr.fastAccessDx(
i)/expr.val())
183 expr.dx(
i)/(
log(value_type(10))*expr.val()),
184 expr.fastAccessDx(
i) / (
log(value_type(10))*expr.val()))
189 expr.
dx(
i)/(value_type(2)* sqrt(expr.val())),
193 using std::cos; using std::
sin;,
195 -expr.
dx(
i)* sin(expr.val()),
199 using std::cos; using std::sin;,
201 expr.
dx(
i)* cos(expr.val()),
208 (value_type(1)+ tan(expr.val())* tan(expr.val())),
210 (value_type(1)+ tan(expr.val())* tan(expr.val())))
213 using std::acos; using std::sqrt;,
215 -expr.
dx(
i)/ sqrt(value_type(1)-expr.val()*expr.val()),
217 sqrt(value_type(1)-expr.val()*expr.val()))
220 using std::asin; using std::sqrt;,
222 expr.
dx(
i)/ sqrt(value_type(1)-expr.val()*expr.val()),
224 sqrt(value_type(1)-expr.val()*expr.val()))
229 expr.
dx(
i)/(value_type(1)+expr.val()*expr.val()),
233 using std::cosh; using std::
sinh;,
235 expr.
dx(
i)* sinh(expr.val()),
239 using std::cosh; using std::sinh;,
241 expr.
dx(
i)* cosh(expr.val()),
247 expr.
dx(
i)*(value_type(1)-tanh(expr.val())*tanh(expr.val())),
248 expr.
fastAccessDx(
i)*(value_type(1)-tanh(expr.val())*tanh(expr.val())))
251 using std::acosh; using std::sqrt;,
253 expr.
dx(
i)/ sqrt((expr.val()-value_type(1)) *
254 (expr.val()+value_type(1))),
256 (expr.val()+value_type(1))))
259 using std::asinh; using std::sqrt;,
261 expr.
dx(
i)/ sqrt(value_type(1)+expr.val()*expr.val()),
263 expr.val()*expr.val()))
268 expr.
dx(
i)/(value_type(1)-expr.val()*expr.val()),
270 expr.val()*expr.val()))
275 if_then_else( expr.val() >= 0, expr.
dx(
i), value_type(-expr.
dx(i)) ),
279 using std::fabs; using Sacado::if_then_else;,
281 if_then_else( expr.val() >= 0, expr.
dx(i), value_type(-expr.
dx(i)) ),
287 expr.
dx(i)/(value_type(3)*cbrt(expr.val()*expr.val())),
298 template <
typename T,
typename ExprSpec,
bool is_simd>
304 template <
typename T>
306 public Expr< SafeSqrtOp<T,ExprSpecDefault> > {
309 typedef typename std::remove_cv<T>::type ExprT;
310 typedef typename ExprT::value_type value_type;
311 typedef typename ExprT::scalar_type scalar_type;
313 typedef ExprSpecDefault expr_spec_type;
316 explicit SafeSqrtOp(
const T& expr_) : expr(expr_) {}
319 int size()
const {
return expr.size(); }
322 bool hasFastAccess()
const {
323 return expr.hasFastAccess();
327 value_type
val()
const {
329 return sqrt(expr.val());
333 value_type
dx(
int i)
const {
336 expr.val() == value_type(0.0), value_type(0.0),
337 value_type(expr.dx(i)/(value_type(2)*
sqrt(expr.val()))));
344 expr.val() == value_type(0.0), value_type(0.0),
345 value_type(expr.fastAccessDx(i)/(value_type(2)*
sqrt(expr.val()))));
356 template <
typename T>
358 public Expr< SafeSqrtOp<T,ExprSpecDefault> > {
361 typedef typename std::remove_cv<T>::type ExprT;
362 typedef typename ExprT::value_type value_type;
363 typedef typename ExprT::scalar_type scalar_type;
365 typedef ExprSpecDefault expr_spec_type;
368 explicit SafeSqrtOp(
const T& expr_) : expr(expr_) {}
371 int size()
const {
return expr.size(); }
374 bool hasFastAccess()
const {
375 return expr.hasFastAccess();
379 value_type
val()
const {
381 return sqrt(expr.val());
385 value_type
dx(
int i)
const {
387 return expr.val() == value_type(0.0) ? value_type(0.0) :
388 value_type(expr.dx(i)/(value_type(2)*
sqrt(expr.val())));
394 return expr.val() == value_type(0.0) ? value_type(0.0) :
395 value_type(expr.fastAccessDx(i)/(value_type(2)*
sqrt(expr.val())));
403 template <
typename T>
405 SafeSqrtOp< typename Expr<T>::derived_type,
406 typename T::expr_spec_type >
409 typedef SafeSqrtOp< typename Expr<T>::derived_type,
410 typename T::expr_spec_type > expr_t;
412 return expr_t(expr.derived());
415 template <
typename T,
typename E>
416 struct ExprLevel< SafeSqrtOp< T,E > > {
420 template <
typename T,
typename E>
421 struct IsFadExpr< SafeSqrtOp< T,E > > {
422 static const unsigned value =
true;
428 template <
typename T,
typename E>
430 static const bool value =
true;
433 template <
typename T,
typename E>
435 typedef typename BaseExprType<T>::type type;
438 template <
typename T,
typename E>
440 static const bool value =
441 IsSimdType< typename Fad::Exp::SafeSqrtOp< T,E >::scalar_type >
::value;
444 template <
typename T,
typename E>
446 typedef typename Fad::Exp::SafeSqrtOp< T,E >::value_type type;
449 template <
typename T,
typename E>
451 typedef typename Fad::Exp::SafeSqrtOp< T,E >::scalar_type type;
456 #undef FAD_UNARYOP_MACRO
458 #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) \
463 template <typename T1, typename T2, \
464 bool is_const_T1, bool is_const_T2, \
465 typename ExprSpec > \
468 template <typename T1, typename T2> \
469 class OP< T1, T2, false, false, ExprSpecDefault > : \
470 public Expr< OP< T1, T2, false, false, ExprSpecDefault > > { \
473 typedef typename std::remove_cv<T1>::type ExprT1; \
474 typedef typename std::remove_cv<T2>::type ExprT2; \
475 typedef typename ExprT1::value_type value_type_1; \
476 typedef typename ExprT2::value_type value_type_2; \
477 typedef typename Sacado::Promote<value_type_1, \
478 value_type_2>::type value_type; \
480 typedef typename ExprT1::scalar_type scalar_type_1; \
481 typedef typename ExprT2::scalar_type scalar_type_2; \
482 typedef typename Sacado::Promote<scalar_type_1, \
483 scalar_type_2>::type scalar_type; \
485 typedef ExprSpecDefault expr_spec_type; \
487 SACADO_INLINE_FUNCTION \
488 OP(const T1& expr1_, const T2& expr2_) : \
489 expr1(expr1_), expr2(expr2_) {} \
491 SACADO_INLINE_FUNCTION \
493 const int sz1 = expr1.size(), sz2 = expr2.size(); \
494 return sz1 > sz2 ? sz1 : sz2; \
497 SACADO_INLINE_FUNCTION \
498 bool hasFastAccess() const { \
499 return expr1.hasFastAccess() && expr2.hasFastAccess(); \
502 SACADO_INLINE_FUNCTION \
503 value_type val() const { \
508 SACADO_INLINE_FUNCTION \
509 value_type dx(int i) const { \
511 const int sz1 = expr1.size(), sz2 = expr2.size(); \
512 if (sz1 > 0 && sz2 > 0) \
520 SACADO_INLINE_FUNCTION \
521 value_type fastAccessDx(int i) const { \
523 return FASTACCESSDX; \
533 template <typename T1, typename T2> \
534 class OP< T1, T2, false, true, ExprSpecDefault > \
535 : public Expr< OP< T1, T2, false, true, ExprSpecDefault > > { \
538 typedef typename std::remove_cv<T1>::type ExprT1; \
540 typedef typename ExprT1::value_type value_type; \
541 typedef typename ExprT1::scalar_type scalar_type; \
543 typedef ExprSpecDefault expr_spec_type; \
545 SACADO_INLINE_FUNCTION \
546 OP(const T1& expr1_, const ConstT& c_) : \
547 expr1(expr1_), c(c_) {} \
549 SACADO_INLINE_FUNCTION \
551 return expr1.size(); \
554 SACADO_INLINE_FUNCTION \
555 bool hasFastAccess() const { \
556 return expr1.hasFastAccess(); \
559 SACADO_INLINE_FUNCTION \
560 value_type val() const { \
562 return VAL_CONST_DX_2; \
565 SACADO_INLINE_FUNCTION \
566 value_type dx(int i) const { \
571 SACADO_INLINE_FUNCTION \
572 value_type fastAccessDx(int i) const { \
574 return CONST_FASTACCESSDX_2; \
583 template <typename T1, typename T2> \
584 class OP< T1, T2, true, false, ExprSpecDefault > \
585 : public Expr< OP< T1, T2, true, false, ExprSpecDefault > > { \
588 typedef typename std::remove_cv<T2>::type ExprT2; \
590 typedef typename ExprT2::value_type value_type; \
591 typedef typename ExprT2::scalar_type scalar_type; \
593 typedef ExprSpecDefault expr_spec_type; \
595 SACADO_INLINE_FUNCTION \
596 OP(const ConstT& c_, const T2& expr2_) : \
597 c(c_), expr2(expr2_) {} \
599 SACADO_INLINE_FUNCTION \
601 return expr2.size(); \
604 SACADO_INLINE_FUNCTION \
605 bool hasFastAccess() const { \
606 return expr2.hasFastAccess(); \
609 SACADO_INLINE_FUNCTION \
610 value_type val() const { \
612 return VAL_CONST_DX_1; \
615 SACADO_INLINE_FUNCTION \
616 value_type dx(int i) const { \
621 SACADO_INLINE_FUNCTION \
622 value_type fastAccessDx(int i) const { \
624 return CONST_FASTACCESSDX_1; \
633 template <typename T1, typename T2> \
634 SACADO_INLINE_FUNCTION \
635 SACADO_FAD_EXP_OP_ENABLE_EXPR_EXPR(OP) \
636 OPNAME (const T1& expr1, const T2& expr2) \
638 typedef OP< typename Expr<T1>::derived_type, \
639 typename Expr<T2>::derived_type, \
640 false, false, typename T1::expr_spec_type > expr_t; \
642 return expr_t(expr1.derived(), expr2.derived()); \
645 template <typename T> \
646 SACADO_INLINE_FUNCTION \
647 OP< typename T::value_type, typename Expr<T>::derived_type, \
648 true, false, typename T::expr_spec_type > \
649 OPNAME (const typename T::value_type& c, \
650 const Expr<T>& expr) \
652 typedef typename T::value_type ConstT; \
653 typedef OP< ConstT, typename Expr<T>::derived_type, \
654 true, false, typename T::expr_spec_type > expr_t; \
656 return expr_t(c, expr.derived()); \
659 template <typename T> \
660 SACADO_INLINE_FUNCTION \
661 OP< typename Expr<T>::derived_type, typename T::value_type, \
662 false, true, typename T::expr_spec_type > \
663 OPNAME (const Expr<T>& expr, \
664 const typename T::value_type& c) \
666 typedef typename T::value_type ConstT; \
667 typedef OP< typename Expr<T>::derived_type, ConstT, \
668 false, true, typename T::expr_spec_type > expr_t; \
670 return expr_t(expr.derived(), c); \
673 template <typename T> \
674 SACADO_INLINE_FUNCTION \
675 SACADO_FAD_EXP_OP_ENABLE_SCALAR_EXPR(OP) \
676 OPNAME (const typename T::scalar_type& c, \
677 const Expr<T>& expr) \
679 typedef typename T::scalar_type ConstT; \
680 typedef OP< ConstT, typename Expr<T>::derived_type, \
681 true, false, typename T::expr_spec_type > expr_t; \
683 return expr_t(c, expr.derived()); \
686 template <typename T> \
687 SACADO_INLINE_FUNCTION \
688 SACADO_FAD_EXP_OP_ENABLE_EXPR_SCALAR(OP) \
689 OPNAME (const Expr<T>& expr, \
690 const typename T::scalar_type& c) \
692 typedef typename T::scalar_type ConstT; \
693 typedef OP< typename Expr<T>::derived_type, ConstT, \
694 false, true, typename T::expr_spec_type > expr_t; \
696 return expr_t(expr.derived(), c); \
699 template <typename T1, typename T2, bool c1, bool c2, typename E> \
700 struct ExprLevel< OP< T1, T2, c1, c2, E > > { \
701 static constexpr unsigned value_1 = ExprLevel<T1>::value; \
702 static constexpr unsigned value_2 = ExprLevel<T2>::value; \
703 static constexpr unsigned value = \
704 value_1 >= value_2 ? value_1 : value_2; \
707 template <typename T1, typename T2, bool c1, bool c2, typename E> \
708 struct IsFadExpr< OP< T1, T2, c1, c2, E > > { \
709 static constexpr unsigned value = true; \
715 template <typename T1, typename T2, bool c1, bool c2, typename E> \
716 struct IsExpr< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
717 static constexpr bool value = true; \
720 template <typename T1, typename T2, bool c1, bool c2, typename E> \
721 struct BaseExprType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
722 typedef typename BaseExprType<T1>::type base_expr_1; \
723 typedef typename BaseExprType<T2>::type base_expr_2; \
724 typedef typename Sacado::Promote<base_expr_1, \
725 base_expr_2>::type type; \
728 template <typename T1, typename T2, bool c1, bool c2, typename E> \
729 struct IsSimdType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
730 static const bool value = \
731 IsSimdType< typename Fad::Exp::OP< T1, T2, c1, c2, E >::value_type >::value; \
734 template <typename T1, typename T2, bool c1, bool c2, typename E> \
735 struct ValueType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
736 typedef typename Fad::Exp::OP< T1, T2, c1, c2, E >::value_type type;\
739 template <typename T1, typename T2, bool c1, bool c2, typename E> \
740 struct ScalarType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
741 typedef typename Fad::Exp::OP< T1, T2, c1, c2, E >::scalar_type type;\
750 expr1.val() + expr2.val(),
751 expr1.dx(
i) + expr2.dx(
i),
754 expr1.fastAccessDx(
i) + expr2.fastAccessDx(
i),
759 expr2.fastAccessDx(
i),
760 expr1.fastAccessDx(
i))
764 expr1.val() - expr2.val(),
765 expr1.dx(
i) - expr2.dx(
i),
768 expr1.fastAccessDx(
i) - expr2.fastAccessDx(
i),
773 -expr2.fastAccessDx(
i),
774 expr1.fastAccessDx(
i))
778 expr1.val() * expr2.val(),
779 expr1.val()*expr2.dx(
i) + expr1.dx(
i)*expr2.val(),
780 expr1.val()*expr2.dx(
i),
781 expr1.dx(
i)*expr2.val(),
782 expr1.val()*expr2.fastAccessDx(
i) +
783 expr1.fastAccessDx(
i)*expr2.val(),
788 c*expr2.fastAccessDx(
i),
789 expr1.fastAccessDx(
i)*
c)
793 expr1.val() / expr2.val(),
794 (expr1.dx(
i)*expr2.val() - expr2.dx(
i)*expr1.val()) /
795 (expr2.val()*expr2.val()),
796 -expr2.dx(
i)*expr1.val() / (expr2.val()*expr2.val()),
797 expr1.dx(
i)/expr2.val(),
798 (expr1.fastAccessDx(
i)*expr2.val() -
799 expr2.fastAccessDx(
i)*expr1.val()) /
800 (expr2.val()*expr2.val()),
803 -expr2.dx(
i)*
c / (expr2.val()*expr2.val()),
805 -expr2.fastAccessDx(
i)*
c / (expr2.val()*expr2.val()),
806 expr1.fastAccessDx(
i)/
c)
810 atan2(expr1.val(), expr2.val()),
811 (expr2.val()*expr1.dx(
i) - expr1.val()*expr2.dx(
i))/
812 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
813 -expr1.val()*expr2.dx(
i)/
814 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
815 expr2.val()*expr1.dx(
i)/
816 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
817 (expr2.val()*expr1.fastAccessDx(
i) - expr1.val()*expr2.fastAccessDx(
i))/
818 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
821 (-
c*expr2.dx(
i)) / (
c*
c + expr2.val()*expr2.val()),
822 (
c*expr1.dx(
i))/ (expr1.val()*expr1.val() +
c*
c),
823 (-
c*expr2.fastAccessDx(
i))/ (
c*
c + expr2.val()*expr2.val()),
824 (
c*expr1.fastAccessDx(
i))/ (expr1.val()*expr1.val() +
c*
c))
842 if_then_else( expr1.
val() >= expr2.
val(), expr1.val(), expr2.val() ),
843 if_then_else( expr1.val() >= expr2.val(), expr1.
dx(
i), expr2.
dx(i) ),
844 if_then_else( expr1.val() >= expr2.val(), value_type(0.0), expr2.
dx(i) ),
845 if_then_else( expr1.val() >= expr2.val(), expr1.
dx(i), value_type(0.0) ),
847 if_then_else(
c >= expr2.val(), value_type(
c), expr2.val() ),
848 if_then_else( expr1.val() >= c, expr1.val(), value_type(c) ),
849 if_then_else( c >= expr2.val(), value_type(0.0), expr2.
dx(i) ),
850 if_then_else( expr1.val() >= c, expr1.
dx(i), value_type(0.0) ),
851 if_then_else( c >= expr2.val(), value_type(0.0), expr2.
fastAccessDx(i) ),
852 if_then_else( expr1.val() >= c, expr1.
fastAccessDx(i), value_type(0.0) ) )
855 using Sacado::if_then_else;,
856 if_then_else( expr1.val() <= expr2.val(), expr1.val(), expr2.val() ),
857 if_then_else( expr1.val() <= expr2.val(), expr1.
dx(i), expr2.
dx(i) ),
858 if_then_else( expr1.val() <= expr2.val(), value_type(0.0), expr2.
dx(i) ),
859 if_then_else( expr1.val() <= expr2.val(), expr1.
dx(i), value_type(0.0) ),
861 if_then_else( c <= expr2.val(), value_type(c), expr2.val() ),
862 if_then_else( expr1.val() <= c, expr1.val(), value_type(c) ),
863 if_then_else( c <= expr2.val(), value_type(0), expr2.
dx(i) ),
864 if_then_else( expr1.val() <= c, expr1.
dx(i), value_type(0) ),
865 if_then_else( c <= expr2.val(), value_type(0), expr2.
fastAccessDx(i) ),
866 if_then_else( expr1.val() <= c, expr1.
fastAccessDx(i), value_type(0) ) )
877 template <
typename T1,
typename T2,
878 bool is_const_T1,
bool is_const_T2,
879 typename ExprSpec,
typename Impl >
885 template <
typename T1,
typename T2>
886 class PowerOp< T1, T2, false, false, ExprSpecDefault,
888 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault,
889 PowerImpl::Simd > > {
892 typedef typename std::remove_cv<T1>::type ExprT1;
893 typedef typename std::remove_cv<T2>::type ExprT2;
894 typedef typename ExprT1::value_type value_type_1;
895 typedef typename ExprT2::value_type value_type_2;
897 value_type_2>::type value_type;
899 typedef typename ExprT1::scalar_type scalar_type_1;
900 typedef typename ExprT2::scalar_type scalar_type_2;
902 scalar_type_2>::type scalar_type;
904 typedef ExprSpecDefault expr_spec_type;
907 PowerOp(
const T1& expr1_,
const T2& expr2_) :
908 expr1(expr1_), expr2(expr2_) {}
912 const int sz1 = expr1.size(), sz2 = expr2.size();
913 return sz1 > sz2 ? sz1 : sz2;
917 bool hasFastAccess()
const {
918 return expr1.hasFastAccess() && expr2.hasFastAccess();
922 value_type
val()
const {
924 return pow(expr1.val(), expr2.val());
928 value_type
dx(
int i)
const {
930 const int sz1 = expr1.size(), sz2 = expr2.size();
931 if (sz1 > 0 && sz2 > 0)
932 return if_then_else( expr1.val() == scalar_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())) );
936 return if_then_else( expr2.val() == scalar_type(1.0), expr1.dx(i),
if_then_else(expr1.val() == scalar_type(0.0), value_type(0.0), value_type(expr2.val()*expr1.dx(i)/expr1.val()*
pow(expr1.val(),expr2.val())) ));
938 return if_then_else( expr1.val() == scalar_type(0.0), value_type(0.0), value_type(expr2.dx(i)*
log(expr1.val())*
pow(expr1.val(),expr2.val())) );
944 return if_then_else( expr1.val() == scalar_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())));
954 template <
typename T1,
typename T2>
955 class PowerOp< T1, T2, false, true, ExprSpecDefault,
957 public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault,
958 PowerImpl::Simd > > {
961 typedef typename std::remove_cv<T1>::type ExprT1;
963 typedef typename ExprT1::value_type value_type;
964 typedef typename ExprT1::scalar_type scalar_type;
966 typedef ExprSpecDefault expr_spec_type;
969 PowerOp(
const T1& expr1_,
const ConstT&
c_) :
970 expr1(expr1_),
c(c_) {}
978 bool hasFastAccess()
const {
979 return expr1.hasFastAccess();
983 value_type
val()
const {
985 return pow(expr1.val(),
c);
989 value_type
dx(
int i)
const {
993 return if_then_else( c == scalar_type(1.0), expr1.dx(i),
if_then_else( expr1.val() == scalar_type(0.0), value_type(0.0), value_type(c*expr1.dx(i)/expr1.val()*
pow(expr1.val(),
c)) ));
1001 return if_then_else( c == scalar_type(1.0), expr1.fastAccessDx(i),
if_then_else( expr1.val() == scalar_type(0.0), value_type(0.0), value_type(c*expr1.fastAccessDx(i)/expr1.val()*
pow(expr1.val(),
c)) ));
1010 template <
typename T1,
typename T2>
1011 class PowerOp< T1, T2, true, false, ExprSpecDefault,
1013 public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault,
1014 PowerImpl::Simd > > {
1017 typedef typename std::remove_cv<T2>::type ExprT2;
1019 typedef typename ExprT2::value_type value_type;
1020 typedef typename ExprT2::scalar_type scalar_type;
1022 typedef ExprSpecDefault expr_spec_type;
1025 PowerOp(
const ConstT&
c_,
const T2& expr2_) :
1026 c(c_), expr2(expr2_) {}
1030 return expr2.size();
1034 bool hasFastAccess()
const {
1035 return expr2.hasFastAccess();
1039 value_type
val()
const {
1041 return pow(c, expr2.val());
1045 value_type
dx(
int i)
const {
1047 return if_then_else( c == scalar_type(0.0), value_type(0.0), value_type(expr2.dx(i)*
log(c)*
pow(c,expr2.val())) );
1053 return if_then_else( c == scalar_type(0.0), value_type(0.0), value_type(expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val())) );
1066 template <
typename T1,
typename T2>
1067 class PowerOp< T1, T2, false, false, ExprSpecDefault,
1068 PowerImpl::Scalar > :
1069 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault,
1070 PowerImpl::Scalar > > {
1073 typedef typename std::remove_cv<T1>::type ExprT1;
1074 typedef typename std::remove_cv<T2>::type ExprT2;
1075 typedef typename ExprT1::value_type value_type_1;
1076 typedef typename ExprT2::value_type value_type_2;
1078 value_type_2>::type value_type;
1080 typedef typename ExprT1::scalar_type scalar_type_1;
1081 typedef typename ExprT2::scalar_type scalar_type_2;
1083 scalar_type_2>::type scalar_type;
1085 typedef ExprSpecDefault expr_spec_type;
1088 PowerOp(
const T1& expr1_,
const T2& expr2_) :
1089 expr1(expr1_), expr2(expr2_) {}
1093 const int sz1 = expr1.size(), sz2 = expr2.size();
1094 return sz1 > sz2 ? sz1 : sz2;
1098 bool hasFastAccess()
const {
1099 return expr1.hasFastAccess() && expr2.hasFastAccess();
1103 value_type
val()
const {
1105 return pow(expr1.val(), expr2.val());
1109 value_type
dx(
int i)
const {
1111 const int sz1 = expr1.size(), sz2 = expr2.size();
1112 if (sz1 > 0 && sz2 > 0)
1113 return expr1.val() == scalar_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()));
1117 return expr2.val() == scalar_type(1.0) ? expr1.dx(i) : expr1.val() == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.val()*expr1.dx(i)/expr1.val()*
pow(expr1.val(),expr2.val()));
1119 return expr1.val() == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.dx(i)*
log(expr1.val())*
pow(expr1.val(),expr2.val()));
1125 return expr1.val() == scalar_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()));
1135 template <
typename T1,
typename T2>
1136 class PowerOp< T1, T2, false, true, ExprSpecDefault,
1137 PowerImpl::Scalar > :
1138 public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault,
1139 PowerImpl::Scalar > > {
1142 typedef typename std::remove_cv<T1>::type ExprT1;
1144 typedef typename ExprT1::value_type value_type;
1145 typedef typename ExprT1::scalar_type scalar_type;
1147 typedef ExprSpecDefault expr_spec_type;
1150 PowerOp(
const T1& expr1_,
const ConstT&
c_) :
1151 expr1(expr1_),
c(c_) {}
1155 return expr1.size();
1159 bool hasFastAccess()
const {
1160 return expr1.hasFastAccess();
1164 value_type
val()
const {
1166 return pow(expr1.val(),
c);
1170 value_type
dx(
int i)
const {
1174 return c == scalar_type(1.0) ? expr1.dx(i) : expr1.val() == scalar_type(0.0) ? value_type(0.0) : value_type(c*expr1.dx(i)/expr1.val()*
pow(expr1.val(),
c));
1182 return c == scalar_type(1.0) ? expr1.fastAccessDx(i) : expr1.val() == scalar_type(0.0) ? value_type(0.0) : value_type(c*expr1.fastAccessDx(i)/expr1.val()*
pow(expr1.val(),
c));
1191 template <
typename T1,
typename T2>
1192 class PowerOp< T1, T2, true, false, ExprSpecDefault,
1193 PowerImpl::Scalar > :
1194 public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault,
1195 PowerImpl::Scalar > > {
1198 typedef typename std::remove_cv<T2>::type ExprT2;
1200 typedef typename ExprT2::value_type value_type;
1201 typedef typename ExprT2::scalar_type scalar_type;
1203 typedef ExprSpecDefault expr_spec_type;
1206 PowerOp(
const ConstT&
c_,
const T2& expr2_) :
1207 c(c_), expr2(expr2_) {}
1211 return expr2.size();
1215 bool hasFastAccess()
const {
1216 return expr2.hasFastAccess();
1220 value_type
val()
const {
1222 return pow(c, expr2.val());
1226 value_type
dx(
int i)
const {
1228 return c == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.dx(i)*
log(c)*
pow(c,expr2.val()));
1234 return c == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val()));
1248 template <
typename T1,
typename T2>
1249 class PowerOp< T1, T2, false, false, ExprSpecDefault,
1250 PowerImpl::Nested > :
1251 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault,
1252 PowerImpl::Nested > > {
1255 typedef typename std::remove_cv<T1>::type ExprT1;
1256 typedef typename std::remove_cv<T2>::type ExprT2;
1257 typedef typename ExprT1::value_type value_type_1;
1258 typedef typename ExprT2::value_type value_type_2;
1260 value_type_2>::type value_type;
1262 typedef typename ExprT1::scalar_type scalar_type_1;
1263 typedef typename ExprT2::scalar_type scalar_type_2;
1265 scalar_type_2>::type scalar_type;
1267 typedef ExprSpecDefault expr_spec_type;
1270 PowerOp(
const T1& expr1_,
const T2& expr2_) :
1271 expr1(expr1_), expr2(expr2_) {}
1275 const int sz1 = expr1.size(), sz2 = expr2.size();
1276 return sz1 > sz2 ? sz1 : sz2;
1280 bool hasFastAccess()
const {
1281 return expr1.hasFastAccess() && expr2.hasFastAccess();
1285 value_type
val()
const {
1287 return pow(expr1.val(), expr2.val());
1291 value_type
dx(
int i)
const {
1293 const int sz1 = expr1.size(), sz2 = expr2.size();
1294 if (sz1 > 0 && sz2 > 0)
1295 return (expr2.dx(i)*
log(expr1.val())+expr2.val()*expr1.dx(i)/expr1.val())*
pow(expr1.val(),expr2.val());
1297 return expr2.val() == scalar_type(0.0) ? value_type(0.0) : value_type((expr2.val()*expr1.dx(i))*
pow(expr1.val(),expr2.val()-scalar_type(1.0)));
1299 return expr2.dx(i)*
log(expr1.val())*
pow(expr1.val(),expr2.val());
1305 return (expr2.fastAccessDx(i)*
log(expr1.val())+expr2.val()*expr1.fastAccessDx(i)/expr1.val())*
pow(expr1.val(),expr2.val());
1315 template <
typename T1,
typename T2>
1316 class PowerOp< T1, T2, false, true, ExprSpecDefault,
1317 PowerImpl::Nested > :
1318 public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault,
1319 PowerImpl::Nested > > {
1322 typedef typename std::remove_cv<T1>::type ExprT1;
1324 typedef typename ExprT1::value_type value_type;
1325 typedef typename ExprT1::scalar_type scalar_type;
1327 typedef ExprSpecDefault expr_spec_type;
1330 PowerOp(
const T1& expr1_,
const ConstT&
c_) :
1331 expr1(expr1_),
c(c_) {}
1335 return expr1.size();
1339 bool hasFastAccess()
const {
1340 return expr1.hasFastAccess();
1344 value_type
val()
const {
1346 return pow(expr1.val(),
c);
1350 value_type
dx(
int i)
const {
1352 return c == scalar_type(0.0) ? value_type(0.0) : value_type(c*expr1.dx(i)*
pow(expr1.val(),c-scalar_type(1.0)));
1358 return c == scalar_type(0.0) ? value_type(0.0) : value_type(c*expr1.fastAccessDx(i)*
pow(expr1.val(),c-scalar_type(1.0)));
1367 template <
typename T1,
typename T2>
1368 class PowerOp<T1, T2, true, false, ExprSpecDefault,
1369 PowerImpl::Nested > :
1370 public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault,
1371 PowerImpl::Nested > > {
1374 typedef typename std::remove_cv<T2>::type ExprT2;
1376 typedef typename ExprT2::value_type value_type;
1377 typedef typename ExprT2::scalar_type scalar_type;
1379 typedef ExprSpecDefault expr_spec_type;
1382 PowerOp(
const ConstT&
c_,
const T2& expr2_) :
1383 c(c_), expr2(expr2_) {}
1387 return expr2.size();
1391 bool hasFastAccess()
const {
1392 return expr2.hasFastAccess();
1396 value_type
val()
const {
1398 return pow(c, expr2.val());
1402 value_type
dx(
int i)
const {
1404 return expr2.dx(i)*
log(c)*
pow(c,expr2.val());
1410 return expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val());
1424 template <
typename T1,
typename T2>
1425 class PowerOp< T1, T2, false, false, ExprSpecDefault,
1426 PowerImpl::NestedSimd > :
1427 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault,
1428 PowerImpl::NestedSimd > > {
1431 typedef typename std::remove_cv<T1>::type ExprT1;
1432 typedef typename std::remove_cv<T2>::type ExprT2;
1433 typedef typename ExprT1::value_type value_type_1;
1434 typedef typename ExprT2::value_type value_type_2;
1436 value_type_2>::type value_type;
1438 typedef typename ExprT1::scalar_type scalar_type_1;
1439 typedef typename ExprT2::scalar_type scalar_type_2;
1441 scalar_type_2>::type scalar_type;
1443 typedef ExprSpecDefault expr_spec_type;
1446 PowerOp(
const T1& expr1_,
const T2& expr2_) :
1447 expr1(expr1_), expr2(expr2_) {}
1451 const int sz1 = expr1.size(), sz2 = expr2.size();
1452 return sz1 > sz2 ? sz1 : sz2;
1456 bool hasFastAccess()
const {
1457 return expr1.hasFastAccess() && expr2.hasFastAccess();
1461 value_type
val()
const {
1463 return pow(expr1.val(), expr2.val());
1467 value_type
dx(
int i)
const {
1469 const int sz1 = expr1.size(), sz2 = expr2.size();
1470 if (sz1 > 0 && sz2 > 0)
1471 return (expr2.dx(i)*
log(expr1.val())+expr2.val()*expr1.dx(i)/expr1.val())*
pow(expr1.val(),expr2.val());
1473 return if_then_else( expr2.val() == scalar_type(0.0), value_type(0.0), value_type((expr2.val()*expr1.dx(i))*
pow(expr1.val(),expr2.val()-scalar_type(1.0))));
1475 return expr2.dx(i)*
log(expr1.val())*
pow(expr1.val(),expr2.val());
1481 return (expr2.fastAccessDx(i)*
log(expr1.val())+expr2.val()*expr1.fastAccessDx(i)/expr1.val())*
pow(expr1.val(),expr2.val());
1491 template <
typename T1,
typename T2>
1492 class PowerOp< T1, T2, false, true, ExprSpecDefault,
1493 PowerImpl::NestedSimd > :
1494 public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault,
1495 PowerImpl::NestedSimd > > {
1498 typedef typename std::remove_cv<T1>::type ExprT1;
1500 typedef typename ExprT1::value_type value_type;
1501 typedef typename ExprT1::scalar_type scalar_type;
1503 typedef ExprSpecDefault expr_spec_type;
1506 PowerOp(
const T1& expr1_,
const ConstT&
c_) :
1507 expr1(expr1_),
c(c_) {}
1511 return expr1.size();
1515 bool hasFastAccess()
const {
1516 return expr1.hasFastAccess();
1520 value_type
val()
const {
1522 return pow(expr1.val(),
c);
1526 value_type
dx(
int i)
const {
1528 return if_then_else( c == scalar_type(0.0), value_type(0.0), value_type(c*expr1.dx(i)*
pow(expr1.val(),c-scalar_type(1.0))));
1534 return if_then_else( c == scalar_type(0.0), value_type(0.0), value_type(c*expr1.fastAccessDx(i)*
pow(expr1.val(),c-scalar_type(1.0))));
1543 template <
typename T1,
typename T2>
1544 class PowerOp<T1, T2, true, false, ExprSpecDefault,
1545 PowerImpl::NestedSimd > :
1546 public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault,
1547 PowerImpl::NestedSimd > > {
1550 typedef typename std::remove_cv<T2>::type ExprT2;
1552 typedef typename ExprT2::value_type value_type;
1553 typedef typename ExprT2::scalar_type scalar_type;
1555 typedef ExprSpecDefault expr_spec_type;
1558 PowerOp(
const ConstT&
c_,
const T2& expr2_) :
1559 c(c_), expr2(expr2_) {}
1563 return expr2.size();
1567 bool hasFastAccess()
const {
1568 return expr2.hasFastAccess();
1572 value_type
val()
const {
1574 return pow(c, expr2.val());
1578 value_type
dx(
int i)
const {
1580 return expr2.dx(i)*
log(c)*
pow(c,expr2.val());
1586 return expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val());
1595 template <
typename T1,
typename T2>
1598 pow (
const T1& expr1,
const T2& expr2)
1600 typedef PowerOp< typename Expr<T1>::derived_type,
1601 typename Expr<T2>::derived_type,
1602 false,
false,
typename T1::expr_spec_type > expr_t;
1604 return expr_t(expr1.derived(), expr2.derived());
1607 template <
typename T>
1609 PowerOp< typename T::value_type, typename Expr<T>::derived_type,
1610 true,
false,
typename T::expr_spec_type >
1611 pow (
const typename T::value_type& c,
1612 const Expr<T>& expr)
1614 typedef typename T::value_type ConstT;
1615 typedef PowerOp< ConstT, typename Expr<T>::derived_type,
1616 true,
false,
typename T::expr_spec_type > expr_t;
1618 return expr_t(c, expr.derived());
1621 template <
typename T>
1623 PowerOp< typename Expr<T>::derived_type,
typename T::value_type,
1624 false,
true,
typename T::expr_spec_type >
1625 pow (
const Expr<T>& expr,
1626 const typename T::value_type& c)
1628 typedef typename T::value_type ConstT;
1629 typedef PowerOp< typename Expr<T>::derived_type, ConstT,
1630 false,
true,
typename T::expr_spec_type > expr_t;
1632 return expr_t(expr.derived(),
c);
1635 template <
typename T>
1638 pow (
const typename T::scalar_type& c,
1639 const Expr<T>& expr)
1641 typedef typename T::scalar_type ConstT;
1642 typedef PowerOp< ConstT, typename Expr<T>::derived_type,
1643 true,
false,
typename T::expr_spec_type > expr_t;
1645 return expr_t(c, expr.derived());
1648 template <
typename T>
1651 pow (
const Expr<T>& expr,
1652 const typename T::scalar_type& c)
1654 typedef typename T::scalar_type ConstT;
1655 typedef PowerOp< typename Expr<T>::derived_type, ConstT,
1656 false,
true,
typename T::expr_spec_type > expr_t;
1658 return expr_t(expr.derived(),
c);
1661 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1662 struct ExprLevel< PowerOp< T1, T2, c1, c2, E > > {
1665 static constexpr
unsigned value =
1666 value_1 >= value_2 ? value_1 : value_2;
1669 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1670 struct IsFadExpr< PowerOp< T1, T2, c1, c2, E > > {
1671 static constexpr
unsigned value =
true;
1677 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1678 struct IsExpr< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1679 static constexpr
bool value =
true;
1682 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1683 struct BaseExprType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1684 typedef typename BaseExprType<T1>::type base_expr_1;
1685 typedef typename BaseExprType<T2>::type base_expr_2;
1687 base_expr_2>::type type;
1690 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1691 struct IsSimdType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1692 static const bool value =
1693 IsSimdType< typename Fad::Exp::PowerOp< T1, T2, c1, c2, E >::value_type >
::value;
1696 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1697 struct ValueType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1698 typedef typename Fad::Exp::PowerOp< T1, T2, c1, c2, E >::value_type type;
1701 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1702 struct ScalarType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1703 typedef typename Fad::Exp::PowerOp< T1, T2, c1, c2, E >::scalar_type type;
1716 template <
typename CondT,
typename T1,
typename T2,
1717 bool is_const_T1,
bool is_const_T2,
1721 template <
typename CondT,
typename T1,
typename T2>
1723 public Expr< IfThenElseOp< CondT, T1, T2, false, false, ExprSpecDefault > > {
1727 typedef typename std::remove_cv<T1>::type
ExprT1;
1728 typedef typename std::remove_cv<T2>::type
ExprT2;
1743 cond(cond_), expr1(expr1_), expr2(expr2_) {}
1747 int sz1 = expr1.size(), sz2 = expr2.size();
1748 return sz1 > sz2 ? sz1 : sz2;
1753 return expr1.hasFastAccess() && expr2.hasFastAccess();
1771 return if_then_else( cond, expr1.fastAccessDx(i), expr2.fastAccessDx(i) );
1782 template <
typename CondT,
typename T1,
typename T2>
1784 public Expr< IfThenElseOp< CondT, T1, T2, false, true, ExprSpecDefault > > {
1788 typedef typename std::remove_cv<T1>::type
ExprT1;
1797 cond(cond_), expr1(expr1_),
c(c_) {}
1801 return expr1.size();
1806 return expr1.hasFastAccess();
1834 template <
typename CondT,
typename T1,
typename T2>
1836 public Expr< IfThenElseOp< CondT, T1, T2, true, false, ExprSpecDefault > > {
1840 typedef typename std::remove_cv<T2>::type
ExprT2;
1849 cond(cond_),
c(c_), expr2(expr2_) {}
1853 return expr2.size();
1858 return expr2.hasFastAccess();
1886 template <
typename CondT,
typename T1,
typename T2>
1894 typename T1::expr_spec_type >
1900 false,
false,
typename T1::expr_spec_type > expr_t;
1902 return expr_t(cond, expr1.derived(), expr2.derived());
1905 template <
typename CondT,
typename T>
1908 true,
false,
typename T::expr_spec_type >
1912 typedef typename T::value_type ConstT;
1914 true,
false,
typename T::expr_spec_type > expr_t;
1916 return expr_t(cond, c, expr.
derived());
1919 template <
typename CondT,
typename T>
1922 false,
true,
typename T::expr_spec_type >
1924 const typename T::value_type&
c)
1926 typedef typename T::value_type ConstT;
1928 false,
true,
typename T::expr_spec_type > expr_t;
1930 return expr_t(cond, expr.
derived(),
c);
1933 template <
typename CondT,
typename T>
1936 std::is_same<
typename T::value_type,
1937 typename T::scalar_type >,
1940 true,
false,
typename T::expr_spec_type >
1945 typedef typename T::scalar_type ConstT;
1947 true,
false,
typename T::expr_spec_type > expr_t;
1949 return expr_t(cond, c, expr.
derived());
1952 template <
typename CondT,
typename T>
1955 std::is_same<
typename T::value_type,
1956 typename T::scalar_type >,
1958 typename T::scalar_type,
1959 false,
true,
typename T::expr_spec_type >
1964 typedef typename T::scalar_type ConstT;
1966 false,
true,
typename T::expr_spec_type > expr_t;
1968 return expr_t(cond, expr.
derived(),
c);
1971 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1977 value_1 >= value_2 ? value_1 : value_2;
1980 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1989 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1991 struct IsExpr< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
1995 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1997 struct BaseExprType< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
2004 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
2006 struct IsSimdType< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
2011 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
2013 struct ValueType< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
2017 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
2019 struct ScalarType< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
2024 #undef FAD_BINARYOP_MACRO
2037 template <
typename T1,
typename T2 =
T1,
2041 template <
typename T1,
typename T2>
2043 typedef decltype( std::declval<T1>() == std::declval<T2>() ) type;
2050 #define FAD_RELOP_MACRO(OP) \
2051 namespace Sacado { \
2054 template <typename T1, typename T2> \
2055 SACADO_INLINE_FUNCTION \
2056 typename mpl::enable_if_c< \
2057 IsFadExpr<T1>::value && IsFadExpr<T2>::value && \
2058 ExprLevel<T1>::value == ExprLevel<T2>::value, \
2059 typename Impl::ConditionalReturnType<typename T1::value_type, \
2060 typename T2::value_type>::type \
2062 operator OP (const T1& expr1, const T2& expr2) \
2064 return expr1.derived().val() OP expr2.derived().val(); \
2067 template <typename T2> \
2068 SACADO_INLINE_FUNCTION \
2069 typename Impl::ConditionalReturnType<typename T2::value_type>::type \
2070 operator OP (const typename T2::value_type& a, \
2071 const Expr<T2>& expr2) \
2073 return a OP expr2.derived().val(); \
2076 template <typename T1> \
2077 SACADO_INLINE_FUNCTION \
2078 typename Impl::ConditionalReturnType<typename T1::value_type>::type \
2079 operator OP (const Expr<T1>& expr1, \
2080 const typename T1::value_type& b) \
2082 return expr1.derived().val() OP b; \
2099 #undef FAD_RELOP_MACRO
2106 template <
typename ExprT>
2110 return ! expr.
derived().val();
2124 template <
typename T>
2128 bool is_zero = (x.val() == 0.0);
2129 for (
int i=0;
i<x.size();
i++)
2130 is_zero = is_zero && (x.dx(
i) == 0.0);
2139 #define FAD_BOOL_MACRO(OP) \
2140 namespace Sacado { \
2143 template <typename T1, typename T2> \
2144 SACADO_INLINE_FUNCTION \
2146 operator OP (const Expr<T1>& expr1, \
2147 const Expr<T2>& expr2) \
2149 return toBool(expr1) OP toBool(expr2); \
2152 template <typename T2> \
2153 SACADO_INLINE_FUNCTION \
2155 operator OP (const typename Expr<T2>::value_type& a, \
2156 const Expr<T2>& expr2) \
2158 return a OP toBool(expr2); \
2161 template <typename T1> \
2162 SACADO_INLINE_FUNCTION \
2164 operator OP (const Expr<T1>& expr1, \
2165 const typename Expr<T1>::value_type& b) \
2167 return toBool(expr1) OP b; \
2176 #undef FAD_BOOL_MACRO
2185 template <
typename T>
2186 std::ostream& operator << (std::ostream& os, const Expr<T>& xx) {
2188 os << x.val() <<
" [";
2190 for (
int i=0;
i< x.size();
i++) {
2191 os <<
" " << x.dx(
i);
2203 #if defined(HAVE_SACADO_KOKKOS)
2213 template <
typename S>
2215 void atomic_add(GeneralFad<S>* dst,
const GeneralFad<S>&
x) {
2216 using Kokkos::atomic_add;
2218 const int xsz = x.size();
2219 const int sz = dst->size();
2225 "Sacado error: Fad resize within atomic_add() not supported!");
2227 if (xsz != sz && sz > 0 && xsz > 0)
2229 "Sacado error: Fad assignment of incompatiable sizes!");
2232 if (sz > 0 && xsz > 0) {
2237 atomic_add(&(dst->
val()), x.val());
2245 #endif // HAVE_SACADO_KOKKOS
2247 #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
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SACADO_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E >::value_type type
#define FAD_UNARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, FASTACCESSDX)
SACADO_INLINE_FUNCTION int size() const
static constexpr bool value
#define SACADO_FAD_EXP_OP_ENABLE_EXPR_EXPR(OP)
SACADO_INLINE_FUNCTION IfThenElseOp(const CondT &cond_, const ConstT &c_, const T2 &expr2_)
SACADO_INLINE_FUNCTION value_type val() const
Base template specification for ScalarType.
#define SACADO_FAD_THREAD_SINGLE
SACADO_INLINE_FUNCTION bool hasFastAccess() const
ExprT2::scalar_type scalar_type
Sacado::Promote< base_expr_1, base_expr_2 >::type type
SACADO_INLINE_FUNCTION value_type fastAccessDx(int i) const
Determine whether a given type is an expression.
Wrapper for a generic expression template.
Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E >::scalar_type type
BaseExprType< T1 >::type base_expr_1
ExprT1::scalar_type scalar_type
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
ExprT1::value_type value_type_1
ExprT1::scalar_type scalar_type_1
Base template specification for IsSimdType.
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
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)
SACADO_INLINE_FUNCTION const derived_type & derived() const
Return derived object.
SACADO_INLINE_FUNCTION T if_then_else(const Cond cond, const T &a, const T &b)
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
SACADO_INLINE_FUNCTION value_type dx(int i) const
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
SACADO_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)
SACADO_INLINE_FUNCTION IfThenElseOp(const CondT &cond_, const T1 &expr1_, const T2 &expr2_)
Meta-function for determining nesting with an expression.
#define FAD_RELOP_MACRO(OP)
atan2(expr1.val(), expr2.val())
#define SACADO_FAD_EXP_OP_ENABLE_EXPR_SCALAR(OP)
SACADO_INLINE_FUNCTION value_type dx(int i) const
ExprSpecDefault expr_spec_type
SACADO_INLINE_FUNCTION int size() const
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
SACADO_INLINE_FUNCTION IfThenElseOp(const CondT &cond_, const T1 &expr1_, const ConstT &c_)
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION T safe_sqrt(const T &x)
SACADO_INLINE_FUNCTION value_type val() const
Sacado::Promote< scalar_type_1, scalar_type_2 >::type scalar_type
std::remove_cv< T1 >::type ExprT1
SACADO_INLINE_FUNCTION bool toBool(const Expr< T > &xx)
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)
SACADO_INLINE_FUNCTION value_type dx(int i) const
ExprSpecDefault expr_spec_type
SACADO_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)
ExprSpecDefault expr_spec_type
BaseExprType< T2 >::type base_expr_2
SACADO_INLINE_FUNCTION value_type fastAccessDx(int i) const
Sacado::Promote< value_type_1, value_type_2 >::type value_type
#define SACADO_INLINE_FUNCTION
SACADO_INLINE_FUNCTION value_type fastAccessDx(int i) const
std::remove_cv< T2 >::type ExprT2
Base template specification for ValueType.
static constexpr unsigned value
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SACADO_INLINE_FUNCTION int size() 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