52#ifndef SACADO_FAD_OPS_MP_VECTOR_HPP
53#define SACADO_FAD_OPS_MP_VECTOR_HPP
55#include "Sacado_Fad_Ops.hpp"
56#include "Sacado_mpl_enable_if.hpp"
59#define FAD_UNARYOP_MACRO(OPNAME,OP,MPVALUE,VALUE,DX,FASTACCESSDX) \
63 template <typename ExprT> \
64 class Expr< OP<ExprT>,ExprSpecMPVector > { \
67 typedef typename ExprT::value_type value_type; \
68 typedef typename ExprT::scalar_type scalar_type; \
69 typedef typename ExprT::base_expr_type base_expr_type; \
71 typedef typename value_type::value_type val_type; \
73 KOKKOS_INLINE_FUNCTION \
74 Expr(const ExprT& expr_) : expr(expr_) {} \
76 KOKKOS_INLINE_FUNCTION \
77 int size() const { return expr.size(); } \
79 KOKKOS_INLINE_FUNCTION \
80 bool hasFastAccess() const { return expr.hasFastAccess(); } \
82 KOKKOS_INLINE_FUNCTION \
83 bool isPassive() const { return expr.isPassive();} \
85 KOKKOS_INLINE_FUNCTION \
86 bool updateValue() const { return expr.updateValue(); } \
88 KOKKOS_INLINE_FUNCTION \
89 value_type val() const { \
93 KOKKOS_INLINE_FUNCTION \
94 val_type val(int j) const { \
98 KOKKOS_INLINE_FUNCTION \
99 val_type dx(int i, int j) const { \
103 KOKKOS_INLINE_FUNCTION \
104 val_type fastAccessDx(int i, int j) const { \
105 return FASTACCESSDX; \
121 expr.fastAccessDx(i,
j))
127 -expr.fastAccessDx(i,
j))
130 std::exp(expr.val()),
131 std::exp(expr.val(
j)),
132 std::exp(expr.val(
j))*expr.dx(i,
j),
133 std::exp(expr.val(
j))*expr.fastAccessDx(i,
j))
144 expr.
dx(i,
j)/(
std::log(val_type(10))*expr.
val(
j)),
190 expr.
dx(i,
j)/(val_type(1)+expr.
val(
j)*expr.
val(
j)),
216 (expr.
val(
j)+val_type(1))),
218 (expr.
val(
j)+val_type(1))))
230 expr.
dx(i,
j)/(val_type(1)-expr.
val(
j)*expr.
val(
j)),
237 expr.
val(
j) >= 0 ? val_type(+expr.
dx(i,
j)) :
238 val_type(-expr.
dx(i,
j)),
245 expr.
val(
j) >= 0 ? val_type(+expr.
dx(i,
j)) :
246 val_type(-expr.
dx(i,
j)),
256#undef FAD_UNARYOP_MACRO
258#define FAD_BINARYOP_MACRO(OPNAME,OP,MPVALUE,VALUE,DX,FASTACCESSDX,MPVAL_CONST_DX_1,MPVAL_CONST_DX_2,VAL_CONST_DX_1,VAL_CONST_DX_2,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
262 template <typename ExprT1, typename ExprT2> \
263 class Expr< OP< ExprT1, ExprT2 >,ExprSpecMPVector > { \
267 typedef typename ExprT1::value_type value_type_1; \
268 typedef typename ExprT2::value_type value_type_2; \
269 typedef typename Sacado::Promote<value_type_1, \
270 value_type_2>::type value_type; \
272 typedef typename ExprT1::scalar_type scalar_type_1; \
273 typedef typename ExprT2::scalar_type scalar_type_2; \
274 typedef typename Sacado::Promote<scalar_type_1, \
275 scalar_type_2>::type scalar_type; \
277 typedef typename ExprT1::base_expr_type base_expr_type_1; \
278 typedef typename ExprT2::base_expr_type base_expr_type_2; \
279 typedef typename Sacado::Promote<base_expr_type_1, \
280 base_expr_type_2>::type base_expr_type; \
282 typedef typename value_type::value_type val_type; \
284 KOKKOS_INLINE_FUNCTION \
285 Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
286 expr1(expr1_), expr2(expr2_) {} \
288 KOKKOS_INLINE_FUNCTION \
290 int sz1 = expr1.size(), sz2 = expr2.size(); \
291 return sz1 > sz2 ? sz1 : sz2; \
294 KOKKOS_INLINE_FUNCTION \
295 bool hasFastAccess() const { \
296 return expr1.hasFastAccess() && expr2.hasFastAccess(); \
299 KOKKOS_INLINE_FUNCTION \
300 bool isPassive() const { \
301 return expr1.isPassive() && expr2.isPassive(); \
304 KOKKOS_INLINE_FUNCTION \
305 bool updateValue() const { \
306 return expr1.updateValue() && expr2.updateValue(); \
309 KOKKOS_INLINE_FUNCTION \
310 const value_type val() const { \
314 KOKKOS_INLINE_FUNCTION \
315 const val_type val(int j) const { \
319 KOKKOS_INLINE_FUNCTION \
320 const val_type dx(int i, int j) const { \
324 KOKKOS_INLINE_FUNCTION \
325 const val_type fastAccessDx(int i, int j) const { \
326 return FASTACCESSDX; \
331 const ExprT1& expr1; \
332 const ExprT2& expr2; \
336 template <typename ExprT1, typename T2> \
337 class Expr< OP< ExprT1, ConstExpr<T2> >,ExprSpecMPVector > { \
341 typedef ConstExpr<T2> ConstT; \
342 typedef ConstExpr<T2> ExprT2; \
343 typedef typename ExprT1::value_type value_type_1; \
344 typedef typename ExprT2::value_type value_type_2; \
345 typedef typename Sacado::Promote<value_type_1, \
346 value_type_2>::type value_type; \
348 typedef typename ExprT1::scalar_type scalar_type_1; \
349 typedef typename ExprT2::scalar_type scalar_type_2; \
350 typedef typename Sacado::Promote<scalar_type_1, \
351 scalar_type_2>::type scalar_type; \
353 typedef typename ExprT1::base_expr_type base_expr_type_1; \
354 typedef typename ExprT2::base_expr_type base_expr_type_2; \
355 typedef typename Sacado::Promote<base_expr_type_1, \
356 base_expr_type_2>::type base_expr_type; \
358 typedef typename value_type::value_type val_type; \
360 KOKKOS_INLINE_FUNCTION \
361 Expr(const ExprT1& expr1_, const ConstT& c_) : \
362 expr1(expr1_), c(c_) {} \
364 KOKKOS_INLINE_FUNCTION \
366 return expr1.size(); \
369 KOKKOS_INLINE_FUNCTION \
370 bool hasFastAccess() const { \
371 return expr1.hasFastAccess(); \
374 KOKKOS_INLINE_FUNCTION \
375 bool isPassive() const { \
376 return expr1.isPassive(); \
379 KOKKOS_INLINE_FUNCTION \
380 bool updateValue() const { return expr1.updateValue(); } \
382 KOKKOS_INLINE_FUNCTION \
383 const value_type val() const { \
384 return MPVAL_CONST_DX_2; \
387 KOKKOS_INLINE_FUNCTION \
388 const val_type val(int j) const { \
389 return VAL_CONST_DX_2; \
392 KOKKOS_INLINE_FUNCTION \
393 const val_type dx(int i, int j) const { \
397 KOKKOS_INLINE_FUNCTION \
398 const val_type fastAccessDx(int i, int j) const { \
399 return CONST_FASTACCESSDX_2; \
404 const ExprT1& expr1; \
408 template <typename T1, typename ExprT2> \
409 class Expr< OP< ConstExpr<T1>, ExprT2 >,ExprSpecMPVector > { \
413 typedef ConstExpr<T1> ConstT; \
414 typedef ConstExpr<T1> ExprT1; \
415 typedef typename ExprT1::value_type value_type_1; \
416 typedef typename ExprT2::value_type value_type_2; \
417 typedef typename Sacado::Promote<value_type_1, \
418 value_type_2>::type value_type; \
420 typedef typename ExprT1::scalar_type scalar_type_1; \
421 typedef typename ExprT2::scalar_type scalar_type_2; \
422 typedef typename Sacado::Promote<scalar_type_1, \
423 scalar_type_2>::type scalar_type; \
425 typedef typename ExprT1::base_expr_type base_expr_type_1; \
426 typedef typename ExprT2::base_expr_type base_expr_type_2; \
427 typedef typename Sacado::Promote<base_expr_type_1, \
428 base_expr_type_2>::type base_expr_type; \
430 typedef typename value_type::value_type val_type; \
432 KOKKOS_INLINE_FUNCTION \
433 Expr(const ConstT& c_, const ExprT2& expr2_) : \
434 c(c_), expr2(expr2_) {} \
436 KOKKOS_INLINE_FUNCTION \
438 return expr2.size(); \
441 KOKKOS_INLINE_FUNCTION \
442 bool hasFastAccess() const { \
443 return expr2.hasFastAccess(); \
446 KOKKOS_INLINE_FUNCTION \
447 bool isPassive() const { \
448 return expr2.isPassive(); \
451 KOKKOS_INLINE_FUNCTION \
452 bool updateValue() const { return expr2.updateValue(); } \
454 KOKKOS_INLINE_FUNCTION \
455 const value_type val() const { \
456 return MPVAL_CONST_DX_1; \
459 KOKKOS_INLINE_FUNCTION \
460 const val_type val(int j) const { \
461 return VAL_CONST_DX_1; \
464 KOKKOS_INLINE_FUNCTION \
465 const val_type dx(int i, int j) const { \
469 KOKKOS_INLINE_FUNCTION \
470 const val_type fastAccessDx(int i, int j) const { \
471 return CONST_FASTACCESSDX_1; \
477 const ExprT2& expr2; \
486 expr1.val() + expr2.val(),
487 expr1.val(
j) + expr2.val(
j),
488 expr1.dx(i,
j) + expr2.dx(i,
j),
489 expr1.fastAccessDx(i,
j) + expr2.fastAccessDx(i,
j),
490 c.val() + expr2.val(),
491 expr1.val() + c.val(),
492 c.val(
j) + expr2.val(
j),
493 expr1.val(
j) + c.val(
j),
496 expr2.fastAccessDx(i,
j),
497 expr1.fastAccessDx(i,
j))
500 expr1.val() - expr2.val(),
501 expr1.val(
j) - expr2.val(
j),
502 expr1.dx(i,
j) - expr2.dx(i,
j),
503 expr1.fastAccessDx(i,
j) - expr2.fastAccessDx(i,
j),
504 c.val() - expr2.val(),
505 expr1.val() - c.val(),
506 c.val(
j) - expr2.val(
j),
507 expr1.val(
j) - c.val(
j),
510 -expr2.fastAccessDx(i,
j),
511 expr1.fastAccessDx(i,
j))
529 expr1.val() / expr2.val(),
530 expr1.val(
j) / expr2.val(
j),
531 (expr1.dx(i,
j)*expr2.val(
j) - expr2.dx(i,
j)*expr1.val(
j)) /
532 (expr2.val(
j)*expr2.val(
j)),
533 (expr1.fastAccessDx(i,
j)*expr2.val(
j) -
534 expr2.fastAccessDx(i,
j)*expr1.val(
j)) /
535 (expr2.val(
j)*expr2.val(
j)),
536 c.val() / expr2.val(),
537 expr1.val() / c.val(),
538 c.val(
j) / expr2.val(
j),
539 expr1.val(
j) / c.val(
j),
540 -expr2.dx(i,
j)*c.val(
j) / (expr2.val(
j)*expr2.val(
j)),
541 expr1.dx(i,
j)/c.val(
j),
542 -expr2.fastAccessDx(i,
j)*c.val(
j) / (expr2.val(
j)*expr2.val(
j)),
543 expr1.fastAccessDx(i,
j)/c.val(
j))
546 std::atan2(expr1.val(), expr2.val()),
547 std::atan2(expr1.val(
j), expr2.val(
j)),
548 (expr2.val(
j)*expr1.dx(i,
j) - expr1.val(
j)*expr2.dx(i,
j))/
549 (expr1.val(
j)*expr1.val(
j) + expr2.val(
j)*expr2.val(
j)),
550 (expr2.val(
j)*expr1.fastAccessDx(i,
j) - expr1.val(
j)*expr2.fastAccessDx(i,
j))/
551 (expr1.val(
j)*expr1.val(
j) + expr2.val(
j)*expr2.val(
j)),
552 std::atan2(c.val(), expr2.val()),
553 std::atan2(expr1.val(), c.val()),
554 std::atan2(c.val(
j), expr2.val(
j)),
555 std::atan2(expr1.val(
j), c.val(
j)),
556 (-c.val(
j)*expr2.dx(i,
j)) / (c.val(
j)*c.val(
j) + expr2.val(
j)*expr2.val(
j)),
557 (c.val(
j)*expr1.dx(i,
j))/ (expr1.val(
j)*expr1.val(
j) + c.val(
j)*c.val(
j)),
558 (-c.val(
j)*expr2.fastAccessDx(i,
j))/ (c.val(
j)*c.val(
j) + expr2.val(
j)*expr2.val(
j)),
559 (c.val(
j)*expr1.fastAccessDx(i,
j))/ (expr1.val(
j)*expr1.val(
j) + c.val(
j)*c.val(
j)))
562 std::pow(expr1.val(), expr2.val()),
563 std::pow(expr1.val(
j), expr2.val(
j)),
564 expr1.val(
j) == val_type(0) ? val_type(0) : val_type((expr2.dx(i,
j)*std::log(expr1.val(
j))+expr2.val(
j)*expr1.dx(i,
j)/expr1.val(
j))*std::pow(expr1.val(
j),expr2.val(
j))),
565 expr1.val(
j) == val_type(0) ? val_type(0.0) : val_type((expr2.fastAccessDx(i,
j)*std::log(expr1.val(
j))+expr2.val(
j)*expr1.fastAccessDx(i,
j)/expr1.val(
j))*std::pow(expr1.val(
j),expr2.val(
j))),
566 std::pow(c.val(), expr2.val()),
567 std::pow(expr1.val(), c.val()),
568 std::pow(c.val(
j), expr2.val(
j)),
569 std::pow(expr1.val(
j), c.val(
j)),
570 c.val(
j) == val_type(0) ? val_type(0) : val_type(expr2.dx(i,
j)*std::log(c.val(
j))*std::pow(c.val(
j),expr2.val(
j))),
571 expr1.val(
j) == val_type(0) ? val_type(0.0) : val_type(c.val(
j)*expr1.dx(i,
j)/expr1.val(
j)*std::pow(expr1.val(
j),c.val(
j))),
572 c.val(
j) == val_type(0) ? val_type(0) : val_type(expr2.fastAccessDx(i,
j)*std::log(c.val(
j))*std::pow(c.val(
j),expr2.val(
j))),
573 expr1.val(
j) == val_type(0) ? val_type(0.0) : val_type(c.val(
j)*expr1.fastAccessDx(i,
j)/expr1.val(
j)*std::pow(expr1.val(
j),c.val(
j))))
576 std::max(expr1.val(), expr2.val()),
577 std::max(expr1.val(
j), expr2.val(
j)),
578 expr1.val(
j) >= expr2.val(
j) ? expr1.dx(i,
j) : expr2.dx(i,
j),
579 expr1.val(
j) >= expr2.val(
j) ? expr1.fastAccessDx(i,
j) :
580 expr2.fastAccessDx(i,
j),
581 std::max(c.val(), expr2.val()),
582 std::max(expr1.val(), c.val()),
583 std::max(c.val(
j), expr2.val(
j)),
584 std::max(expr1.val(
j), c.val(
j)),
585 c.val(
j) >= expr2.val(
j) ? val_type(0) : expr2.dx(i,
j),
586 expr1.val(
j) >= c.val(
j) ? expr1.dx(i,
j) : val_type(0),
587 c.val(
j) >= expr2.val(
j) ? val_type(0) : expr2.fastAccessDx(i,
j),
588 expr1.val(
j) >= c.val(
j) ? expr1.fastAccessDx(i,
j) : val_type(0))
600 c.
val(
j) <= expr2.
val(
j) ? val_type(0) : expr2.
dx(i,
j),
601 expr1.
val(
j) <= c.
val(
j) ? expr1.
dx(i,
j) : val_type(0),
606#undef FAD_BINARYOP_MACRO
611 template <
typename ExprT1,
typename ExprT2>
616 typedef typename ExprT1::value_type value_type_1;
617 typedef typename ExprT2::value_type value_type_2;
618 typedef typename Sacado::Promote<value_type_1,
619 value_type_2>::type value_type;
621 typedef typename ExprT1::scalar_type scalar_type_1;
622 typedef typename ExprT2::scalar_type scalar_type_2;
623 typedef typename Sacado::Promote<scalar_type_1,
624 scalar_type_2>::type scalar_type;
626 typedef typename ExprT1::base_expr_type base_expr_type_1;
627 typedef typename ExprT2::base_expr_type base_expr_type_2;
628 typedef typename Sacado::Promote<base_expr_type_1,
629 base_expr_type_2>::type base_expr_type;
631 typedef typename value_type::value_type val_type;
633 KOKKOS_INLINE_FUNCTION
634 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
635 expr1(expr1_), expr2(expr2_) {}
637 KOKKOS_INLINE_FUNCTION
639 int sz1 = expr1.size(), sz2 = expr2.size();
640 return sz1 > sz2 ? sz1 : sz2;
643 KOKKOS_INLINE_FUNCTION
644 bool hasFastAccess()
const {
645 return expr1.hasFastAccess() && expr2.hasFastAccess();
648 KOKKOS_INLINE_FUNCTION
649 bool isPassive()
const {
650 return expr1.isPassive() && expr2.isPassive();
653 KOKKOS_INLINE_FUNCTION
654 bool updateValue()
const {
655 return expr1.updateValue() && expr2.updateValue();
658 KOKKOS_INLINE_FUNCTION
659 const value_type
val()
const {
660 return expr1.val()*expr2.val();
663 KOKKOS_INLINE_FUNCTION
664 const val_type
val(
int j)
const {
665 return expr1.val(
j)*expr2.val(
j);
668 KOKKOS_INLINE_FUNCTION
669 const val_type
dx(
int i,
int j)
const {
670 if (expr1.size() > 0 && expr2.size() > 0)
671 return expr1.val(
j)*expr2.dx(i,
j) + expr1.dx(i,
j)*expr2.val(
j);
672 else if (expr1.size() > 0)
673 return expr1.dx(i,
j)*expr2.val(
j);
675 return expr1.val(
j)*expr2.dx(i,
j);
678 KOKKOS_INLINE_FUNCTION
680 return expr1.val(
j)*expr2.fastAccessDx(i,
j) +
681 expr1.fastAccessDx(i,
j)*expr2.val(
j);
691 template <
typename ExprT1,
typename T2>
696 typedef ConstExpr<T2> ConstT;
697 typedef ConstExpr<T2> ExprT2;
698 typedef typename ExprT1::value_type value_type_1;
699 typedef typename ExprT2::value_type value_type_2;
700 typedef typename Sacado::Promote<value_type_1,
701 value_type_2>::type value_type;
703 typedef typename ExprT1::scalar_type scalar_type_1;
704 typedef typename ExprT2::scalar_type scalar_type_2;
705 typedef typename Sacado::Promote<scalar_type_1,
706 scalar_type_2>::type scalar_type;
708 typedef typename ExprT1::base_expr_type base_expr_type_1;
709 typedef typename ExprT2::base_expr_type base_expr_type_2;
710 typedef typename Sacado::Promote<base_expr_type_1,
711 base_expr_type_2>::type base_expr_type;
713 typedef typename value_type::value_type val_type;
715 KOKKOS_INLINE_FUNCTION
716 Expr(
const ExprT1& expr1_,
const ConstT& c_) :
717 expr1(expr1_), c(c_) {}
719 KOKKOS_INLINE_FUNCTION
724 KOKKOS_INLINE_FUNCTION
725 bool hasFastAccess()
const {
726 return expr1.hasFastAccess();
729 KOKKOS_INLINE_FUNCTION
730 bool isPassive()
const {
731 return expr1.isPassive();
734 KOKKOS_INLINE_FUNCTION
735 bool updateValue()
const {
return expr1.updateValue(); }
737 KOKKOS_INLINE_FUNCTION
738 const value_type
val()
const {
739 return expr1.val()*c.val();
742 KOKKOS_INLINE_FUNCTION
743 const val_type
val(
int j)
const {
744 return expr1.val(
j)*c.val(
j);
747 KOKKOS_INLINE_FUNCTION
748 const val_type
dx(
int i,
int j)
const {
749 return expr1.dx(i,
j)*c.val(
j);
752 KOKKOS_INLINE_FUNCTION
754 return expr1.fastAccessDx(i,
j)*c.val(
j);
763 template <
typename T1,
typename ExprT2>
768 typedef ConstExpr<T1> ConstT;
769 typedef ConstExpr<T1> ExprT1;
770 typedef typename ExprT1::value_type value_type_1;
771 typedef typename ExprT2::value_type value_type_2;
772 typedef typename Sacado::Promote<value_type_1,
773 value_type_2>::type value_type;
775 typedef typename ExprT1::scalar_type scalar_type_1;
776 typedef typename ExprT2::scalar_type scalar_type_2;
777 typedef typename Sacado::Promote<scalar_type_1,
778 scalar_type_2>::type scalar_type;
780 typedef typename ExprT1::base_expr_type base_expr_type_1;
781 typedef typename ExprT2::base_expr_type base_expr_type_2;
782 typedef typename Sacado::Promote<base_expr_type_1,
783 base_expr_type_2>::type base_expr_type;
785 typedef typename value_type::value_type val_type;
787 KOKKOS_INLINE_FUNCTION
788 Expr(
const ConstT& c_,
const ExprT2& expr2_) :
789 c(c_), expr2(expr2_) {}
791 KOKKOS_INLINE_FUNCTION
796 KOKKOS_INLINE_FUNCTION
797 bool hasFastAccess()
const {
798 return expr2.hasFastAccess();
801 KOKKOS_INLINE_FUNCTION
802 bool isPassive()
const {
803 return expr2.isPassive();
806 KOKKOS_INLINE_FUNCTION
807 bool updateValue()
const {
return expr2.updateValue(); }
809 KOKKOS_INLINE_FUNCTION
810 const value_type
val()
const {
811 return c.val()*expr2.val();
814 KOKKOS_INLINE_FUNCTION
815 const val_type
val(
int j)
const {
816 return c.val(
j)*expr2.val(
j);
819 KOKKOS_INLINE_FUNCTION
820 const val_type
dx(
int i,
int j)
const {
821 return c.val(
j)*expr2.dx(i,
j);
824 KOKKOS_INLINE_FUNCTION
826 return c.val(
j)*expr2.fastAccessDx(i,
j);
835 template <
typename ExprT>
836 KOKKOS_INLINE_FUNCTION
837 bool toBool(
const Expr<ExprT,ExprSpecMPVector>& x) {
838 bool is_zero = (x.val() == 0.0);
839 for (
int i=0; i<x.size(); i++)
840 for (
int j=0;
j<x.val().size(); ++
j)
841 is_zero = is_zero && (x.dx(i,
j) == 0.0);
845 template <
typename ExprT>
846 std::ostream& operator << (std::ostream& os,
const Expr<ExprT,ExprSpecMPVector>& x) {
847 os << x.val() <<
" [";
849 for (
int i=0; i< x.size(); i++) {
851 for (
int j=0;
j<x.val().size(); ++
j) {
852 os <<
" " << x.dx(i,
j);
expr2 j expr1 expr1 expr2 expr2 j expr1 c c c c MinOp
#define FAD_BINARYOP_MACRO(OPNAME, OP, USING, MPVALUE, VALUE, DX, CDX1, CDX2, FASTACCESSDX, MPVAL_CONST_DX_1, MPVAL_CONST_DX_2, VAL_CONST_DX_1, VAL_CONST_DX_2, CONST_DX_1, CONST_DX_2, CONST_FASTACCESSDX_1, CONST_FASTACCESSDX_2)
expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 c expr1 expr2 expr1 expr2 expr1 MultiplicationOp
expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 c expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 j expr1 expr1 expr1 expr1 j expr1 c *expr2 expr1 c expr1 c expr1 c expr1 expr1 expr1 expr1 j *expr1 expr2 expr1 expr1 j *expr1 c expr2 expr1 c expr1 expr2 expr1 expr2 expr1 Atan2Op
expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 c expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 j expr1 expr1 expr1 expr1 j expr1 c *expr2 expr1 c expr1 c expr1 c expr1 DivisionOp
atan2(expr1.val(), expr2.val())
expr expr expr expr ExpOp
expr expr expr expr fastAccessDx(i, j)) FAD_UNARYOP_MACRO(exp
expr2 j expr1 expr1 expr2 expr2 j expr1 c c c c MaxOp
#define FAD_UNARYOP_MACRO(OPNAME, OP, USING, MPVALUE, VALUE, DX, FASTACCESSDX)
#define FAD_BINARYOP_MACRO(OPNAME, OP, MPVALUE, VALUE, DX, FASTACCESSDX, MPVAL_CONST_DX_1, MPVAL_CONST_DX_2, VAL_CONST_DX_1, VAL_CONST_DX_2, CONST_DX_1, CONST_DX_2, CONST_FASTACCESSDX_1, CONST_FASTACCESSDX_2)
#define FAD_UNARYOP_MACRO(OPNAME, OP, MPVALUE, VALUE, DX, FASTACCESSDX)