4 #ifndef ROOT_Math_Functions
5 #define ROOT_Math_Functions
60 template <
class T,
unsigned int D>
class SVector;
73 inline const T Square(
const T& x) {
return x*x; }
85 inline const T Maximum(
const T& lhs,
const T& rhs) {
86 return (lhs > rhs) ? lhs : rhs;
99 inline const T Minimum(
const T& lhs,
const T& rhs) {
100 return (lhs < rhs) ? lhs : rhs;
112 inline int Round(
const T& x) {
113 return (x-static_cast<int>(x) < 0.5) ?
static_cast<int>(x) : static_cast<int>(x+1);
127 inline int Sign(
const T& x) {
return (x==0)? 0 : (x<0)? -1 : 1; }
132 template <
unsigned int I>
134 template <
class A,
class B,
class T>
135 static inline T f(
const A& lhs,
const B& rhs,
const T& x) {
136 return lhs.apply(I) * rhs.apply(I) + meta_dot<I-1>::f(lhs,rhs,x);
146 template <
class A,
class B,
class T>
147 static inline T f(
const A& lhs,
const B& rhs,
const T& ) {
148 return lhs.apply(0) * rhs.apply(0);
163 template <
class T,
unsigned int D>
164 inline T Dot(
const SVector<T,D>& lhs,
const SVector<T,D>& rhs) {
165 return meta_dot<D-1>::f(lhs,rhs, T());
171 template <
class A,
class T,
unsigned int D>
172 inline T Dot(
const SVector<T,D>& lhs,
const VecExpr<A,T,D>& rhs) {
173 return meta_dot<D-1>::f(lhs,rhs, T());
179 template <
class A,
class T,
unsigned int D>
180 inline T Dot(
const VecExpr<A,T,D>& lhs,
const SVector<T,D>& rhs) {
181 return meta_dot<D-1>::f(lhs,rhs, T());
188 template <
class A,
class B,
class T,
unsigned int D>
189 inline T Dot(
const VecExpr<A,T,D>& lhs,
const VecExpr<B,T,D>& rhs) {
190 return meta_dot<D-1>::f(rhs,lhs, T());
197 template <
unsigned int I>
199 template <
class A,
class T>
200 static inline T f(
const A& rhs,
const T& x) {
201 return Square(rhs.apply(I)) + meta_mag<I-1>::f(rhs, x);
211 template <
class A,
class T>
212 static inline T f(
const A& rhs,
const T& ) {
213 return Square(rhs.apply(0));
228 template <
class T,
unsigned int D>
229 inline T Mag2(
const SVector<T,D>& rhs) {
230 return meta_mag<D-1>::f(rhs, T());
236 template <
class A,
class T,
unsigned int D>
237 inline T Mag2(
const VecExpr<A,T,D>& rhs) {
238 return meta_mag<D-1>::f(rhs, T());
251 template <
class T,
unsigned int D>
252 inline T Mag(
const SVector<T,D>& rhs) {
253 return std::sqrt(Mag2(rhs));
259 template <
class A,
class T,
unsigned int D>
260 inline T Mag(
const VecExpr<A,T,D>& rhs) {
261 return std::sqrt(Mag2(rhs));
275 inline T Lmag2(
const SVector<T,4>& rhs) {
276 return Square(rhs[0]) - Square(rhs[1]) - Square(rhs[2]) - Square(rhs[3]);
282 template <
class A,
class T>
283 inline T Lmag2(
const VecExpr<A,T,4>& rhs) {
284 return Square(rhs.apply(0))
285 - Square(rhs.apply(1)) - Square(rhs.apply(2)) - Square(rhs.apply(3));
299 inline T Lmag(
const SVector<T,4>& rhs) {
300 return std::sqrt(Lmag2(rhs));
306 template <
class A,
class T>
307 inline T Lmag(
const VecExpr<A,T,4>& rhs) {
308 return std::sqrt(Lmag2(rhs));
322 inline SVector<T,3> Cross(
const SVector<T,3>& lhs,
const SVector<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));
334 template <
class A,
class T>
335 inline SVector<T,3> Cross(
const VecExpr<A,T,3>& lhs,
const SVector<T,3>& rhs) {
336 return SVector<T,3>(lhs.apply(1)*rhs.apply(2) -
337 lhs.apply(2)*rhs.apply(1),
338 lhs.apply(2)*rhs.apply(0) -
339 lhs.apply(0)*rhs.apply(2),
340 lhs.apply(0)*rhs.apply(1) -
341 lhs.apply(1)*rhs.apply(0));
347 template <
class T,
class A>
348 inline SVector<T,3> Cross(
const SVector<T,3>& lhs,
const VecExpr<A,T,3>& rhs) {
349 return SVector<T,3>(lhs.apply(1)*rhs.apply(2) -
350 lhs.apply(2)*rhs.apply(1),
351 lhs.apply(2)*rhs.apply(0) -
352 lhs.apply(0)*rhs.apply(2),
353 lhs.apply(0)*rhs.apply(1) -
354 lhs.apply(1)*rhs.apply(0));
360 template <
class A,
class B,
class T>
361 inline SVector<T,3> Cross(
const VecExpr<A,T,3>& lhs,
const VecExpr<B,T,3>& rhs) {
362 return SVector<T,3>(lhs.apply(1)*rhs.apply(2) -
363 lhs.apply(2)*rhs.apply(1),
364 lhs.apply(2)*rhs.apply(0) -
365 lhs.apply(0)*rhs.apply(2),
366 lhs.apply(0)*rhs.apply(1) -
367 lhs.apply(1)*rhs.apply(0));
380 template <
class T,
unsigned int D>
381 inline SVector<T,D> Unit(
const SVector<T,D>& rhs) {
382 return SVector<T,D>(rhs).Unit();
388 template <
class A,
class T,
unsigned int D>
389 inline SVector<T,D> Unit(
const VecExpr<A,T,D>& rhs) {
390 return SVector<T,D>(rhs).Unit();
397 template <
class T,
unsigned int D>
398 inline VecExpr<BinaryOp<DivOp<T>, SVector<T,D>, Constant<T>, T>, T, D>
399 unit(
const SVector<T,D>& lhs) {
400 typedef BinaryOp<DivOp<T>, SVector<T,D>, Constant<T>, T> DivOpBinOp;
401 return VecExpr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,Constant<T>(mag(lhs))));
407 template <
class A,
class T,
unsigned int D>
408 inline VecExpr<BinaryOp<DivOp<T>, VecExpr<A,T,D>, Constant<T>, T>, T, D>
409 unit(
const VecExpr<A,T,D>& lhs) {
410 typedef BinaryOp<DivOp<T>, VecExpr<A,T,D>, Constant<T>, T> DivOpBinOp;
411 return VecExpr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,Constant<T>(mag(lhs))));