Logo ROOT   6.16/01
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
50namespace 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*/
63template <class ExprType, class T, unsigned int D >
64class VecExpr {
65
66public:
67 typedef T value_type;
68
69 ///
70 VecExpr(const ExprType& rhs) :
71 rhs_(rhs) {}
72
73 ///
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
123private:
124 ExprType rhs_; // cannot be a reference!
125};
126
127
128/**
129 Expression wrapper class for Matrix objects
130
131 @ingroup Expression
132*/
133
134template <class T, unsigned int D, unsigned int D2> class MatRepStd;
135
136template <class ExprType, class T, unsigned int D, unsigned int D2 = 1,
137 class R1=MatRepStd<T,D,D2> >
138class Expr {
139public:
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
202private:
203 ExprType rhs_; // cannot be a reference!
204};
205
206//==============================================================================
207// operator<<
208//==============================================================================
209template <class A, class T, unsigned int D>
210inline std::ostream& operator<<(std::ostream& os, const VecExpr<A,T,D>& rhs) {
211 return rhs.print(os);
212}
213
214template <class A, class T, unsigned int D1, unsigned int D2, class R1>
215inline 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//==============================================================================
233template <class Operator, class LHS, class RHS, class T>
234class BinaryOp {
235public:
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
255protected:
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//==============================================================================
276template <class Operator, class LHS, class RHS, class T>
278public:
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
299protected:
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//==============================================================================
317template <class Operator, class LHS, class RHS, class T>
319public:
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
340protected:
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//==============================================================================
360template <class Operator, class RHS, class T>
361class UnaryOp {
362public:
363 ///
364 UnaryOp( Operator /* op */ , const RHS& rhs) :
365 rhs_(rhs) {}
366
367 ///
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
382protected:
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//==============================================================================
399template <class T>
400class Constant {
401public:
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
416protected:
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 */
Binary Operation class with value storage for the left argument.
Definition: Expression.h:277
T operator()(unsigned int i, unsigned int j) const
Definition: Expression.h:290
T apply(unsigned int i) const
Definition: Expression.h:287
BinaryOpCopyL(Operator, const LHS &lhs, const RHS &rhs)
Definition: Expression.h:280
bool IsInUse(const T *p) const
Definition: Expression.h:294
Binary Operation class with value storage for the right argument.
Definition: Expression.h:318
bool IsInUse(const T *p) const
Definition: Expression.h:335
BinaryOpCopyR(Operator, const LHS &lhs, const RHS &rhs)
Definition: Expression.h:321
T operator()(unsigned int i, unsigned int j) const
Definition: Expression.h:331
T apply(unsigned int i) const
Definition: Expression.h:328
BinaryOperation class A class representing binary operators in the parse tree.
Definition: Expression.h:234
BinaryOp(Operator, const LHS &lhs, const RHS &rhs)
Definition: Expression.h:237
const RHS & rhs_
Definition: Expression.h:258
const LHS & lhs_
Definition: Expression.h:257
T apply(unsigned int i) const
Definition: Expression.h:244
bool IsInUse(const T *p) const
Definition: Expression.h:251
T operator()(unsigned int i, unsigned int j) const
Definition: Expression.h:247
Constant expression class A class representing constant expressions (literals) in the parse tree.
Definition: Expression.h:400
T apply(unsigned int) const
Definition: Expression.h:410
T operator()(unsigned int, unsigned int) const
Definition: Expression.h:412
Constant(const T &rhs)
Definition: Expression.h:403
T apply(unsigned int i) const
Definition: Expression.h:150
std::ostream & print(std::ostream &os) const
used by operator<<() simplify to use apply(i,j)
Definition: Expression.h:184
Expr(const ExprType &rhs)
Definition: Expression.h:143
T operator()(unsigned int i, unsigned j) const
Definition: Expression.h:153
bool IsInUse(const T *p) const
function to determine if any use operand is being used (has same memory adress)
Definition: Expression.h:161
Expression wrapper class for Matrix objects.
UnaryOperation class A class representing unary operators in the parse tree.
Definition: Expression.h:361
const RHS & rhs_
Definition: Expression.h:384
T apply(unsigned int i) const
Definition: Expression.h:371
UnaryOp(Operator, const RHS &rhs)
Definition: Expression.h:364
bool IsInUse(const T *p) const
Definition: Expression.h:378
T operator()(unsigned int i, unsigned int j) const
Definition: Expression.h:374
Expression wrapper class for Vector objects.
Definition: Expression.h:64
T apply(unsigned int i) const
Definition: Expression.h:77
VecExpr(const ExprType &rhs)
Definition: Expression.h:70
bool IsInUse(const T *p) const
function to determine if any use operand is being used (has same memory adress)
Definition: Expression.h:104
T operator()(unsigned int i) const
Definition: Expression.h:81
std::ostream & print(std::ostream &os) const
used by operator<<()
Definition: Expression.h:110
Namespace for new Math classes and functions.
double T(double x)
Definition: ChebyshevPol.h:34
std::ostream & operator<<(std::ostream &os, const AxisAngle &a)
Stream Output and Input.
Definition: AxisAngle.cxx:91
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
constexpr decltype(auto) apply(F &&f, Tuple &&t)
#define R1(v, w, x, y, z, i)
Definition: sha1.inl:134