Functions.h

Go to the documentation of this file.
00001 // @(#)root/smatrix:$Id: Functions.h 20882 2007-11-19 11:31:26Z rdm $
00002 // Authors: T. Glebe, L. Moneta    2005
00003 
00004 #ifndef ROOT_Math_Functions
00005 #define ROOT_Math_Functions
00006 // ********************************************************************
00007 //
00008 // source:
00009 //
00010 // type:      source code
00011 //
00012 // created:   16. Mar 2001
00013 //
00014 // author:    Thorsten Glebe
00015 //            HERA-B Collaboration
00016 //            Max-Planck-Institut fuer Kernphysik
00017 //            Saupfercheckweg 1
00018 //            69117 Heidelberg
00019 //            Germany
00020 //            E-mail: T.Glebe@mpi-hd.mpg.de
00021 //
00022 // Description: Functions which are not applied like a unary operator
00023 //
00024 // changes:
00025 // 16 Mar 2001 (TG) creation
00026 // 03 Apr 2001 (TG) minimum added, doc++ comments added
00027 // 07 Apr 2001 (TG) Lmag2, Lmag added
00028 // 19 Apr 2001 (TG) added #include <cmath>
00029 // 24 Apr 2001 (TG) added sign()
00030 // 26 Jul 2001 (TG) round() added
00031 // 27 Sep 2001 (TG) added Expr declaration
00032 //
00033 // ********************************************************************
00034 #include <cmath>
00035 
00036 #ifndef ROOT_Math_Expression
00037 #include "Math/Expression.h"
00038 #endif
00039 
00040 /**
00041    @defgroup TempFunction Generic Template Functions 
00042    @ingroup SMatrixGroup
00043 
00044    These functions apply for any type T, such as a scalar, a vector or a matrix. 
00045  */
00046 /**
00047    @defgroup VectFunction Vector Template Functions 
00048    @ingroup SMatrixGroup
00049 
00050    These functions apply to SVector types (and also to Vector expressions) and can 
00051    return a vector expression or 
00052    a scalar, like in the Dot product, or a matrix, like in the Tensor product 
00053  */
00054 
00055 
00056 namespace ROOT {
00057 
00058   namespace Math {
00059 
00060 
00061 
00062 template <class T, unsigned int D> class SVector;
00063 
00064 
00065 /** square  
00066     Template function to compute \f$x\cdot x \f$, for any type T returning a type T
00067 
00068     @ingroup TempFunction
00069     @author T. Glebe
00070 */
00071 //==============================================================================
00072 // square: x*x
00073 //==============================================================================
00074 template <class T>
00075 inline const T Square(const T& x) { return x*x; }
00076 
00077 /** maximum.
00078     Template to find max(a,b) where a,b are of type T
00079 
00080     @ingroup TempFunction
00081     @author T. Glebe
00082 */
00083 //==============================================================================
00084 // maximum
00085 //==============================================================================
00086 template <class T>
00087 inline const T Maximum(const T& lhs, const T& rhs) {
00088   return (lhs > rhs) ? lhs : rhs;
00089 }
00090 
00091 /** minimum.
00092     Template to find min(a,b) where a,b are of type T
00093 
00094     @ingroup TempFunction
00095     @author T. Glebe
00096 */
00097 //==============================================================================
00098 // minimum
00099 //==============================================================================
00100 template <class T>
00101 inline const T Minimum(const T& lhs, const T& rhs) {
00102   return (lhs < rhs) ? lhs : rhs;
00103 }
00104 
00105 /** round.
00106     Template to compute nearest integer value for any type T
00107     @ingroup TempFunction
00108     @author T. Glebe
00109 */
00110 //==============================================================================
00111 // round
00112 //==============================================================================
00113 template <class T>
00114 inline int Round(const T& x) {
00115   return (x-static_cast<int>(x) < 0.5) ? static_cast<int>(x) : static_cast<int>(x+1);
00116 }
00117 
00118 
00119 /** sign.
00120     Template to compute the sign of a number 
00121 
00122     @ingroup TempFunction
00123     @author T. Glebe
00124 */
00125 //==============================================================================
00126 // sign
00127 //==============================================================================
00128 template <class T>
00129 inline int Sign(const T& x) { return (x==0)? 0 : (x<0)? -1 : 1; }
00130 
00131 //==============================================================================
00132 // meta_dot
00133 //==============================================================================
00134 template <unsigned int I>
00135 struct meta_dot {
00136   template <class A, class B, class T>
00137   static inline T f(const A& lhs, const B& rhs, const T& x) {
00138     return lhs.apply(I) * rhs.apply(I) + meta_dot<I-1>::f(lhs,rhs,x);
00139   }
00140 };
00141 
00142 
00143 //==============================================================================
00144 // meta_dot<0>
00145 //==============================================================================
00146 template <>
00147 struct meta_dot<0> {
00148   template <class A, class B, class T>
00149   static inline T f(const A& lhs, const B& rhs, const T& /*x */) {
00150     return lhs.apply(0) * rhs.apply(0);
00151   }
00152 };
00153 
00154 
00155 /** 
00156     Vector dot product. 
00157     Template to compute \f$\vec{a}\cdot\vec{b} = \sum_i a_i\cdot b_i \f$.
00158 
00159     @ingroup VectFunction
00160     @author T. Glebe
00161 */
00162 //==============================================================================
00163 // dot
00164 //==============================================================================
00165 template <class T, unsigned int D>
00166 inline T Dot(const SVector<T,D>& lhs, const SVector<T,D>& rhs) {
00167   return meta_dot<D-1>::f(lhs,rhs, T());
00168 }
00169 
00170 //==============================================================================
00171 // dot
00172 //==============================================================================
00173 template <class A, class T, unsigned int D>
00174 inline T Dot(const SVector<T,D>& lhs, const VecExpr<A,T,D>& rhs) {
00175   return meta_dot<D-1>::f(lhs,rhs, T());
00176 }
00177 
00178 //==============================================================================
00179 // dot
00180 //==============================================================================
00181 template <class A, class T, unsigned int D>
00182 inline T Dot(const VecExpr<A,T,D>& lhs, const SVector<T,D>& rhs) {
00183   return meta_dot<D-1>::f(lhs,rhs, T());
00184 }
00185 
00186 
00187 //==============================================================================
00188 // dot
00189 //==============================================================================
00190 template <class A, class B, class T, unsigned int D>
00191 inline T Dot(const VecExpr<A,T,D>& lhs, const VecExpr<B,T,D>& rhs) {
00192   return meta_dot<D-1>::f(rhs,lhs, T());
00193 }
00194 
00195 
00196 //==============================================================================
00197 // meta_mag
00198 //==============================================================================
00199 template <unsigned int I>
00200 struct meta_mag {
00201   template <class A, class T>
00202   static inline T f(const A& rhs, const T& x) {
00203     return Square(rhs.apply(I)) + meta_mag<I-1>::f(rhs, x);
00204   }
00205 };
00206 
00207 
00208 //==============================================================================
00209 // meta_mag<0>
00210 //==============================================================================
00211 template <>
00212 struct meta_mag<0> {
00213   template <class A, class T>
00214   static inline T f(const A& rhs, const T& ) {
00215     return Square(rhs.apply(0));
00216   }
00217 };
00218 
00219 
00220 /** 
00221     Vector magnitude square
00222     Template to compute \f$|\vec{v}|^2 = \sum_iv_i^2 \f$.
00223 
00224     @ingroup VectFunction
00225     @author T. Glebe
00226 */
00227 //==============================================================================
00228 // mag2
00229 //==============================================================================
00230 template <class T, unsigned int D>
00231 inline T Mag2(const SVector<T,D>& rhs) {
00232   return meta_mag<D-1>::f(rhs, T());
00233 }
00234 
00235 //==============================================================================
00236 // mag2
00237 //==============================================================================
00238 template <class A, class T, unsigned int D>
00239 inline T Mag2(const VecExpr<A,T,D>& rhs) {
00240   return meta_mag<D-1>::f(rhs, T());
00241 }
00242 
00243 /** 
00244     Vector magnitude (Euclidian norm) 
00245     Compute : \f$ |\vec{v}| = \sqrt{\sum_iv_i^2} \f$.
00246 
00247     @ingroup VectFunction
00248     @author T. Glebe
00249 */
00250 //==============================================================================
00251 // mag
00252 //==============================================================================
00253 template <class T, unsigned int D>
00254 inline T Mag(const SVector<T,D>& rhs) {
00255   return std::sqrt(Mag2(rhs));
00256 }
00257 
00258 //==============================================================================
00259 // mag
00260 //==============================================================================
00261 template <class A, class T, unsigned int D>
00262 inline T Mag(const VecExpr<A,T,D>& rhs) {
00263   return std::sqrt(Mag2(rhs));
00264 }
00265 
00266 
00267 /** Lmag2: Square of Minkowski Lorentz-Vector norm (only for 4D Vectors)
00268     Template to compute \f$ |\vec{v}|^2 = v_0^2 - v_1^2 - v_2^2 -v_3^2 \f$.
00269 
00270     @ingroup VectFunction
00271     @author T. Glebe
00272 */
00273 //==============================================================================
00274 // Lmag2
00275 //==============================================================================
00276 template <class T>
00277 inline T Lmag2(const SVector<T,4>& rhs) {
00278   return Square(rhs[0]) - Square(rhs[1]) - Square(rhs[2]) - Square(rhs[3]);
00279 }
00280 
00281 //==============================================================================
00282 // Lmag2
00283 //==============================================================================
00284 template <class A, class T>
00285 inline T Lmag2(const VecExpr<A,T,4>& rhs) {
00286   return Square(rhs.apply(0))
00287     - Square(rhs.apply(1)) - Square(rhs.apply(2)) - Square(rhs.apply(3));
00288 }
00289 
00290 /** Lmag: Minkowski Lorentz-Vector norm (only for 4-dim vectors)
00291     Length of a vector Lorentz-Vector: 
00292     \f$ |\vec{v}| = \sqrt{v_0^2 - v_1^2 - v_2^2 -v_3^2} \f$.
00293 
00294     @ingroup VectFunction
00295     @author T. Glebe
00296 */
00297 //==============================================================================
00298 // Lmag
00299 //==============================================================================
00300 template <class T>
00301 inline T Lmag(const SVector<T,4>& rhs) {
00302   return std::sqrt(Lmag2(rhs));
00303 }
00304 
00305 //==============================================================================
00306 // Lmag
00307 //==============================================================================
00308 template <class A, class T>
00309 inline T Lmag(const VecExpr<A,T,4>& rhs) {
00310   return std::sqrt(Lmag2(rhs));
00311 }
00312 
00313 
00314 /** Vector Cross Product (only for 3-dim vectors)
00315     \f$ \vec{c} = \vec{a}\times\vec{b} \f$.
00316 
00317     @ingroup VectFunction
00318     @author T. Glebe
00319 */
00320 //==============================================================================
00321 // cross product
00322 //==============================================================================
00323 template <class T>
00324 inline SVector<T,3> Cross(const SVector<T,3>& lhs, const SVector<T,3>& rhs) {
00325   return SVector<T,3>(lhs.apply(1)*rhs.apply(2) -
00326                       lhs.apply(2)*rhs.apply(1),
00327                       lhs.apply(2)*rhs.apply(0) -
00328                       lhs.apply(0)*rhs.apply(2),
00329                       lhs.apply(0)*rhs.apply(1) -
00330                       lhs.apply(1)*rhs.apply(0));
00331 }
00332 
00333 //==============================================================================
00334 // cross product
00335 //==============================================================================
00336 template <class A, class T>
00337 inline SVector<T,3> Cross(const VecExpr<A,T,3>& lhs, const SVector<T,3>& rhs) {
00338   return SVector<T,3>(lhs.apply(1)*rhs.apply(2) -
00339                       lhs.apply(2)*rhs.apply(1),
00340                       lhs.apply(2)*rhs.apply(0) -
00341                       lhs.apply(0)*rhs.apply(2),
00342                       lhs.apply(0)*rhs.apply(1) -
00343                       lhs.apply(1)*rhs.apply(0));
00344 }
00345 
00346 //==============================================================================
00347 // cross product
00348 //==============================================================================
00349 template <class T, class A>
00350 inline SVector<T,3> Cross(const SVector<T,3>& lhs, const VecExpr<A,T,3>& rhs) {
00351   return SVector<T,3>(lhs.apply(1)*rhs.apply(2) -
00352                       lhs.apply(2)*rhs.apply(1),
00353                       lhs.apply(2)*rhs.apply(0) -
00354                       lhs.apply(0)*rhs.apply(2),
00355                       lhs.apply(0)*rhs.apply(1) -
00356                       lhs.apply(1)*rhs.apply(0));
00357 }
00358 
00359 //==============================================================================
00360 // cross product
00361 //==============================================================================
00362 template <class A, class B, class T>
00363 inline SVector<T,3> Cross(const VecExpr<A,T,3>& lhs, const VecExpr<B,T,3>& rhs) {
00364   return SVector<T,3>(lhs.apply(1)*rhs.apply(2) -
00365                       lhs.apply(2)*rhs.apply(1),
00366                       lhs.apply(2)*rhs.apply(0) -
00367                       lhs.apply(0)*rhs.apply(2),
00368                       lhs.apply(0)*rhs.apply(1) -
00369                       lhs.apply(1)*rhs.apply(0));
00370 }
00371 
00372 
00373 /** Unit.
00374     Return a vector of unit lenght: \f$ \vec{e}_v = \vec{v}/|\vec{v}| \f$.
00375 
00376     @ingroup VectFunction
00377     @author T. Glebe
00378 */
00379 //==============================================================================
00380 // unit: returns a unit vector
00381 //==============================================================================
00382 template <class T, unsigned int D>
00383 inline SVector<T,D> Unit(const SVector<T,D>& rhs) {
00384   return SVector<T,D>(rhs).Unit();
00385 }
00386 
00387 //==============================================================================
00388 // unit: returns a unit vector
00389 //==============================================================================
00390 template <class A, class T, unsigned int D>
00391 inline SVector<T,D> Unit(const VecExpr<A,T,D>& rhs) {
00392   return SVector<T,D>(rhs).Unit();
00393 }
00394 
00395 #ifdef XXX
00396 //==============================================================================
00397 // unit: returns a unit vector (worse performance)
00398 //==============================================================================
00399 template <class T, unsigned int D>
00400 inline VecExpr<BinaryOp<DivOp<T>, SVector<T,D>, Constant<T>, T>, T, D>
00401  unit(const SVector<T,D>& lhs) {
00402   typedef BinaryOp<DivOp<T>, SVector<T,D>, Constant<T>, T> DivOpBinOp;
00403   return VecExpr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,Constant<T>(mag(lhs))));
00404 }
00405 
00406 //==============================================================================
00407 // unit: returns a unit vector (worse performance)
00408 //==============================================================================
00409 template <class A, class T, unsigned int D>
00410 inline VecExpr<BinaryOp<DivOp<T>, VecExpr<A,T,D>, Constant<T>, T>, T, D>
00411  unit(const VecExpr<A,T,D>& lhs) {
00412   typedef BinaryOp<DivOp<T>, VecExpr<A,T,D>, Constant<T>, T> DivOpBinOp;
00413   return VecExpr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,Constant<T>(mag(lhs))));
00414 }
00415 #endif
00416 
00417 
00418   }  // namespace Math
00419 
00420 }  // namespace ROOT
00421 
00422 
00423 
00424 #endif   /* ROOT_Math_Functions */

Generated on Tue Jul 5 14:25:13 2011 for ROOT_528-00b_version by  doxygen 1.5.1