// @(#)root/smatrix:$Name: $:$Id: Functions.h,v 1.2 2005/12/11 00:24:49 rdm Exp $ // Authors: T. Glebe, L. Moneta 2005 #ifndef ROOT_Math_Functions #define ROOT_Math_Functions // ******************************************************************** // // source: // // type: source code // // created: 16. Mar 2001 // // author: Thorsten Glebe // HERA-B Collaboration // Max-Planck-Institut fuer Kernphysik // Saupfercheckweg 1 // 69117 Heidelberg // Germany // E-mail: T.Glebe@mpi-hd.mpg.de // // Description: Functions which are not applied like a unary operator // // changes: // 16 Mar 2001 (TG) creation // 03 Apr 2001 (TG) minimum added, doc++ comments added // 07 Apr 2001 (TG) Lmag2, Lmag added // 19 Apr 2001 (TG) added #include // 24 Apr 2001 (TG) added sign() // 26 Jul 2001 (TG) round() added // 27 Sep 2001 (TG) added Expr declaration // // ******************************************************************** #include #include "Math/Expression.h" namespace ROOT { namespace Math { template class SVector; /** square. Template to compute $x\cdot x$ @author T. Glebe */ //============================================================================== // square: x*x //============================================================================== template inline const T Square(const T& x) { return x*x; } /** maximum. Template to compute $\max(i,j)$ @author T. Glebe */ //============================================================================== // maximum //============================================================================== template inline const T Maximum(const T& lhs, const T& rhs) { return (lhs > rhs) ? lhs : rhs; } /** minimum. Template to compute $\min(i,j)$ @author T. Glebe */ //============================================================================== // minimum //============================================================================== template inline const T Minimum(const T& lhs, const T& rhs) { return (lhs < rhs) ? lhs : rhs; } /** round. Template to compute nearest integer value. @author T. Glebe */ //============================================================================== // round //============================================================================== template inline int Round(const T& x) { return (x-static_cast(x) < 0.5) ? static_cast(x) : static_cast(x+1); } /** sign. Template to compute the sign of a number $\textrm{sgn}(i)$. @author T. Glebe */ //============================================================================== // sign //============================================================================== template inline int Sign(const T& x) { return (x==0)? 0 : (x<0)? -1 : 1; } //============================================================================== // meta_dot //============================================================================== template struct meta_dot { template static inline T f(const A& lhs, const B& rhs, const T& x) { return lhs.apply(I) * rhs.apply(I) + meta_dot::f(lhs,rhs,x); } }; //============================================================================== // meta_dot<0> //============================================================================== template <> struct meta_dot<0> { template static inline T f(const A& lhs, const B& rhs, const T& /*x */) { return lhs.apply(0) * rhs.apply(0); } }; /** dot. Template to compute $\vec{a}\cdot\vec{b} = \sum_i a_i\cdot b_i$. @author T. Glebe */ //============================================================================== // dot //============================================================================== template inline T Dot(const SVector& lhs, const SVector& rhs) { return meta_dot::f(lhs,rhs, T()); } //============================================================================== // dot //============================================================================== template inline T Dot(const SVector& lhs, const Expr& rhs) { return meta_dot::f(lhs,rhs, T()); } //============================================================================== // dot //============================================================================== template inline T Dot(const Expr& lhs, const SVector& rhs) { return meta_dot::f(lhs,rhs, T()); } //============================================================================== // dot //============================================================================== template inline T Dot(const Expr& lhs, const Expr& rhs) { return meta_dot::f(rhs,lhs, T()); } //============================================================================== // meta_mag //============================================================================== template struct meta_mag { template static inline T f(const A& rhs, const T& x) { return Square(rhs.apply(I)) + meta_mag::f(rhs, x); } }; //============================================================================== // meta_mag<0> //============================================================================== template <> struct meta_mag<0> { template static inline T f(const A& rhs, const T& ) { return Square(rhs.apply(0)); } }; /** mag2. Template to compute $|\vec{v}|^2 = \sum_iv_i^2$. @author T. Glebe */ //============================================================================== // mag2 //============================================================================== template inline T Mag2(const SVector& rhs) { return meta_mag::f(rhs, T()); } //============================================================================== // mag2 //============================================================================== template inline T Mag2(const Expr& rhs) { return meta_mag::f(rhs, T()); } /** mag. Length of a vector: $|\vec{v}| = \sqrt{\sum_iv_i^2}$. @author T. Glebe */ //============================================================================== // mag //============================================================================== template inline T Mag(const SVector& rhs) { return std::sqrt(Mag2(rhs)); } //============================================================================== // mag //============================================================================== template inline T Mag(const Expr& rhs) { return std::sqrt(Mag2(rhs)); } /** Lmag2. Template to compute $|\vec{v}|^2 = v_0^2 - v_1^2 - v_2^2 -v_3^2$. @author T. Glebe */ //============================================================================== // Lmag2 //============================================================================== template inline T Lmag2(const SVector& rhs) { return Square(rhs[0]) - Square(rhs[1]) - Square(rhs[2]) - Square(rhs[3]); } //============================================================================== // Lmag2 //============================================================================== template inline T Lmag2(const Expr& rhs) { return Square(rhs.apply(0)) - Square(rhs.apply(1)) - Square(rhs.apply(2)) - Square(rhs.apply(3)); } /** Lmag. Length of a vector Lorentz-Vector: $|\vec{v}| = \sqrt{v_0^2 - v_1^2 - v_2^2 -v_3^2}$. @author T. Glebe */ //============================================================================== // Lmag //============================================================================== template inline T Lmag(const SVector& rhs) { return std::sqrt(Lmag2(rhs)); } //============================================================================== // Lmag //============================================================================== template inline T Lmag(const Expr& rhs) { return std::sqrt(Lmag2(rhs)); } /** cross. Cross product of two 3-dim vectors: $\vec{c} = \vec{a}\times\vec{b}$. @author T. Glebe */ //============================================================================== // cross product //============================================================================== template inline SVector Cross(const SVector& lhs, const SVector& rhs) { return SVector(lhs.apply(1)*rhs.apply(2) - lhs.apply(2)*rhs.apply(1), lhs.apply(2)*rhs.apply(0) - lhs.apply(0)*rhs.apply(2), lhs.apply(0)*rhs.apply(1) - lhs.apply(1)*rhs.apply(0)); } //============================================================================== // cross product //============================================================================== template inline SVector Cross(const Expr& lhs, const SVector& rhs) { return SVector(lhs.apply(1)*rhs.apply(2) - lhs.apply(2)*rhs.apply(1), lhs.apply(2)*rhs.apply(0) - lhs.apply(0)*rhs.apply(2), lhs.apply(0)*rhs.apply(1) - lhs.apply(1)*rhs.apply(0)); } //============================================================================== // cross product //============================================================================== template inline SVector Cross(const SVector& lhs, const Expr& rhs) { return SVector(lhs.apply(1)*rhs.apply(2) - lhs.apply(2)*rhs.apply(1), lhs.apply(2)*rhs.apply(0) - lhs.apply(0)*rhs.apply(2), lhs.apply(0)*rhs.apply(1) - lhs.apply(1)*rhs.apply(0)); } //============================================================================== // cross product //============================================================================== template inline SVector Cross(const Expr& lhs, const Expr& rhs) { return SVector(lhs.apply(1)*rhs.apply(2) - lhs.apply(2)*rhs.apply(1), lhs.apply(2)*rhs.apply(0) - lhs.apply(0)*rhs.apply(2), lhs.apply(0)*rhs.apply(1) - lhs.apply(1)*rhs.apply(0)); } /** Unit. Return a vector of unit lenght: $\vec{e}_v = \vec{v}/|\vec{v}|$. @author T. Glebe */ //============================================================================== // unit: returns a unit vector //============================================================================== template inline SVector Unit(const SVector& rhs) { return SVector(rhs).Unit(); } //============================================================================== // unit: returns a unit vector //============================================================================== template inline SVector Unit(const Expr& rhs) { return SVector(rhs).Unit(); } #ifdef XXX //============================================================================== // unit: returns a unit vector (worse performance) //============================================================================== template inline Expr, SVector, Constant, T>, T, D> unit(const SVector& lhs) { typedef BinaryOp, SVector, Constant, T> DivOpBinOp; return Expr(DivOpBinOp(DivOp(),lhs,Constant(mag(lhs)))); } //============================================================================== // unit: returns a unit vector (worse performance) //============================================================================== template inline Expr, Expr, Constant, T>, T, D> unit(const Expr& lhs) { typedef BinaryOp, Expr, Constant, T> DivOpBinOp; return Expr(DivOpBinOp(DivOp(),lhs,Constant(mag(lhs)))); } #endif } // namespace Math } // namespace ROOT #endif /* ROOT_Math_Functions */