33 #ifndef SACADO_ELRFAD_OPS_HPP
34 #define SACADO_ELRFAD_OPS_HPP
40 #define FAD_UNARYOP_MACRO(OPNAME,OP,VALUE,ADJOINT, \
41 LINEAR,DX,FASTACCESSDX) \
45 template <typename ExprT> \
48 template <typename ExprT> \
49 class Expr< OP<ExprT> > { \
52 typedef typename ExprT::value_type value_type; \
53 typedef typename ExprT::scalar_type scalar_type; \
54 typedef typename ExprT::base_expr_type base_expr_type; \
56 static const int num_args = ExprT::num_args; \
58 static const bool is_linear = LINEAR; \
60 SACADO_INLINE_FUNCTION \
61 explicit Expr(const ExprT& expr_) : expr(expr_) {} \
63 SACADO_INLINE_FUNCTION \
64 int size() const { return expr.size(); } \
67 SACADO_INLINE_FUNCTION \
68 bool isActive() const { return expr.template isActive<Arg>(); } \
70 SACADO_INLINE_FUNCTION \
71 bool isActive2(int j) const { return expr.isActive2(j); } \
73 SACADO_INLINE_FUNCTION \
74 bool updateValue() const { return expr.updateValue(); } \
76 SACADO_INLINE_FUNCTION \
77 void cache() const {} \
79 SACADO_INLINE_FUNCTION \
80 value_type val() const { \
84 SACADO_INLINE_FUNCTION \
85 void computePartials(const value_type& bar, \
86 value_type partials[]) const { \
87 expr.computePartials(ADJOINT, partials); \
90 SACADO_INLINE_FUNCTION \
91 void getTangents(int i, value_type dots[]) const { \
92 expr.getTangents(i, dots); } \
95 SACADO_INLINE_FUNCTION \
96 const value_type& getTangent(int i) const { \
97 return expr.template getTangent<Arg>(i); \
100 SACADO_INLINE_FUNCTION \
101 bool isLinear() const { \
105 SACADO_INLINE_FUNCTION \
106 bool hasFastAccess() const { \
107 return expr.hasFastAccess(); \
110 SACADO_INLINE_FUNCTION \
111 const value_type dx(int i) const { \
115 SACADO_INLINE_FUNCTION \
116 const value_type fastAccessDx(int i) const { \
117 return FASTACCESSDX; \
120 SACADO_INLINE_FUNCTION \
121 const value_type* getDx(int j) const { \
122 return expr.getDx(j); \
125 SACADO_INLINE_FUNCTION \
126 int numActiveArgs() const { \
127 return expr.numActiveArgs(); \
130 SACADO_INLINE_FUNCTION \
131 void computeActivePartials(const value_type& bar, \
132 value_type *partials) const { \
133 expr.computePartials(ADJOINT, partials); \
141 template <typename T> \
142 SACADO_INLINE_FUNCTION \
143 Expr< OP< Expr<T> > > \
144 OPNAME (const Expr<T>& expr) \
146 typedef OP< Expr<T> > expr_t; \
148 return Expr<expr_t>(expr); \
159 expr.fastAccessDx(
i))
166 -expr.fastAccessDx(
i))
173 std::exp(expr.val())*expr.fastAccessDx(
i))
179 expr.dx(
i)/expr.val(),
180 expr.fastAccessDx(
i)/expr.val())
187 expr.fastAccessDx(
i) / (
std::log(value_type(10))*expr.val()))
190 std::sqrt(expr.
val()),
191 value_type(0.5)*
bar/std::sqrt(expr.val()),
193 expr.
dx(
i)/(value_type(2)* std::sqrt(expr.val())),
197 std::sqrt(expr.val()),
198 expr.val() == value_type(0.0) ? value_type(0.0) : value_type(value_type(0.5)*
bar/std::sqrt(expr.val())),
200 expr.val() == value_type(0.0) ? value_type(0.0) : value_type(expr.
dx(
i)/(value_type(2)*std::sqrt(expr.val()))),
201 expr.val() == value_type(0.0) ? value_type(0.0) : value_type(expr.
fastAccessDx(
i)/(value_type(2)*std::sqrt(expr.val()))))
204 std::cos(expr.val()),
205 -
bar*std::
sin(expr.val()),
207 -expr.
dx(
i)* std::
sin(expr.val()),
211 std::sin(expr.val()),
212 bar*std::cos(expr.val()),
214 expr.
dx(
i)* std::cos(expr.val()),
218 std::tan(expr.val()),
219 bar*(value_type(1.)+ std::tan(expr.val())*std::tan(expr.val())),
222 (value_type(1)+ std::tan(expr.val())* std::tan(expr.val())),
224 (value_type(1)+ std::tan(expr.val())* std::tan(expr.val())))
227 std::acos(expr.val()),
228 -
bar/std::sqrt(value_type(1.)-expr.val()*expr.val()),
230 -expr.
dx(
i)/ std::sqrt(value_type(1)-expr.val()*expr.val()),
232 std::sqrt(value_type(1)-expr.val()*expr.val()))
235 std::asin(expr.val()),
236 bar/std::sqrt(value_type(1.)-expr.val()*expr.val()),
238 expr.
dx(
i)/ std::sqrt(value_type(1)-expr.val()*expr.val()),
240 std::sqrt(value_type(1)-expr.val()*expr.val()))
243 std::atan(expr.val()),
244 bar/(value_type(1.)+expr.val()*expr.val()),
246 expr.
dx(
i)/(value_type(1)+expr.val()*expr.val()),
250 std::cosh(expr.val()),
253 expr.
dx(
i)* std::
sinh(expr.val()),
257 std::sinh(expr.val()),
258 bar*std::cosh(expr.val()),
260 expr.
dx(
i)* std::cosh(expr.val()),
264 std::tanh(expr.val()),
265 bar*(value_type(1)-std::tanh(expr.val())*std::tanh(expr.val())),
267 expr.
dx(
i)*(value_type(1)-std::tanh(expr.val())*std::tanh(expr.val())),
268 expr.
fastAccessDx(
i)*(value_type(1)-std::tanh(expr.val())*std::tanh(expr.val())))
271 std::acosh(expr.val()),
272 bar/std::sqrt((expr.val()-value_type(1.)) *
273 (expr.val()+value_type(1.))),
275 expr.
dx(
i)/ std::sqrt((expr.val()-value_type(1)) *
276 (expr.val()+value_type(1))),
278 (expr.val()+value_type(1))))
281 std::asinh(expr.val()),
282 bar/std::sqrt(value_type(1.)+expr.val()*expr.val()),
284 expr.
dx(
i)/ std::sqrt(value_type(1)+expr.val()*expr.val()),
286 expr.val()*expr.val()))
289 std::atanh(expr.val()),
290 bar/(value_type(1.)-expr.val()*expr.val()),
292 expr.
dx(
i)/(value_type(1)-expr.val()*expr.val()),
294 expr.val()*expr.val()))
297 std::abs(expr.val()),
298 (expr.val() >= value_type(0.)) ?
bar : value_type(-
bar),
300 expr.val() >= 0 ? value_type(+expr.
dx(
i)) :
301 value_type(-expr.
dx(
i)),
306 std::fabs(expr.val()),
307 (expr.val() >= value_type(0.)) ? bar : value_type(-bar),
309 expr.val() >= 0 ? value_type(+expr.
dx(i)) :
310 value_type(-expr.
dx(i)),
315 std::cbrt(expr.val()),
316 bar/(value_type(3)*std::cbrt(expr.val()*expr.val())),
318 expr.
dx(i)/(value_type(3)*std::cbrt(expr.val()*expr.val())),
319 expr.
fastAccessDx(i)/(value_type(3)*std::cbrt(expr.val()*expr.val())))
321 #undef FAD_UNARYOP_MACRO
323 #define FAD_BINARYOP_MACRO( \
324 OPNAME,OP,VALUE,LADJOINT,RADJOINT, \
325 LINEAR,CONST_LINEAR_1, CONST_LINEAR_2, \
326 LINEAR_2,CONST_LINEAR_1_2, CONST_LINEAR_2_2, \
327 DX,FASTACCESSDX,CONST_DX_1,CONST_DX_2, \
328 CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
332 template <typename ExprT1, typename ExprT2> \
335 template <typename ExprT1, typename ExprT2> \
336 class Expr< OP<ExprT1,ExprT2> > { \
340 typedef typename ExprT1::value_type value_type_1; \
341 typedef typename ExprT2::value_type value_type_2; \
342 typedef typename Sacado::Promote<value_type_1, \
343 value_type_2>::type value_type; \
345 typedef typename ExprT1::scalar_type scalar_type_1; \
346 typedef typename ExprT2::scalar_type scalar_type_2; \
347 typedef typename Sacado::Promote<scalar_type_1, \
348 scalar_type_2>::type scalar_type; \
350 typedef typename ExprT1::base_expr_type base_expr_type_1; \
351 typedef typename ExprT2::base_expr_type base_expr_type_2; \
352 typedef typename Sacado::Promote<base_expr_type_1, \
353 base_expr_type_2>::type base_expr_type; \
355 static const int num_args1 = ExprT1::num_args; \
356 static const int num_args2 = ExprT2::num_args; \
357 static const int num_args = num_args1 + num_args2; \
359 static const bool is_linear = LINEAR_2; \
361 SACADO_INLINE_FUNCTION \
362 Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
363 expr1(expr1_), expr2(expr2_) {} \
365 SACADO_INLINE_FUNCTION \
367 int sz1 = expr1.size(), sz2 = expr2.size(); \
368 return sz1 > sz2 ? sz1 : sz2; \
372 SACADO_INLINE_FUNCTION \
373 bool isActive() const { \
374 if (Arg < num_args1) \
375 return expr1.template isActive<Arg>(); \
377 return expr2.template isActive<Arg-num_args1>(); \
380 SACADO_INLINE_FUNCTION \
381 bool isActive2(int j) const { \
383 return expr1.isActive2(j); \
385 return expr2.isActive2(j); \
388 SACADO_INLINE_FUNCTION \
389 bool updateValue() const { \
390 return expr1.updateValue() && expr2.updateValue(); \
393 SACADO_INLINE_FUNCTION \
394 void cache() const {} \
396 SACADO_INLINE_FUNCTION \
397 value_type val() const { \
401 SACADO_INLINE_FUNCTION \
402 void computePartials(const value_type& bar, \
403 value_type partials[]) const { \
405 expr1.computePartials(LADJOINT, partials); \
407 expr2.computePartials(RADJOINT, partials+num_args1); \
410 SACADO_INLINE_FUNCTION \
411 void getTangents(int i, value_type dots[]) const { \
412 expr1.getTangents(i, dots); \
413 expr2.getTangents(i, dots+num_args1); \
417 SACADO_INLINE_FUNCTION \
418 const value_type& getTangent(int i) const { \
419 if (Arg < num_args1) \
420 return expr1.template getTangent<Arg>(i); \
422 return expr2.template getTangent<Arg-num_args1>(i); \
425 SACADO_INLINE_FUNCTION \
426 bool isLinear() const { \
430 SACADO_INLINE_FUNCTION \
431 bool hasFastAccess() const { \
432 return expr1.hasFastAccess() && expr2.hasFastAccess(); \
435 SACADO_INLINE_FUNCTION \
436 const value_type dx(int i) const { \
440 SACADO_INLINE_FUNCTION \
441 const value_type fastAccessDx(int i) const { \
442 return FASTACCESSDX; \
445 SACADO_INLINE_FUNCTION \
446 const value_type* getDx(int j) const { \
448 return expr1.getDx(j); \
450 return expr2.getDx(j-num_args1); \
453 SACADO_INLINE_FUNCTION \
454 int numActiveArgs() const { \
455 return expr1.numActiveArgs() + expr2.numActiveArgs(); \
458 SACADO_INLINE_FUNCTION \
459 void computeActivePartials(const value_type& bar, \
460 value_type *partials) const { \
461 if (expr1.numActiveArgs() > 0) \
462 expr1.computePartials(LADJOINT, partials); \
463 if (expr2.numActiveArgs() > 0) \
464 expr2.computePartials(RADJOINT, partials+expr2.numActiveArgs()); \
468 typename ExprConstRef<ExprT1>::type expr1; \
469 typename ExprConstRef<ExprT2>::type expr2; \
473 template <typename ExprT1, typename T2> \
474 class Expr< OP<ExprT1, ConstExpr<T2> > > { \
478 typedef ConstExpr<T2> ExprT2; \
479 typedef typename ExprT1::value_type value_type_1; \
480 typedef typename ExprT2::value_type value_type_2; \
481 typedef typename Sacado::Promote<value_type_1, \
482 value_type_2>::type value_type; \
484 typedef typename ExprT1::scalar_type scalar_type_1; \
485 typedef typename ExprT2::scalar_type scalar_type_2; \
486 typedef typename Sacado::Promote<scalar_type_1, \
487 scalar_type_2>::type scalar_type; \
489 typedef typename ExprT1::base_expr_type base_expr_type_1; \
490 typedef typename ExprT2::base_expr_type base_expr_type_2; \
491 typedef typename Sacado::Promote<base_expr_type_1, \
492 base_expr_type_2>::type base_expr_type; \
494 static const int num_args = ExprT1::num_args; \
496 static const bool is_linear = CONST_LINEAR_2_2; \
498 SACADO_INLINE_FUNCTION \
499 Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
500 expr1(expr1_), expr2(expr2_) {} \
502 SACADO_INLINE_FUNCTION \
504 return expr1.size(); \
508 SACADO_INLINE_FUNCTION \
509 bool isActive() const { \
510 return expr1.template isActive<Arg>(); \
513 SACADO_INLINE_FUNCTION \
514 bool isActive2(int j) const { return expr1.isActive2(j); } \
516 SACADO_INLINE_FUNCTION \
517 bool updateValue() const { \
518 return expr1.updateValue(); \
521 SACADO_INLINE_FUNCTION \
522 void cache() const {} \
524 SACADO_INLINE_FUNCTION \
525 value_type val() const { \
529 SACADO_INLINE_FUNCTION \
530 void computePartials(const value_type& bar, \
531 value_type partials[]) const { \
532 expr1.computePartials(LADJOINT, partials); \
535 SACADO_INLINE_FUNCTION \
536 void getTangents(int i, value_type dots[]) const { \
537 expr1.getTangents(i, dots); \
541 SACADO_INLINE_FUNCTION \
542 const value_type& getTangent(int i) const { \
543 return expr1.template getTangent<Arg>(i); \
546 SACADO_INLINE_FUNCTION \
547 bool isLinear() const { \
548 return CONST_LINEAR_2; \
551 SACADO_INLINE_FUNCTION \
552 bool hasFastAccess() const { \
553 return expr1.hasFastAccess(); \
556 SACADO_INLINE_FUNCTION \
557 const value_type dx(int i) const { \
561 SACADO_INLINE_FUNCTION \
562 const value_type fastAccessDx(int i) const { \
563 return CONST_FASTACCESSDX_2; \
566 SACADO_INLINE_FUNCTION \
567 const value_type* getDx(int j) const { \
568 return expr1.getDx(j); \
571 SACADO_INLINE_FUNCTION \
572 int numActiveArgs() const { \
573 return expr1.numActiveArgs(); \
576 SACADO_INLINE_FUNCTION \
577 void computeActivePartials(const value_type& bar, \
578 value_type *partials) const { \
579 expr1.computePartials(LADJOINT, partials); \
584 typename ExprConstRef<ExprT1>::type expr1; \
585 typename ExprConstRef<ExprT2>::type expr2; \
589 template <typename T1, typename ExprT2> \
590 class Expr< OP<ConstExpr<T1>,ExprT2> > { \
594 typedef ConstExpr<T1> ExprT1; \
595 typedef typename ExprT1::value_type value_type_1; \
596 typedef typename ExprT2::value_type value_type_2; \
597 typedef typename Sacado::Promote<value_type_1, \
598 value_type_2>::type value_type; \
600 typedef typename ExprT1::scalar_type scalar_type_1; \
601 typedef typename ExprT2::scalar_type scalar_type_2; \
602 typedef typename Sacado::Promote<scalar_type_1, \
603 scalar_type_2>::type scalar_type; \
605 typedef typename ExprT1::base_expr_type base_expr_type_1; \
606 typedef typename ExprT2::base_expr_type base_expr_type_2; \
607 typedef typename Sacado::Promote<base_expr_type_1, \
608 base_expr_type_2>::type base_expr_type; \
610 static const int num_args = ExprT2::num_args; \
612 static const bool is_linear = CONST_LINEAR_1_2; \
614 SACADO_INLINE_FUNCTION \
615 Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
616 expr1(expr1_), expr2(expr2_) {} \
618 SACADO_INLINE_FUNCTION \
620 return expr2.size(); \
624 SACADO_INLINE_FUNCTION \
625 bool isActive() const { \
626 return expr2.template isActive<Arg>(); \
629 SACADO_INLINE_FUNCTION \
630 bool isActive2(int j) const { return expr2.isActive2(j); } \
632 SACADO_INLINE_FUNCTION \
633 bool updateValue() const { \
634 return expr2.updateValue(); \
637 SACADO_INLINE_FUNCTION \
638 void cache() const {} \
640 SACADO_INLINE_FUNCTION \
641 value_type val() const { \
645 SACADO_INLINE_FUNCTION \
646 void computePartials(const value_type& bar, \
647 value_type partials[]) const { \
648 expr2.computePartials(RADJOINT, partials); \
651 SACADO_INLINE_FUNCTION \
652 void getTangents(int i, value_type dots[]) const { \
653 expr2.getTangents(i, dots); \
657 SACADO_INLINE_FUNCTION \
658 const value_type& getTangent(int i) const { \
659 return expr2.template getTangent<Arg>(i); \
662 SACADO_INLINE_FUNCTION \
663 bool isLinear() const { \
664 return CONST_LINEAR_1; \
667 SACADO_INLINE_FUNCTION \
668 bool hasFastAccess() const { \
669 return expr2.hasFastAccess(); \
672 SACADO_INLINE_FUNCTION \
673 const value_type dx(int i) const { \
677 SACADO_INLINE_FUNCTION \
678 const value_type fastAccessDx(int i) const { \
679 return CONST_FASTACCESSDX_1; \
682 SACADO_INLINE_FUNCTION \
683 const value_type* getDx(int j) const { \
684 return expr2.getDx(j); \
687 SACADO_INLINE_FUNCTION \
688 int numActiveArgs() const { \
689 return expr2.numActiveArgs(); \
692 SACADO_INLINE_FUNCTION \
693 void computeActivePartials(const value_type& bar, \
694 value_type *partials) const { \
695 expr2.computePartials(RADJOINT, partials); \
699 typename ExprConstRef<ExprT1>::type expr1; \
700 typename ExprConstRef<ExprT2>::type expr2; \
704 template <typename T1, typename T2> \
705 SACADO_INLINE_FUNCTION \
706 SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \
707 OPNAME (const T1& expr1, const T2& expr2) \
709 typedef OP< T1, T2 > expr_t; \
711 return Expr<expr_t>(expr1, expr2); \
714 template <typename T> \
715 SACADO_INLINE_FUNCTION \
716 Expr< OP< Expr<T>, Expr<T> > > \
717 OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
719 typedef OP< Expr<T>, Expr<T> > expr_t; \
721 return Expr<expr_t>(expr1, expr2); \
724 template <typename T> \
725 SACADO_INLINE_FUNCTION \
726 Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
728 OPNAME (const typename Expr<T>::value_type& c, \
729 const Expr<T>& expr) \
731 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
732 typedef OP< ConstT, Expr<T> > expr_t; \
734 return Expr<expr_t>(ConstT(c), expr); \
737 template <typename T> \
738 SACADO_INLINE_FUNCTION \
740 ConstExpr<typename Expr<T>::value_type> > > \
741 OPNAME (const Expr<T>& expr, \
742 const typename Expr<T>::value_type& c) \
744 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
745 typedef OP< Expr<T>, ConstT > expr_t; \
747 return Expr<expr_t>(expr, ConstT(c)); \
750 template <typename T> \
751 SACADO_INLINE_FUNCTION \
752 SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \
753 OPNAME (const typename Expr<T>::scalar_type& c, \
754 const Expr<T>& expr) \
756 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
757 typedef OP< ConstT, Expr<T> > expr_t; \
759 return Expr<expr_t>(ConstT(c), expr); \
762 template <typename T> \
763 SACADO_INLINE_FUNCTION \
764 SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \
765 OPNAME (const Expr<T>& expr, \
766 const typename Expr<T>::scalar_type& c) \
768 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
769 typedef OP< Expr<T>, ConstT > expr_t; \
771 return Expr<expr_t>(expr, ConstT(c)); \
779 expr1.val() + expr2.val(),
782 expr1.isLinear() && expr2.isLinear(),
785 ExprT1::is_linear && ExprT2::is_linear,
788 expr1.dx(i) + expr2.dx(i),
789 expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
792 expr2.fastAccessDx(i),
793 expr1.fastAccessDx(i))
796 expr1.val() - expr2.val(),
799 expr1.isLinear() && expr2.isLinear(),
802 ExprT1::is_linear && ExprT2::is_linear,
805 expr1.dx(i) - expr2.dx(i),
806 expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
809 -expr2.fastAccessDx(i),
810 expr1.fastAccessDx(i))
813 expr1.val() * expr2.val(),
822 expr1.val()*expr2.dx(i) + expr1.dx(i)*expr2.val(),
823 expr1.val()*expr2.fastAccessDx(i) +
824 expr1.fastAccessDx(i)*expr2.val(),
825 expr1.val()*expr2.dx(i),
826 expr1.dx(i)*expr2.val(),
827 expr1.val()*expr2.fastAccessDx(i),
828 expr1.fastAccessDx(i)*expr2.val())
831 expr1.val() / expr2.val(),
833 -bar*expr1.val()/(expr2.val()*expr2.val()),
840 (expr1.dx(i)*expr2.val() - expr2.dx(i)*expr1.val()) /
841 (expr2.val()*expr2.val()),
842 (expr1.fastAccessDx(i)*expr2.val() -
843 expr2.fastAccessDx(i)*expr1.val()) /
844 (expr2.val()*expr2.val()),
845 -expr2.dx(i)*expr1.val() / (expr2.val()*expr2.val()),
846 expr1.dx(i)/expr2.val(),
847 -expr2.fastAccessDx(i)*expr1.val() / (expr2.val()*expr2.val()),
848 expr1.fastAccessDx(i)/expr2.val())
853 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
855 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
862 (expr2.val()*expr1.dx(i) - expr1.val()*expr2.dx(i))/ (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
863 (expr2.val()*expr1.fastAccessDx(i) - expr1.val()*expr2.fastAccessDx(i))/
864 (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
865 (-expr1.val()*expr2.dx(i)) / (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
866 (expr2.val()*expr1.dx(i))/ (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
867 (-expr1.val()*expr2.fastAccessDx(i))/ (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
868 (expr2.val()*expr1.fastAccessDx(i))/ (expr1.val()*expr1.val() + expr2.val()*expr2.val()))
871 std::pow(expr1.val(), expr2.val()),
872 expr2.size() == 0 && expr2.val() == value_type(1) ? bar : expr1.val() == value_type(0) ? value_type(0) : value_type(bar*std::pow(expr1.val(),expr2.val())*expr2.val()/expr1.val()),
873 expr1.val() == value_type(0) ? value_type(0) : value_type(bar*std::pow(expr1.val(),expr2.val())*std::
log(expr1.val())),
880 expr1.val() == value_type(0) ? value_type(0) : value_type((expr2.
dx(i)*std::
log(expr1.val())+expr2.val()*expr1.
dx(i)/expr1.val())*std::pow(expr1.val(),expr2.val())),
881 expr1.val() == value_type(0) ? value_type(0) : value_type((expr2.
fastAccessDx(i)*std::
log(expr1.val())+expr2.val()*expr1.
fastAccessDx(i)/expr1.val())*std::pow(expr1.val(),expr2.val())),
882 expr1.val() == value_type(0) ? value_type(0) : value_type(expr2.
dx(i)*std::
log(expr1.val())*std::pow(expr1.val(),expr2.val())),
883 expr2.val() == value_type(1) ? expr1.
dx(i) : expr1.val() == value_type(0) ? value_type(0) : value_type(expr2.val()*expr1.
dx(i)/expr1.val()*std::pow(expr1.val(),expr2.val())),
884 expr1.val() == value_type(0) ? value_type(0) : value_type(expr2.
fastAccessDx(i)*std::
log(expr1.val())*std::pow(expr1.val(),expr2.val())),
885 expr2.val() == value_type(1) ? expr1.
fastAccessDx(i) : expr1.val() == value_type(0) ? value_type(0) : value_type(expr2.val()*expr1.
fastAccessDx(i)/expr1.val()*std::pow(expr1.val(),expr2.val())))
888 expr1.val() >= expr2.val() ? expr1.val() : expr2.val(),
889 expr1.val() >= expr2.val() ? bar : value_type(0.),
890 expr2.val() > expr1.val() ? bar : value_type(0.),
891 expr1.isLinear() && expr2.isLinear(),
894 ExprT1::is_linear && ExprT2::is_linear,
897 expr1.val() >= expr2.val() ? expr1.
dx(i) : expr2.
dx(i),
900 expr1.val() >= expr2.val() ? value_type(0) : expr2.
dx(i),
901 expr1.val() >= expr2.val() ? expr1.
dx(i) : value_type(0),
902 expr1.val() >= expr2.val() ? value_type(0) :
908 expr1.val() <= expr2.val() ? expr1.val() : expr2.val(),
909 expr1.val() <= expr2.val() ? bar : value_type(0.),
910 expr2.val() < expr1.val() ? bar : value_type(0.),
911 expr1.isLinear() && expr2.isLinear(),
914 ExprT1::is_linear && ExprT2::is_linear,
917 expr1.val() <= expr2.val() ? expr1.
dx(i) : expr2.
dx(i),
920 expr1.val() <= expr2.val() ? value_type(0) : expr2.
dx(i),
921 expr1.val() <= expr2.val() ? expr1.
dx(i) : value_type(0),
922 expr1.val() <= expr2.val() ? value_type(0) :
927 #undef FAD_BINARYOP_MACRO
931 #define FAD_RELOP_MACRO(OP) \
934 template <typename ExprT1, typename ExprT2> \
935 SACADO_INLINE_FUNCTION \
937 operator OP (const Expr<ExprT1>& expr1, \
938 const Expr<ExprT2>& expr2) \
940 return expr1.val() OP expr2.val(); \
943 template <typename ExprT2> \
944 SACADO_INLINE_FUNCTION \
946 operator OP (const typename Expr<ExprT2>::value_type& a, \
947 const Expr<ExprT2>& expr2) \
949 return a OP expr2.val(); \
952 template <typename ExprT1> \
953 SACADO_INLINE_FUNCTION \
955 operator OP (const Expr<ExprT1>& expr1, \
956 const typename Expr<ExprT1>::value_type& b) \
958 return expr1.val() OP b; \
974 #undef FAD_RELOP_MACRO
980 template <
typename ExprT>
996 template <
typename ExprT>
999 bool is_zero = (x.val() == 0.0);
1000 for (
int i=0; i<x.size(); i++)
1001 is_zero = is_zero && (x.dx(i) == 0.0);
1009 #define FAD_BOOL_MACRO(OP) \
1010 namespace Sacado { \
1011 namespace ELRFad { \
1012 template <typename ExprT1, typename ExprT2> \
1013 SACADO_INLINE_FUNCTION \
1015 operator OP (const Expr<ExprT1>& expr1, \
1016 const Expr<ExprT2>& expr2) \
1018 return toBool(expr1) OP toBool(expr2); \
1021 template <typename ExprT2> \
1022 SACADO_INLINE_FUNCTION \
1024 operator OP (const typename Expr<ExprT2>::value_type& a, \
1025 const Expr<ExprT2>& expr2) \
1027 return a OP toBool(expr2); \
1030 template <typename ExprT1> \
1031 SACADO_INLINE_FUNCTION \
1033 operator OP (const Expr<ExprT1>& expr1, \
1034 const typename Expr<ExprT1>::value_type& b) \
1036 return toBool(expr1) OP b; \
1044 #undef FAD_BOOL_MACRO
1052 template <
typename ExprT>
1053 std::ostream& operator << (std::ostream& os, const Expr<ExprT>&
x) {
1054 os <<
x.val() <<
" [";
1056 for (
int i=0; i<
x.size(); i++) {
1057 os <<
" " <<
x.dx(i);
1068 #endif // SACADO_FAD_OPS_HPP
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
SACADO_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
#define FAD_UNARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, FASTACCESSDX)
#define FAD_BOOL_MACRO(OP)
SACADO_INLINE_FUNCTION bool toBool(const Expr< ExprT > &x)
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 expr1 expr1 c *expr2 expr1 c *expr2 expr1 c *expr2 expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 Atan2Op
#define 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)
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
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
atan2(expr1.val(), expr2.val())
#define FAD_RELOP_MACRO(OP)
Wrapper for a generic expression template.
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
SACADO_INLINE_FUNCTION T safe_sqrt(const T &x)
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
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)
#define SACADO_INLINE_FUNCTION
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