10 #ifndef SACADO_FAD_EXP_OPS_HPP
11 #define SACADO_FAD_EXP_OPS_HPP
13 #include <type_traits>
23 #if defined(HAVE_SACADO_KOKKOS)
24 #include "Kokkos_Atomic.hpp"
25 #include "impl/Kokkos_Error.hpp"
28 #define FAD_UNARYOP_MACRO(OPNAME,OP,USING,VALUE,DX,FASTACCESSDX) \
33 template <typename T, typename ExprSpec> \
36 template <typename T> \
37 class OP< T,ExprSpecDefault > : \
38 public Expr< OP<T,ExprSpecDefault> > { \
41 typedef typename std::remove_cv<T>::type ExprT; \
42 typedef typename ExprT::value_type value_type; \
43 typedef typename ExprT::scalar_type scalar_type; \
45 typedef ExprSpecDefault expr_spec_type; \
47 SACADO_INLINE_FUNCTION \
48 explicit OP(const T& expr_) : expr(expr_) {} \
50 SACADO_INLINE_FUNCTION \
51 int size() const { return expr.size(); } \
53 SACADO_INLINE_FUNCTION \
54 bool hasFastAccess() const { \
55 return expr.hasFastAccess(); \
58 SACADO_INLINE_FUNCTION \
59 value_type val() const { \
64 SACADO_INLINE_FUNCTION \
65 value_type dx(int i) const { \
70 SACADO_INLINE_FUNCTION \
71 value_type fastAccessDx(int i) const { \
73 return FASTACCESSDX; \
81 template <typename T> \
82 SACADO_INLINE_FUNCTION \
83 OP< typename Expr<T>::derived_type, \
84 typename T::expr_spec_type > \
85 OPNAME (const Expr<T>& expr) \
87 typedef OP< typename Expr<T>::derived_type, \
88 typename T::expr_spec_type > expr_t; \
90 return expr_t(expr.derived()); \
93 template <typename T, typename E> \
94 struct ExprLevel< OP< T,E > > { \
95 static const unsigned value = ExprLevel<T>::value; \
98 template <typename T, typename E> \
99 struct IsFadExpr< OP< T,E > > { \
100 static const unsigned value = true; \
106 template <typename T, typename E> \
107 struct IsExpr< Fad::Exp::OP< T,E > > { \
108 static const bool value = true; \
111 template <typename T, typename E> \
112 struct BaseExprType< Fad::Exp::OP< T,E > > { \
113 typedef typename BaseExprType<T>::type type; \
116 template <typename T, typename E> \
117 struct IsSimdType< Fad::Exp::OP< T,E > > { \
118 static const bool value = \
119 IsSimdType< typename Fad::Exp::OP< T,E >::scalar_type >::value; \
122 template <typename T, typename E> \
123 struct ValueType< Fad::Exp::OP< T,E > > { \
124 typedef typename Fad::Exp::OP< T,E >::value_type type; \
127 template <typename T, typename E> \
128 struct ScalarType< Fad::Exp::OP< T,E > > { \
129 typedef typename Fad::Exp::OP< T,E >::scalar_type type; \
139 expr.fastAccessDx(
i))
145 -expr.fastAccessDx(
i))
150 exp(expr.val())*expr.dx(
i),
151 exp(expr.val())*expr.fastAccessDx(
i))
156 expr.dx(
i)/expr.val(),
157 expr.fastAccessDx(
i)/expr.val())
162 expr.dx(
i)/(
log(value_type(10))*expr.val()),
163 expr.fastAccessDx(
i) / (
log(value_type(10))*expr.val()))
168 expr.
dx(
i)/(value_type(2)* sqrt(expr.val())),
172 using std::cos; using std::
sin;,
174 -expr.
dx(
i)* sin(expr.val()),
178 using std::cos; using std::sin;,
180 expr.
dx(
i)* cos(expr.val()),
187 (value_type(1)+ tan(expr.val())* tan(expr.val())),
189 (value_type(1)+ tan(expr.val())* tan(expr.val())))
192 using std::acos; using std::sqrt;,
194 -expr.
dx(
i)/ sqrt(value_type(1)-expr.val()*expr.val()),
196 sqrt(value_type(1)-expr.val()*expr.val()))
199 using std::asin; using std::sqrt;,
201 expr.
dx(
i)/ sqrt(value_type(1)-expr.val()*expr.val()),
203 sqrt(value_type(1)-expr.val()*expr.val()))
208 expr.
dx(
i)/(value_type(1)+expr.val()*expr.val()),
212 using std::cosh; using std::
sinh;,
214 expr.
dx(
i)* sinh(expr.val()),
218 using std::cosh; using std::sinh;,
220 expr.
dx(
i)* cosh(expr.val()),
226 expr.
dx(
i)*(value_type(1)-tanh(expr.val())*tanh(expr.val())),
227 expr.
fastAccessDx(
i)*(value_type(1)-tanh(expr.val())*tanh(expr.val())))
230 using std::acosh; using std::sqrt;,
232 expr.
dx(
i)/ sqrt((expr.val()-value_type(1)) *
233 (expr.val()+value_type(1))),
235 (expr.val()+value_type(1))))
238 using std::asinh; using std::sqrt;,
240 expr.
dx(
i)/ sqrt(value_type(1)+expr.val()*expr.val()),
242 expr.val()*expr.val()))
247 expr.
dx(
i)/(value_type(1)-expr.val()*expr.val()),
249 expr.val()*expr.val()))
254 if_then_else( expr.val() >= 0, expr.
dx(
i), value_type(-expr.
dx(i)) ),
258 using std::fabs; using Sacado::if_then_else;,
260 if_then_else( expr.val() >= 0, expr.
dx(i), value_type(-expr.
dx(i)) ),
266 expr.
dx(i)/(value_type(3)*cbrt(expr.val()*expr.val())),
277 template <
typename T,
typename ExprSpec,
bool is_simd>
283 template <
typename T>
285 public Expr< SafeSqrtOp<T,ExprSpecDefault> > {
288 typedef typename std::remove_cv<T>::type ExprT;
289 typedef typename ExprT::value_type value_type;
290 typedef typename ExprT::scalar_type scalar_type;
292 typedef ExprSpecDefault expr_spec_type;
295 explicit SafeSqrtOp(
const T& expr_) : expr(expr_) {}
298 int size()
const {
return expr.size(); }
301 bool hasFastAccess()
const {
302 return expr.hasFastAccess();
306 value_type
val()
const {
308 return sqrt(expr.val());
312 value_type
dx(
int i)
const {
315 expr.val() == value_type(0.0), value_type(0.0),
316 value_type(expr.dx(i)/(value_type(2)*
sqrt(expr.val()))));
323 expr.val() == value_type(0.0), value_type(0.0),
324 value_type(expr.fastAccessDx(i)/(value_type(2)*
sqrt(expr.val()))));
335 template <
typename T>
337 public Expr< SafeSqrtOp<T,ExprSpecDefault> > {
340 typedef typename std::remove_cv<T>::type ExprT;
341 typedef typename ExprT::value_type value_type;
342 typedef typename ExprT::scalar_type scalar_type;
344 typedef ExprSpecDefault expr_spec_type;
347 explicit SafeSqrtOp(
const T& expr_) : expr(expr_) {}
350 int size()
const {
return expr.size(); }
353 bool hasFastAccess()
const {
354 return expr.hasFastAccess();
358 value_type
val()
const {
360 return sqrt(expr.val());
364 value_type
dx(
int i)
const {
366 return expr.val() == value_type(0.0) ? value_type(0.0) :
367 value_type(expr.dx(i)/(value_type(2)*
sqrt(expr.val())));
373 return expr.val() == value_type(0.0) ? value_type(0.0) :
374 value_type(expr.fastAccessDx(i)/(value_type(2)*
sqrt(expr.val())));
382 template <
typename T>
384 SafeSqrtOp< typename Expr<T>::derived_type,
385 typename T::expr_spec_type >
388 typedef SafeSqrtOp< typename Expr<T>::derived_type,
389 typename T::expr_spec_type > expr_t;
391 return expr_t(expr.derived());
394 template <
typename T,
typename E>
395 struct ExprLevel< SafeSqrtOp< T,E > > {
399 template <
typename T,
typename E>
400 struct IsFadExpr< SafeSqrtOp< T,E > > {
401 static const unsigned value =
true;
407 template <
typename T,
typename E>
409 static const bool value =
true;
412 template <
typename T,
typename E>
414 typedef typename BaseExprType<T>::type type;
417 template <
typename T,
typename E>
419 static const bool value =
420 IsSimdType< typename Fad::Exp::SafeSqrtOp< T,E >::scalar_type >
::value;
423 template <
typename T,
typename E>
425 typedef typename Fad::Exp::SafeSqrtOp< T,E >::value_type type;
428 template <
typename T,
typename E>
430 typedef typename Fad::Exp::SafeSqrtOp< T,E >::scalar_type type;
435 #undef FAD_UNARYOP_MACRO
437 #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) \
442 template <typename T1, typename T2, \
443 bool is_const_T1, bool is_const_T2, \
444 typename ExprSpec > \
447 template <typename T1, typename T2> \
448 class OP< T1, T2, false, false, ExprSpecDefault > : \
449 public Expr< OP< T1, T2, false, false, ExprSpecDefault > > { \
452 typedef typename std::remove_cv<T1>::type ExprT1; \
453 typedef typename std::remove_cv<T2>::type ExprT2; \
454 typedef typename ExprT1::value_type value_type_1; \
455 typedef typename ExprT2::value_type value_type_2; \
456 typedef typename Sacado::Promote<value_type_1, \
457 value_type_2>::type value_type; \
459 typedef typename ExprT1::scalar_type scalar_type_1; \
460 typedef typename ExprT2::scalar_type scalar_type_2; \
461 typedef typename Sacado::Promote<scalar_type_1, \
462 scalar_type_2>::type scalar_type; \
464 typedef ExprSpecDefault expr_spec_type; \
466 SACADO_INLINE_FUNCTION \
467 OP(const T1& expr1_, const T2& expr2_) : \
468 expr1(expr1_), expr2(expr2_) {} \
470 SACADO_INLINE_FUNCTION \
472 const int sz1 = expr1.size(), sz2 = expr2.size(); \
473 return sz1 > sz2 ? sz1 : sz2; \
476 SACADO_INLINE_FUNCTION \
477 bool hasFastAccess() const { \
478 return expr1.hasFastAccess() && expr2.hasFastAccess(); \
481 SACADO_INLINE_FUNCTION \
482 value_type val() const { \
487 SACADO_INLINE_FUNCTION \
488 value_type dx(int i) const { \
490 const int sz1 = expr1.size(), sz2 = expr2.size(); \
491 if (sz1 > 0 && sz2 > 0) \
499 SACADO_INLINE_FUNCTION \
500 value_type fastAccessDx(int i) const { \
502 return FASTACCESSDX; \
512 template <typename T1, typename T2> \
513 class OP< T1, T2, false, true, ExprSpecDefault > \
514 : public Expr< OP< T1, T2, false, true, ExprSpecDefault > > { \
517 typedef typename std::remove_cv<T1>::type ExprT1; \
519 typedef typename ExprT1::value_type value_type; \
520 typedef typename ExprT1::scalar_type scalar_type; \
522 typedef ExprSpecDefault expr_spec_type; \
524 SACADO_INLINE_FUNCTION \
525 OP(const T1& expr1_, const ConstT& c_) : \
526 expr1(expr1_), c(c_) {} \
528 SACADO_INLINE_FUNCTION \
530 return expr1.size(); \
533 SACADO_INLINE_FUNCTION \
534 bool hasFastAccess() const { \
535 return expr1.hasFastAccess(); \
538 SACADO_INLINE_FUNCTION \
539 value_type val() const { \
541 return VAL_CONST_DX_2; \
544 SACADO_INLINE_FUNCTION \
545 value_type dx(int i) const { \
550 SACADO_INLINE_FUNCTION \
551 value_type fastAccessDx(int i) const { \
553 return CONST_FASTACCESSDX_2; \
562 template <typename T1, typename T2> \
563 class OP< T1, T2, true, false, ExprSpecDefault > \
564 : public Expr< OP< T1, T2, true, false, ExprSpecDefault > > { \
567 typedef typename std::remove_cv<T2>::type ExprT2; \
569 typedef typename ExprT2::value_type value_type; \
570 typedef typename ExprT2::scalar_type scalar_type; \
572 typedef ExprSpecDefault expr_spec_type; \
574 SACADO_INLINE_FUNCTION \
575 OP(const ConstT& c_, const T2& expr2_) : \
576 c(c_), expr2(expr2_) {} \
578 SACADO_INLINE_FUNCTION \
580 return expr2.size(); \
583 SACADO_INLINE_FUNCTION \
584 bool hasFastAccess() const { \
585 return expr2.hasFastAccess(); \
588 SACADO_INLINE_FUNCTION \
589 value_type val() const { \
591 return VAL_CONST_DX_1; \
594 SACADO_INLINE_FUNCTION \
595 value_type dx(int i) const { \
600 SACADO_INLINE_FUNCTION \
601 value_type fastAccessDx(int i) const { \
603 return CONST_FASTACCESSDX_1; \
612 template <typename T1, typename T2> \
613 SACADO_INLINE_FUNCTION \
614 SACADO_FAD_EXP_OP_ENABLE_EXPR_EXPR(OP) \
615 OPNAME (const T1& expr1, const T2& expr2) \
617 typedef OP< typename Expr<T1>::derived_type, \
618 typename Expr<T2>::derived_type, \
619 false, false, typename T1::expr_spec_type > expr_t; \
621 return expr_t(expr1.derived(), expr2.derived()); \
624 template <typename T> \
625 SACADO_INLINE_FUNCTION \
626 OP< typename T::value_type, typename Expr<T>::derived_type, \
627 true, false, typename T::expr_spec_type > \
628 OPNAME (const typename T::value_type& c, \
629 const Expr<T>& expr) \
631 typedef typename T::value_type ConstT; \
632 typedef OP< ConstT, typename Expr<T>::derived_type, \
633 true, false, typename T::expr_spec_type > expr_t; \
635 return expr_t(c, expr.derived()); \
638 template <typename T> \
639 SACADO_INLINE_FUNCTION \
640 OP< typename Expr<T>::derived_type, typename T::value_type, \
641 false, true, typename T::expr_spec_type > \
642 OPNAME (const Expr<T>& expr, \
643 const typename T::value_type& c) \
645 typedef typename T::value_type ConstT; \
646 typedef OP< typename Expr<T>::derived_type, ConstT, \
647 false, true, typename T::expr_spec_type > expr_t; \
649 return expr_t(expr.derived(), c); \
652 template <typename T> \
653 SACADO_INLINE_FUNCTION \
654 SACADO_FAD_EXP_OP_ENABLE_SCALAR_EXPR(OP) \
655 OPNAME (const typename T::scalar_type& c, \
656 const Expr<T>& expr) \
658 typedef typename T::scalar_type ConstT; \
659 typedef OP< ConstT, typename Expr<T>::derived_type, \
660 true, false, typename T::expr_spec_type > expr_t; \
662 return expr_t(c, expr.derived()); \
665 template <typename T> \
666 SACADO_INLINE_FUNCTION \
667 SACADO_FAD_EXP_OP_ENABLE_EXPR_SCALAR(OP) \
668 OPNAME (const Expr<T>& expr, \
669 const typename T::scalar_type& c) \
671 typedef typename T::scalar_type ConstT; \
672 typedef OP< typename Expr<T>::derived_type, ConstT, \
673 false, true, typename T::expr_spec_type > expr_t; \
675 return expr_t(expr.derived(), c); \
678 template <typename T1, typename T2, bool c1, bool c2, typename E> \
679 struct ExprLevel< OP< T1, T2, c1, c2, E > > { \
680 static constexpr unsigned value_1 = ExprLevel<T1>::value; \
681 static constexpr unsigned value_2 = ExprLevel<T2>::value; \
682 static constexpr unsigned value = \
683 value_1 >= value_2 ? value_1 : value_2; \
686 template <typename T1, typename T2, bool c1, bool c2, typename E> \
687 struct IsFadExpr< OP< T1, T2, c1, c2, E > > { \
688 static constexpr unsigned value = true; \
694 template <typename T1, typename T2, bool c1, bool c2, typename E> \
695 struct IsExpr< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
696 static constexpr bool value = true; \
699 template <typename T1, typename T2, bool c1, bool c2, typename E> \
700 struct BaseExprType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
701 typedef typename BaseExprType<T1>::type base_expr_1; \
702 typedef typename BaseExprType<T2>::type base_expr_2; \
703 typedef typename Sacado::Promote<base_expr_1, \
704 base_expr_2>::type type; \
707 template <typename T1, typename T2, bool c1, bool c2, typename E> \
708 struct IsSimdType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
709 static const bool value = \
710 IsSimdType< typename Fad::Exp::OP< T1, T2, c1, c2, E >::value_type >::value; \
713 template <typename T1, typename T2, bool c1, bool c2, typename E> \
714 struct ValueType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
715 typedef typename Fad::Exp::OP< T1, T2, c1, c2, E >::value_type type;\
718 template <typename T1, typename T2, bool c1, bool c2, typename E> \
719 struct ScalarType< Fad::Exp::OP< T1, T2, c1, c2, E > > { \
720 typedef typename Fad::Exp::OP< T1, T2, c1, c2, E >::scalar_type type;\
729 expr1.val() + expr2.val(),
730 expr1.dx(
i) + expr2.dx(
i),
733 expr1.fastAccessDx(
i) + expr2.fastAccessDx(
i),
738 expr2.fastAccessDx(
i),
739 expr1.fastAccessDx(
i))
743 expr1.val() - expr2.val(),
744 expr1.dx(
i) - expr2.dx(
i),
747 expr1.fastAccessDx(
i) - expr2.fastAccessDx(
i),
752 -expr2.fastAccessDx(
i),
753 expr1.fastAccessDx(
i))
757 expr1.val() * expr2.val(),
758 expr1.val()*expr2.dx(
i) + expr1.dx(
i)*expr2.val(),
759 expr1.val()*expr2.dx(
i),
760 expr1.dx(
i)*expr2.val(),
761 expr1.val()*expr2.fastAccessDx(
i) +
762 expr1.fastAccessDx(
i)*expr2.val(),
767 c*expr2.fastAccessDx(
i),
768 expr1.fastAccessDx(
i)*
c)
772 expr1.val() / expr2.val(),
773 (expr1.dx(
i)*expr2.val() - expr2.dx(
i)*expr1.val()) /
774 (expr2.val()*expr2.val()),
775 -expr2.dx(
i)*expr1.val() / (expr2.val()*expr2.val()),
776 expr1.dx(
i)/expr2.val(),
777 (expr1.fastAccessDx(
i)*expr2.val() -
778 expr2.fastAccessDx(
i)*expr1.val()) /
779 (expr2.val()*expr2.val()),
782 -expr2.dx(
i)*
c / (expr2.val()*expr2.val()),
784 -expr2.fastAccessDx(
i)*
c / (expr2.val()*expr2.val()),
785 expr1.fastAccessDx(
i)/
c)
789 atan2(expr1.val(), expr2.val()),
790 (expr2.val()*expr1.dx(
i) - expr1.val()*expr2.dx(
i))/
791 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
792 -expr1.val()*expr2.dx(
i)/
793 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
794 expr2.val()*expr1.dx(
i)/
795 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
796 (expr2.val()*expr1.fastAccessDx(
i) - expr1.val()*expr2.fastAccessDx(
i))/
797 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
800 (-
c*expr2.dx(
i)) / (
c*
c + expr2.val()*expr2.val()),
801 (
c*expr1.dx(
i))/ (expr1.val()*expr1.val() +
c*
c),
802 (-
c*expr2.fastAccessDx(
i))/ (
c*
c + expr2.val()*expr2.val()),
803 (
c*expr1.fastAccessDx(
i))/ (expr1.val()*expr1.val() +
c*
c))
821 if_then_else( expr1.
val() >= expr2.
val(), expr1.val(), expr2.val() ),
822 if_then_else( expr1.val() >= expr2.val(), expr1.
dx(
i), expr2.
dx(i) ),
823 if_then_else( expr1.val() >= expr2.val(), value_type(0.0), expr2.
dx(i) ),
824 if_then_else( expr1.val() >= expr2.val(), expr1.
dx(i), value_type(0.0) ),
826 if_then_else(
c >= expr2.val(), value_type(
c), expr2.val() ),
827 if_then_else( expr1.val() >= c, expr1.val(), value_type(c) ),
828 if_then_else( c >= expr2.val(), value_type(0.0), expr2.
dx(i) ),
829 if_then_else( expr1.val() >= c, expr1.
dx(i), value_type(0.0) ),
830 if_then_else( c >= expr2.val(), value_type(0.0), expr2.
fastAccessDx(i) ),
831 if_then_else( expr1.val() >= c, expr1.
fastAccessDx(i), value_type(0.0) ) )
834 using Sacado::if_then_else;,
835 if_then_else( expr1.val() <= expr2.val(), expr1.val(), expr2.val() ),
836 if_then_else( expr1.val() <= expr2.val(), expr1.
dx(i), expr2.
dx(i) ),
837 if_then_else( expr1.val() <= expr2.val(), value_type(0.0), expr2.
dx(i) ),
838 if_then_else( expr1.val() <= expr2.val(), expr1.
dx(i), value_type(0.0) ),
840 if_then_else( c <= expr2.val(), value_type(c), expr2.val() ),
841 if_then_else( expr1.val() <= c, expr1.val(), value_type(c) ),
842 if_then_else( c <= expr2.val(), value_type(0), expr2.
dx(i) ),
843 if_then_else( expr1.val() <= c, expr1.
dx(i), value_type(0) ),
844 if_then_else( c <= expr2.val(), value_type(0), expr2.
fastAccessDx(i) ),
845 if_then_else( expr1.val() <= c, expr1.
fastAccessDx(i), value_type(0) ) )
856 template <
typename T1,
typename T2,
857 bool is_const_T1,
bool is_const_T2,
858 typename ExprSpec,
typename Impl >
864 template <
typename T1,
typename T2>
865 class PowerOp< T1, T2, false, false, ExprSpecDefault,
867 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault,
868 PowerImpl::Simd > > {
871 typedef typename std::remove_cv<T1>::type ExprT1;
872 typedef typename std::remove_cv<T2>::type ExprT2;
873 typedef typename ExprT1::value_type value_type_1;
874 typedef typename ExprT2::value_type value_type_2;
876 value_type_2>::type value_type;
878 typedef typename ExprT1::scalar_type scalar_type_1;
879 typedef typename ExprT2::scalar_type scalar_type_2;
881 scalar_type_2>::type scalar_type;
883 typedef ExprSpecDefault expr_spec_type;
886 PowerOp(
const T1& expr1_,
const T2& expr2_) :
887 expr1(expr1_), expr2(expr2_) {}
891 const int sz1 = expr1.size(), sz2 = expr2.size();
892 return sz1 > sz2 ? sz1 : sz2;
896 bool hasFastAccess()
const {
897 return expr1.hasFastAccess() && expr2.hasFastAccess();
901 value_type
val()
const {
903 return pow(expr1.val(), expr2.val());
907 value_type
dx(
int i)
const {
909 const int sz1 = expr1.size(), sz2 = expr2.size();
910 if (sz1 > 0 && sz2 > 0)
911 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())) );
915 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())) ));
917 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())) );
923 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())));
933 template <
typename T1,
typename T2>
934 class PowerOp< T1, T2, false, true, ExprSpecDefault,
936 public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault,
937 PowerImpl::Simd > > {
940 typedef typename std::remove_cv<T1>::type ExprT1;
942 typedef typename ExprT1::value_type value_type;
943 typedef typename ExprT1::scalar_type scalar_type;
945 typedef ExprSpecDefault expr_spec_type;
948 PowerOp(
const T1& expr1_,
const ConstT&
c_) :
949 expr1(expr1_),
c(c_) {}
957 bool hasFastAccess()
const {
958 return expr1.hasFastAccess();
962 value_type
val()
const {
964 return pow(expr1.val(),
c);
968 value_type
dx(
int i)
const {
972 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)) ));
980 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)) ));
989 template <
typename T1,
typename T2>
990 class PowerOp< T1, T2, true, false, ExprSpecDefault,
992 public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault,
993 PowerImpl::Simd > > {
996 typedef typename std::remove_cv<T2>::type ExprT2;
998 typedef typename ExprT2::value_type value_type;
999 typedef typename ExprT2::scalar_type scalar_type;
1001 typedef ExprSpecDefault expr_spec_type;
1004 PowerOp(
const ConstT&
c_,
const T2& expr2_) :
1005 c(c_), expr2(expr2_) {}
1009 return expr2.size();
1013 bool hasFastAccess()
const {
1014 return expr2.hasFastAccess();
1018 value_type
val()
const {
1020 return pow(c, expr2.val());
1024 value_type
dx(
int i)
const {
1026 return if_then_else( c == scalar_type(0.0), value_type(0.0), value_type(expr2.dx(i)*
log(c)*
pow(c,expr2.val())) );
1032 return if_then_else( c == scalar_type(0.0), value_type(0.0), value_type(expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val())) );
1045 template <
typename T1,
typename T2>
1046 class PowerOp< T1, T2, false, false, ExprSpecDefault,
1047 PowerImpl::Scalar > :
1048 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault,
1049 PowerImpl::Scalar > > {
1052 typedef typename std::remove_cv<T1>::type ExprT1;
1053 typedef typename std::remove_cv<T2>::type ExprT2;
1054 typedef typename ExprT1::value_type value_type_1;
1055 typedef typename ExprT2::value_type value_type_2;
1057 value_type_2>::type value_type;
1059 typedef typename ExprT1::scalar_type scalar_type_1;
1060 typedef typename ExprT2::scalar_type scalar_type_2;
1062 scalar_type_2>::type scalar_type;
1064 typedef ExprSpecDefault expr_spec_type;
1067 PowerOp(
const T1& expr1_,
const T2& expr2_) :
1068 expr1(expr1_), expr2(expr2_) {}
1072 const int sz1 = expr1.size(), sz2 = expr2.size();
1073 return sz1 > sz2 ? sz1 : sz2;
1077 bool hasFastAccess()
const {
1078 return expr1.hasFastAccess() && expr2.hasFastAccess();
1082 value_type
val()
const {
1084 return pow(expr1.val(), expr2.val());
1088 value_type
dx(
int i)
const {
1090 const int sz1 = expr1.size(), sz2 = expr2.size();
1091 if (sz1 > 0 && sz2 > 0)
1092 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()));
1096 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()));
1098 return expr1.val() == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.dx(i)*
log(expr1.val())*
pow(expr1.val(),expr2.val()));
1104 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()));
1114 template <
typename T1,
typename T2>
1115 class PowerOp< T1, T2, false, true, ExprSpecDefault,
1116 PowerImpl::Scalar > :
1117 public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault,
1118 PowerImpl::Scalar > > {
1121 typedef typename std::remove_cv<T1>::type ExprT1;
1123 typedef typename ExprT1::value_type value_type;
1124 typedef typename ExprT1::scalar_type scalar_type;
1126 typedef ExprSpecDefault expr_spec_type;
1129 PowerOp(
const T1& expr1_,
const ConstT&
c_) :
1130 expr1(expr1_),
c(c_) {}
1134 return expr1.size();
1138 bool hasFastAccess()
const {
1139 return expr1.hasFastAccess();
1143 value_type
val()
const {
1145 return pow(expr1.val(),
c);
1149 value_type
dx(
int i)
const {
1153 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));
1161 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));
1170 template <
typename T1,
typename T2>
1171 class PowerOp< T1, T2, true, false, ExprSpecDefault,
1172 PowerImpl::Scalar > :
1173 public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault,
1174 PowerImpl::Scalar > > {
1177 typedef typename std::remove_cv<T2>::type ExprT2;
1179 typedef typename ExprT2::value_type value_type;
1180 typedef typename ExprT2::scalar_type scalar_type;
1182 typedef ExprSpecDefault expr_spec_type;
1185 PowerOp(
const ConstT&
c_,
const T2& expr2_) :
1186 c(c_), expr2(expr2_) {}
1190 return expr2.size();
1194 bool hasFastAccess()
const {
1195 return expr2.hasFastAccess();
1199 value_type
val()
const {
1201 return pow(c, expr2.val());
1205 value_type
dx(
int i)
const {
1207 return c == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.dx(i)*
log(c)*
pow(c,expr2.val()));
1213 return c == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val()));
1227 template <
typename T1,
typename T2>
1228 class PowerOp< T1, T2, false, false, ExprSpecDefault,
1229 PowerImpl::Nested > :
1230 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault,
1231 PowerImpl::Nested > > {
1234 typedef typename std::remove_cv<T1>::type ExprT1;
1235 typedef typename std::remove_cv<T2>::type ExprT2;
1236 typedef typename ExprT1::value_type value_type_1;
1237 typedef typename ExprT2::value_type value_type_2;
1239 value_type_2>::type value_type;
1241 typedef typename ExprT1::scalar_type scalar_type_1;
1242 typedef typename ExprT2::scalar_type scalar_type_2;
1244 scalar_type_2>::type scalar_type;
1246 typedef ExprSpecDefault expr_spec_type;
1249 PowerOp(
const T1& expr1_,
const T2& expr2_) :
1250 expr1(expr1_), expr2(expr2_) {}
1254 const int sz1 = expr1.size(), sz2 = expr2.size();
1255 return sz1 > sz2 ? sz1 : sz2;
1259 bool hasFastAccess()
const {
1260 return expr1.hasFastAccess() && expr2.hasFastAccess();
1264 value_type
val()
const {
1266 return pow(expr1.val(), expr2.val());
1270 value_type
dx(
int i)
const {
1272 const int sz1 = expr1.size(), sz2 = expr2.size();
1273 if (sz1 > 0 && sz2 > 0)
1274 return (expr2.dx(i)*
log(expr1.val())+expr2.val()*expr1.dx(i)/expr1.val())*
pow(expr1.val(),expr2.val());
1276 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)));
1278 return expr2.dx(i)*
log(expr1.val())*
pow(expr1.val(),expr2.val());
1284 return (expr2.fastAccessDx(i)*
log(expr1.val())+expr2.val()*expr1.fastAccessDx(i)/expr1.val())*
pow(expr1.val(),expr2.val());
1294 template <
typename T1,
typename T2>
1295 class PowerOp< T1, T2, false, true, ExprSpecDefault,
1296 PowerImpl::Nested > :
1297 public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault,
1298 PowerImpl::Nested > > {
1301 typedef typename std::remove_cv<T1>::type ExprT1;
1303 typedef typename ExprT1::value_type value_type;
1304 typedef typename ExprT1::scalar_type scalar_type;
1306 typedef ExprSpecDefault expr_spec_type;
1309 PowerOp(
const T1& expr1_,
const ConstT&
c_) :
1310 expr1(expr1_),
c(c_) {}
1314 return expr1.size();
1318 bool hasFastAccess()
const {
1319 return expr1.hasFastAccess();
1323 value_type
val()
const {
1325 return pow(expr1.val(),
c);
1329 value_type
dx(
int i)
const {
1331 return c == scalar_type(0.0) ? value_type(0.0) : value_type(c*expr1.dx(i)*
pow(expr1.val(),c-scalar_type(1.0)));
1337 return c == scalar_type(0.0) ? value_type(0.0) : value_type(c*expr1.fastAccessDx(i)*
pow(expr1.val(),c-scalar_type(1.0)));
1346 template <
typename T1,
typename T2>
1347 class PowerOp<T1, T2, true, false, ExprSpecDefault,
1348 PowerImpl::Nested > :
1349 public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault,
1350 PowerImpl::Nested > > {
1353 typedef typename std::remove_cv<T2>::type ExprT2;
1355 typedef typename ExprT2::value_type value_type;
1356 typedef typename ExprT2::scalar_type scalar_type;
1358 typedef ExprSpecDefault expr_spec_type;
1361 PowerOp(
const ConstT&
c_,
const T2& expr2_) :
1362 c(c_), expr2(expr2_) {}
1366 return expr2.size();
1370 bool hasFastAccess()
const {
1371 return expr2.hasFastAccess();
1375 value_type
val()
const {
1377 return pow(c, expr2.val());
1381 value_type
dx(
int i)
const {
1383 return expr2.dx(i)*
log(c)*
pow(c,expr2.val());
1389 return expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val());
1403 template <
typename T1,
typename T2>
1404 class PowerOp< T1, T2, false, false, ExprSpecDefault,
1405 PowerImpl::NestedSimd > :
1406 public Expr< PowerOp< T1, T2, false, false, ExprSpecDefault,
1407 PowerImpl::NestedSimd > > {
1410 typedef typename std::remove_cv<T1>::type ExprT1;
1411 typedef typename std::remove_cv<T2>::type ExprT2;
1412 typedef typename ExprT1::value_type value_type_1;
1413 typedef typename ExprT2::value_type value_type_2;
1415 value_type_2>::type value_type;
1417 typedef typename ExprT1::scalar_type scalar_type_1;
1418 typedef typename ExprT2::scalar_type scalar_type_2;
1420 scalar_type_2>::type scalar_type;
1422 typedef ExprSpecDefault expr_spec_type;
1425 PowerOp(
const T1& expr1_,
const T2& expr2_) :
1426 expr1(expr1_), expr2(expr2_) {}
1430 const int sz1 = expr1.size(), sz2 = expr2.size();
1431 return sz1 > sz2 ? sz1 : sz2;
1435 bool hasFastAccess()
const {
1436 return expr1.hasFastAccess() && expr2.hasFastAccess();
1440 value_type
val()
const {
1442 return pow(expr1.val(), expr2.val());
1446 value_type
dx(
int i)
const {
1448 const int sz1 = expr1.size(), sz2 = expr2.size();
1449 if (sz1 > 0 && sz2 > 0)
1450 return (expr2.dx(i)*
log(expr1.val())+expr2.val()*expr1.dx(i)/expr1.val())*
pow(expr1.val(),expr2.val());
1452 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))));
1454 return expr2.dx(i)*
log(expr1.val())*
pow(expr1.val(),expr2.val());
1460 return (expr2.fastAccessDx(i)*
log(expr1.val())+expr2.val()*expr1.fastAccessDx(i)/expr1.val())*
pow(expr1.val(),expr2.val());
1470 template <
typename T1,
typename T2>
1471 class PowerOp< T1, T2, false, true, ExprSpecDefault,
1472 PowerImpl::NestedSimd > :
1473 public Expr< PowerOp< T1, T2, false, true, ExprSpecDefault,
1474 PowerImpl::NestedSimd > > {
1477 typedef typename std::remove_cv<T1>::type ExprT1;
1479 typedef typename ExprT1::value_type value_type;
1480 typedef typename ExprT1::scalar_type scalar_type;
1482 typedef ExprSpecDefault expr_spec_type;
1485 PowerOp(
const T1& expr1_,
const ConstT&
c_) :
1486 expr1(expr1_),
c(c_) {}
1490 return expr1.size();
1494 bool hasFastAccess()
const {
1495 return expr1.hasFastAccess();
1499 value_type
val()
const {
1501 return pow(expr1.val(),
c);
1505 value_type
dx(
int i)
const {
1507 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))));
1513 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))));
1522 template <
typename T1,
typename T2>
1523 class PowerOp<T1, T2, true, false, ExprSpecDefault,
1524 PowerImpl::NestedSimd > :
1525 public Expr< PowerOp< T1, T2, true, false, ExprSpecDefault,
1526 PowerImpl::NestedSimd > > {
1529 typedef typename std::remove_cv<T2>::type ExprT2;
1531 typedef typename ExprT2::value_type value_type;
1532 typedef typename ExprT2::scalar_type scalar_type;
1534 typedef ExprSpecDefault expr_spec_type;
1537 PowerOp(
const ConstT&
c_,
const T2& expr2_) :
1538 c(c_), expr2(expr2_) {}
1542 return expr2.size();
1546 bool hasFastAccess()
const {
1547 return expr2.hasFastAccess();
1551 value_type
val()
const {
1553 return pow(c, expr2.val());
1557 value_type
dx(
int i)
const {
1559 return expr2.dx(i)*
log(c)*
pow(c,expr2.val());
1565 return expr2.fastAccessDx(i)*
log(c)*
pow(c,expr2.val());
1574 template <
typename T1,
typename T2>
1577 pow (
const T1& expr1,
const T2& expr2)
1579 typedef PowerOp< typename Expr<T1>::derived_type,
1580 typename Expr<T2>::derived_type,
1581 false,
false,
typename T1::expr_spec_type > expr_t;
1583 return expr_t(expr1.derived(), expr2.derived());
1586 template <
typename T>
1588 PowerOp< typename T::value_type, typename Expr<T>::derived_type,
1589 true,
false,
typename T::expr_spec_type >
1590 pow (
const typename T::value_type& c,
1591 const Expr<T>& expr)
1593 typedef typename T::value_type ConstT;
1594 typedef PowerOp< ConstT, typename Expr<T>::derived_type,
1595 true,
false,
typename T::expr_spec_type > expr_t;
1597 return expr_t(c, expr.derived());
1600 template <
typename T>
1602 PowerOp< typename Expr<T>::derived_type,
typename T::value_type,
1603 false,
true,
typename T::expr_spec_type >
1604 pow (
const Expr<T>& expr,
1605 const typename T::value_type& c)
1607 typedef typename T::value_type ConstT;
1608 typedef PowerOp< typename Expr<T>::derived_type, ConstT,
1609 false,
true,
typename T::expr_spec_type > expr_t;
1611 return expr_t(expr.derived(),
c);
1614 template <
typename T>
1617 pow (
const typename T::scalar_type& c,
1618 const Expr<T>& expr)
1620 typedef typename T::scalar_type ConstT;
1621 typedef PowerOp< ConstT, typename Expr<T>::derived_type,
1622 true,
false,
typename T::expr_spec_type > expr_t;
1624 return expr_t(c, expr.derived());
1627 template <
typename T>
1630 pow (
const Expr<T>& expr,
1631 const typename T::scalar_type& c)
1633 typedef typename T::scalar_type ConstT;
1634 typedef PowerOp< typename Expr<T>::derived_type, ConstT,
1635 false,
true,
typename T::expr_spec_type > expr_t;
1637 return expr_t(expr.derived(),
c);
1640 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1641 struct ExprLevel< PowerOp< T1, T2, c1, c2, E > > {
1644 static constexpr
unsigned value =
1645 value_1 >= value_2 ? value_1 : value_2;
1648 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1649 struct IsFadExpr< PowerOp< T1, T2, c1, c2, E > > {
1650 static constexpr
unsigned value =
true;
1656 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1657 struct IsExpr< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1658 static constexpr
bool value =
true;
1661 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1662 struct BaseExprType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1663 typedef typename BaseExprType<T1>::type base_expr_1;
1664 typedef typename BaseExprType<T2>::type base_expr_2;
1666 base_expr_2>::type type;
1669 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1670 struct IsSimdType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1671 static const bool value =
1672 IsSimdType< typename Fad::Exp::PowerOp< T1, T2, c1, c2, E >::value_type >
::value;
1675 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1676 struct ValueType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1677 typedef typename Fad::Exp::PowerOp< T1, T2, c1, c2, E >::value_type type;
1680 template <
typename T1,
typename T2,
bool c1,
bool c2,
typename E>
1681 struct ScalarType< Fad::
Exp::PowerOp< T1, T2, c1, c2, E > > {
1682 typedef typename Fad::Exp::PowerOp< T1, T2, c1, c2, E >::scalar_type type;
1695 template <
typename CondT,
typename T1,
typename T2,
1696 bool is_const_T1,
bool is_const_T2,
1700 template <
typename CondT,
typename T1,
typename T2>
1702 public Expr< IfThenElseOp< CondT, T1, T2, false, false, ExprSpecDefault > > {
1706 typedef typename std::remove_cv<T1>::type
ExprT1;
1707 typedef typename std::remove_cv<T2>::type
ExprT2;
1722 cond(cond_), expr1(expr1_), expr2(expr2_) {}
1726 int sz1 = expr1.size(), sz2 = expr2.size();
1727 return sz1 > sz2 ? sz1 : sz2;
1732 return expr1.hasFastAccess() && expr2.hasFastAccess();
1750 return if_then_else( cond, expr1.fastAccessDx(i), expr2.fastAccessDx(i) );
1761 template <
typename CondT,
typename T1,
typename T2>
1763 public Expr< IfThenElseOp< CondT, T1, T2, false, true, ExprSpecDefault > > {
1767 typedef typename std::remove_cv<T1>::type
ExprT1;
1776 cond(cond_), expr1(expr1_),
c(c_) {}
1780 return expr1.size();
1785 return expr1.hasFastAccess();
1813 template <
typename CondT,
typename T1,
typename T2>
1815 public Expr< IfThenElseOp< CondT, T1, T2, true, false, ExprSpecDefault > > {
1819 typedef typename std::remove_cv<T2>::type
ExprT2;
1828 cond(cond_),
c(c_), expr2(expr2_) {}
1832 return expr2.size();
1837 return expr2.hasFastAccess();
1865 template <
typename CondT,
typename T1,
typename T2>
1873 typename T1::expr_spec_type >
1879 false,
false,
typename T1::expr_spec_type > expr_t;
1881 return expr_t(cond, expr1.derived(), expr2.derived());
1884 template <
typename CondT,
typename T>
1887 true,
false,
typename T::expr_spec_type >
1891 typedef typename T::value_type ConstT;
1893 true,
false,
typename T::expr_spec_type > expr_t;
1895 return expr_t(cond, c, expr.
derived());
1898 template <
typename CondT,
typename T>
1901 false,
true,
typename T::expr_spec_type >
1903 const typename T::value_type&
c)
1905 typedef typename T::value_type ConstT;
1907 false,
true,
typename T::expr_spec_type > expr_t;
1909 return expr_t(cond, expr.
derived(),
c);
1912 template <
typename CondT,
typename T>
1915 std::is_same<
typename T::value_type,
1916 typename T::scalar_type >,
1919 true,
false,
typename T::expr_spec_type >
1924 typedef typename T::scalar_type ConstT;
1926 true,
false,
typename T::expr_spec_type > expr_t;
1928 return expr_t(cond, c, expr.
derived());
1931 template <
typename CondT,
typename T>
1934 std::is_same<
typename T::value_type,
1935 typename T::scalar_type >,
1937 typename T::scalar_type,
1938 false,
true,
typename T::expr_spec_type >
1943 typedef typename T::scalar_type ConstT;
1945 false,
true,
typename T::expr_spec_type > expr_t;
1947 return expr_t(cond, expr.
derived(),
c);
1950 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1956 value_1 >= value_2 ? value_1 : value_2;
1959 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1968 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1970 struct IsExpr< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
1974 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1976 struct BaseExprType< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
1983 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1985 struct IsSimdType< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
1990 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1992 struct ValueType< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
1996 template <
typename CondT,
typename T1,
typename T2,
bool c1,
bool c2,
1998 struct ScalarType< Fad::Exp::IfThenElseOp< CondT, T1, T2, c1, c2, E > > {
2003 #undef FAD_BINARYOP_MACRO
2016 template <
typename T1,
typename T2 =
T1,
2020 template <
typename T1,
typename T2>
2022 typedef decltype( std::declval<T1>() == std::declval<T2>() ) type;
2029 #define FAD_RELOP_MACRO(OP) \
2030 namespace Sacado { \
2033 template <typename T1, typename T2> \
2034 SACADO_INLINE_FUNCTION \
2035 typename mpl::enable_if_c< \
2036 IsFadExpr<T1>::value && IsFadExpr<T2>::value && \
2037 ExprLevel<T1>::value == ExprLevel<T2>::value, \
2038 typename Impl::ConditionalReturnType<typename T1::value_type, \
2039 typename T2::value_type>::type \
2041 operator OP (const T1& expr1, const T2& expr2) \
2043 return expr1.derived().val() OP expr2.derived().val(); \
2046 template <typename T2> \
2047 SACADO_INLINE_FUNCTION \
2048 typename Impl::ConditionalReturnType<typename T2::value_type>::type \
2049 operator OP (const typename T2::value_type& a, \
2050 const Expr<T2>& expr2) \
2052 return a OP expr2.derived().val(); \
2055 template <typename T1> \
2056 SACADO_INLINE_FUNCTION \
2057 typename Impl::ConditionalReturnType<typename T1::value_type>::type \
2058 operator OP (const Expr<T1>& expr1, \
2059 const typename T1::value_type& b) \
2061 return expr1.derived().val() OP b; \
2078 #undef FAD_RELOP_MACRO
2085 template <
typename ExprT>
2089 return ! expr.
derived().val();
2103 template <
typename T>
2107 bool is_zero = (x.val() == 0.0);
2108 for (
int i=0;
i<x.size();
i++)
2109 is_zero = is_zero && (x.dx(
i) == 0.0);
2118 #define FAD_BOOL_MACRO(OP) \
2119 namespace Sacado { \
2122 template <typename T1, typename T2> \
2123 SACADO_INLINE_FUNCTION \
2125 operator OP (const Expr<T1>& expr1, \
2126 const Expr<T2>& expr2) \
2128 return toBool(expr1) OP toBool(expr2); \
2131 template <typename T2> \
2132 SACADO_INLINE_FUNCTION \
2134 operator OP (const typename Expr<T2>::value_type& a, \
2135 const Expr<T2>& expr2) \
2137 return a OP toBool(expr2); \
2140 template <typename T1> \
2141 SACADO_INLINE_FUNCTION \
2143 operator OP (const Expr<T1>& expr1, \
2144 const typename Expr<T1>::value_type& b) \
2146 return toBool(expr1) OP b; \
2155 #undef FAD_BOOL_MACRO
2164 template <
typename T>
2165 std::ostream& operator << (std::ostream& os, const Expr<T>& xx) {
2167 os << x.val() <<
" [";
2169 for (
int i=0;
i< x.size();
i++) {
2170 os <<
" " << x.dx(
i);
2182 #if defined(HAVE_SACADO_KOKKOS)
2192 template <
typename S>
2194 void atomic_add(GeneralFad<S>* dst,
const GeneralFad<S>&
x) {
2195 using Kokkos::atomic_add;
2197 const int xsz = x.size();
2198 const int sz = dst->size();
2204 "Sacado error: Fad resize within atomic_add() not supported!");
2206 if (xsz != sz && sz > 0 && xsz > 0)
2208 "Sacado error: Fad assignment of incompatiable sizes!");
2211 if (sz > 0 && xsz > 0) {
2216 atomic_add(&(dst->
val()), x.val());
2224 #endif // HAVE_SACADO_KOKKOS
2226 #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