TMath.h

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: TMath.h 36792 2010-11-19 16:53:42Z rdm $
00002 // Authors: Rene Brun, Anna Kreshuk, Eddy Offermann, Fons Rademakers   29/07/95
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #ifndef ROOT_TMath
00013 #define ROOT_TMath
00014 
00015 
00016 //////////////////////////////////////////////////////////////////////////
00017 //                                                                      //
00018 // TMath                                                                //
00019 //                                                                      //
00020 // Encapsulate most frequently used Math functions.                     //
00021 // NB. The basic functions Min, Max, Abs and Sign are defined           //
00022 // in TMathBase.                                                        //
00023 //                                                                      //
00024 //////////////////////////////////////////////////////////////////////////
00025 
00026 #ifndef ROOT_Rtypes
00027 #include "Rtypes.h"
00028 #endif
00029 #ifndef ROOT_TMathBase
00030 #include "TMathBase.h"
00031 #endif
00032 
00033 #include "TError.h"
00034 #include <algorithm>
00035 
00036 namespace TMath {
00037 
00038    /* ************************* */
00039    /* * Fundamental constants * */
00040    /* ************************* */
00041 
00042    inline Double_t Pi()       { return 3.14159265358979323846; }
00043    inline Double_t TwoPi()    { return 2.0 * Pi(); }
00044    inline Double_t PiOver2()  { return Pi() / 2.0; }
00045    inline Double_t PiOver4()  { return Pi() / 4.0; }
00046    inline Double_t InvPi()    { return 1.0 / Pi(); }
00047    inline Double_t RadToDeg() { return 180.0 / Pi(); }
00048    inline Double_t DegToRad() { return Pi() / 180.0; }
00049    inline Double_t Sqrt2()    { return 1.4142135623730950488016887242097; }
00050 
00051    // e (base of natural log)
00052    inline Double_t E()        { return 2.71828182845904523536; }
00053 
00054    // natural log of 10 (to convert log to ln)
00055    inline Double_t Ln10()     { return 2.30258509299404568402; }
00056 
00057    // base-10 log of e  (to convert ln to log)
00058    inline Double_t LogE()     { return 0.43429448190325182765; }
00059 
00060    // velocity of light
00061    inline Double_t C()        { return 2.99792458e8; }        // m s^-1
00062    inline Double_t Ccgs()     { return 100.0 * C(); }         // cm s^-1
00063    inline Double_t CUncertainty() { return 0.0; }             // exact
00064 
00065    // gravitational constant
00066    inline Double_t G()        { return 6.673e-11; }           // m^3 kg^-1 s^-2
00067    inline Double_t Gcgs()     { return G() / 1000.0; }        // cm^3 g^-1 s^-2
00068    inline Double_t GUncertainty() { return 0.010e-11; }
00069 
00070    // G over h-bar C
00071    inline Double_t GhbarC()   { return 6.707e-39; }           // (GeV/c^2)^-2
00072    inline Double_t GhbarCUncertainty() { return 0.010e-39; }
00073 
00074    // standard acceleration of gravity
00075    inline Double_t Gn()       { return 9.80665; }             // m s^-2
00076    inline Double_t GnUncertainty() { return 0.0; }            // exact
00077 
00078    // Planck's constant
00079    inline Double_t H()        { return 6.62606876e-34; }      // J s
00080    inline Double_t Hcgs()     { return 1.0e7 * H(); }         // erg s
00081    inline Double_t HUncertainty() { return 0.00000052e-34; }
00082 
00083    // h-bar (h over 2 pi)
00084    inline Double_t Hbar()     { return 1.054571596e-34; }     // J s
00085    inline Double_t Hbarcgs()  { return 1.0e7 * Hbar(); }      // erg s
00086    inline Double_t HbarUncertainty() { return 0.000000082e-34; }
00087 
00088    // hc (h * c)
00089    inline Double_t HC()       { return H() * C(); }           // J m
00090    inline Double_t HCcgs()    { return Hcgs() * Ccgs(); }     // erg cm
00091 
00092    // Boltzmann's constant
00093    inline Double_t K()        { return 1.3806503e-23; }       // J K^-1
00094    inline Double_t Kcgs()     { return 1.0e7 * K(); }         // erg K^-1
00095    inline Double_t KUncertainty() { return 0.0000024e-23; }
00096 
00097    // Stefan-Boltzmann constant
00098    inline Double_t Sigma()    { return 5.6704e-8; }           // W m^-2 K^-4
00099    inline Double_t SigmaUncertainty() { return 0.000040e-8; }
00100 
00101    // Avogadro constant (Avogadro's Number)
00102    inline Double_t Na()       { return 6.02214199e+23; }      // mol^-1
00103    inline Double_t NaUncertainty() { return 0.00000047e+23; }
00104 
00105    // universal gas constant (Na * K)
00106    // http://scienceworld.wolfram.com/physics/UniversalGasConstant.html
00107    inline Double_t R()        { return K() * Na(); }          // J K^-1 mol^-1
00108    inline Double_t RUncertainty() { return R()*((KUncertainty()/K()) + (NaUncertainty()/Na())); }
00109 
00110    // Molecular weight of dry air
00111    // 1976 US Standard Atmosphere,
00112    // also see http://atmos.nmsu.edu/jsdap/encyclopediawork.html
00113    inline Double_t MWair()    { return 28.9644; }             // kg kmol^-1 (or gm mol^-1)
00114 
00115    // Dry Air Gas Constant (R / MWair)
00116    // http://atmos.nmsu.edu/education_and_outreach/encyclopedia/gas_constant.htm
00117    inline Double_t Rgair()    { return (1000.0 * R()) / MWair(); }  // J kg^-1 K^-1
00118 
00119    // Euler-Mascheroni Constant
00120    inline Double_t EulerGamma() { return 0.577215664901532860606512090082402431042; }
00121 
00122    // Elementary charge
00123    inline Double_t Qe()       { return 1.602176462e-19; }     // C
00124    inline Double_t QeUncertainty() { return 0.000000063e-19; }
00125 
00126    /* ************************** */
00127    /* * Mathematical Functions * */
00128    /* ************************** */
00129 
00130    /* ***************************** */
00131    /* * Trigonometrical Functions * */
00132    /* ***************************** */
00133    inline Double_t Sin(Double_t);
00134    inline Double_t Cos(Double_t);
00135    inline Double_t Tan(Double_t);
00136    inline Double_t SinH(Double_t);
00137    inline Double_t CosH(Double_t);
00138    inline Double_t TanH(Double_t);
00139    inline Double_t ASin(Double_t);
00140    inline Double_t ACos(Double_t);
00141    inline Double_t ATan(Double_t);
00142    inline Double_t ATan2(Double_t, Double_t);
00143           Double_t ASinH(Double_t);
00144           Double_t ACosH(Double_t);
00145           Double_t ATanH(Double_t);
00146           Double_t Hypot(Double_t x, Double_t y);
00147 
00148 
00149    /* ************************ */
00150    /* * Elementary Functions * */
00151    /* ************************ */
00152    inline Double_t Sqrt(Double_t x);
00153    inline Double_t Ceil(Double_t x);
00154    inline Int_t    CeilNint(Double_t x);
00155    inline Double_t Floor(Double_t x);
00156    inline Int_t    FloorNint(Double_t x);
00157    inline Double_t Exp(Double_t x);
00158    inline Double_t Ldexp(Double_t x, Int_t exp);
00159           Double_t Factorial(Int_t i);
00160    inline Double_t Power(Double_t x, Double_t y);
00161    inline Double_t Log(Double_t x);
00162           Double_t Log2(Double_t x);
00163    inline Double_t Log10(Double_t x);
00164           Int_t    Nint(Float_t x);
00165           Int_t    Nint(Double_t x);
00166    inline Int_t    Finite(Double_t x);
00167    inline Int_t    IsNaN(Double_t x);
00168 
00169    // Some integer math
00170    Long_t   Hypot(Long_t x, Long_t y);     // sqrt(px*px + py*py)
00171 
00172    // Comparing floating points
00173    inline Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon) {
00174       //return kTRUE if absolute difference between af and bf is less than epsilon
00175       return TMath::Abs(af-bf) < epsilon;
00176    }
00177    inline Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec) {
00178       //return kTRUE if relative difference between af and bf is less than relPrec
00179       return TMath::Abs(af-bf) <= 0.5*relPrec*(TMath::Abs(af)+TMath::Abs(bf));
00180    }
00181 
00182    /* ******************** */
00183    /* * Array Algorithms * */
00184    /* ******************** */
00185 
00186    // Min, Max of an array
00187    template <typename T> T MinElement(Long64_t n, const T *a);
00188    template <typename T> T MaxElement(Long64_t n, const T *a);
00189 
00190    // Locate Min, Max element number in an array
00191    template <typename T> Long64_t  LocMin(Long64_t n, const T *a);
00192    template <typename Iterator> Iterator LocMin(Iterator first, Iterator last);
00193    template <typename T> Long64_t  LocMax(Long64_t n, const T *a);
00194    template <typename Iterator> Iterator LocMax(Iterator first, Iterator last);
00195 
00196    // Binary search
00197    template <typename T> Long64_t BinarySearch(Long64_t n, const T  *array, T value);
00198    template <typename T> Long64_t BinarySearch(Long64_t n, const T **array, T value);
00199    template <typename Iterator, typename Element> Iterator BinarySearch(Iterator first, Iterator last, Element value);
00200 
00201    // Hashing
00202    ULong_t Hash(const void *txt, Int_t ntxt);
00203    ULong_t Hash(const char *str);
00204 
00205    // Sorting
00206    template <typename Element, typename Index>
00207    void Sort(Index n, const Element* a, Index* index, Bool_t down=kTRUE);
00208    template <typename Iterator, typename IndexIterator>
00209    void SortItr(Iterator first, Iterator last, IndexIterator index, Bool_t down=kTRUE);
00210 
00211    void BubbleHigh(Int_t Narr, Double_t *arr1, Int_t *arr2);
00212    void BubbleLow (Int_t Narr, Double_t *arr1, Int_t *arr2);
00213 
00214    Bool_t   Permute(Int_t n, Int_t *a); // Find permutations
00215 
00216    /* ************************* */
00217    /* * Geometrical Functions * */
00218    /* ************************* */
00219 
00220    //Sample quantiles
00221    void      Quantiles(Int_t n, Int_t nprob, Double_t *x, Double_t *quantiles, Double_t *prob,
00222                        Bool_t isSorted=kTRUE, Int_t *index = 0, Int_t type=7);
00223 
00224    // IsInside
00225    template <typename T> Bool_t IsInside(T xp, T yp, Int_t np, T *x, T *y);
00226 
00227    // Calculate the Cross Product of two vectors
00228    template <typename T> T *Cross(const T v1[3],const T v2[3], T out[3]);
00229 
00230    Float_t   Normalize(Float_t v[3]);  // Normalize a vector
00231    Double_t  Normalize(Double_t v[3]); // Normalize a vector
00232 
00233    //Calculate the Normalized Cross Product of two vectors
00234    template <typename T> inline T NormCross(const T v1[3],const T v2[3],T out[3]);
00235 
00236    // Calculate a normal vector of a plane
00237    template <typename T> T *Normal2Plane(const T v1[3],const T v2[3],const T v3[3], T normal[3]);
00238 
00239    /* ************************ */
00240    /* * Polynomial Functions * */
00241    /* ************************ */
00242 
00243    Bool_t    RootsCubic(const Double_t coef[4],Double_t &a, Double_t &b, Double_t &c);
00244 
00245    /* *********************** */
00246    /* * Statistic Functions * */
00247    /* *********************** */
00248 
00249    Double_t Binomial(Int_t n,Int_t k);  // Calculate the binomial coefficient n over k
00250    Double_t BinomialI(Double_t p, Int_t n, Int_t k);
00251    Double_t BreitWigner(Double_t x, Double_t mean=0, Double_t gamma=1);
00252    Double_t CauchyDist(Double_t x, Double_t t=0, Double_t s=1);
00253    Double_t ChisquareQuantile(Double_t p, Double_t ndf);
00254    Double_t FDist(Double_t F, Double_t N, Double_t M);
00255    Double_t FDistI(Double_t F, Double_t N, Double_t M);
00256    Double_t Gaus(Double_t x, Double_t mean=0, Double_t sigma=1, Bool_t norm=kFALSE);
00257    Double_t KolmogorovProb(Double_t z);
00258    Double_t KolmogorovTest(Int_t na, const Double_t *a, Int_t nb, const Double_t *b, Option_t *option);
00259    Double_t Landau(Double_t x, Double_t mpv=0, Double_t sigma=1, Bool_t norm=kFALSE);
00260    Double_t LandauI(Double_t x);
00261    Double_t LaplaceDist(Double_t x, Double_t alpha=0, Double_t beta=1);
00262    Double_t LaplaceDistI(Double_t x, Double_t alpha=0, Double_t beta=1);
00263    Double_t LogNormal(Double_t x, Double_t sigma, Double_t theta=0, Double_t m=1);
00264    Double_t NormQuantile(Double_t p);
00265    Double_t Poisson(Double_t x, Double_t par);
00266    Double_t PoissonI(Double_t x, Double_t par);
00267    Double_t Prob(Double_t chi2,Int_t ndf);
00268    Double_t Student(Double_t T, Double_t ndf);
00269    Double_t StudentI(Double_t T, Double_t ndf);
00270    Double_t StudentQuantile(Double_t p, Double_t ndf, Bool_t lower_tail=kTRUE);
00271    Double_t Vavilov(Double_t x, Double_t kappa, Double_t beta2);
00272    Double_t VavilovI(Double_t x, Double_t kappa, Double_t beta2);
00273    Double_t Voigt(Double_t x, Double_t sigma, Double_t lg, Int_t R = 4);
00274 
00275    /* ************************** */
00276    /* * Statistics over arrays * */
00277    /* ************************** */
00278 
00279    //Mean, Geometric Mean, Median, RMS(sigma)
00280 
00281    template <typename T> Double_t Mean(Long64_t n, const T *a, const Double_t *w=0);
00282    template <typename Iterator> Double_t Mean(Iterator first, Iterator last);
00283    template <typename Iterator, typename WeightIterator> Double_t Mean(Iterator first, Iterator last, WeightIterator w);
00284 
00285    template <typename T> Double_t GeomMean(Long64_t n, const T *a);
00286    template <typename Iterator> Double_t GeomMean(Iterator first, Iterator last);
00287 
00288    template <typename T> Double_t RMS(Long64_t n, const T *a);
00289    template <typename Iterator> Double_t RMS(Iterator first, Iterator last);
00290 
00291    template <typename T> Double_t Median(Long64_t n, const T *a,  const Double_t *w=0, Long64_t *work=0);
00292 
00293    //k-th order statistic
00294    template <class Element, typename Size> Element KOrdStat(Size n, const Element *a, Size k, Size *work = 0);
00295 
00296    /* ******************* */
00297    /* * Special Functions */
00298    /* ******************* */
00299 
00300    Double_t Beta(Double_t p, Double_t q);
00301    Double_t BetaCf(Double_t x, Double_t a, Double_t b);
00302    Double_t BetaDist(Double_t x, Double_t p, Double_t q);
00303    Double_t BetaDistI(Double_t x, Double_t p, Double_t q);
00304    Double_t BetaIncomplete(Double_t x, Double_t a, Double_t b);
00305 
00306    // Bessel functions
00307    Double_t BesselI(Int_t n,Double_t x);  // integer order modified Bessel function I_n(x)
00308    Double_t BesselK(Int_t n,Double_t x);  // integer order modified Bessel function K_n(x)
00309    Double_t BesselI0(Double_t x);         // modified Bessel function I_0(x)
00310    Double_t BesselK0(Double_t x);         // modified Bessel function K_0(x)
00311    Double_t BesselI1(Double_t x);         // modified Bessel function I_1(x)
00312    Double_t BesselK1(Double_t x);         // modified Bessel function K_1(x)
00313    Double_t BesselJ0(Double_t x);         // Bessel function J0(x) for any real x
00314    Double_t BesselJ1(Double_t x);         // Bessel function J1(x) for any real x
00315    Double_t BesselY0(Double_t x);         // Bessel function Y0(x) for positive x
00316    Double_t BesselY1(Double_t x);         // Bessel function Y1(x) for positive x
00317    Double_t StruveH0(Double_t x);         // Struve functions of order 0
00318    Double_t StruveH1(Double_t x);         // Struve functions of order 1
00319    Double_t StruveL0(Double_t x);         // Modified Struve functions of order 0
00320    Double_t StruveL1(Double_t x);         // Modified Struve functions of order 1
00321 
00322    Double_t DiLog(Double_t x);
00323    Double_t Erf(Double_t x);
00324    Double_t ErfInverse(Double_t x);
00325    Double_t Erfc(Double_t x);
00326    Double_t ErfcInverse(Double_t x);
00327    Double_t Freq(Double_t x);
00328    Double_t Gamma(Double_t z);
00329    Double_t Gamma(Double_t a,Double_t x);
00330    Double_t GammaDist(Double_t x, Double_t gamma, Double_t mu=0, Double_t beta=1);
00331    Double_t LnGamma(Double_t z);
00332 }
00333 
00334 
00335 //---- Trig and other functions ------------------------------------------------
00336 
00337 #include <float.h>
00338 
00339 #if defined(R__WIN32) && !defined(__CINT__)
00340 #   ifndef finite
00341 #      define finite _finite
00342 #      define isnan  _isnan
00343 #   endif
00344 #endif
00345 #if defined(R__AIX) || defined(R__SOLARIS_CC50) || \
00346     defined(R__HPUX11) || defined(R__GLIBC) || \
00347     (defined(R__MACOSX) && (defined(__INTEL_COMPILER) || defined(__arm__)))
00348 // math functions are defined inline so we have to include them here
00349 #   include <math.h>
00350 #   ifdef R__SOLARIS_CC50
00351        extern "C" { int finite(double); }
00352 #   endif
00353 #   if defined(R__GLIBC) && defined(__STRICT_ANSI__)
00354 #      ifndef finite
00355 #         define finite __finite
00356 #      endif
00357 #      ifndef isnan
00358 #         define isnan  __isnan
00359 #      endif
00360 #   endif
00361 #else
00362 // don't want to include complete <math.h>
00363 extern "C" {
00364    extern double sin(double);
00365    extern double cos(double);
00366    extern double tan(double);
00367    extern double sinh(double);
00368    extern double cosh(double);
00369    extern double tanh(double);
00370    extern double asin(double);
00371    extern double acos(double);
00372    extern double atan(double);
00373    extern double atan2(double, double);
00374    extern double sqrt(double);
00375    extern double exp(double);
00376    extern double pow(double, double);
00377    extern double log(double);
00378    extern double log10(double);
00379 #ifndef R__WIN32
00380 #   if !defined(finite)
00381        extern int finite(double);
00382 #   endif
00383 #   if !defined(isnan)
00384        extern int isnan(double);
00385 #   endif
00386    extern double ldexp(double, int);
00387    extern double ceil(double);
00388    extern double floor(double);
00389 #else
00390    _CRTIMP double ldexp(double, int);
00391    _CRTIMP double ceil(double);
00392    _CRTIMP double floor(double);
00393 #endif
00394 }
00395 #endif
00396 
00397 inline Double_t TMath::Sin(Double_t x)
00398    { return sin(x); }
00399 
00400 inline Double_t TMath::Cos(Double_t x)
00401    { return cos(x); }
00402 
00403 inline Double_t TMath::Tan(Double_t x)
00404    { return tan(x); }
00405 
00406 inline Double_t TMath::SinH(Double_t x)
00407    { return sinh(x); }
00408 
00409 inline Double_t TMath::CosH(Double_t x)
00410    { return cosh(x); }
00411 
00412 inline Double_t TMath::TanH(Double_t x)
00413    { return tanh(x); }
00414 
00415 inline Double_t TMath::ASin(Double_t x)
00416    { if (x < -1.) return -TMath::Pi()/2;
00417      if (x >  1.) return  TMath::Pi()/2;
00418      return asin(x);
00419    }
00420 
00421 inline Double_t TMath::ACos(Double_t x)
00422    { if (x < -1.) return TMath::Pi();
00423      if (x >  1.) return 0;
00424      return acos(x);
00425    }
00426 
00427 inline Double_t TMath::ATan(Double_t x)
00428    { return atan(x); }
00429 
00430 inline Double_t TMath::ATan2(Double_t y, Double_t x)
00431    { if (x != 0) return  atan2(y, x);
00432      if (y == 0) return  0;
00433      if (y >  0) return  Pi()/2;
00434      else        return -Pi()/2;
00435    }
00436 
00437 inline Double_t TMath::Sqrt(Double_t x)
00438    { return sqrt(x); }
00439 
00440 inline Double_t TMath::Ceil(Double_t x)
00441    { return ceil(x); }
00442 
00443 inline Int_t TMath::CeilNint(Double_t x)
00444    { return TMath::Nint(ceil(x)); }
00445 
00446 inline Double_t TMath::Floor(Double_t x)
00447    { return floor(x); }
00448 
00449 inline Int_t TMath::FloorNint(Double_t x)
00450    { return TMath::Nint(floor(x)); }
00451 
00452 inline Double_t TMath::Exp(Double_t x)
00453    { return exp(x); }
00454 
00455 inline Double_t TMath::Ldexp(Double_t x, Int_t exp)
00456    { return ldexp(x, exp); }
00457 
00458 inline Double_t TMath::Power(Double_t x, Double_t y)
00459    { return pow(x, y); }
00460 
00461 inline Double_t TMath::Log(Double_t x)
00462    { return log(x); }
00463 
00464 inline Double_t TMath::Log10(Double_t x)
00465    { return log10(x); }
00466 
00467 inline Int_t TMath::Finite(Double_t x)
00468 #if defined(R__HPUX11)
00469    { return isfinite(x); }
00470 #elif defined(R__MACOSX) && defined(__arm__)
00471 #ifdef isfinite
00472    // from math.h
00473    { return isfinite(x); }
00474 #else
00475    // from cmath
00476    { return std::isfinite(x); }
00477 #endif
00478 #else
00479    { return finite(x); }
00480 #endif
00481 
00482 inline Int_t TMath::IsNaN(Double_t x)
00483 #if defined(R__MACOSX) && defined(__arm__)
00484 #ifdef isnan
00485    // from math.h
00486    { return isnan(x); }
00487 #else
00488    // from cmath
00489    { return std::isnan(x); }
00490 #endif
00491 #else
00492    { return isnan(x); }
00493 #endif
00494 
00495 //-------- Advanced -------------
00496 
00497 template <typename T> inline T TMath::NormCross(const T v1[3],const T v2[3],T out[3])
00498 {
00499    // Calculate the Normalized Cross Product of two vectors
00500    return Normalize(Cross(v1,v2,out));
00501 }
00502 
00503 template <typename T>
00504 T TMath::MinElement(Long64_t n, const T *a) {
00505    // Return minimum of array a of length n.
00506 
00507    return *std::min_element(a,a+n);
00508 }
00509 
00510 template <typename T>
00511 T TMath::MaxElement(Long64_t n, const T *a) {
00512    // Return maximum of array a of length n.
00513 
00514    return *std::max_element(a,a+n);
00515 }
00516 
00517 template <typename T>
00518 Long64_t TMath::LocMin(Long64_t n, const T *a) {
00519    // Return index of array with the minimum element.
00520    // If more than one element is minimum returns first found.
00521 
00522    // Implement here since this one is found to be faster (mainly on 64 bit machines)
00523    // than stl generic implementation.
00524    // When performing the comparison,  the STL implementation needs to de-reference both the array iterator
00525    // and the iterator pointing to the resulting minimum location
00526 
00527    if  (n <= 0 || !a) return -1;
00528    T xmin = a[0];
00529    Long64_t loc = 0;
00530    for  (Long64_t i = 1; i < n; i++) {
00531       if (xmin > a[i])  {
00532          xmin = a[i];
00533          loc = i;
00534       }
00535    }
00536    return loc;
00537 }
00538 
00539 template <typename Iterator>
00540 Iterator TMath::LocMin(Iterator first, Iterator last) {
00541    // Return index of array with the minimum element.
00542    // If more than one element is minimum returns first found.
00543    return std::min_element(first, last);
00544 }
00545 
00546 template <typename T>
00547 Long64_t TMath::LocMax(Long64_t n, const T *a) {
00548    // Return index of array with the maximum element.
00549    // If more than one element is maximum returns first found.
00550 
00551    // Implement here since it is faster (see comment in LocMin function)
00552 
00553    if  (n <= 0 || !a) return -1;
00554    T xmax = a[0];
00555    Long64_t loc = 0;
00556    for  (Long64_t i = 1; i < n; i++) {
00557       if (xmax < a[i])  {
00558          xmax = a[i];
00559          loc = i;
00560       }
00561    }
00562    return loc;
00563 }
00564 
00565 template <typename Iterator>
00566 Iterator TMath::LocMax(Iterator first, Iterator last)
00567 {
00568    // Return index of array with the maximum element.
00569    // If more than one element is maximum returns first found.
00570 
00571    return std::max_element(first, last);
00572 }
00573 
00574 template<typename T>
00575 struct CompareDesc {
00576 
00577    CompareDesc(T d) : fData(d) {}
00578 
00579    template<typename Index>
00580    bool operator()(Index i1, Index i2) {
00581       return *(fData + i1) > *(fData + i2);
00582    }
00583 
00584    T fData;
00585 };
00586 
00587 template<typename T>
00588 struct CompareAsc {
00589 
00590    CompareAsc(T d) : fData(d) {}
00591 
00592    template<typename Index>
00593    bool operator()(Index i1, Index i2) {
00594       return *(fData + i1) < *(fData + i2);
00595    }
00596 
00597    T fData;
00598 };
00599 
00600 template <typename Iterator>
00601 Double_t TMath::Mean(Iterator first, Iterator last)
00602 {
00603    // Return the weighted mean of an array defined by the iterators.
00604 
00605    Double_t sum = 0;
00606    Double_t sumw = 0;
00607    while ( first != last )
00608    {
00609       sum += *first;
00610       sumw += 1;
00611       first++;
00612    }
00613 
00614    return sum/sumw;
00615 }
00616 
00617 template <typename Iterator, typename WeightIterator>
00618 Double_t TMath::Mean(Iterator first, Iterator last, WeightIterator w)
00619 {
00620    // Return the weighted mean of an array defined by the first and
00621    // last iterators. The w iterator should point to the first element
00622    // of a vector of weights of the same size as the main array.
00623 
00624    Double_t sum = 0;
00625    Double_t sumw = 0;
00626    int i = 0;
00627    while ( first != last ) {
00628       if ( *w < 0) {
00629          ::Error("TMath::Mean","w[%d] = %.4e < 0 ?!",i,*w);
00630          return 0;
00631       }
00632       sum  += (*w) * (*first);
00633       sumw += (*w) ;
00634       ++w;
00635       ++first;
00636       ++i;
00637    }
00638    if (sumw <= 0) {
00639       ::Error("TMath::Mean","sum of weights == 0 ?!");
00640       return 0;
00641    }
00642 
00643    return sum/sumw;
00644 }
00645 
00646 template <typename T>
00647 Double_t TMath::Mean(Long64_t n, const T *a, const Double_t *w)
00648 {
00649    // Return the weighted mean of an array a with length n.
00650 
00651    if (w) {
00652       return TMath::Mean(a, a+n, w);
00653    } else {
00654       return TMath::Mean(a, a+n);
00655    }
00656 }
00657 
00658 template <typename Iterator>
00659 Double_t TMath::GeomMean(Iterator first, Iterator last)
00660 {
00661    // Return the geometric mean of an array defined by the iterators.
00662    // geometric_mean = (Prod_i=0,n-1 |a[i]|)^1/n
00663 
00664    Double_t logsum = 0.;
00665    Long64_t n = 0;
00666    while ( first != last ) {
00667       if (*first == 0) return 0.;
00668       Double_t absa = (Double_t) TMath::Abs(*first);
00669       logsum += TMath::Log(absa);
00670       ++first;
00671       ++n;
00672    }
00673 
00674    return TMath::Exp(logsum/n);
00675 }
00676 
00677 template <typename T>
00678 Double_t TMath::GeomMean(Long64_t n, const T *a)
00679 {
00680    // Return the geometric mean of an array a of size n.
00681    // geometric_mean = (Prod_i=0,n-1 |a[i]|)^1/n
00682 
00683    return TMath::GeomMean(a, a+n);
00684 }
00685 
00686 template <typename Iterator>
00687 Double_t TMath::RMS(Iterator first, Iterator last)
00688 {
00689    // Return the Standard Deviation of an array defined by the iterators.
00690    // Note that this function returns the sigma(standard deviation) and
00691    // not the root mean square of the array.
00692 
00693    Double_t n = 0;
00694 
00695    Double_t tot = 0, tot2 =0, adouble;
00696    while ( first != last ) {
00697       adouble=Double_t(*first);
00698       tot += adouble; tot2 += adouble*adouble;
00699       ++first;
00700       ++n;
00701    }
00702    Double_t n1 = 1./n;
00703    Double_t mean = tot*n1;
00704    Double_t rms = TMath::Sqrt(TMath::Abs(tot2*n1 -mean*mean));
00705    return rms;
00706 }
00707 
00708 template <typename T>
00709 Double_t TMath::RMS(Long64_t n, const T *a)
00710 {
00711    // Return the Standard Deviation of an array a with length n.
00712    // Note that this function returns the sigma(standard deviation) and
00713    // not the root mean square of the array.
00714 
00715    return TMath::RMS(a, a+n);
00716 }
00717 
00718 template <typename Iterator, typename Element>
00719 Iterator TMath::BinarySearch(Iterator first, Iterator last, Element value)
00720 {
00721    // Binary search in an array defined by its iterators.
00722    //
00723    // The values in the iterators range are supposed to be sorted
00724    // prior to this call.  If match is found, function returns
00725    // position of element.  If no match found, function gives nearest
00726    // element smaller than value.
00727 
00728    Iterator pind;
00729    pind = std::lower_bound(first, last, value);
00730    if ( (pind != last) && (*pind == value) )
00731       return pind;
00732    else
00733       return ( pind - 1);
00734 }
00735 
00736 
00737 template <typename T> Long64_t TMath::BinarySearch(Long64_t n, const T  *array, T value)
00738 {
00739    // Binary search in an array of n values to locate value.
00740    //
00741    // Array is supposed  to be sorted prior to this call.
00742    // If match is found, function returns position of element.
00743    // If no match found, function gives nearest element smaller than value.
00744 
00745    const T* pind;
00746    pind = std::lower_bound(array, array + n, value);
00747    if ( (pind != array + n) && (*pind == value) )
00748       return (pind - array);
00749    else
00750       return ( pind - array - 1);
00751 }
00752 
00753 template <typename T> Long64_t TMath::BinarySearch(Long64_t n, const T **array, T value)
00754 {
00755    // Binary search in an array of n values to locate value.
00756    //
00757    // Array is supposed  to be sorted prior to this call.
00758    // If match is found, function returns position of element.
00759    // If no match found, function gives nearest element smaller than value.
00760 
00761    const T* pind;
00762    pind = std::lower_bound(*array, *array + n, value);
00763    if ( (pind != *array + n) && (*pind == value) )
00764       return (pind - *array);
00765    else
00766       return ( pind - *array - 1);
00767 }
00768 
00769 template <typename Iterator, typename IndexIterator>
00770 void TMath::SortItr(Iterator first, Iterator last, IndexIterator index, Bool_t down)
00771 {
00772    // Sort the n1 elements of the Short_t array defined by its
00773    // iterators.  In output the array index contains the indices of
00774    // the sorted array.  If down is false sort in increasing order
00775    // (default is decreasing order).
00776 
00777    // NOTE that the array index must be created with a length bigger
00778    // or equal than the main array before calling this function.
00779 
00780    int i = 0;
00781 
00782    IndexIterator cindex = index;
00783    for ( Iterator cfirst = first; cfirst != last; ++cfirst )
00784    {
00785       *cindex = i++;
00786       ++cindex;
00787    }
00788 
00789    if ( down )
00790       std::sort(index, cindex, CompareDesc<Iterator>(first) );
00791    else
00792       std::sort(index, cindex, CompareAsc<Iterator>(first) );
00793 }
00794 
00795 template <typename Element, typename Index> void TMath::Sort(Index n, const Element* a, Index* index, Bool_t down)
00796 {
00797    // Sort the n elements of the  array a of generic templated type Element.
00798    // In output the array index of type Index contains the indices of the sorted array.
00799    // If down is false sort in increasing order (default is decreasing order).
00800 
00801    // NOTE that the array index must be created with a length >= n
00802    // before calling this function.
00803    // NOTE also that the size type for n must be the same type used for the index array
00804    // (templated type Index)
00805 
00806    for(Index i = 0; i < n; i++) { index[i] = i; }
00807    if ( down )
00808       std::sort(index, index + n, CompareDesc<const Element*>(a) );
00809    else
00810       std::sort(index, index + n, CompareAsc<const Element*>(a) );
00811 }
00812 
00813 template <typename T> T *TMath::Cross(const T v1[3],const T v2[3], T out[3])
00814 {
00815    // Calculate the Cross Product of two vectors:
00816    //         out = [v1 x v2]
00817 
00818    out[0] = v1[1] * v2[2] - v1[2] * v2[1];
00819    out[1] = v1[2] * v2[0] - v1[0] * v2[2];
00820    out[2] = v1[0] * v2[1] - v1[1] * v2[0];
00821 
00822    return out;
00823 }
00824 
00825 template <typename T> T * TMath::Normal2Plane(const T p1[3],const T p2[3],const T p3[3], T normal[3])
00826 {
00827    // Calculate a normal vector of a plane.
00828    //
00829    //  Input:
00830    //     Float_t *p1,*p2,*p3  -  3 3D points belonged the plane to define it.
00831    //
00832    //  Return:
00833    //     Pointer to 3D normal vector (normalized)
00834 
00835    T v1[3], v2[3];
00836 
00837    v1[0] = p2[0] - p1[0];
00838    v1[1] = p2[1] - p1[1];
00839    v1[2] = p2[2] - p1[2];
00840 
00841    v2[0] = p3[0] - p1[0];
00842    v2[1] = p3[1] - p1[1];
00843    v2[2] = p3[2] - p1[2];
00844 
00845    NormCross(v1,v2,normal);
00846    return normal;
00847 }
00848 
00849 template <typename T> Bool_t TMath::IsInside(T xp, T yp, Int_t np, T *x, T *y)
00850 {
00851    // Function which returns kTRUE if point xp,yp lies inside the
00852    // polygon defined by the np points in arrays x and y, kFALSE otherwise.
00853    // Note that the polygon may be open or closed.
00854 
00855    Int_t i, j = np-1 ;
00856    Bool_t oddNodes = kFALSE;
00857 
00858    for (i=0; i<np; i++) {
00859       if ((y[i]<yp && y[j]>=yp) || (y[j]<yp && y[i]>=yp)) {
00860          if (x[i]+(yp-y[i])/(y[j]-y[i])*(x[j]-x[i])<xp) {
00861             oddNodes = !oddNodes;
00862          }
00863       }
00864       j=i;
00865    }
00866 
00867    return oddNodes;
00868 }
00869 
00870 template <typename T> Double_t TMath::Median(Long64_t n, const T *a,  const Double_t *w, Long64_t *work)
00871 {
00872    // Return the median of the array a where each entry i has weight w[i] .
00873    // Both arrays have a length of at least n . The median is a number obtained
00874    // from the sorted array a through
00875    //
00876    // median = (a[jl]+a[jh])/2.  where (using also the sorted index on the array w)
00877    //
00878    // sum_i=0,jl w[i] <= sumTot/2
00879    // sum_i=0,jh w[i] >= sumTot/2
00880    // sumTot = sum_i=0,n w[i]
00881    //
00882    // If w=0, the algorithm defaults to the median definition where it is
00883    // a number that divides the sorted sequence into 2 halves.
00884    // When n is odd or n > 1000, the median is kth element k = (n + 1) / 2.
00885    // when n is even and n < 1000the median is a mean of the elements k = n/2 and k = n/2 + 1.
00886    //
00887    // If the weights are supplied (w not 0) all weights must be >= 0
00888    //
00889    // If work is supplied, it is used to store the sorting index and assumed to be
00890    // >= n . If work=0, local storage is used, either on the stack if n < kWorkMax
00891    // or on the heap for n >= kWorkMax .
00892 
00893    const Int_t kWorkMax = 100;
00894 
00895    if (n <= 0 || !a) return 0;
00896    Bool_t isAllocated = kFALSE;
00897    Double_t median;
00898    Long64_t *ind;
00899    Long64_t workLocal[kWorkMax];
00900 
00901    if (work) {
00902       ind = work;
00903    } else {
00904       ind = workLocal;
00905       if (n > kWorkMax) {
00906          isAllocated = kTRUE;
00907          ind = new Long64_t[n];
00908       }
00909    }
00910 
00911    if (w) {
00912       Double_t sumTot2 = 0;
00913       for (Int_t j = 0; j < n; j++) {
00914          if (w[j] < 0) {
00915             ::Error("TMath::Median","w[%d] = %.4e < 0 ?!",j,w[j]);
00916             if (isAllocated)  delete [] ind;
00917             return 0;
00918          }
00919          sumTot2 += w[j];
00920       }
00921 
00922       sumTot2 /= 2.;
00923 
00924       Sort(n, a, ind, kFALSE);
00925 
00926       Double_t sum = 0.;
00927       Int_t jl;
00928       for (jl = 0; jl < n; jl++) {
00929          sum += w[ind[jl]];
00930          if (sum >= sumTot2) break;
00931       }
00932 
00933       Int_t jh;
00934       sum = 2.*sumTot2;
00935       for (jh = n-1; jh >= 0; jh--) {
00936          sum -= w[ind[jh]];
00937          if (sum <= sumTot2) break;
00938       }
00939 
00940       median = 0.5*(a[ind[jl]]+a[ind[jh]]);
00941 
00942    } else {
00943 
00944       if (n%2 == 1)
00945          median = KOrdStat(n, a,n/2, ind);
00946       else {
00947          median = 0.5*(KOrdStat(n, a, n/2 -1, ind)+KOrdStat(n, a, n/2, ind));
00948       }
00949    }
00950 
00951    if (isAllocated)
00952       delete [] ind;
00953    return median;
00954 }
00955 
00956 
00957 
00958 
00959 template <class Element, typename Size>
00960 Element TMath::KOrdStat(Size n, const Element *a, Size k, Size *work)
00961 {
00962    // Returns k_th order statistic of the array a of size n
00963    // (k_th smallest element out of n elements).
00964    //
00965    // C-convention is used for array indexing, so if you want
00966    // the second smallest element, call KOrdStat(n, a, 1).
00967    //
00968    // If work is supplied, it is used to store the sorting index and
00969    // assumed to be >= n. If work=0, local storage is used, either on
00970    // the stack if n < kWorkMax or on the heap for n >= kWorkMax.
00971    //
00972    // Taken from "Numerical Recipes in C++" without the index array
00973    // implemented by Anna Khreshuk.
00974    //
00975    // See also the declarations at the top of this file
00976 
00977    const Int_t kWorkMax = 100;
00978 
00979    typedef Size Index;
00980 
00981    Bool_t isAllocated = kFALSE;
00982    Size i, ir, j, l, mid;
00983    Index arr;
00984    Index *ind;
00985    Index workLocal[kWorkMax];
00986    Index temp;
00987 
00988    if (work) {
00989       ind = work;
00990    } else {
00991       ind = workLocal;
00992       if (n > kWorkMax) {
00993          isAllocated = kTRUE;
00994          ind = new Index[n];
00995       }
00996    }
00997 
00998    for (Size ii=0; ii<n; ii++) {
00999       ind[ii]=ii;
01000    }
01001    Size rk = k;
01002    l=0;
01003    ir = n-1;
01004    for(;;) {
01005       if (ir<=l+1) { //active partition contains 1 or 2 elements
01006          if (ir == l+1 && a[ind[ir]]<a[ind[l]])
01007             {temp = ind[l]; ind[l]=ind[ir]; ind[ir]=temp;}
01008          Element tmp = a[ind[rk]];
01009          if (isAllocated)
01010             delete [] ind;
01011          return tmp;
01012       } else {
01013          mid = (l+ir) >> 1; //choose median of left, center and right
01014          {temp = ind[mid]; ind[mid]=ind[l+1]; ind[l+1]=temp;}//elements as partitioning element arr.
01015          if (a[ind[l]]>a[ind[ir]])  //also rearrange so that a[l]<=a[l+1]
01016             {temp = ind[l]; ind[l]=ind[ir]; ind[ir]=temp;}
01017 
01018          if (a[ind[l+1]]>a[ind[ir]])
01019             {temp=ind[l+1]; ind[l+1]=ind[ir]; ind[ir]=temp;}
01020 
01021          if (a[ind[l]]>a[ind[l+1]])
01022             {temp = ind[l]; ind[l]=ind[l+1]; ind[l+1]=temp;}
01023 
01024          i=l+1;        //initialize pointers for partitioning
01025          j=ir;
01026          arr = ind[l+1];
01027          for (;;){
01028             do i++; while (a[ind[i]]<a[arr]);
01029             do j--; while (a[ind[j]]>a[arr]);
01030             if (j<i) break;  //pointers crossed, partitioning complete
01031                {temp=ind[i]; ind[i]=ind[j]; ind[j]=temp;}
01032          }
01033          ind[l+1]=ind[j];
01034          ind[j]=arr;
01035          if (j>=rk) ir = j-1; //keep active the partition that
01036          if (j<=rk) l=i;      //contains the k_th element
01037       }
01038    }
01039 }
01040 
01041 #endif

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