Logo ROOT   6.10/09
Reference Guide
Expression.h
Go to the documentation of this file.
1 // @(#)root/smatrix:$Id$
2 // Authors: T. Glebe, L. Moneta 2005
3 
4 #ifndef ROOT_Math_Expression
5 #define ROOT_Math_Expression
6 // ********************************************************************
7 //
8 // source:
9 //
10 // type: source code
11 //
12 // created: 19. Mar 2001
13 //
14 // author: Thorsten Glebe
15 // HERA-B Collaboration
16 // Max-Planck-Institut fuer Kernphysik
17 // Saupfercheckweg 1
18 // 69117 Heidelberg
19 // Germany
20 // E-mail: T.Glebe@mpi-hd.mpg.de
21 //
22 // Description: Expression Template Elements for SVector
23 //
24 // changes:
25 // 19 Mar 2001 (TG) creation
26 // 20 Mar 2001 (TG) added rows(), cols() to Expr
27 // 21 Mar 2001 (TG) added Expr::value_type
28 // 11 Apr 2001 (TG) rows(), cols() replaced by rows, cols
29 // 10 Okt 2001 (TG) added print() and operator<<() for Expr class
30 //
31 // ********************************************************************
32 
33 /**
34  @defgroup Expression Expression Template Classes
35  @ingroup SMatrixGroup
36  */
37 
38 //==============================================================================
39 // Expr: class representing SVector expressions
40 //=============================================================================
41 
42 // modified BinaryOp with two extension BinaryOpCopyL and BinaryOpCopyR to store the
43 // object in BinaryOp by value and not reference. When used with constant BinaryOp reference give problems
44 // on some compilers (like Windows) where a temporary Constant object is ccreated and then destructed
45 
46 
47 #include <iomanip>
48 #include <iostream>
49 
50 namespace ROOT {
51 
52  namespace Math {
53 
54 
55 
56 // template <class T, unsigned int D, unsigned int D2> class MatRepStd;
57 
58 /**
59  Expression wrapper class for Vector objects
60 
61  @ingroup Expression
62 */
63 template <class ExprType, class T, unsigned int D >
64 class VecExpr {
65 
66 public:
67  typedef T value_type;
68 
69  ///
70  VecExpr(const ExprType& rhs) :
71  rhs_(rhs) {}
72 
73  ///
74  ~VecExpr() {}
75 
76  ///
77  inline T apply(unsigned int i) const {
78  return rhs_.apply(i);
79  }
80 
81  inline T operator() (unsigned int i) const {
82  return rhs_.apply(i);
83  }
84 
85 
86 #ifdef OLD_IMPL
87  ///
88  static const unsigned int rows = D;
89  ///
90  ///static const unsigned int cols = D2;
91 #else
92  // use enumerations
93  enum {
94 
95  kRows = D
96 
97  };
98 #endif
99 
100  /**
101  function to determine if any use operand
102  is being used (has same memory adress)
103  */
104  inline bool IsInUse (const T * p) const {
105  return rhs_.IsInUse(p);
106  }
107 
108 
109  /// used by operator<<()
110  std::ostream& print(std::ostream& os) const {
111  os.setf(std::ios::right,std::ios::adjustfield);
112  unsigned int i=0;
113  os << "[ ";
114  for(; i<D-1; ++i) {
115  os << apply(i) << ", ";
116  }
117  os << apply(i);
118  os << " ]";
119 
120  return os;
121  }
122 
123 private:
124  ExprType rhs_; // cannot be a reference!
125 };
126 
127 
128 /**
129  Expression wrapper class for Matrix objects
130 
131  @ingroup Expression
132 */
133 
134 template <class T, unsigned int D, unsigned int D2> class MatRepStd;
135 
136 template <class ExprType, class T, unsigned int D, unsigned int D2 = 1,
137  class R1=MatRepStd<T,D,D2> >
138 class Expr {
139 public:
140  typedef T value_type;
141 
142  ///
143  Expr(const ExprType& rhs) :
144  rhs_(rhs) {}
145 
146  ///
147  ~Expr() {}
148 
149  ///
150  inline T apply(unsigned int i) const {
151  return rhs_.apply(i);
152  }
153  inline T operator() (unsigned int i, unsigned j) const {
154  return rhs_(i,j);
155  }
156 
157  /**
158  function to determine if any use operand
159  is being used (has same memory adress)
160  */
161  inline bool IsInUse (const T * p) const {
162  return rhs_.IsInUse(p);
163  }
164 
165 
166 
167 #ifdef OLD_IMPL
168  ///
169  static const unsigned int rows = D;
170  ///
171  static const unsigned int cols = D2;
172 #else
173  // use enumerations
174  enum {
175  ///
176  kRows = D,
177  ///
178  kCols = D2
179  };
180 #endif
181 
182  /// used by operator<<()
183  /// simplify to use apply(i,j)
184  std::ostream& print(std::ostream& os) const {
185  os.setf(std::ios::right,std::ios::adjustfield);
186  os << "[ ";
187  for (unsigned int i=0; i < D; ++i) {
188  unsigned int d2 = D2; // to avoid some annoying warnings in case of vectors (D2 = 0)
189  for (unsigned int j=0; j < D2; ++j) {
190  os << std::setw(12) << this->operator() (i,j);
191  if ((!((j+1)%12)) && (j < d2-1))
192  os << std::endl << " ...";
193  }
194  if (i != D - 1)
195  os << std::endl << " ";
196  }
197  os << " ]";
198 
199  return os;
200  }
201 
202 private:
203  ExprType rhs_; // cannot be a reference!
204 };
205 
206 //==============================================================================
207 // operator<<
208 //==============================================================================
209 template <class A, class T, unsigned int D>
210 inline std::ostream& operator<<(std::ostream& os, const VecExpr<A,T,D>& rhs) {
211  return rhs.print(os);
212 }
213 
214 template <class A, class T, unsigned int D1, unsigned int D2, class R1>
215 inline std::ostream& operator<<(std::ostream& os, const Expr<A,T,D1,D2,R1>& rhs) {
216  return rhs.print(os);
217 }
218 
219 /**
220  BinaryOperation class
221  A class representing binary operators in the parse tree.
222  This is the default case where objects are kept by reference
223 
224  @ingroup Expression
225  @author T. Glebe
226 */
227 
228 
229 
230 //==============================================================================
231 // BinaryOp
232 //==============================================================================
233 template <class Operator, class LHS, class RHS, class T>
234 class BinaryOp {
235 public:
236  ///
237  BinaryOp( Operator /* op */, const LHS& lhs, const RHS& rhs) :
238  lhs_(lhs), rhs_(rhs) {}
239 
240  ///
242 
243  ///
244  inline T apply(unsigned int i) const {
245  return Operator::apply(lhs_.apply(i), rhs_.apply(i));
246  }
247  inline T operator() (unsigned int i, unsigned int j) const {
248  return Operator::apply(lhs_(i,j), rhs_(i,j) );
249  }
250 
251  inline bool IsInUse (const T * p) const {
252  return lhs_.IsInUse(p) || rhs_.IsInUse(p);
253  }
254 
255 protected:
256 
257  const LHS& lhs_;
258  const RHS& rhs_;
259 
260 };
261 
262 //LM :: add specialization of BinaryOP when first or second argument needs to be copied
263 // (maybe it can be doen with a template specialization, but it is not worth, easier to have a separate class
264 
265 //==============================================================================
266 /**
267  Binary Operation class with value storage for the left argument.
268  Special case of BinaryOp where for the left argument the passed object
269  is copied and stored by value instead of a reference.
270  This is used in the case of operations involving a constant, where we cannot store a
271  reference to the constant (we get a temporary object) and we need to copy it.
272 
273  @ingroup Expression
274 */
275 //==============================================================================
276 template <class Operator, class LHS, class RHS, class T>
278 public:
279  ///
280  BinaryOpCopyL( Operator /* op */, const LHS& lhs, const RHS& rhs) :
281  lhs_(lhs), rhs_(rhs) {}
282 
283  ///
285 
286  ///
287  inline T apply(unsigned int i) const {
288  return Operator::apply(lhs_.apply(i), rhs_.apply(i));
289  }
290  inline T operator() (unsigned int i, unsigned int j) const {
291  return Operator::apply(lhs_(i,j), rhs_(i,j) );
292  }
293 
294  inline bool IsInUse (const T * p) const {
295  // no need to check left since we copy it
296  return rhs_.IsInUse(p);
297  }
298 
299 protected:
300 
301  const LHS lhs_;
302  const RHS& rhs_;
303 
304 };
305 
306 
307 //==============================================================================
308 /**
309  Binary Operation class with value storage for the right argument.
310  Special case of BinaryOp where for the wight argument a copy is stored instead of a reference
311  This is use in the case for example of constant where we cannot store by reference
312  but need to copy since Constant is a temporary object
313 
314  @ingroup Expression
315 */
316 //==============================================================================
317 template <class Operator, class LHS, class RHS, class T>
319 public:
320  ///
321  BinaryOpCopyR( Operator /* op */, const LHS& lhs, const RHS& rhs) :
322  lhs_(lhs), rhs_(rhs) {}
323 
324  ///
326 
327  ///
328  inline T apply(unsigned int i) const {
329  return Operator::apply(lhs_.apply(i), rhs_.apply(i));
330  }
331  inline T operator() (unsigned int i, unsigned int j) const {
332  return Operator::apply(lhs_(i,j), rhs_(i,j) );
333  }
334 
335  inline bool IsInUse (const T * p) const {
336  // no need for right since we copied
337  return lhs_.IsInUse(p);
338  }
339 
340 protected:
341 
342  const LHS& lhs_;
343  const RHS rhs_;
344 
345 };
346 
347 
348 
349 /**
350  UnaryOperation class
351  A class representing unary operators in the parse tree.
352  The objects are stored by reference
353 
354  @ingroup Expression
355  @author T. Glebe
356 */
357 //==============================================================================
358 // UnaryOp
359 //==============================================================================
360 template <class Operator, class RHS, class T>
361 class UnaryOp {
362 public:
363  ///
364  UnaryOp( Operator /* op */ , const RHS& rhs) :
365  rhs_(rhs) {}
366 
367  ///
368  ~UnaryOp() {}
369 
370  ///
371  inline T apply(unsigned int i) const {
372  return Operator::apply(rhs_.apply(i));
373  }
374  inline T operator() (unsigned int i, unsigned int j) const {
375  return Operator::apply(rhs_(i,j));
376  }
377 
378  inline bool IsInUse (const T * p) const {
379  return rhs_.IsInUse(p);
380  }
381 
382 protected:
383 
384  const RHS& rhs_;
385 
386 };
387 
388 
389 /**
390  Constant expression class
391  A class representing constant expressions (literals) in the parse tree.
392 
393  @ingroup Expression
394  @author T. Glebe
395 */
396 //==============================================================================
397 // Constant
398 //==============================================================================
399 template <class T>
400 class Constant {
401 public:
402  ///
403  Constant( const T& rhs ) :
404  rhs_(rhs) {}
405 
406  ///
408 
409  ///
410  inline T apply(unsigned int /*i */ ) const { return rhs_; }
411 
412  inline T operator() (unsigned int /*i */, unsigned int /*j */ ) const { return rhs_; }
413 
414  //inline bool IsInUse (const T * ) const { return false; }
415 
416 protected:
417 
418  const T rhs_; // no need for reference. It is a fundamental type normally
419 
420 
421 };
422 
423 
424 
425  } // namespace Math
426 
427 } // namespace ROOT
428 
429 
430 
431 #endif /* ROOT_Math_Expression */
Constant expression class A class representing constant expressions (literals) in the parse tree...
Definition: Expression.h:400
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
T apply(unsigned int i) const
Definition: Expression.h:287
BinaryOpCopyR(Operator, const LHS &lhs, const RHS &rhs)
Definition: Expression.h:321
double T(double x)
Definition: ChebyshevPol.h:34
Binary Operation class with value storage for the left argument.
Definition: Expression.h:277
bool IsInUse(const T *p) const
Definition: Expression.h:378
bool IsInUse(const T *p) const
Definition: Expression.h:335
Expr(const ExprType &rhs)
Definition: Expression.h:143
T apply(unsigned int i) const
Definition: Expression.h:371
const RHS & rhs_
Definition: Expression.h:258
Expression wrapper class for Matrix objects.
Definition: Expression.h:134
Binary Operation class with value storage for the right argument.
Definition: Expression.h:318
std::ostream & print(std::ostream &os) const
used by operator<<() simplify to use apply(i,j)
Definition: Expression.h:184
bool IsInUse(const T *p) const
function to determine if any use operand is being used (has same memory adress)
Definition: Expression.h:104
bool IsInUse(const T *p) const
Definition: Expression.h:294
BinaryOperation class A class representing binary operators in the parse tree.
Definition: Expression.h:234
UnaryOperation class A class representing unary operators in the parse tree.
Definition: Expression.h:361
VecExpr(const ExprType &rhs)
Definition: Expression.h:70
T apply(unsigned int i) const
Definition: Expression.h:328
BinaryOp(Operator, const LHS &lhs, const RHS &rhs)
Definition: Expression.h:237
T apply(unsigned int i) const
Definition: Expression.h:244
T operator()(unsigned int i) const
Definition: Expression.h:81
const LHS & lhs_
Definition: Expression.h:257
BinaryOpCopyL(Operator, const LHS &lhs, const RHS &rhs)
Definition: Expression.h:280
Namespace for new Math classes and functions.
Constant(const T &rhs)
Definition: Expression.h:403
Expression wrapper class for Vector objects.
Definition: Expression.h:64
const RHS & rhs_
Definition: Expression.h:384
bool IsInUse(const T *p) const
function to determine if any use operand is being used (has same memory adress)
Definition: Expression.h:161
T apply(unsigned int) const
Definition: Expression.h:410
UnaryOp(Operator, const RHS &rhs)
Definition: Expression.h:364
T apply(unsigned int i) const
Definition: Expression.h:150
decltype(auto) constexpr apply(F &&f, Tuple &&t)
std::ostream & print(std::ostream &os) const
used by operator<<()
Definition: Expression.h:110
bool IsInUse(const T *p) const
Definition: Expression.h:251
T apply(unsigned int i) const
Definition: Expression.h:77