Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:16

0001 // @(#)root/smatrix:$Id$
0002 // Authors: T. Glebe, L. Moneta    2005
0003 
0004 #ifndef ROOT_Math_Expression
0005 #define ROOT_Math_Expression
0006 // ********************************************************************
0007 //
0008 // source:
0009 //
0010 // type:      source code
0011 //
0012 // created:   19. Mar 2001
0013 //
0014 // author:    Thorsten Glebe
0015 //            HERA-B Collaboration
0016 //            Max-Planck-Institut fuer Kernphysik
0017 //            Saupfercheckweg 1
0018 //            69117 Heidelberg
0019 //            Germany
0020 //            E-mail: T.Glebe@mpi-hd.mpg.de
0021 //
0022 // Description: Expression Template Elements for SVector
0023 //
0024 // changes:
0025 // 19 Mar 2001 (TG) creation
0026 // 20 Mar 2001 (TG) added rows(), cols() to Expr
0027 // 21 Mar 2001 (TG) added Expr::value_type
0028 // 11 Apr 2001 (TG) rows(), cols() replaced by rows, cols
0029 // 10 Okt 2001 (TG) added print() and operator<<() for Expr class
0030 //
0031 // ********************************************************************
0032 
0033 /**
0034 \defgroup Expression Expression Template Classes
0035 \ingroup SMatrixGroup
0036 */
0037 
0038 //==============================================================================
0039 // Expr: class representing SVector expressions
0040 //=============================================================================
0041 
0042 // modified BinaryOp with two extension BinaryOpCopyL and BinaryOpCopyR to store the
0043 // object in BinaryOp by value and not reference. When used with constant BinaryOp reference give problems
0044 // on some compilers (like Windows) where a temporary Constant object is ccreated and then destructed
0045 
0046 
0047 #include <iomanip>
0048 #include <iostream>
0049 
0050 namespace ROOT {
0051 
0052   namespace Math {
0053 
0054 
0055 
0056 //    template <class T, unsigned int D, unsigned int D2> class MatRepStd;
0057 
0058 /**
0059     Expression wrapper class for Vector objects
0060 
0061     @ingroup Expression
0062 */
0063 template <class ExprType, class T, unsigned int D >
0064 class VecExpr {
0065 
0066 public:
0067   typedef T  value_type;
0068 
0069   ///
0070   VecExpr(const ExprType& rhs) :
0071     rhs_(rhs) {}
0072 
0073   ///
0074   ~VecExpr() {}
0075 
0076    ///
0077   inline T apply(unsigned int i) const {
0078     return rhs_.apply(i);
0079   }
0080 
0081   inline T operator() (unsigned int i) const {
0082     return rhs_.apply(i);
0083   }
0084 
0085 
0086 #ifdef OLD_IMPL
0087   ///
0088   static const unsigned int rows = D;
0089   ///
0090   ///static const unsigned int cols = D2;
0091 #else
0092   // use enumerations
0093   enum {
0094 
0095     kRows = D
0096 
0097   };
0098 #endif
0099 
0100   /**
0101       function to  determine if any use operand
0102       is being used (has same memory address)
0103    */
0104   inline bool IsInUse (const T * p) const {
0105     return rhs_.IsInUse(p);
0106   }
0107 
0108 
0109   /// used by operator<<()
0110   std::ostream& print(std::ostream& os) const {
0111     os.setf(std::ios::right,std::ios::adjustfield);
0112     unsigned int i=0;
0113     os << "[ ";
0114     for(; i<D-1; ++i) {
0115       os << apply(i) << ", ";
0116     }
0117     os << apply(i);
0118     os << " ]";
0119 
0120     return os;
0121   }
0122 
0123 private:
0124   ExprType rhs_; // cannot be a reference!
0125 };
0126 
0127 
0128 /**
0129     Expression wrapper class for Matrix objects
0130 
0131     @ingroup Expression
0132 */
0133 
0134 template <class T, unsigned int D, unsigned int D2> class MatRepStd;
0135 
0136 template <class ExprType, class T, unsigned int D, unsigned int D2 = 1,
0137      class R1=MatRepStd<T,D,D2> >
0138 class Expr {
0139 public:
0140   typedef T  value_type;
0141 
0142   ///
0143   Expr(const ExprType& rhs) :
0144     rhs_(rhs) {}
0145 
0146   ///
0147   ~Expr() {}
0148 
0149   ///
0150   inline T apply(unsigned int i) const {
0151     return rhs_.apply(i);
0152   }
0153   inline T operator() (unsigned int i, unsigned j) const {
0154     return rhs_(i,j);
0155   }
0156 
0157   /**
0158       function to  determine if any use operand
0159       is being used (has same memory address)
0160    */
0161   inline bool IsInUse (const T * p) const {
0162     return rhs_.IsInUse(p);
0163   }
0164 
0165 
0166 
0167 #ifdef OLD_IMPL
0168   ///
0169   static const unsigned int rows = D;
0170   ///
0171   static const unsigned int cols = D2;
0172 #else
0173   // use enumerations
0174   enum {
0175     ///
0176     kRows = D,
0177   ///
0178     kCols = D2
0179   };
0180 #endif
0181 
0182   /// used by operator<<()
0183   /// simplify to use apply(i,j)
0184   std::ostream& print(std::ostream& os) const {
0185     os.setf(std::ios::right,std::ios::adjustfield);
0186       os << "[ ";
0187       for (unsigned int i=0; i < D; ++i) {
0188          unsigned int d2 = D2; // to avoid some annoying warnings in case of vectors (D2 = 0)
0189          for (unsigned int j=0; j < D2; ++j) {
0190             os << std::setw(12) << this->operator() (i,j);
0191             if ((!((j+1)%12)) && (j < d2-1))
0192             os << std::endl << "         ...";
0193          }
0194          if (i != D - 1)
0195          os << std::endl  << "  ";
0196       }
0197      os << " ]";
0198 
0199      return os;
0200   }
0201 
0202 private:
0203   ExprType rhs_; // cannot be a reference!
0204 };
0205 
0206 //==============================================================================
0207 // operator<<
0208 //==============================================================================
0209 template <class A, class T, unsigned int D>
0210 inline std::ostream& operator<<(std::ostream& os, const VecExpr<A,T,D>& rhs) {
0211   return rhs.print(os);
0212 }
0213 
0214 template <class A, class T, unsigned int D1, unsigned int D2, class R1>
0215 inline std::ostream& operator<<(std::ostream& os, const Expr<A,T,D1,D2,R1>& rhs) {
0216   return rhs.print(os);
0217 }
0218 
0219 /**
0220     BinaryOperation class
0221     A class representing binary operators in the parse tree.
0222     This is the default case where objects are kept by reference
0223 
0224     @ingroup  Expression
0225     @author T. Glebe
0226 */
0227 
0228 
0229 
0230 //==============================================================================
0231 // BinaryOp
0232 //==============================================================================
0233 template <class Operator, class LHS, class RHS, class T>
0234 class BinaryOp {
0235 public:
0236   ///
0237   BinaryOp( Operator /* op */, const LHS& lhs, const RHS& rhs) :
0238     lhs_(lhs), rhs_(rhs) {}
0239 
0240   ///
0241   ~BinaryOp() {}
0242 
0243   ///
0244   inline T apply(unsigned int i) const {
0245     return Operator::apply(lhs_.apply(i), rhs_.apply(i));
0246   }
0247   inline T operator() (unsigned int i, unsigned int j) const {
0248     return Operator::apply(lhs_(i,j), rhs_(i,j) );
0249   }
0250 
0251   inline bool IsInUse (const T * p) const {
0252     return lhs_.IsInUse(p) || rhs_.IsInUse(p);
0253   }
0254 
0255 protected:
0256 
0257   const LHS& lhs_;
0258   const RHS& rhs_;
0259 
0260 };
0261 
0262 //LM :: add specialization of BinaryOP when first or second argument needs to be copied
0263 // (maybe it can be done with a template specialization, but it is not worth, easier to have a separate class
0264 
0265 //==============================================================================
0266 /**
0267    Binary Operation class with value storage for the left argument.
0268    Special case of BinaryOp where for the left argument the passed object
0269    is copied and stored by value instead of a reference.
0270    This is used in the case of operations involving a constant, where we cannot store a
0271    reference to the constant (we get a temporary object) and we need to copy it.
0272 
0273    @ingroup  Expression
0274 */
0275 //==============================================================================
0276 template <class Operator, class LHS, class RHS, class T>
0277 class BinaryOpCopyL {
0278 public:
0279   ///
0280   BinaryOpCopyL( Operator /* op */, const LHS& lhs, const RHS& rhs) :
0281     lhs_(lhs), rhs_(rhs) {}
0282 
0283   ///
0284   ~BinaryOpCopyL() {}
0285 
0286   ///
0287   inline T apply(unsigned int i) const {
0288     return Operator::apply(lhs_.apply(i), rhs_.apply(i));
0289   }
0290   inline T operator() (unsigned int i, unsigned int j) const {
0291     return Operator::apply(lhs_(i,j), rhs_(i,j) );
0292   }
0293 
0294   inline bool IsInUse (const T * p) const {
0295     // no need to check left since we copy it
0296     return rhs_.IsInUse(p);
0297   }
0298 
0299 protected:
0300 
0301   const LHS  lhs_;
0302   const RHS& rhs_;
0303 
0304 };
0305 
0306 
0307 //==============================================================================
0308 /**
0309    Binary Operation class with value storage for the right argument.
0310    Special case of BinaryOp where for the wight argument a copy is stored instead of a reference
0311    This is use in the case for example of constant where we cannot store by reference
0312    but need to copy since Constant is a temporary object
0313 
0314    @ingroup  Expression
0315 */
0316 //==============================================================================
0317 template <class Operator, class LHS, class RHS, class T>
0318 class BinaryOpCopyR {
0319 public:
0320   ///
0321   BinaryOpCopyR( Operator /* op */, const LHS& lhs, const RHS& rhs) :
0322     lhs_(lhs), rhs_(rhs) {}
0323 
0324   ///
0325   ~BinaryOpCopyR() {}
0326 
0327   ///
0328   inline T apply(unsigned int i) const {
0329     return Operator::apply(lhs_.apply(i), rhs_.apply(i));
0330   }
0331   inline T operator() (unsigned int i, unsigned int j) const {
0332     return Operator::apply(lhs_(i,j), rhs_(i,j) );
0333   }
0334 
0335   inline bool IsInUse (const T * p) const {
0336     // no need for right since we copied
0337     return lhs_.IsInUse(p);
0338   }
0339 
0340 protected:
0341 
0342   const LHS&  lhs_;
0343   const RHS rhs_;
0344 
0345 };
0346 
0347 
0348 
0349 /**
0350     UnaryOperation class
0351     A class representing unary operators in the parse tree.
0352     The objects are stored by reference
0353 
0354     @ingroup  Expression
0355     @author T. Glebe
0356 */
0357 //==============================================================================
0358 // UnaryOp
0359 //==============================================================================
0360 template <class Operator, class RHS, class T>
0361 class UnaryOp {
0362 public:
0363   ///
0364   UnaryOp( Operator /* op */ , const RHS& rhs) :
0365     rhs_(rhs) {}
0366 
0367   ///
0368   ~UnaryOp() {}
0369 
0370   ///
0371   inline T apply(unsigned int i) const {
0372     return Operator::apply(rhs_.apply(i));
0373   }
0374   inline T operator() (unsigned int i, unsigned int j) const {
0375     return Operator::apply(rhs_(i,j));
0376   }
0377 
0378   inline bool IsInUse (const T * p) const {
0379     return rhs_.IsInUse(p);
0380   }
0381 
0382 protected:
0383 
0384   const RHS& rhs_;
0385 
0386 };
0387 
0388 
0389 /**
0390     Constant expression class
0391     A class representing constant expressions (literals) in the parse tree.
0392 
0393     @ingroup Expression
0394     @author T. Glebe
0395 */
0396 //==============================================================================
0397 // Constant
0398 //==============================================================================
0399 template <class T>
0400 class Constant {
0401 public:
0402   ///
0403   Constant( const T& rhs ) :
0404     rhs_(rhs) {}
0405 
0406   ///
0407   ~Constant() {}
0408 
0409   ///
0410   inline T apply(unsigned int /*i */ ) const { return rhs_; }
0411 
0412   inline T operator() (unsigned int /*i */, unsigned int /*j */ ) const { return rhs_; }
0413 
0414   //inline bool IsInUse (const T * ) const { return false; }
0415 
0416 protected:
0417 
0418   const T rhs_;  // no need for reference. It is  a fundamental type normally
0419 
0420 
0421 };
0422 
0423 
0424 
0425   }  // namespace Math
0426 
0427 }  // namespace ROOT
0428 
0429 
0430 
0431 #endif  /* ROOT_Math_Expression */