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
34template <class T, unsigned int D> class SVector;
35
36
42//==============================================================================
43// square: x*x
44//==============================================================================
45template <class T>
46inline const T square(const T& x) { return x*x; }
47
53//==============================================================================
54// maximum
55//==============================================================================
56template <class T>
57inline const T maximum(const T& lhs, const T& rhs) {
58 return (lhs > rhs) ? lhs : rhs;
59}
60
66//==============================================================================
67// minimum
68//==============================================================================
69template <class T>
70inline const T minimum(const T& lhs, const T& rhs) {
71 return (lhs < rhs) ? lhs : rhs;
72}
73
79//==============================================================================
80// round
81//==============================================================================
82template <class T>
83inline 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//==============================================================================
96template <class T>
97inline const int sign(const T& x) { return (x==0)? 0 : (x<0)? -1 : 1; }
98
99//==============================================================================
100// meta_dot
101//==============================================================================
102template <unsigned int I>
103struct 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//==============================================================================
114template <>
115struct 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//==============================================================================
131template <class T, unsigned int D>
132inline 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//==============================================================================
139template <class A, class T, unsigned int D>
140inline 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//==============================================================================
147template <class A, class T, unsigned int D>
148inline 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//==============================================================================
156template <class A, class B, class T, unsigned int D>
157inline 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//==============================================================================
165template <unsigned int I>
166struct 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//==============================================================================
177template <>
178struct 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//==============================================================================
194template <class T, unsigned int D>
195inline T mag2(const SVector<T,D>& rhs) {
196 return meta_mag<D-1>::f(rhs, T());
197}
198
199//==============================================================================
200// mag2
201//==============================================================================
202template <class A, class T, unsigned int D>
203inline T mag2(const Expr<A,T,D>& rhs) {
204 return meta_mag<D-1>::f(rhs, T());
205}
206
212//==============================================================================
213// mag
214//==============================================================================
215template <class T, unsigned int D>
216inline T mag(const SVector<T,D>& rhs) {
217 return sqrt(mag2(rhs));
218}
219
220//==============================================================================
221// mag
222//==============================================================================
223template <class A, class T, unsigned int D>
224inline T mag(const Expr<A,T,D>& rhs) {
225 return sqrt(mag2(rhs));
226}
227
228
234//==============================================================================
235// Lmag2
236//==============================================================================
237template <class T>
238inline 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//==============================================================================
245template <class A, class T>
246inline 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//==============================================================================
260template <class T>
261inline T Lmag(const SVector<T,4>& rhs) {
262 return sqrt(Lmag2(rhs));
263}
264
265//==============================================================================
266// Lmag
267//==============================================================================
268template <class A, class T>
269inline T Lmag(const Expr<A,T,4>& rhs) {
270 return sqrt(Lmag2(rhs));
271}
272
273
279//==============================================================================
280// cross product
281//==============================================================================
282template <class T>
283inline 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//==============================================================================
295template <class A, class T>
296inline 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//==============================================================================
308template <class T, class A>
309inline 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//==============================================================================
321template <class A, class B, class T>
322inline 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//==============================================================================
340template <class T, unsigned int D>
341inline 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//==============================================================================
348template <class A, class T, unsigned int D>
349inline 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//==============================================================================
357template <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//==============================================================================
367template <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
T dot(const SVector< T, D > &lhs, const SVector< T, D > &rhs)
Definition: Functions.hh:132
SVector< T, 3 > cross(const SVector< T, 3 > &lhs, const SVector< T, 3 > &rhs)
Definition: Functions.hh:283
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
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