00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00025
00026 #ifndef IPPL_EXPRESSIONS_H
00027 #define IPPL_EXPRESSIONS_H
00028
00029
00030
00031
00032 #define PETE_USER_REDUCTION_CODE \
00033 R global_ret; \
00034 reduce_masked(ret, global_ret, acc_op, 0 < n ); \
00035 ret = global_ret;
00036
00037
00038 #include "Message/Message.h"
00039 #include "PETE/IpplTypeComputations.h"
00040 #include "PETE/PETE.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 PETE_DefineUnary(Abs, (0 < a ? a : -a), FnAbs)
00053
00054 inline double
00055 PETE_apply(FnAbs, dcomplex a)
00056 {
00057 return abs(a);
00058 }
00059
00060 template<class T>
00061 inline PETE_TUTree<FnAbs, typename T::PETE_Expr_t>
00062 abs(const PETE_Expr<T>& l)
00063 {
00064 return PETE_TUTree<FnAbs, typename T::PETE_Expr_t>
00065 (l.PETE_unwrap().MakeExpression());
00066 }
00067
00068 PETE_DefineUnary(conj, (conj(a)), FnConj)
00069 PETE_DefineUnary(arg, (arg(a)), FnArg)
00070 PETE_DefineUnary(norm, (norm(a)), FnNorm)
00071 PETE_DefineUnary(real, (real(a)), FnReal)
00072 PETE_DefineUnary(imag, (imag(a)), FnImag)
00073 PETE_DefineUnary(sign, (sign(a)), FnSign)
00074 PETE_DefineUnary(trace, (trace(a)), FnTrace)
00075 PETE_DefineUnary(transpose, (transpose(a)), FnTranspose)
00076 PETE_DefineUnary(det, (det(a)), FnDet)
00077 PETE_DefineUnary(cofactors, (cofactors(a)), FnCofactors)
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 #define PETE_DefineScalarMinMax(Sca) \
00088 inline Sca \
00089 Min(const Sca& a, const Sca& b) \
00090 { \
00091 return (a<b ? a : b); \
00092 } \
00093 inline Sca \
00094 Max(const Sca& a, const Sca& b) \
00095 { \
00096 return (b<a ? a : b); \
00097 }
00098
00099 PETE_DefineScalarMinMax(short)
00100 PETE_DefineScalarMinMax(int)
00101 PETE_DefineScalarMinMax(long)
00102 PETE_DefineScalarMinMax(float)
00103 PETE_DefineScalarMinMax(double)
00104
00105 PETE_DefineBinary(Min, (Min(a,b)), FnMin)
00106 PETE_DefineBinary(Max, (Max(a,b)), FnMax)
00107
00108 PETE_DefineBinary(dot, (dot(a,b)), FnDot)
00109 PETE_DefineBinary(dotdot, (dotdot(a,b)), FnDotDot)
00110 PETE_DefineBinary(outerProduct, (outerProduct(a,b)), FnOuterProduct)
00111 PETE_DefineBinary(cross, (cross(a,b)), FnCross)
00112
00113 PETE_DefineBinarySynonym(lt, OpLT)
00114 PETE_DefineBinarySynonym(gt, OpGT)
00115 PETE_DefineBinarySynonym(le, OpLE)
00116 PETE_DefineBinarySynonym(ge, OpGE)
00117 PETE_DefineBinarySynonym(eq, OpEQ)
00118 PETE_DefineBinarySynonym(ne, OpNE)
00119
00120
00121 #define PETE_DefineIPPLScalar(Sca) \
00122 PETE_DefineBinaryWithScalars(Min, FnMin, Sca) \
00123 PETE_DefineBinaryWithScalars(Max, FnMax, Sca) \
00124 PETE_DefineBinaryWithScalars(dot, FnDot, Sca) \
00125 PETE_DefineBinaryWithScalars(dotdot, FnDotDot, Sca) \
00126 PETE_DefineBinaryWithScalars(outerProduct, FnOuterProduct, Sca) \
00127 PETE_DefineBinaryWithScalars(cross, FnDot, Sca) \
00128 PETE_DefineBinaryWithScalars(lt, OpLT, Sca) \
00129 PETE_DefineBinaryWithScalars(le, OpLE, Sca) \
00130 PETE_DefineBinaryWithScalars(gt, OpGT, Sca) \
00131 PETE_DefineBinaryWithScalars(ge, OpGE, Sca) \
00132 PETE_DefineBinaryWithScalars(eq, OpEQ, Sca) \
00133 PETE_DefineBinaryWithScalars(ne, OpNE, Sca)
00134
00135 PETE_DefineIPPLScalar(short)
00136 PETE_DefineIPPLScalar(int)
00137 PETE_DefineIPPLScalar(long)
00138 PETE_DefineIPPLScalar(float)
00139 PETE_DefineIPPLScalar(double)
00140
00141 PETE_DefineScalar(dcomplex)
00142 PETE_DefineBinaryWithScalars(eq, OpEQ, dcomplex)
00143 PETE_DefineBinaryWithScalars(ne, OpNE, dcomplex)
00144
00145 #undef PETE_DefineIPPLScalar
00146
00147
00148
00149
00150 #define PETE_DefineBinaryWithVSTScalars(Fun,Op,Sca) \
00151 template<class T1, unsigned Dim, class T2> \
00152 inline PETE_TBTree<Op, PETE_Scalar< Sca<T1, Dim> >, \
00153 typename T2::PETE_Expr_t> \
00154 Fun(const Sca<T1, Dim> &l, const PETE_Expr<T2>& r) \
00155 { \
00156 typedef PETE_TBTree<Op, PETE_Scalar< Sca<T1, Dim> >, \
00157 typename T2::PETE_Expr_t> ret; \
00158 return ret(PETE_Scalar< Sca<T1, Dim> >(l), \
00159 r.PETE_unwrap().MakeExpression()); \
00160 } \
00161 template<class T1, class T2, unsigned Dim> \
00162 inline PETE_TBTree<Op, typename T1::PETE_Expr_t, \
00163 PETE_Scalar< Sca<T2, Dim> > > \
00164 Fun(const PETE_Expr<T1>& l, const Sca<T2, Dim> &r) \
00165 { \
00166 typedef PETE_TBTree<Op, typename T1::PETE_Expr_t, \
00167 PETE_Scalar< Sca<T2, Dim> > > ret; \
00168 return ret(l.PETE_unwrap().MakeExpression(), \
00169 PETE_Scalar< Sca<T2, Dim> >(r)); \
00170 }
00171
00172 #define PETE_DefineTrinaryWithVSTScalars(Fun, Op, Sca) \
00173 template<class Cond_t, class True_t, class T, unsigned Dim> \
00174 inline PETE_TTTree<Op, typename Cond_t::PETE_Expr_t, \
00175 typename True_t::PETE_Expr_t, PETE_Scalar< Sca<T, Dim> > > \
00176 Fun(const PETE_Expr<Cond_t>& c, const PETE_Expr<True_t>& t, \
00177 const Sca<T, Dim> &f) \
00178 { \
00179 typedef PETE_TTTree<Op, typename Cond_t::PETE_Expr_t, \
00180 typename True_t::PETE_Expr_t, PETE_Scalar< Sca<T, Dim> > > ret; \
00181 return ret(c.PETE_unwrap().MakeExpression(), \
00182 t.PETE_unwrap().MakeExpression(), PETE_Scalar< Sca<T, Dim> >(f)); \
00183 } \
00184 template<class Cond_t, class T, unsigned Dim, class False_t> \
00185 inline PETE_TTTree<Op, typename Cond_t::PETE_Expr_t, \
00186 PETE_Scalar< Sca<T, Dim> >, typename False_t::PETE_Expr_t > \
00187 Fun(const PETE_Expr<Cond_t>& c, const Sca<T, Dim> &t, \
00188 const PETE_Expr<False_t>& f) \
00189 { \
00190 typedef PETE_TTTree<Op, typename Cond_t::PETE_Expr_t, PETE_Scalar< Sca<T, Dim> >, \
00191 typename False_t::PETE_Expr_t > ret; \
00192 return ret(c.PETE_unwrap().MakeExpression(), \
00193 PETE_Scalar< Sca<T, Dim> >(t), f.PETE_unwrap().MakeExpression()); \
00194 } \
00195 template<class Cond_t, class T, unsigned Dim> \
00196 inline PETE_TTTree<Op, typename Cond_t::PETE_Expr_t, \
00197 PETE_Scalar< Sca<T, Dim> >, PETE_Scalar< Sca<T, Dim> > > \
00198 Fun(const PETE_Expr<Cond_t>& c, const Sca<T, Dim> &t, const Sca<T, Dim> &f) \
00199 { \
00200 typedef PETE_TTTree<Op, typename Cond_t::PETE_Expr_t, \
00201 PETE_Scalar< Sca<T, Dim> >, PETE_Scalar< Sca<T, Dim> > > ret; \
00202 return ret(c.PETE_unwrap().MakeExpression(), \
00203 PETE_Scalar< Sca<T, Dim> >(t), PETE_Scalar< Sca<T, Dim> >(f)); \
00204 }
00205
00206
00207
00208 #define PETE_DefineVSTScalar(Sca) \
00209 PETE_DefineBinaryWithVSTScalars(operator+, OpAdd, Sca) \
00210 PETE_DefineBinaryWithVSTScalars(operator-, OpSubtract, Sca) \
00211 PETE_DefineBinaryWithVSTScalars(operator*, OpMultipply, Sca) \
00212 PETE_DefineBinaryWithVSTScalars(operator/, OpDivide, Sca) \
00213 PETE_DefineBinaryWithVSTScalars(operator%, OpMod, Sca) \
00214 PETE_DefineBinaryWithVSTScalars(operator<, OpLT, Sca) \
00215 PETE_DefineBinaryWithVSTScalars(operator<=, OpLE, Sca) \
00216 PETE_DefineBinaryWithVSTScalars(operator>, OpGT, Sca) \
00217 PETE_DefineBinaryWithVSTScalars(operator>=, OpGE, Sca) \
00218 PETE_DefineBinaryWithVSTScalars(operator==, OpEQ, Sca) \
00219 PETE_DefineBinaryWithVSTScalars(operator!=, OpNE, Sca) \
00220 PETE_DefineBinaryWithVSTScalars(operator&&, OpAnd, Sca) \
00221 PETE_DefineBinaryWithVSTScalars(operator||, OpOr, Sca) \
00222 PETE_DefineBinaryWithVSTScalars(operator&, OpBitwiseAnd, Sca) \
00223 PETE_DefineBinaryWithVSTScalars(operator|, OpBitwiseOr, Sca) \
00224 PETE_DefineBinaryWithVSTScalars(operator^, OpBitwiseXor, Sca) \
00225 PETE_DefineBinaryWithVSTScalars(copysign, FnCopysign, Sca) \
00226 PETE_DefineBinaryWithVSTScalars(ldexp, FnLdexp, Sca) \
00227 PETE_DefineBinaryWithVSTScalars(pow, FnPow, Sca) \
00228 PETE_DefineBinaryWithVSTScalars(fmod, FnFmod, Sca) \
00229 PETE_DefineBinaryWithVSTScalars(atan2, FnArcTan2, Sca) \
00230 PETE_DefineTrinaryWithVSTScalars(where, OpWhere, Sca) \
00231 PETE_DefineBinaryWithVSTScalars(Min, FnMin, Sca) \
00232 PETE_DefineBinaryWithVSTScalars(Max, FnMax, Sca) \
00233 PETE_DefineBinaryWithVSTScalars(dot, FnDot, Sca) \
00234 PETE_DefineBinaryWithVSTScalars(dotdot, FnDotDot, Sca) \
00235 PETE_DefineBinaryWithVSTScalars(outerProduct, FnOuterProduct, Sca) \
00236 PETE_DefineBinaryWithVSTScalars(cross, FnCross, Sca) \
00237 PETE_DefineBinaryWithVSTScalars(lt, OpLT, Sca) \
00238 PETE_DefineBinaryWithVSTScalars(le, OpLE, Sca) \
00239 PETE_DefineBinaryWithVSTScalars(gt, OpGT, Sca) \
00240 PETE_DefineBinaryWithVSTScalars(ge, OpGE, Sca) \
00241 PETE_DefineBinaryWithVSTScalars(eq, OpEQ, Sca) \
00242 PETE_DefineBinaryWithVSTScalars(ne, OpNE, Sca)
00243
00244 PETE_DefineVSTScalar(Vektor)
00245 PETE_DefineVSTScalar(SymTenzor)
00246 PETE_DefineVSTScalar(Tenzor)
00247
00248 #undef PETE_DefineVSTScalar
00249
00250
00251
00252
00253
00254
00255
00256
00257 PETE_DefineAssign((a = Min(a,b)),(a = Min(a,b.value)), OpMinAssign)
00258 PETE_DefineAssign((a = Max(a,b)),(a = Max(a,b.value)), OpMaxAssign)
00259 PETE_DefineAssign((a = (a&&b)) ,(a = (a&&b.value)) , OpAndAssign)
00260 PETE_DefineAssign((a = (a||b)) ,(a = (a||b.value)) , OpOrAssign)
00261
00262
00263
00264
00265
00266
00267
00268
00269 #ifdef __MWERKS__
00270
00271
00272 template<class T>
00273 struct MMin {
00274 typedef typename T::PETE_Expr_t::PETE_Return_t type_t;
00275 static inline type_t apply(const PETE_Expr<T>& expr) {
00276 type_t val ;
00277 Reduction(val, Expressionize<typename T::PETE_Expr_t>::apply( expr.PETE_unwrap().MakeExpression() ),
00278 OpAssign(), OpMinAssign());
00279 return val;
00280 }
00281 };
00282
00283 template<class T>
00284 inline typename MMin<T>::type_t
00285 min(const PETE_Expr<T>& expr) {
00286 return MMin<T>::apply(expr);
00287 }
00288 #else
00289 template<class T>
00290 typename T::PETE_Expr_t::PETE_Return_t
00291 min(const PETE_Expr<T>& expr)
00292 {
00293 typename T::PETE_Expr_t::PETE_Return_t val ;
00294 Reduction(val,
00295 Expressionize<typename T::PETE_Expr_t>::apply(expr.PETE_unwrap().MakeExpression()),
00296 OpAssign(),
00297 OpMinAssign());
00298 return val;
00299 }
00300 #endif // __MWERKS__
00301
00302 #ifdef __MWERKS__
00303
00304
00305 template<class T>
00306 struct MMax {
00307 typedef typename T::PETE_Expr_t::PETE_Return_t type_t;
00308 static inline type_t apply(const PETE_Expr<T>& expr) {
00309 type_t val ;
00310 Reduction(val, Expressionize<typename T::PETE_Expr_t>::apply(expr.PETE_unwrap().MakeExpression()),
00311 OpAssign(), OpMaxAssign());
00312 return val;
00313 }
00314 };
00315
00316 template<class T>
00317 inline typename MMax<T>::type_t
00318 max(const PETE_Expr<T>& expr) {
00319 return MMax<T>::apply(expr);
00320 }
00321 #else
00322 template<class T>
00323 typename T::PETE_Expr_t::PETE_Return_t
00324 max(const PETE_Expr<T>& expr)
00325 {
00326 typename T::PETE_Expr_t::PETE_Return_t val ;
00327 Reduction(val,
00328 Expressionize<typename T::PETE_Expr_t>::apply(expr.PETE_unwrap().MakeExpression()),
00329 OpAssign(),
00330 OpMaxAssign());
00331 return val;
00332 }
00333 #endif // __MWERKS__
00334
00335
00336
00337
00338
00339
00340
00341
00342 template<class T>
00343 struct MinMaxHolder {
00344 T a;
00345 T b;
00346 MinMaxHolder() { }
00347 MinMaxHolder(const MinMaxHolder<T>& rhs) : a(rhs.a), b(rhs.b) { }
00348 const MinMaxHolder<T>& operator=(const MinMaxHolder<T>& rhs) {
00349 a = rhs.a;
00350 b = rhs.b;
00351 return *this;
00352 }
00353 const MinMaxHolder<T>& operator=(const T& rhs) {
00354 T c = rhs;
00355 a = c;
00356 b = c;
00357 return *this;
00358 }
00359 const MinMaxHolder<T>& operator*=(const MinMaxHolder<T>& rhs) {
00360 a = (a < rhs.a ? a : rhs.a);
00361 b = (rhs.b < b ? b : rhs.b);
00362 return *this;
00363 }
00364 const MinMaxHolder<T>& operator*=(const T& rhs) {
00365 T c = rhs;
00366 a = (a < c ? a : c);
00367 b = (c < b ? b : c);
00368 return *this;
00369 }
00370 Message& putMessage(Message& m) {
00371 m.put(a);
00372 m.put(b);
00373 return m;
00374 }
00375 Message& getMessage(Message& m) {
00376 m.get(a);
00377 m.get(b);
00378 return m;
00379 }
00380 };
00381
00382 template<class T1, class T2>
00383 void
00384 minmax(const PETE_Expr<T1>& expr, T2& minval, T2& maxval)
00385 {
00386 typedef typename T1::PETE_Expr_t::PETE_Return_t val_t;
00387 MinMaxHolder<val_t> ret;
00388 Reduction(ret,
00389 Expressionize<typename T1::PETE_Expr_t>::apply(expr.PETE_unwrap().MakeExpression()),
00390 OpAssign(),
00391 OpMultipplyAssign());
00392 minval = static_cast<T2>(ret.a);
00393 maxval = static_cast<T2>(ret.b);
00394 }
00395
00396
00398
00399
00400
00401
00403
00404 template<class T, class OP>
00405 struct AnyHolder
00406 {
00407 bool Test;
00408 T Val;
00409 OP Op;
00410 AnyHolder() : Test(false), Val(T(0)), Op(OP()) {}
00411 AnyHolder(const T& t, OP op) : Test(false), Val(t), Op(op) {}
00412 AnyHolder(const AnyHolder<T,OP>& rhs)
00413 : Test(rhs.Test), Val(rhs.Val), Op(rhs.Op) { }
00414 const AnyHolder<T,OP>& operator=(const T& rhs)
00415 {
00416 if ( PETE_apply(Op,rhs,Val) )
00417 Test = true;
00418 return *this;
00419 }
00420 const AnyHolder<T,OP>& operator=(const AnyHolder<T,OP>& rhs)
00421 {
00422 Test = rhs.Test;
00423 Val = rhs.Val;
00424 Op = rhs.Op;
00425 return *this;
00426 }
00427 const AnyHolder<T,OP>& operator*=(const T& rhs)
00428 {
00429 if ( PETE_apply(Op,rhs,Val) )
00430 Test = true;
00431 return *this;
00432 }
00433 const AnyHolder<T,OP>& operator*=(const AnyHolder<T,OP>& rhs)
00434 {
00435 Test = (Test || rhs.Test);
00436 return *this;
00437 }
00438 Message& putMessage(Message& m)
00439 {
00440 m.put(Test);
00441 return m;
00442 }
00443 Message& getMessage(Message& m)
00444 {
00445 m.get(Test);
00446 return m;
00447 }
00448 };
00449
00450 template<class T1, class T2>
00451 bool
00452 any(const PETE_Expr<T1>& expr, T2 val)
00453 {
00454 AnyHolder<T2,OpEQ> ret(val,OpEQ());
00455 Reduction(ret,
00456 Expressionize<typename T1::PETE_Expr_t>::apply(expr.PETE_unwrap().MakeExpression()),
00457 OpAssign(),
00458 OpMultipplyAssign());
00459 return ret.Test;
00460 }
00461
00462 template<class T1, class T2, class Op>
00463 bool
00464 any(const PETE_Expr<T1>& expr, T2 val, Op op)
00465 {
00466 AnyHolder<T2,Op> ret(val,op);
00467 Reduction(ret,
00468 Expressionize<typename T1::PETE_Expr_t>::apply(expr.PETE_unwrap().MakeExpression()),
00469 OpAssign(),
00470 OpMultipplyAssign());
00471 return ret.Test;
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 template<class T, unsigned int D>
00484 struct BoundsHolder {
00485 Vektor<T,D> a;
00486 Vektor<T,D> b;
00487 BoundsHolder() { }
00488 BoundsHolder(const BoundsHolder<T,D>& rhs) : a(rhs.a), b(rhs.b) { }
00489 const BoundsHolder<T,D>& operator=(const BoundsHolder<T,D>& rhs) {
00490 a = rhs.a;
00491 b = rhs.b;
00492 return *this;
00493 }
00494 const BoundsHolder<T,D>& operator=(const Vektor<T,D>& rhs) {
00495 Vektor<T,D> c(rhs);
00496 a = c;
00497 b = c;
00498 return *this;
00499 }
00500 const BoundsHolder<T,D>& operator=(const T& rhs) {
00501 Vektor<T,D> c(rhs);
00502 a = c;
00503 b = c;
00504 return *this;
00505 }
00506 const BoundsHolder<T,D>& operator*=(const BoundsHolder<T,D>& rhs) {
00507 for (unsigned int d=0; d < D; ++d) {
00508 a[d] = (a[d] < rhs.a[d] ? a[d] : rhs.a[d]);
00509 b[d] = (rhs.b[d] < b[d] ? b[d] : rhs.b[d]);
00510 }
00511 return *this;
00512 }
00513 const BoundsHolder<T,D>& operator*=(const Vektor<T,D>& rhs) {
00514 Vektor<T,D> c(rhs);
00515 for (unsigned int d=0; d < D; ++d) {
00516 a[d] = (a[d] < c[d] ? a[d] : c[d]);
00517 b[d] = (c[d] < b[d] ? b[d] : c[d]);
00518 }
00519 return *this;
00520 }
00521 const BoundsHolder<T,D>& operator*=(const T& rhs) {
00522 Vektor<T,D> c(rhs);
00523 for (unsigned int d=0; d < D; ++d) {
00524 a[d] = (a[d] < c[d] ? a[d] : c[d]);
00525 b[d] = (c[d] < b[d] ? b[d] : c[d]);
00526 }
00527 return *this;
00528 }
00529 Message& putMessage(Message& m) {
00530 m.put(a);
00531 m.put(b);
00532 return m;
00533 }
00534 Message& getMessage(Message& m) {
00535 m.get(a);
00536 m.get(b);
00537 return m;
00538 }
00539 };
00540
00541 template<class T1, class T2, unsigned int D>
00542 void
00543 bounds(const PETE_Expr<T1>& expr, Vektor<T2,D>& minval, Vektor<T2,D>& maxval)
00544 {
00545 BoundsHolder<T2,D> ret;
00546 Reduction(ret,
00547 Expressionize<typename T1::PETE_Expr_t>::apply(expr.PETE_unwrap().MakeExpression()),
00548 OpAssign(),
00549 OpMultipplyAssign());
00550 minval = ret.a;
00551 maxval = ret.b;
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561 template<class T, class TP>
00562 inline typename PETEUnaryReturn<T,OpParens<TP> >::type
00563 PETE_apply(OpParens<TP> op, const T& a)
00564 {
00565 return a(op.Arg);
00566 }
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 template<class Op> struct OperatorTraits { enum { IsAssign=0 }; };
00582 template<> struct OperatorTraits<OpAssign> { enum { IsAssign=1 }; };
00583
00584
00586
00587
00588
00590
00591 #endif // IPPL_EXPRESSIONS_H
00592
00593
00594
00595
00596
00597