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_LFAD_LOGICALSPARSEOPS_HPP
00055 #define SACADO_LFAD_LOGICALSPARSEOPS_HPP
00056
00057 #include <cmath>
00058 #include <algorithm>
00059 #include <ostream>
00060
00061 #define FAD_UNARYOP_MACRO(OPNAME,OP,VALUE) \
00062 namespace Sacado { \
00063 namespace LFad { \
00064 \
00065 template <typename ExprT> \
00066 class OP {}; \
00067 \
00068 template <typename ExprT> \
00069 class Expr< OP<ExprT> > { \
00070 public: \
00071 \
00072 typedef typename ExprT::value_type value_type; \
00073 typedef typename ExprT::logical_type logical_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 return VALUE; \
00085 } \
00086 \
00087 logical_type dx(int i) const { \
00088 return expr.dx(i); \
00089 } \
00090 \
00091 logical_type fastAccessDx(int i) const { \
00092 return expr.fastAccessDx(i); \
00093 } \
00094 \
00095 protected: \
00096 \
00097 const ExprT& expr; \
00098 }; \
00099 \
00100 template <typename T> \
00101 inline Expr< OP< Expr<T> > > \
00102 OPNAME (const Expr<T>& expr) \
00103 { \
00104 typedef OP< Expr<T> > expr_t; \
00105 \
00106 return Expr<expr_t>(expr); \
00107 } \
00108 } \
00109 }
00110
00111 FAD_UNARYOP_MACRO(operator+,
00112 UnaryPlusOp,
00113 expr.val())
00114 FAD_UNARYOP_MACRO(operator-,
00115 UnaryMinusOp,
00116 -expr.val())
00117 FAD_UNARYOP_MACRO(exp,
00118 ExpOp,
00119 std::exp(expr.val()))
00120 FAD_UNARYOP_MACRO(log,
00121 LogOp,
00122 std::log(expr.val()))
00123 FAD_UNARYOP_MACRO(log10,
00124 Log10Op,
00125 std::log10(expr.val()))
00126 FAD_UNARYOP_MACRO(sqrt,
00127 SqrtOp,
00128 std::sqrt(expr.val()))
00129 FAD_UNARYOP_MACRO(cos,
00130 CosOp,
00131 std::cos(expr.val()))
00132 FAD_UNARYOP_MACRO(sin,
00133 SinOp,
00134 std::sin(expr.val()))
00135 FAD_UNARYOP_MACRO(tan,
00136 TanOp,
00137 std::tan(expr.val()))
00138 FAD_UNARYOP_MACRO(acos,
00139 ACosOp,
00140 std::acos(expr.val()))
00141 FAD_UNARYOP_MACRO(asin,
00142 ASinOp,
00143 std::asin(expr.val()))
00144 FAD_UNARYOP_MACRO(atan,
00145 ATanOp,
00146 std::atan(expr.val()))
00147 FAD_UNARYOP_MACRO(cosh,
00148 CoshOp,
00149 std::cosh(expr.val()))
00150 FAD_UNARYOP_MACRO(sinh,
00151 SinhOp,
00152 std::sinh(expr.val()))
00153 FAD_UNARYOP_MACRO(tanh,
00154 TanhOp,
00155 std::tanh(expr.val()))
00156 FAD_UNARYOP_MACRO(acosh,
00157 ACoshOp,
00158 acosh(expr.val()))
00159 FAD_UNARYOP_MACRO(asinh,
00160 ASinhOp,
00161 asinh(expr.val()))
00162 FAD_UNARYOP_MACRO(atanh,
00163 ATanhOp,
00164 atanh(expr.val()))
00165 FAD_UNARYOP_MACRO(abs,
00166 AbsOp,
00167 std::abs(expr.val()))
00168 FAD_UNARYOP_MACRO(fabs,
00169 FAbsOp,
00170 std::fabs(expr.val()))
00171
00172 #undef FAD_UNARYOP_MACRO
00173
00174 #define FAD_BINARYOP_MACRO(OPNAME,OP,VALUE,DX,FASTACCESSDX,VAL_CONST_DX_1,VAL_CONST_DX_2,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
00175 namespace Sacado { \
00176 namespace LFad { \
00177 \
00178 template <typename ExprT1, typename ExprT2> \
00179 class OP {}; \
00180 \
00181 template <typename T1, typename T2> \
00182 class Expr< OP< Expr<T1>, Expr<T2> > > { \
00183 \
00184 public: \
00185 \
00186 typedef Expr<T1> ExprT1; \
00187 typedef Expr<T2> ExprT2; \
00188 typedef typename ExprT1::value_type value_type_1; \
00189 typedef typename ExprT2::value_type value_type_2; \
00190 typedef typename Sacado::Promote<value_type_1, \
00191 value_type_2>::type value_type; \
00192 typedef typename ExprT1::logical_type logical_type; \
00193 \
00194 Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
00195 expr1(expr1_), expr2(expr2_) {} \
00196 \
00197 int size() const { \
00198 int sz1 = expr1.size(), sz2 = expr2.size(); \
00199 return sz1 > sz2 ? sz1 : sz2; \
00200 } \
00201 \
00202 bool hasFastAccess() const { \
00203 return expr1.hasFastAccess() && expr2.hasFastAccess(); \
00204 } \
00205 \
00206 bool isPassive() const { \
00207 return expr1.isPassive() && expr2.isPassive(); \
00208 } \
00209 \
00210 const value_type val() const { \
00211 return VALUE; \
00212 } \
00213 \
00214 const logical_type dx(int i) const { \
00215 return DX; \
00216 } \
00217 \
00218 const logical_type fastAccessDx(int i) const { \
00219 return FASTACCESSDX; \
00220 } \
00221 \
00222 protected: \
00223 \
00224 const ExprT1& expr1; \
00225 const ExprT2& expr2; \
00226 \
00227 }; \
00228 \
00229 template <typename T1> \
00230 class Expr< OP< Expr<T1>, typename Expr<T1>::value_type> > { \
00231 \
00232 public: \
00233 \
00234 typedef Expr<T1> ExprT1; \
00235 typedef typename ExprT1::value_type value_type; \
00236 typedef typename ExprT1::value_type ConstT; \
00237 typedef typename ExprT1::logical_type logical_type; \
00238 \
00239 Expr(const ExprT1& expr1_, const ConstT& c_) : \
00240 expr1(expr1_), c(c_) {} \
00241 \
00242 int size() const { \
00243 return expr1.size(); \
00244 } \
00245 \
00246 bool hasFastAccess() const { \
00247 return expr1.hasFastAccess(); \
00248 } \
00249 \
00250 bool isPassive() const { \
00251 return expr1.isPassive(); \
00252 } \
00253 \
00254 const value_type val() const { \
00255 return VAL_CONST_DX_2; \
00256 } \
00257 \
00258 const logical_type dx(int i) const { \
00259 return CONST_DX_2; \
00260 } \
00261 \
00262 const logical_type fastAccessDx(int i) const { \
00263 return CONST_FASTACCESSDX_2; \
00264 } \
00265 \
00266 protected: \
00267 \
00268 const ExprT1& expr1; \
00269 const ConstT& c; \
00270 }; \
00271 \
00272 template <typename T2> \
00273 class Expr< OP< typename Expr<T2>::value_type, Expr<T2> > > { \
00274 \
00275 public: \
00276 \
00277 typedef Expr<T2> ExprT2; \
00278 typedef typename ExprT2::value_type value_type; \
00279 typedef typename ExprT2::value_type ConstT; \
00280 typedef typename ExprT2::logical_type logical_type; \
00281 \
00282 Expr(const ConstT& c_, const ExprT2& expr2_) : \
00283 c(c_), expr2(expr2_) {} \
00284 \
00285 int size() const { \
00286 return expr2.size(); \
00287 } \
00288 \
00289 bool hasFastAccess() const { \
00290 return expr2.hasFastAccess(); \
00291 } \
00292 \
00293 bool isPassive() const { \
00294 return expr2.isPassive(); \
00295 } \
00296 \
00297 const value_type val() const { \
00298 return VAL_CONST_DX_1; \
00299 } \
00300 \
00301 const logical_type dx(int i) const { \
00302 return CONST_DX_1; \
00303 } \
00304 \
00305 const logical_type fastAccessDx(int i) const { \
00306 return CONST_FASTACCESSDX_1; \
00307 } \
00308 \
00309 protected: \
00310 \
00311 const ConstT& c; \
00312 const ExprT2& expr2; \
00313 }; \
00314 \
00315 template <typename T1, typename T2> \
00316 inline Expr< OP< Expr<T1>, Expr<T2> > > \
00317 OPNAME (const Expr<T1>& expr1, const Expr<T2>& expr2) \
00318 { \
00319 typedef OP< Expr<T1>, Expr<T2> > expr_t; \
00320 \
00321 return Expr<expr_t>(expr1, expr2); \
00322 } \
00323 \
00324 template <typename T> \
00325 inline Expr< OP< Expr<T>, Expr<T> > > \
00326 OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
00327 { \
00328 typedef OP< Expr<T>, Expr<T> > expr_t; \
00329 \
00330 return Expr<expr_t>(expr1, expr2); \
00331 } \
00332 \
00333 template <typename T> \
00334 inline Expr< OP< typename Expr<T>::value_type, Expr<T> > > \
00335 OPNAME (const typename Expr<T>::value_type& c, \
00336 const Expr<T>& expr) \
00337 { \
00338 typedef typename Expr<T>::value_type ConstT; \
00339 typedef OP< ConstT, Expr<T> > expr_t; \
00340 \
00341 return Expr<expr_t>(c, expr); \
00342 } \
00343 \
00344 template <typename T> \
00345 inline Expr< OP< Expr<T>, typename Expr<T>::value_type > > \
00346 OPNAME (const Expr<T>& expr, \
00347 const typename Expr<T>::value_type& c) \
00348 { \
00349 typedef typename Expr<T>::value_type ConstT; \
00350 typedef OP< Expr<T>, ConstT > expr_t; \
00351 \
00352 return Expr<expr_t>(expr, c); \
00353 } \
00354 } \
00355 }
00356
00357
00358 FAD_BINARYOP_MACRO(operator+,
00359 AdditionOp,
00360 expr1.val() + expr2.val(),
00361 expr1.dx(i) || expr2.dx(i),
00362 expr1.fastAccessDx(i) || expr2.fastAccessDx(i),
00363 c + expr2.val(),
00364 expr1.val() + c,
00365 expr2.dx(i),
00366 expr1.dx(i),
00367 expr2.fastAccessDx(i),
00368 expr1.fastAccessDx(i))
00369 FAD_BINARYOP_MACRO(operator-,
00370 SubtractionOp,
00371 expr1.val() - expr2.val(),
00372 expr1.dx(i) || expr2.dx(i),
00373 expr1.fastAccessDx(i) || expr2.fastAccessDx(i),
00374 c - expr2.val(),
00375 expr1.val() - c,
00376 expr2.dx(i),
00377 expr1.dx(i),
00378 expr2.fastAccessDx(i),
00379 expr1.fastAccessDx(i))
00380 FAD_BINARYOP_MACRO(operator*,
00381 MultiplicationOp,
00382 expr1.val() * expr2.val(),
00383 expr1.dx(i) || expr2.dx(i),
00384 expr1.fastAccessDx(i) || expr2.fastAccessDx(i),
00385 c * expr2.val(),
00386 expr1.val() * c,
00387 expr2.dx(i),
00388 expr1.dx(i),
00389 expr2.fastAccessDx(i),
00390 expr1.fastAccessDx(i))
00391 FAD_BINARYOP_MACRO(operator/,
00392 DivisionOp,
00393 expr1.val() / expr2.val(),
00394 expr1.dx(i) || expr2.dx(i),
00395 expr1.fastAccessDx(i) || expr2.fastAccessDx(i),
00396 c / expr2.val(),
00397 expr1.val() / c,
00398 expr2.dx(i),
00399 expr1.dx(i),
00400 expr2.fastAccessDx(i),
00401 expr1.fastAccessDx(i))
00402 FAD_BINARYOP_MACRO(atan2,
00403 Atan2Op,
00404 std::atan2(expr1.val(), expr2.val()),
00405 expr1.dx(i) || expr2.dx(i),
00406 expr1.fastAccessDx(i) || expr2.fastAccessDx(i),
00407 std::atan2(c, expr2.val()),
00408 std::atan2(expr1.val(), c),
00409 expr2.dx(i),
00410 expr1.dx(i),
00411 expr2.fastAccessDx(i),
00412 expr1.fastAccessDx(i))
00413 FAD_BINARYOP_MACRO(pow,
00414 PowerOp,
00415 std::pow(expr1.val(), expr2.val()),
00416 expr1.dx(i) || expr2.dx(i),
00417 expr1.fastAccessDx(i) || expr2.fastAccessDx(i),
00418 std::pow(c, expr2.val()),
00419 std::pow(expr1.val(), c),
00420 expr2.dx(i),
00421 expr1.dx(i),
00422 expr2.fastAccessDx(i),
00423 expr1.fastAccessDx(i))
00424 FAD_BINARYOP_MACRO(max,
00425 MaxOp,
00426 std::max(expr1.val(), expr2.val()),
00427 expr1.val() >= expr2.val() ? expr1.dx(i) : expr2.dx(i),
00428 expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) :
00429 expr2.fastAccessDx(i),
00430 std::max(c, expr2.val()),
00431 std::max(expr1.val(), c),
00432 c >= expr2.val() ? logical_type(0) : expr2.dx(i),
00433 expr1.val() >= c ? expr1.dx(i) : logical_type(0),
00434 c >= expr2.val() ? logical_type(0) : expr2.fastAccessDx(i),
00435 expr1.val() >= c ? expr1.fastAccessDx(i) : logical_type(0))
00436 FAD_BINARYOP_MACRO(min,
00437 MinOp,
00438 std::min(expr1.val(), expr2.val()),
00439 expr1.val() <= expr2.val() ? expr1.dx(i) : expr2.dx(i),
00440 expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) :
00441 expr2.fastAccessDx(i),
00442 std::min(c, expr2.val()),
00443 std::min(expr1.val(), c),
00444 c <= expr2.val() ? logical_type(0) : expr2.dx(i),
00445 expr1.val() <= c ? expr1.dx(i) : logical_type(0),
00446 c <= expr2.val() ? logical_type(0) : expr2.fastAccessDx(i),
00447 expr1.val() <= c ? expr1.fastAccessDx(i) : logical_type(0))
00448
00449 #undef FAD_BINARYOP_MACRO
00450
00451
00452
00453 #define FAD_RELOP_MACRO(OP) \
00454 namespace Sacado { \
00455 namespace LFad { \
00456 template <typename ExprT1, typename ExprT2> \
00457 inline bool \
00458 operator OP (const Expr<ExprT1>& expr1, \
00459 const Expr<ExprT2>& expr2) \
00460 { \
00461 return expr1.val() OP expr2.val(); \
00462 } \
00463 \
00464 template <typename ExprT2> \
00465 inline bool \
00466 operator OP (const typename Expr<ExprT2>::value_type& a, \
00467 const Expr<ExprT2>& expr2) \
00468 { \
00469 return a OP expr2.val(); \
00470 } \
00471 \
00472 template <typename ExprT1> \
00473 inline bool \
00474 operator OP (const Expr<ExprT1>& expr1, \
00475 const typename Expr<ExprT1>::value_type& b) \
00476 { \
00477 return expr1.val() OP b; \
00478 } \
00479 } \
00480 }
00481
00482 FAD_RELOP_MACRO(==)
00483 FAD_RELOP_MACRO(!=)
00484 FAD_RELOP_MACRO(<)
00485 FAD_RELOP_MACRO(>)
00486 FAD_RELOP_MACRO(<=)
00487 FAD_RELOP_MACRO(>=)
00488 FAD_RELOP_MACRO(<<=)
00489 FAD_RELOP_MACRO(>>=)
00490 FAD_RELOP_MACRO(&)
00491 FAD_RELOP_MACRO(|)
00492
00493 #undef FAD_RELOP_MACRO
00494
00495 namespace Sacado {
00496
00497 namespace LFad {
00498
00499 template <typename ExprT>
00500 inline bool operator ! (const Expr<ExprT>& expr)
00501 {
00502 return ! expr.val();
00503 }
00504
00505 }
00506
00507 }
00508
00509
00510
00511 namespace Sacado {
00512
00513 namespace LFad {
00514
00515 template <typename ExprT>
00516 std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
00517 os << x.val() << " [";
00518
00519 for (int i=0; i< x.size(); i++) {
00520 os << " " << x.dx(i);
00521 }
00522
00523 os << " ]\n";
00524 return os;
00525 }
00526
00527 }
00528
00529 }
00530
00531
00532 #endif // SACADO_LFAD_LOGICALSPARSEOPS_HPP