00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #ifndef SACADO_CACHEFAD_OPS_HPP
00055 #define SACADO_CACHEFAD_OPS_HPP
00056
00057 #include "Sacado_CacheFad_Expression.hpp"
00058 #include <cmath>
00059 #include <algorithm>
00060 #include <ostream>
00061
00062 #define FAD_UNARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE,DX,FASTACCESSDX) \
00063 namespace Sacado { \
00064 namespace CacheFad { \
00065 \
00066 template <typename ExprT> \
00067 class OP {}; \
00068 \
00069 template <typename ExprT> \
00070 class Expr< OP<ExprT> > { \
00071 public: \
00072 \
00073 typedef typename ExprT::value_type value_type; \
00074 \
00075 Expr(const ExprT& expr_) : expr(expr_) {} \
00076 \
00077 int size() const { return expr.size(); } \
00078 \
00079 bool hasFastAccess() const { return expr.hasFastAccess(); } \
00080 \
00081 bool isPassive() const { return expr.isPassive();} \
00082 \
00083 value_type val() const { \
00084 v = expr.val(); \
00085 PARTIAL; \
00086 return VALUE; \
00087 } \
00088 \
00089 value_type dx(int i) const { \
00090 return DX; \
00091 } \
00092 \
00093 value_type fastAccessDx(int i) const { \
00094 return FASTACCESSDX; \
00095 } \
00096 \
00097 protected: \
00098 \
00099 const ExprT& expr; \
00100 mutable value_type v; \
00101 mutable value_type a; \
00102 }; \
00103 \
00104 template <typename T> \
00105 inline Expr< OP< Expr<T> > > \
00106 OPNAME (const Expr<T>& expr) \
00107 { \
00108 typedef OP< Expr<T> > expr_t; \
00109 \
00110 return Expr<expr_t>(expr); \
00111 } \
00112 } \
00113 }
00114
00115 FAD_UNARYOP_MACRO(operator+,
00116 UnaryPlusOp,
00117 ;,
00118 v,
00119 expr.dx(i),
00120 expr.fastAccessDx(i))
00121 FAD_UNARYOP_MACRO(operator-,
00122 UnaryMinusOp,
00123 ;,
00124 -v,
00125 -expr.dx(i),
00126 -expr.fastAccessDx(i))
00127 FAD_UNARYOP_MACRO(exp,
00128 ExpOp,
00129 a = std::exp(v),
00130 a,
00131 expr.dx(i)*a,
00132 expr.fastAccessDx(i)*a)
00133 FAD_UNARYOP_MACRO(log,
00134 LogOp,
00135 ;,
00136 std::log(v),
00137 expr.dx(i)/v,
00138 expr.fastAccessDx(i)/v)
00139 FAD_UNARYOP_MACRO(log10,
00140 Log10Op,
00141 a = std::log(value_type(10))*v,
00142 std::log10(v),
00143 expr.dx(i)/a,
00144 expr.fastAccessDx(i)/a)
00145 FAD_UNARYOP_MACRO(sqrt,
00146 SqrtOp,
00147 a = value_type(2)*std::sqrt(v),
00148 std::sqrt(v),
00149 expr.dx(i)/a,
00150 expr.fastAccessDx(i)/a)
00151 FAD_UNARYOP_MACRO(cos,
00152 CosOp,
00153 a = std::sin(v),
00154 std::cos(v),
00155 -expr.dx(i)*a,
00156 -expr.fastAccessDx(i)*a)
00157 FAD_UNARYOP_MACRO(sin,
00158 SinOp,
00159 a = std::cos(v),
00160 std::sin(v),
00161 expr.dx(i)*a,
00162 expr.fastAccessDx(i)*a)
00163 FAD_UNARYOP_MACRO(tan,
00164 TanOp,
00165 value_type t = std::tan(v); a = value_type(1)+t*t,
00166 t,
00167 expr.dx(i)*a,
00168 expr.fastAccessDx(i)*a)
00169 FAD_UNARYOP_MACRO(acos,
00170 ACosOp,
00171 a = - std::sqrt(value_type(1)-v*v),
00172 std::acos(v),
00173 expr.dx(i)/a,
00174 expr.fastAccessDx(i)/a)
00175 FAD_UNARYOP_MACRO(asin,
00176 ASinOp,
00177 a = std::sqrt(value_type(1)-v*v),
00178 std::asin(v),
00179 expr.dx(i)/a,
00180 expr.fastAccessDx(i)/a)
00181 FAD_UNARYOP_MACRO(atan,
00182 ATanOp,
00183 a = (value_type(1)+v*v),
00184 std::atan(v),
00185 expr.dx(i)/a,
00186 expr.fastAccessDx(i)/a)
00187 FAD_UNARYOP_MACRO(cosh,
00188 CoshOp,
00189 a = std::sinh(v),
00190 std::cosh(v),
00191 expr.dx(i)*a,
00192 expr.fastAccessDx(i)*a)
00193 FAD_UNARYOP_MACRO(sinh,
00194 SinhOp,
00195 a = std::cosh(v),
00196 std::sinh(v),
00197 expr.dx(i)*a,
00198 expr.fastAccessDx(i)*a)
00199 FAD_UNARYOP_MACRO(tanh,
00200 TanhOp,
00201 a = std::cosh(v); a = a*a,
00202 std::tanh(v),
00203 expr.dx(i)/a,
00204 expr.fastAccessDx(i)/a)
00205 FAD_UNARYOP_MACRO(acosh,
00206 ACoshOp,
00207 a = std::sqrt((v-value_type(1))*(v+value_type(1))),
00208 acosh(v),
00209 expr.dx(i)/a,
00210 expr.fastAccessDx(i)/a)
00211 FAD_UNARYOP_MACRO(asinh,
00212 ASinhOp,
00213 a = std::sqrt(value_type(1)+v*v),
00214 asinh(v),
00215 expr.dx(i)/a,
00216 expr.fastAccessDx(i)/a)
00217 FAD_UNARYOP_MACRO(atanh,
00218 ATanhOp,
00219 a = value_type(1)-v*v,
00220 atanh(v),
00221 expr.dx(i)/a,
00222 expr.fastAccessDx(i)/a)
00223 FAD_UNARYOP_MACRO(abs,
00224 AbsOp,
00225 ;,
00226 std::abs(v),
00227 v >= 0 ? value_type(+expr.dx(i)) : value_type(-expr.dx(i)),
00228 v >= 0 ? value_type(+expr.fastAccessDx(i)) :
00229 value_type(-expr.fastAccessDx(i)))
00230 FAD_UNARYOP_MACRO(fabs,
00231 FAbsOp,
00232 ;,
00233 std::fabs(v),
00234 v >= 0 ? value_type(+expr.dx(i)) : value_type(-expr.dx(i)),
00235 v >= 0 ? value_type(+expr.fastAccessDx(i)) :
00236 value_type(-expr.fastAccessDx(i)))
00237
00238 #undef FAD_UNARYOP_MACRO
00239
00240 #define FAD_BINARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE,DX,FASTACCESSDX,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
00241 namespace Sacado { \
00242 namespace CacheFad { \
00243 \
00244 template <typename ExprT1, typename ExprT2> \
00245 class OP {}; \
00246 \
00247 template <typename ExprT1, typename ExprT2> \
00248 class Expr< OP<ExprT1,ExprT2> > { \
00249 \
00250 public: \
00251 \
00252 typedef typename ExprT1::value_type value_type_1; \
00253 typedef typename ExprT2::value_type value_type_2; \
00254 typedef typename Sacado::Promote<value_type_1, \
00255 value_type_2>::type value_type; \
00256 \
00257 Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
00258 expr1(expr1_), expr2(expr2_) {} \
00259 \
00260 int size() const { \
00261 int sz1 = expr1.size(), sz2 = expr2.size(); \
00262 return sz1 > sz2 ? sz1 : sz2; \
00263 } \
00264 \
00265 bool hasFastAccess() const { \
00266 return expr1.hasFastAccess() && expr2.hasFastAccess(); \
00267 } \
00268 \
00269 bool isPassive() const { \
00270 return expr1.isPassive() && expr2.isPassive(); \
00271 } \
00272 \
00273 value_type val() const { \
00274 v1 = expr1.val(); \
00275 v2 = expr2.val(); \
00276 PARTIAL; \
00277 return VALUE; \
00278 } \
00279 \
00280 value_type dx(int i) const { \
00281 return DX; \
00282 } \
00283 \
00284 value_type fastAccessDx(int i) const { \
00285 return FASTACCESSDX; \
00286 } \
00287 \
00288 protected: \
00289 \
00290 const ExprT1& expr1; \
00291 const ExprT2& expr2; \
00292 mutable value_type_1 v1; \
00293 mutable value_type_2 v2; \
00294 mutable value_type a; \
00295 mutable value_type b; \
00296 }; \
00297 \
00298 template <typename ExprT1> \
00299 class Expr< OP<ExprT1, ConstExpr<typename ExprT1::value_type> > >{ \
00300 \
00301 public: \
00302 \
00303 typedef typename ExprT1::value_type value_type; \
00304 typedef ConstExpr<typename ExprT1::value_type> ExprT2; \
00305 \
00306 Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
00307 expr1(expr1_), expr2(expr2_) {} \
00308 \
00309 int size() const { \
00310 return expr1.size(); \
00311 } \
00312 \
00313 bool hasFastAccess() const { \
00314 return expr1.hasFastAccess(); \
00315 } \
00316 \
00317 bool isPassive() const { \
00318 return expr1.isPassive(); \
00319 } \
00320 \
00321 value_type val() const { \
00322 v1 = expr1.val(); \
00323 v2 = expr2.val(); \
00324 PARTIAL; \
00325 return VALUE; \
00326 } \
00327 \
00328 value_type dx(int i) const { \
00329 return CONST_DX_2; \
00330 } \
00331 \
00332 value_type fastAccessDx(int i) const { \
00333 return CONST_FASTACCESSDX_2; \
00334 } \
00335 \
00336 protected: \
00337 \
00338 const ExprT1& expr1; \
00339 const ExprT2 expr2; \
00340 mutable value_type v1; \
00341 mutable value_type v2; \
00342 mutable value_type a; \
00343 mutable value_type b; \
00344 }; \
00345 \
00346 template <typename ExprT2> \
00347 class Expr< OP<ConstExpr<typename ExprT2::value_type>, ExprT2 > >{ \
00348 \
00349 public: \
00350 \
00351 typedef typename ExprT2::value_type value_type; \
00352 typedef ConstExpr<typename ExprT2::value_type> ExprT1; \
00353 \
00354 Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
00355 expr1(expr1_), expr2(expr2_) {} \
00356 \
00357 int size() const { \
00358 return expr2.size(); \
00359 } \
00360 \
00361 bool hasFastAccess() const { \
00362 return expr2.hasFastAccess(); \
00363 } \
00364 \
00365 bool isPassive() const { \
00366 return expr2.isPassive(); \
00367 } \
00368 \
00369 value_type val() const { \
00370 v1 = expr1.val(); \
00371 v2 = expr2.val(); \
00372 PARTIAL; \
00373 return VALUE; \
00374 } \
00375 \
00376 value_type dx(int i) const { \
00377 return CONST_DX_1; \
00378 } \
00379 \
00380 value_type fastAccessDx(int i) const { \
00381 return CONST_FASTACCESSDX_1; \
00382 } \
00383 \
00384 protected: \
00385 \
00386 const ExprT1 expr1; \
00387 const ExprT2& expr2; \
00388 mutable value_type v1; \
00389 mutable value_type v2; \
00390 mutable value_type a; \
00391 mutable value_type b; \
00392 }; \
00393 \
00394 template <typename T1, typename T2> \
00395 inline Expr< OP< Expr<T1>, Expr<T2> > > \
00396 OPNAME (const Expr<T1>& expr1, const Expr<T2>& expr2) \
00397 { \
00398 typedef OP< Expr<T1>, Expr<T2> > expr_t; \
00399 \
00400 return Expr<expr_t>(expr1, expr2); \
00401 } \
00402 \
00403 template <typename T> \
00404 inline Expr< OP< Expr<T>, Expr<T> > > \
00405 OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
00406 { \
00407 typedef OP< Expr<T>, Expr<T> > expr_t; \
00408 \
00409 return Expr<expr_t>(expr1, expr2); \
00410 } \
00411 \
00412 template <typename T> \
00413 inline Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
00414 Expr<T> > > \
00415 OPNAME (const typename Expr<T>::value_type& c, \
00416 const Expr<T>& expr) \
00417 { \
00418 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
00419 typedef OP< ConstT, Expr<T> > expr_t; \
00420 \
00421 return Expr<expr_t>(ConstT(c), expr); \
00422 } \
00423 \
00424 template <typename T> \
00425 inline Expr< OP< Expr<T>, \
00426 ConstExpr<typename Expr<T>::value_type> > > \
00427 OPNAME (const Expr<T>& expr, \
00428 const typename Expr<T>::value_type& c) \
00429 { \
00430 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
00431 typedef OP< Expr<T>, ConstT > expr_t; \
00432 \
00433 return Expr<expr_t>(expr, ConstT(c)); \
00434 } \
00435 } \
00436 }
00437
00438 FAD_BINARYOP_MACRO(operator+,
00439 AdditionOp,
00440 ;,
00441 v1 + v2,
00442 expr1.dx(i) + expr2.dx(i),
00443 expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
00444 expr2.dx(i),
00445 expr1.dx(i),
00446 expr2.fastAccessDx(i),
00447 expr1.fastAccessDx(i))
00448 FAD_BINARYOP_MACRO(operator-,
00449 SubtractionOp,
00450 ;,
00451 v1 - v2,
00452 expr1.dx(i) - expr2.dx(i),
00453 expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
00454 -expr2.dx(i),
00455 expr1.dx(i),
00456 -expr2.fastAccessDx(i),
00457 expr1.fastAccessDx(i))
00458 FAD_BINARYOP_MACRO(operator*,
00459 MultiplicationOp,
00460 ;,
00461 v1*v2,
00462 v1*expr2.dx(i) + expr1.dx(i)*v2,
00463 v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2,
00464 v1*expr2.dx(i),
00465 expr1.dx(i)*v2,
00466 v1*expr2.fastAccessDx(i),
00467 expr1.fastAccessDx(i)*v2)
00468 FAD_BINARYOP_MACRO(operator/,
00469 DivisionOp,
00470 value_type c = v1/v2; a = value_type(1)/v2; b = -c/v2,
00471 c,
00472 expr1.dx(i)*a + expr2.dx(i)*b,
00473 expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b,
00474 expr2.dx(i)*b,
00475 expr1.dx(i)*a,
00476 expr2.fastAccessDx(i)*b,
00477 expr1.fastAccessDx(i)*a)
00478 FAD_BINARYOP_MACRO(atan2,
00479 Atan2Op,
00480 a=v1*v1 + v2*v2,
00481 std::atan2(v1,v2),
00482 (expr1.dx(i)*v2 - expr2.dx(i)*v1)/a,
00483 (expr1.fastAccessDx(i)*v2 - expr2.fastAccessDx(i)*v1)/a,
00484 (-expr2.dx(i)*v1)/a,
00485 (expr1.dx(i)*v2)/a,
00486 (-expr2.fastAccessDx(i)*v1)/a,
00487 (expr1.fastAccessDx(i)*v2)/a)
00488 FAD_BINARYOP_MACRO(pow,
00489 PowerOp,
00490 value_type c= std::pow(v1,v2); a=c*v2/v1; b=c*std::log(v1),
00491 c,
00492 expr1.dx(i)*a + expr2.dx(i)*b,
00493 expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b,
00494 expr2.dx(i)*b,
00495 expr1.dx(i)*a,
00496 expr2.fastAccessDx(i)*b,
00497 expr1.fastAccessDx(i)*a)
00498 FAD_BINARYOP_MACRO(max,
00499 MaxOp,
00500 ;,
00501 std::max(expr1.val(), expr2.val()),
00502 expr1.val() >= expr2.val() ? expr1.dx(i) : expr2.dx(i),
00503 expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) :
00504 expr2.fastAccessDx(i),
00505 expr1.val() >= expr2.val() ? value_type(0) : expr2.dx(i),
00506 expr1.val() >= expr2.val() ? expr1.dx(i) : value_type(0),
00507 expr1.val() >= expr2.val() ? value_type(0) :
00508 expr2.fastAccessDx(i),
00509 expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) :
00510 value_type(0))
00511 FAD_BINARYOP_MACRO(min,
00512 MinOp,
00513 ;,
00514 std::min(expr1.val(), expr2.val()),
00515 expr1.val() <= expr2.val() ? expr1.dx(i) : expr2.dx(i),
00516 expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) :
00517 expr2.fastAccessDx(i),
00518 expr1.val() <= expr2.val() ? value_type(0) : expr2.dx(i),
00519 expr1.val() <= expr2.val() ? expr1.dx(i) : value_type(0),
00520 expr1.val() <= expr2.val() ? value_type(0) :
00521 expr2.fastAccessDx(i),
00522 expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) :
00523 value_type(0))
00524
00525 #undef FAD_BINARYOP_MACRO
00526
00527
00528
00529
00530
00531 #include "Sacado_mpl_disable_if.hpp"
00532 #include "Sacado_mpl_is_same.hpp"
00533
00534 #define FAD_SFINAE_BINARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE,DX,FASTACCESSDX,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
00535 namespace Sacado { \
00536 namespace CacheFad { \
00537 \
00538 template <typename ExprT1, typename ExprT2> \
00539 class OP { \
00540 \
00541 public: \
00542 \
00543 typedef typename ExprT1::value_type value_type_1; \
00544 typedef typename ExprT2::value_type value_type_2; \
00545 typedef typename Sacado::Promote<value_type_1, \
00546 value_type_2>::type value_type; \
00547 \
00548 OP(const ExprT1& expr1, const ExprT2& expr2) {} \
00549 \
00550 value_type \
00551 computeValue(const ExprT1& expr1, const ExprT2& expr2) const { \
00552 v1 = expr1.val(); \
00553 v2 = expr2.val(); \
00554 PARTIAL; \
00555 return VALUE; \
00556 } \
00557 \
00558 value_type \
00559 computeDx(int i, const ExprT1& expr1, \
00560 const ExprT2& expr2) const { \
00561 return DX; \
00562 } \
00563 \
00564 value_type \
00565 computeFastAccessDx(int i, const ExprT1& expr1, \
00566 const ExprT2& expr2) const { \
00567 return FASTACCESSDX; \
00568 } \
00569 \
00570 protected: \
00571 \
00572 mutable value_type_1 v1; \
00573 mutable value_type_2 v2; \
00574 mutable value_type a; \
00575 mutable value_type b; \
00576 }; \
00577 \
00578 template <typename ExprT1> \
00579 class OP<ExprT1, ConstExpr<typename ExprT1::value_type> > { \
00580 \
00581 public: \
00582 \
00583 typedef typename ExprT1::value_type value_type; \
00584 typedef ConstExpr<typename ExprT1::value_type> ExprT2; \
00585 \
00586 OP(const ExprT1& expr1, const ExprT2& expr2) {} \
00587 \
00588 value_type \
00589 computeValue(const ExprT1& expr1, const ExprT2& expr2) const { \
00590 v1 = expr1.val(); \
00591 v2 = expr2.val(); \
00592 PARTIAL; \
00593 return VALUE; \
00594 } \
00595 \
00596 value_type \
00597 computeDx(int i, const ExprT1& expr1, \
00598 const ExprT2& expr2) const { \
00599 return CONST_DX_2; \
00600 } \
00601 \
00602 value_type \
00603 computeFastAccessDx(int i, const ExprT1& expr1, \
00604 const ExprT2& expr2) const { \
00605 return CONST_FASTACCESSDX_2; \
00606 } \
00607 \
00608 protected: \
00609 \
00610 mutable value_type v1; \
00611 mutable value_type v2; \
00612 mutable value_type a; \
00613 mutable value_type b; \
00614 }; \
00615 \
00616 template <typename ExprT2> \
00617 class OP<ConstExpr<typename ExprT2::value_type>, ExprT2 > { \
00618 \
00619 public: \
00620 \
00621 typedef typename ExprT2::value_type value_type; \
00622 typedef ConstExpr<typename ExprT2::value_type> ExprT1; \
00623 \
00624 OP(const ExprT1& expr1, const ExprT2& expr2) {} \
00625 \
00626 value_type \
00627 computeValue(const ExprT1& expr1, const ExprT2& expr2) const { \
00628 v1 = expr1.val(); \
00629 v2 = expr2.val(); \
00630 PARTIAL; \
00631 return VALUE; \
00632 } \
00633 \
00634 value_type \
00635 computeDx(int i, const ExprT1& expr1, \
00636 const ExprT2& expr2) const { \
00637 return CONST_DX_1; \
00638 } \
00639 \
00640 value_type \
00641 computeFastAccessDx(int i, const ExprT1& expr1, \
00642 const ExprT2& expr2) const { \
00643 return CONST_FASTACCESSDX_1; \
00644 } \
00645 \
00646 protected: \
00647 \
00648 mutable value_type v1; \
00649 mutable value_type v2; \
00650 mutable value_type a; \
00651 mutable value_type b; \
00652 }; \
00653 \
00654 template <typename T1, typename T2> \
00655 inline \
00656 typename \
00657 mpl::disable_if< mpl::is_same<T1,T2>, \
00658 Expr<BinaryExpr<Expr<T1>, Expr<T2>, OP> > >::type \
00659 OPNAME (const Expr<T1>& expr1, const Expr<T2>& expr2) \
00660 { \
00661 typedef BinaryExpr< Expr<T1>, Expr<T2>, OP > expr_t; \
00662 \
00663 return Expr<expr_t>(expr_t(expr1, expr2)); \
00664 } \
00665 \
00666 template <typename T> \
00667 inline Expr< BinaryExpr< ConstExpr<typename Expr<T>::value_type>, \
00668 Expr<T>, OP > > \
00669 OPNAME (const typename Expr<T>::value_type& c, \
00670 const Expr<T>& expr) \
00671 { \
00672 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
00673 typedef BinaryExpr< ConstT, Expr<T>, OP > expr_t; \
00674 \
00675 return Expr<expr_t>(expr_t(ConstT(c), expr)); \
00676 } \
00677 \
00678 template <typename T> \
00679 inline Expr< BinaryExpr< Expr<T>, \
00680 ConstExpr<typename Expr<T>::value_type>, \
00681 OP > > \
00682 OPNAME (const Expr<T>& expr, \
00683 const typename Expr<T>::value_type& c) \
00684 { \
00685 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
00686 typedef BinaryExpr< Expr<T>, ConstT, OP > expr_t; \
00687 \
00688 return Expr<expr_t>(expr_t(expr, ConstT(c))); \
00689 } \
00690 } \
00691 }
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 #undef FAD_SFINAE_BINARYOP_MACRO
00721
00722
00723
00724 #define FAD_RELOP_MACRO(OP) \
00725 namespace Sacado { \
00726 namespace CacheFad { \
00727 template <typename ExprT1, typename ExprT2> \
00728 inline bool \
00729 operator OP (const Expr<ExprT1>& expr1, \
00730 const Expr<ExprT2>& expr2) \
00731 { \
00732 return expr1.val() OP expr2.val(); \
00733 } \
00734 \
00735 template <typename ExprT2> \
00736 inline bool \
00737 operator OP (const typename Expr<ExprT2>::value_type& a, \
00738 const Expr<ExprT2>& expr2) \
00739 { \
00740 return a OP expr2.val(); \
00741 } \
00742 \
00743 template <typename ExprT1> \
00744 inline bool \
00745 operator OP (const Expr<ExprT1>& expr1, \
00746 const typename Expr<ExprT1>::value_type& b) \
00747 { \
00748 return expr1.val() OP b; \
00749 } \
00750 } \
00751 }
00752
00753 FAD_RELOP_MACRO(==)
00754 FAD_RELOP_MACRO(!=)
00755 FAD_RELOP_MACRO(<)
00756 FAD_RELOP_MACRO(>)
00757 FAD_RELOP_MACRO(<=)
00758 FAD_RELOP_MACRO(>=)
00759 FAD_RELOP_MACRO(<<=)
00760 FAD_RELOP_MACRO(>>=)
00761 FAD_RELOP_MACRO(&)
00762 FAD_RELOP_MACRO(|)
00763
00764 #undef FAD_RELOP_MACRO
00765
00766 namespace Sacado {
00767
00768 namespace CacheFad {
00769
00770 template <typename ExprT>
00771 inline bool operator ! (const Expr<ExprT>& expr)
00772 {
00773 return ! expr.val();
00774 }
00775
00776 }
00777
00778 }
00779
00780
00781
00782 namespace Sacado {
00783
00784 namespace CacheFad {
00785
00786 template <typename ExprT>
00787 std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
00788 os << x.val() << " [";
00789
00790 for (int i=0; i< x.size(); i++) {
00791 os << " " << x.dx(i);
00792 }
00793
00794 os << " ]\n";
00795 return os;
00796 }
00797
00798 }
00799
00800 }
00801
00802
00803 #endif // SACADO_CACHEFAD_OPS_HPP