FEDRA emulsion software from the OPERA Collaboration
Functions.hh
Go to the documentation of this file.
1 #ifndef __FUNCTIONS_HH
2 #define __FUNCTIONS_HH
3 // ********************************************************************
4 //
5 // source:
6 //
7 // type: source code
8 //
9 // created: 16. Mar 2001
10 //
11 // author: Thorsten Glebe
12 // HERA-B Collaboration
13 // Max-Planck-Institut fuer Kernphysik
14 // Saupfercheckweg 1
15 // 69117 Heidelberg
16 // Germany
17 // E-mail: T.Glebe@mpi-hd.mpg.de
18 //
19 // Description: Functions which are not applied like a unary operator
20 //
21 // changes:
22 // 16 Mar 2001 (TG) creation
23 // 03 Apr 2001 (TG) minimum added, doc++ comments added
24 // 07 Apr 2001 (TG) Lmag2, Lmag added
25 // 19 Apr 2001 (TG) added #include <cmath>
26 // 24 Apr 2001 (TG) added sign()
27 // 26 Jul 2001 (TG) round() added
28 // 27 Sep 2001 (TG) added Expr declaration
29 //
30 // ********************************************************************
31 #include <cmath>
32 #include "Expression.hh"
33 
34 template <class T, unsigned int D> class SVector;
35 
36 
42 //==============================================================================
43 // square: x*x
44 //==============================================================================
45 template <class T>
46 inline const T square(const T& x) { return x*x; }
47 
53 //==============================================================================
54 // maximum
55 //==============================================================================
56 template <class T>
57 inline const T maximum(const T& lhs, const T& rhs) {
58  return (lhs > rhs) ? lhs : rhs;
59 }
60 
66 //==============================================================================
67 // minimum
68 //==============================================================================
69 template <class T>
70 inline const T minimum(const T& lhs, const T& rhs) {
71  return (lhs < rhs) ? lhs : rhs;
72 }
73 
79 //==============================================================================
80 // round
81 //==============================================================================
82 template <class T>
83 inline int round(const T& x) {
84  return (x-static_cast<int>(x) < 0.5) ? static_cast<int>(x) : static_cast<int>(x+1);
85 }
86 
87 
93 //==============================================================================
94 // sign
95 //==============================================================================
96 template <class T>
97 inline const int sign(const T& x) { return (x==0)? 0 : (x<0)? -1 : 1; }
98 
99 //==============================================================================
100 // meta_dot
101 //==============================================================================
102 template <unsigned int I>
103 struct meta_dot {
104  template <class A, class B, class T>
105  static inline T f(const A& lhs, const B& rhs, const T& x) {
106  return lhs.apply(I) * rhs.apply(I) + meta_dot<I-1>::f(lhs,rhs,x);
107  }
108 };
109 
110 
111 //==============================================================================
112 // meta_dot<0>
113 //==============================================================================
114 template <>
115 struct meta_dot<0> {
116  template <class A, class B, class T>
117  static inline T f(const A& lhs, const B& rhs, const T& x) {
118  return lhs.apply(0) * rhs.apply(0);
119  }
120 };
121 
122 
128 //==============================================================================
129 // dot
130 //==============================================================================
131 template <class T, unsigned int D>
132 inline T dot(const SVector<T,D>& lhs, const SVector<T,D>& rhs) {
133  return meta_dot<D-1>::f(lhs,rhs, T());
134 }
135 
136 //==============================================================================
137 // dot
138 //==============================================================================
139 template <class A, class T, unsigned int D>
140 inline T dot(const SVector<T,D>& lhs, const Expr<A,T,D>& rhs) {
141  return meta_dot<D-1>::f(lhs,rhs, T());
142 }
143 
144 //==============================================================================
145 // dot
146 //==============================================================================
147 template <class A, class T, unsigned int D>
148 inline T dot(const Expr<A,T,D>& lhs, const SVector<T,D>& rhs) {
149  return meta_dot<D-1>::f(lhs,rhs, T());
150 }
151 
152 
153 //==============================================================================
154 // dot
155 //==============================================================================
156 template <class A, class B, class T, unsigned int D>
157 inline T dot(const Expr<A,T,D>& lhs, const Expr<B,T,D>& rhs) {
158  return meta_dot<D-1>::f(rhs,lhs, T());
159 }
160 
161 
162 //==============================================================================
163 // meta_mag
164 //==============================================================================
165 template <unsigned int I>
166 struct meta_mag {
167  template <class A, class T>
168  static inline T f(const A& rhs, const T& x) {
169  return square(rhs.apply(I)) + meta_mag<I-1>::f(rhs, x);
170  }
171 };
172 
173 
174 //==============================================================================
175 // meta_mag<0>
176 //==============================================================================
177 template <>
178 struct meta_mag<0> {
179  template <class A, class T>
180  static inline T f(const A& rhs, const T& x) {
181  return square(rhs.apply(0));
182  }
183 };
184 
185 
191 //==============================================================================
192 // mag2
193 //==============================================================================
194 template <class T, unsigned int D>
195 inline T mag2(const SVector<T,D>& rhs) {
196  return meta_mag<D-1>::f(rhs, T());
197 }
198 
199 //==============================================================================
200 // mag2
201 //==============================================================================
202 template <class A, class T, unsigned int D>
203 inline T mag2(const Expr<A,T,D>& rhs) {
204  return meta_mag<D-1>::f(rhs, T());
205 }
206 
212 //==============================================================================
213 // mag
214 //==============================================================================
215 template <class T, unsigned int D>
216 inline T mag(const SVector<T,D>& rhs) {
217  return sqrt(mag2(rhs));
218 }
219 
220 //==============================================================================
221 // mag
222 //==============================================================================
223 template <class A, class T, unsigned int D>
224 inline T mag(const Expr<A,T,D>& rhs) {
225  return sqrt(mag2(rhs));
226 }
227 
228 
234 //==============================================================================
235 // Lmag2
236 //==============================================================================
237 template <class T>
238 inline T Lmag2(const SVector<T,4>& rhs) {
239  return square(rhs[0]) - square(rhs[1]) - square(rhs[2]) - square(rhs[3]);
240 }
241 
242 //==============================================================================
243 // Lmag2
244 //==============================================================================
245 template <class A, class T>
246 inline T Lmag2(const Expr<A,T,4>& rhs) {
247  return square(rhs.apply(0))
248  - square(rhs.apply(1)) - square(rhs.apply(2)) - square(rhs.apply(3));
249 }
250 
257 //==============================================================================
258 // Lmag
259 //==============================================================================
260 template <class T>
261 inline T Lmag(const SVector<T,4>& rhs) {
262  return sqrt(Lmag2(rhs));
263 }
264 
265 //==============================================================================
266 // Lmag
267 //==============================================================================
268 template <class A, class T>
269 inline T Lmag(const Expr<A,T,4>& rhs) {
270  return sqrt(Lmag2(rhs));
271 }
272 
273 
279 //==============================================================================
280 // cross product
281 //==============================================================================
282 template <class T>
283 inline SVector<T,3> cross(const SVector<T,3>& lhs, const SVector<T,3>& rhs) {
284  return SVector<T,3>(lhs.apply(1)*rhs.apply(2) -
285  lhs.apply(2)*rhs.apply(1),
286  lhs.apply(2)*rhs.apply(0) -
287  lhs.apply(0)*rhs.apply(2),
288  lhs.apply(0)*rhs.apply(1) -
289  lhs.apply(1)*rhs.apply(0));
290 }
291 
292 //==============================================================================
293 // cross product
294 //==============================================================================
295 template <class A, class T>
296 inline SVector<T,3> cross(const Expr<A,T,3>& lhs, const SVector<T,3>& rhs) {
297  return SVector<T,3>(lhs.apply(1)*rhs.apply(2) -
298  lhs.apply(2)*rhs.apply(1),
299  lhs.apply(2)*rhs.apply(0) -
300  lhs.apply(0)*rhs.apply(2),
301  lhs.apply(0)*rhs.apply(1) -
302  lhs.apply(1)*rhs.apply(0));
303 }
304 
305 //==============================================================================
306 // cross product
307 //==============================================================================
308 template <class T, class A>
309 inline SVector<T,3> cross(const SVector<T,3>& lhs, const Expr<A,T,3>& rhs) {
310  return SVector<T,3>(lhs.apply(1)*rhs.apply(2) -
311  lhs.apply(2)*rhs.apply(1),
312  lhs.apply(2)*rhs.apply(0) -
313  lhs.apply(0)*rhs.apply(2),
314  lhs.apply(0)*rhs.apply(1) -
315  lhs.apply(1)*rhs.apply(0));
316 }
317 
318 //==============================================================================
319 // cross product
320 //==============================================================================
321 template <class A, class B, class T>
322 inline SVector<T,3> cross(const Expr<A,T,3>& lhs, const Expr<B,T,3>& rhs) {
323  return SVector<T,3>(lhs.apply(1)*rhs.apply(2) -
324  lhs.apply(2)*rhs.apply(1),
325  lhs.apply(2)*rhs.apply(0) -
326  lhs.apply(0)*rhs.apply(2),
327  lhs.apply(0)*rhs.apply(1) -
328  lhs.apply(1)*rhs.apply(0));
329 }
330 
331 
337 //==============================================================================
338 // unit: returns a unit vector
339 //==============================================================================
340 template <class T, unsigned int D>
341 inline SVector<T,D> unit(const SVector<T,D>& rhs) {
342  return SVector<T,D>(rhs).unit();
343 }
344 
345 //==============================================================================
346 // unit: returns a unit vector
347 //==============================================================================
348 template <class A, class T, unsigned int D>
349 inline SVector<T,D> unit(const Expr<A,T,D>& rhs) {
350  return SVector<T,D>(rhs).unit();
351 }
352 
353 #ifdef XXX
354 //==============================================================================
355 // unit: returns a unit vector (worse performance)
356 //==============================================================================
357 template <class T, unsigned int D>
359  unit(const SVector<T,D>& lhs) {
360  typedef BinaryOp<DivOp<T>, SVector<T,D>, Constant<T>, T> DivOpBinOp;
361  return Expr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,Constant<T>(mag(lhs))));
362 }
363 
364 //==============================================================================
365 // unit: returns a unit vector (worse performance)
366 //==============================================================================
367 template <class A, class T, unsigned int D>
369  unit(const Expr<A,T,D>& lhs) {
370  typedef BinaryOp<DivOp<T>, Expr<A,T,D>, Constant<T>, T> DivOpBinOp;
371  return Expr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,Constant<T>(mag(lhs))));
372 }
373 #endif
374 
375 #endif
const T minimum(const T &lhs, const T &rhs)
Definition: Functions.hh:70
T mag(const SVector< T, D > &rhs)
Definition: Functions.hh:216
const T maximum(const T &lhs, const T &rhs)
Definition: Functions.hh:57
SVector< T, 3 > cross(const SVector< T, 3 > &lhs, const SVector< T, 3 > &rhs)
Definition: Functions.hh:283
T dot(const SVector< T, D > &lhs, const SVector< T, D > &rhs)
Definition: Functions.hh:132
T Lmag2(const SVector< T, 4 > &rhs)
Definition: Functions.hh:238
const T square(const T &x)
Definition: Functions.hh:46
const int sign(const T &x)
Definition: Functions.hh:97
int round(const T &x)
Definition: Functions.hh:83
T Lmag(const SVector< T, 4 > &rhs)
Definition: Functions.hh:261
SVector< T, D > unit(const SVector< T, D > &rhs)
Definition: Functions.hh:341
T mag2(const SVector< T, D > &rhs)
Definition: Functions.hh:195
Definition: Expression.hh:113
Definition: Expression.hh:172
Definition: BinaryOperators.hh:626
Definition: Expression.hh:43
T apply(unsigned int i) const
Definition: Expression.hh:55
Definition: SVector.hh:51
T apply(unsigned int i) const
access the parse tree
SVector< T, D > & unit()
transform vector into a vector of lenght 1
struct @6 B
static T f(const A &lhs, const B &rhs, const T &x)
Definition: Functions.hh:117
Definition: Functions.hh:103
static T f(const A &lhs, const B &rhs, const T &x)
Definition: Functions.hh:105
static T f(const A &rhs, const T &x)
Definition: Functions.hh:180
Definition: Functions.hh:166
static T f(const A &rhs, const T &x)
Definition: Functions.hh:168