1 // @(#)root/mathcore:$Id$ 2 // Authors: Rene Brun, Anna Kreshuk, Eddy Offermann, Fons Rademakers 29/07/95 3 4 /************************************************************************* 5 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. * 6 * All rights reserved. * 7 * * 8 * For the licensing terms see $ROOTSYS/LICENSE. * 9 * For the list of contributors see $ROOTSYS/README/CREDITS. * 10 *************************************************************************/ 11 12 #ifndef ROOT_TMath 13 #define ROOT_TMath 14 15 16 ////////////////////////////////////////////////////////////////////////// 17 // // 18 // TMath // 19 // // 20 // Encapsulate most frequently used Math functions. // 21 // NB. The basic functions Min, Max, Abs and Sign are defined // 22 // in TMathBase. // 23 // // 24 ////////////////////////////////////////////////////////////////////////// 25 26 #ifndef ROOT_Rtypes 27 #include "Rtypes.h" 28 #endif 29 #ifndef ROOT_TMathBase 30 #include "TMathBase.h" 31 #endif 32 33 #include "TError.h" 34 #include <algorithm> 35 #include <limits> 36 #include <cmath> 37 38 namespace TMath { 39 40 /* ************************* */ 41 /* * Fundamental constants * */ 42 /* ************************* */ 43 44 inline Double_t Pi() { return 3.14159265358979323846; } 45 inline Double_t TwoPi() { return 2.0 * Pi(); } 46 inline Double_t PiOver2() { return Pi() / 2.0; } 47 inline Double_t PiOver4() { return Pi() / 4.0; } 48 inline Double_t InvPi() { return 1.0 / Pi(); } 49 inline Double_t RadToDeg() { return 180.0 / Pi(); } 50 inline Double_t DegToRad() { return Pi() / 180.0; } 51 inline Double_t Sqrt2() { return 1.4142135623730950488016887242097; } 52 53 // e (base of natural log) 54 inline Double_t E() { return 2.71828182845904523536; } 55 56 // natural log of 10 (to convert log to ln) 57 inline Double_t Ln10() { return 2.30258509299404568402; } 58 59 // base-10 log of e (to convert ln to log) 60 inline Double_t LogE() { return 0.43429448190325182765; } 61 62 // velocity of light 63 inline Double_t C() { return 2.99792458e8; } // m s^-1 64 inline Double_t Ccgs() { return 100.0 * C(); } // cm s^-1 65 inline Double_t CUncertainty() { return 0.0; } // exact 66 67 // gravitational constant 68 inline Double_t G() { return 6.673e-11; } // m^3 kg^-1 s^-2 69 inline Double_t Gcgs() { return G() / 1000.0; } // cm^3 g^-1 s^-2 70 inline Double_t GUncertainty() { return 0.010e-11; } 71 72 // G over h-bar C 73 inline Double_t GhbarC() { return 6.707e-39; } // (GeV/c^2)^-2 74 inline Double_t GhbarCUncertainty() { return 0.010e-39; } 75 76 // standard acceleration of gravity 77 inline Double_t Gn() { return 9.80665; } // m s^-2 78 inline Double_t GnUncertainty() { return 0.0; } // exact 79 80 // Planck's constant 81 inline Double_t H() { return 6.62606876e-34; } // J s 82 inline Double_t Hcgs() { return 1.0e7 * H(); } // erg s 83 inline Double_t HUncertainty() { return 0.00000052e-34; } 84 85 // h-bar (h over 2 pi) 86 inline Double_t Hbar() { return 1.054571596e-34; } // J s 87 inline Double_t Hbarcgs() { return 1.0e7 * Hbar(); } // erg s 88 inline Double_t HbarUncertainty() { return 0.000000082e-34; } 89 90 // hc (h * c) 91 inline Double_t HC() { return H() * C(); } // J m 92 inline Double_t HCcgs() { return Hcgs() * Ccgs(); } // erg cm 93 94 // Boltzmann's constant 95 inline Double_t K() { return 1.3806503e-23; } // J K^-1 96 inline Double_t Kcgs() { return 1.0e7 * K(); } // erg K^-1 97 inline Double_t KUncertainty() { return 0.0000024e-23; } 98 99 // Stefan-Boltzmann constant 100 inline Double_t Sigma() { return 5.6704e-8; } // W m^-2 K^-4 101 inline Double_t SigmaUncertainty() { return 0.000040e-8; } 102 103 // Avogadro constant (Avogadro's Number) 104 inline Double_t Na() { return 6.02214199e+23; } // mol^-1 105 inline Double_t NaUncertainty() { return 0.00000047e+23; } 106 107 // universal gas constant (Na * K) 108 // http://scienceworld.wolfram.com/physics/UniversalGasConstant.html 109 inline Double_t R() { return K() * Na(); } // J K^-1 mol^-1 110 inline Double_t RUncertainty() { return R()*((KUncertainty()/K()) + (NaUncertainty()/Na())); } 111 112 // Molecular weight of dry air 113 // 1976 US Standard Atmosphere, 114 // also see http://atmos.nmsu.edu/jsdap/encyclopediawork.html 115 inline Double_t MWair() { return 28.9644; } // kg kmol^-1 (or gm mol^-1) 116 117 // Dry Air Gas Constant (R / MWair) 118 // http://atmos.nmsu.edu/education_and_outreach/encyclopedia/gas_constant.htm 119 inline Double_t Rgair() { return (1000.0 * R()) / MWair(); } // J kg^-1 K^-1 120 121 // Euler-Mascheroni Constant 122 inline Double_t EulerGamma() { return 0.577215664901532860606512090082402431042; } 123 124 // Elementary charge 125 inline Double_t Qe() { return 1.602176462e-19; } // C 126 inline Double_t QeUncertainty() { return 0.000000063e-19; } 127 128 /* ************************** */ 129 /* * Mathematical Functions * */ 130 /* ************************** */ 131 132 /* ***************************** */ 133 /* * Trigonometrical Functions * */ 134 /* ***************************** */ 135 inline Double_t Sin(Double_t); 136 inline Double_t Cos(Double_t); 137 inline Double_t Tan(Double_t); 138 inline Double_t SinH(Double_t); 139 inline Double_t CosH(Double_t); 140 inline Double_t TanH(Double_t); 141 inline Double_t ASin(Double_t); 142 inline Double_t ACos(Double_t); 143 inline Double_t ATan(Double_t); 144 inline Double_t ATan2(Double_t, Double_t); 145 Double_t ASinH(Double_t); 146 Double_t ACosH(Double_t); 147 Double_t ATanH(Double_t); 148 Double_t Hypot(Double_t x, Double_t y); 149 150 151 /* ************************ */ 152 /* * Elementary Functions * */ 153 /* ************************ */ 154 inline Double_t Ceil(Double_t x); 155 inline Int_t CeilNint(Double_t x); 156 inline Double_t Floor(Double_t x); 157 inline Int_t FloorNint(Double_t x); 158 template<typename T> 159 inline Int_t Nint(T x); 160 161 inline Double_t Sqrt(Double_t x); 162 inline Double_t Exp(Double_t x); 163 inline Double_t Ldexp(Double_t x, Int_t exp); 164 Double_t Factorial(Int_t i); 165 inline LongDouble_t Power(LongDouble_t x, LongDouble_t y); 166 inline LongDouble_t Power(LongDouble_t x, Long64_t y); 167 inline LongDouble_t Power(Long64_t x, Long64_t y); 168 inline Double_t Power(Double_t x, Double_t y); 169 inline Double_t Power(Double_t x, Int_t y); 170 inline Double_t Log(Double_t x); 171 Double_t Log2(Double_t x); 172 inline Double_t Log10(Double_t x); 173 inline Int_t Finite(Double_t x); 174 inline Int_t IsNaN(Double_t x); 175 176 inline Double_t QuietNaN(); 177 inline Double_t SignalingNaN(); 178 inline Double_t Infinity(); 179 180 template <typename T> 181 struct Limits { 182 inline static T Min(); 183 inline static T Max(); 184 inline static T Epsilon(); 185 }; 186 187 // Some integer math 188 Long_t Hypot(Long_t x, Long_t y); // sqrt(px*px + py*py) 189 190 // Comparing floating points 191 inline Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon) { 192 //return kTRUE if absolute difference between af and bf is less than epsilon 193 return TMath::Abs(af-bf) < epsilon; 194 } 195 inline Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec) { 196 //return kTRUE if relative difference between af and bf is less than relPrec 197 return TMath::Abs(af-bf) <= 0.5*relPrec*(TMath::Abs(af)+TMath::Abs(bf)); 198 } 199 200 /* ******************** */ 201 /* * Array Algorithms * */ 202 /* ******************** */ 203 204 // Min, Max of an array 205 template <typename T> T MinElement(Long64_t n, const T *a); 206 template <typename T> T MaxElement(Long64_t n, const T *a); 207 208 // Locate Min, Max element number in an array 209 template <typename T> Long64_t LocMin(Long64_t n, const T *a); 210 template <typename Iterator> Iterator LocMin(Iterator first, Iterator last); 211 template <typename T> Long64_t LocMax(Long64_t n, const T *a); 212 template <typename Iterator> Iterator LocMax(Iterator first, Iterator last); 213 214 // Binary search 215 template <typename T> Long64_t BinarySearch(Long64_t n, const T *array, T value); 216 template <typename T> Long64_t BinarySearch(Long64_t n, const T **array, T value); 217 template <typename Iterator, typename Element> Iterator BinarySearch(Iterator first, Iterator last, Element value); 218 219 // Hashing 220 ULong_t Hash(const void *txt, Int_t ntxt); 221 ULong_t Hash(const char *str); 222 223 // Sorting 224 template <typename Element, typename Index> 225 void Sort(Index n, const Element* a, Index* index, Bool_t down=kTRUE); 226 template <typename Iterator, typename IndexIterator> 227 void SortItr(Iterator first, Iterator last, IndexIterator index, Bool_t down=kTRUE); 228 229 void BubbleHigh(Int_t Narr, Double_t *arr1, Int_t *arr2); 230 void BubbleLow (Int_t Narr, Double_t *arr1, Int_t *arr2); 231 232 Bool_t Permute(Int_t n, Int_t *a); // Find permutations 233 234 /* ************************* */ 235 /* * Geometrical Functions * */ 236 /* ************************* */ 237 238 //Sample quantiles 239 void Quantiles(Int_t n, Int_t nprob, Double_t *x, Double_t *quantiles, Double_t *prob, 240 Bool_t isSorted=kTRUE, Int_t *index = 0, Int_t type=7); 241 242 // IsInside 243 template <typename T> Bool_t IsInside(T xp, T yp, Int_t np, T *x, T *y); 244 245 // Calculate the Cross Product of two vectors 246 template <typename T> T *Cross(const T v1[3],const T v2[3], T out[3]); 247 248 Float_t Normalize(Float_t v[3]); // Normalize a vector 249 Double_t Normalize(Double_t v[3]); // Normalize a vector 250 251 //Calculate the Normalized Cross Product of two vectors 252 template <typename T> inline T NormCross(const T v1[3],const T v2[3],T out[3]); 253 254 // Calculate a normal vector of a plane 255 template <typename T> T *Normal2Plane(const T v1[3],const T v2[3],const T v3[3], T normal[3]); 256 257 /* ************************ */ 258 /* * Polynomial Functions * */ 259 /* ************************ */ 260 261 Bool_t RootsCubic(const Double_t coef[4],Double_t &a, Double_t &b, Double_t &c); 262 263 /* *********************** */ 264 /* * Statistic Functions * */ 265 /* *********************** */ 266 267 Double_t Binomial(Int_t n,Int_t k); // Calculate the binomial coefficient n over k 268 Double_t BinomialI(Double_t p, Int_t n, Int_t k); 269 Double_t BreitWigner(Double_t x, Double_t mean=0, Double_t gamma=1); 270 Double_t CauchyDist(Double_t x, Double_t t=0, Double_t s=1); 271 Double_t ChisquareQuantile(Double_t p, Double_t ndf); 272 Double_t FDist(Double_t F, Double_t N, Double_t M); 273 Double_t FDistI(Double_t F, Double_t N, Double_t M); 274 Double_t Gaus(Double_t x, Double_t mean=0, Double_t sigma=1, Bool_t norm=kFALSE); 275 Double_t KolmogorovProb(Double_t z); 276 Double_t KolmogorovTest(Int_t na, const Double_t *a, Int_t nb, const Double_t *b, Option_t *option); 277 Double_t Landau(Double_t x, Double_t mpv=0, Double_t sigma=1, Bool_t norm=kFALSE); 278 Double_t LandauI(Double_t x); 279 Double_t LaplaceDist(Double_t x, Double_t alpha=0, Double_t beta=1); 280 Double_t LaplaceDistI(Double_t x, Double_t alpha=0, Double_t beta=1); 281 Double_t LogNormal(Double_t x, Double_t sigma, Double_t theta=0, Double_t m=1); 282 Double_t NormQuantile(Double_t p); 283 Double_t Poisson(Double_t x, Double_t par); 284 Double_t PoissonI(Double_t x, Double_t par); 285 Double_t Prob(Double_t chi2,Int_t ndf); 286 Double_t Student(Double_t T, Double_t ndf); 287 Double_t StudentI(Double_t T, Double_t ndf); 288 Double_t StudentQuantile(Double_t p, Double_t ndf, Bool_t lower_tail=kTRUE); 289 Double_t Vavilov(Double_t x, Double_t kappa, Double_t beta2); 290 Double_t VavilovI(Double_t x, Double_t kappa, Double_t beta2); 291 Double_t Voigt(Double_t x, Double_t sigma, Double_t lg, Int_t r = 4); 292 293 /* ************************** */ 294 /* * Statistics over arrays * */ 295 /* ************************** */ 296 297 //Mean, Geometric Mean, Median, RMS(sigma) 298 299 template <typename T> Double_t Mean(Long64_t n, const T *a, const Double_t *w=0); 300 template <typename Iterator> Double_t Mean(Iterator first, Iterator last); 301 template <typename Iterator, typename WeightIterator> Double_t Mean(Iterator first, Iterator last, WeightIterator wfirst); 302 303 template <typename T> Double_t GeomMean(Long64_t n, const T *a); 304 template <typename Iterator> Double_t GeomMean(Iterator first, Iterator last); 305 306 template <typename T> Double_t RMS(Long64_t n, const T *a, const Double_t *w=0); 307 template <typename Iterator> Double_t RMS(Iterator first, Iterator last); 308 template <typename Iterator, typename WeightIterator> Double_t RMS(Iterator first, Iterator last, WeightIterator wfirst); 309 310 template <typename T> Double_t StdDev(Long64_t n, const T *a, const Double_t * w = 0) { return RMS<T>(n,a,w); } 311 template <typename Iterator> Double_t StdDev(Iterator first, Iterator last) { return RMS<Iterator>(first,last); } 312 template <typename Iterator, typename WeightIterator> Double_t StdDev(Iterator first, Iterator last, WeightIterator wfirst) { return RMS<Iterator,WeightIterator>(first,last,wfirst); } 313 314 template <typename T> Double_t Median(Long64_t n, const T *a, const Double_t *w=0, Long64_t *work=0); 315 316 //k-th order statistic 317 template <class Element, typename Size> Element KOrdStat(Size n, const Element *a, Size k, Size *work = 0); 318 319 /* ******************* */ 320 /* * Special Functions */ 321 /* ******************* */ 322 323 Double_t Beta(Double_t p, Double_t q); 324 Double_t BetaCf(Double_t x, Double_t a, Double_t b); 325 Double_t BetaDist(Double_t x, Double_t p, Double_t q); 326 Double_t BetaDistI(Double_t x, Double_t p, Double_t q); 327 Double_t BetaIncomplete(Double_t x, Double_t a, Double_t b); 328 329 // Bessel functions 330 Double_t BesselI(Int_t n,Double_t x); // integer order modified Bessel function I_n(x) 331 Double_t BesselK(Int_t n,Double_t x); // integer order modified Bessel function K_n(x) 332 Double_t BesselI0(Double_t x); // modified Bessel function I_0(x) 333 Double_t BesselK0(Double_t x); // modified Bessel function K_0(x) 334 Double_t BesselI1(Double_t x); // modified Bessel function I_1(x) 335 Double_t BesselK1(Double_t x); // modified Bessel function K_1(x) 336 Double_t BesselJ0(Double_t x); // Bessel function J0(x) for any real x 337 Double_t BesselJ1(Double_t x); // Bessel function J1(x) for any real x 338 Double_t BesselY0(Double_t x); // Bessel function Y0(x) for positive x 339 Double_t BesselY1(Double_t x); // Bessel function Y1(x) for positive x 340 Double_t StruveH0(Double_t x); // Struve functions of order 0 341 Double_t StruveH1(Double_t x); // Struve functions of order 1 342 Double_t StruveL0(Double_t x); // Modified Struve functions of order 0 343 Double_t StruveL1(Double_t x); // Modified Struve functions of order 1 344 345 Double_t DiLog(Double_t x); 346 Double_t Erf(Double_t x); 347 Double_t ErfInverse(Double_t x); 348 Double_t Erfc(Double_t x); 349 Double_t ErfcInverse(Double_t x); 350 Double_t Freq(Double_t x); 351 Double_t Gamma(Double_t z); 352 Double_t Gamma(Double_t a,Double_t x); 353 Double_t GammaDist(Double_t x, Double_t gamma, Double_t mu=0, Double_t beta=1); 354 Double_t LnGamma(Double_t z); 355 } 356 357 358 //---- Trig and other functions ------------------------------------------------ 359 360 #include <float.h> 361 362 #if defined(R__WIN32) && !defined(__CINT__) 363 # ifndef finite 364 # define finite _finite 365 # define isnan _isnan 366 # endif 367 #endif 368 #if defined(R__AIX) || defined(R__SOLARIS_CC50) || \ 369 defined(R__HPUX11) || defined(R__GLIBC) || \ 370 (defined(R__MACOSX) && (defined(__INTEL_COMPILER) || defined(__arm__))) 371 // math functions are defined inline so we have to include them here 372 # include <math.h> 373 # ifdef R__SOLARIS_CC50 374 extern "C" { int finite(double); } 375 # endif 376 // # if defined(R__GLIBC) && defined(__STRICT_ANSI__) 377 // # ifndef finite 378 // # define finite __finite 379 // # endif 380 // # ifndef isnan 381 // # define isnan __isnan 382 // # endif 383 // # endif 384 #else 385 // don't want to include complete <math.h> 386 extern "C" { 387 extern double sin(double); 388 extern double cos(double); 389 extern double tan(double); 390 extern double sinh(double); 391 extern double cosh(double); 392 extern double tanh(double); 393 extern double asin(double); 394 extern double acos(double); 395 extern double atan(double); 396 extern double atan2(double, double); 397 extern double sqrt(double); 398 extern double exp(double); 399 extern double pow(double, double); 400 extern double log(double); 401 extern double log10(double); 402 #ifndef R__WIN32 403 # if !defined(finite) 404 extern int finite(double); 405 # endif 406 # if !defined(isnan) 407 extern int isnan(double); 408 # endif 409 extern double ldexp(double, int); 410 extern double ceil(double); 411 extern double floor(double); 412 #else 413 _CRTIMP double ldexp(double, int); 414 _CRTIMP double ceil(double); 415 _CRTIMP double floor(double); 416 #endif 417 } 418 #endif 419 420 inline Double_t TMath::Sin(Double_t x) 421 { return sin(x); } 422 423 inline Double_t TMath::Cos(Double_t x) 424 { return cos(x); } 425 426 inline Double_t TMath::Tan(Double_t x) 427 { return tan(x); } 428 429 inline Double_t TMath::SinH(Double_t x) 430 { return sinh(x); } 431 432 inline Double_t TMath::CosH(Double_t x) 433 { return cosh(x); } 434 435 inline Double_t TMath::TanH(Double_t x) 436 { return tanh(x); } 437 438 inline Double_t TMath::ASin(Double_t x) 439 { if (x < -1.) return -TMath::Pi()/2; 440 if (x > 1.) return TMath::Pi()/2; 441 return asin(x); 442 } 443 444 inline Double_t TMath::ACos(Double_t x) 445 { if (x < -1.) return TMath::Pi(); 446 if (x > 1.) return 0; 447 return acos(x); 448 } 449 450 inline Double_t TMath::ATan(Double_t x) 451 { return atan(x); } 452 453 inline Double_t TMath::ATan2(Double_t y, Double_t x) 454 { if (x != 0) return atan2(y, x); 455 if (y == 0) return 0; 456 if (y > 0) return Pi()/2; 457 else return -Pi()/2; 458 } 459 460 inline Double_t TMath::Sqrt(Double_t x) 461 { return sqrt(x); } 462 463 inline Double_t TMath::Ceil(Double_t x) 464 { return ceil(x); } 465 466 inline Int_t TMath::CeilNint(Double_t x) 467 { return TMath::Nint(ceil(x)); } 468 469 inline Double_t TMath::Floor(Double_t x) 470 { return floor(x); } 471 472 inline Int_t TMath::FloorNint(Double_t x) 473 { return TMath::Nint(floor(x)); } 474 475 template<typename T> 476 inline Int_t TMath::Nint(T x) 477 { 478 // Round to nearest integer. Rounds half integers to the nearest 479 // even integer. 480 int i; 481 if (x >= 0) { 482 i = int(x + 0.5); 483 if ( i & 1 && x + 0.5 == T(i) ) i--; 484 } else { 485 i = int(x - 0.5); 486 if ( i & 1 && x - 0.5 == T(i) ) i++; 487 } 488 return i; 489 } 490 491 inline Double_t TMath::Exp(Double_t x) 492 { return exp(x); } 493 494 inline Double_t TMath::Ldexp(Double_t x, Int_t exp) 495 { return ldexp(x, exp); } 496 497 inline LongDouble_t TMath::Power(LongDouble_t x, LongDouble_t y) 498 { return std::pow(x,y); } 499 500 inline LongDouble_t TMath::Power(LongDouble_t x, Long64_t y) 501 { return std::pow(x,(LongDouble_t)y); } 502 503 inline LongDouble_t TMath::Power(Long64_t x, Long64_t y) 504 #if __cplusplus >= 201103 /*C++11*/ 505 { return std::pow(x,y); } 506 #else 507 { return std::pow((LongDouble_t)x,(LongDouble_t)y); } 508 #endif 509 510 inline Double_t TMath::Power(Double_t x, Double_t y) 511 { return pow(x, y); } 512 513 inline Double_t TMath::Power(Double_t x, Int_t y) { 514 #ifdef R__ANSISTREAM 515 return std::pow(x, y); 516 #else 517 return pow(x, (Double_t) y); 518 #endif 519 } 520 521 522 inline Double_t TMath::Log(Double_t x) 523 { return log(x); } 524 525 inline Double_t TMath::Log10(Double_t x) 526 { return log10(x); } 527 528 inline Int_t TMath::Finite(Double_t x) 529 #if defined(R__HPUX11) 530 { return isfinite(x); } 531 #elif defined(R__MACOSX) 532 #ifdef isfinite 533 // from math.h 534 { return isfinite(x); } 535 #else 536 // from cmath 537 { return std::isfinite(x); } 538 #endif 539 #else 540 { return finite(x); } 541 #endif 542 543 inline Int_t TMath::IsNaN(Double_t x) 544 #if (defined(R__ANSISTREAM) || (defined(R__MACOSX) && defined(__arm__))) && !defined(_AIX) && !defined(__CUDACC__) 545 #if defined(isnan) || defined(R__SOLARIS_CC50) || defined(__INTEL_COMPILER) 546 // from math.h 547 { return ::isnan(x); } 548 #else 549 // from cmath 550 { return std::isnan(x); } 551 #endif 552 #else 553 { return isnan(x); } 554 #endif 555 556 //--------wrapper to numeric_limits 557 //____________________________________________________________________________ 558 inline Double_t TMath::QuietNaN() { 559 // returns a quiet NaN as defined by IEEE 754 560 // see http://en.wikipedia.org/wiki/NaN#Quiet_NaN 561 return std::numeric_limits<Double_t>::quiet_NaN(); 562 } 563 564 //____________________________________________________________________________ 565 inline Double_t TMath::SignalingNaN() { 566 // returns a signaling NaN as defined by IEEE 754 567 // see http://en.wikipedia.org/wiki/NaN#Signaling_NaN 568 return std::numeric_limits<Double_t>::signaling_NaN(); 569 } 570 571 inline Double_t TMath::Infinity() { 572 // returns an infinity as defined by the IEEE standard 573 return std::numeric_limits<Double_t>::infinity(); 574 } 575 576 template<typename T> 577 inline T TMath::Limits<T>::Min() { 578 // returns maximum representation for type T 579 return (std::numeric_limits<T>::min)(); //N.B. use this signature to avoid class with macro min() on Windows 580 } 581 582 template<typename T> 583 inline T TMath::Limits<T>::Max() { 584 // returns minimum double representation 585 return (std::numeric_limits<T>::max)(); //N.B. use this signature to avoid class with macro max() on Windows 586 } 587 588 template<typename T> 589 inline T TMath::Limits<T>::Epsilon() { 590 // returns minimum double representation 591 return std::numeric_limits<T>::epsilon(); 592 } 593 594 595 //-------- Advanced ------------- 596 597 template <typename T> inline T TMath::NormCross(const T v1[3],const T v2[3],T out[3]) 598 { 599 // Calculate the Normalized Cross Product of two vectors 600 return Normalize(Cross(v1,v2,out)); 601 } 602 603 template <typename T> 604 T TMath::MinElement(Long64_t n, const T *a) { 605 // Return minimum of array a of length n. 606 607 return *std::min_element(a,a+n); 608 } 609 610 template <typename T> 611 T TMath::MaxElement(Long64_t n, const T *a) { 612 // Return maximum of array a of length n. 613 614 return *std::max_element(a,a+n); 615 } 616 617 template <typename T> 618 Long64_t TMath::LocMin(Long64_t n, const T *a) { 619 // Return index of array with the minimum element. 620 // If more than one element is minimum returns first found. 621 622 // Implement here since this one is found to be faster (mainly on 64 bit machines) 623 // than stl generic implementation. 624 // When performing the comparison, the STL implementation needs to de-reference both the array iterator 625 // and the iterator pointing to the resulting minimum location 626 627 if (n <= 0 || !a) return -1; 628 T xmin = a[0]; 629 Long64_t loc = 0; 630 for (Long64_t i = 1; i < n; i++) { 631 if (xmin > a[i]) { 632 xmin = a[i]; 633 loc = i; 634 } 635 } 636 return loc; 637 } 638 639 template <typename Iterator> 640 Iterator TMath::LocMin(Iterator first, Iterator last) { 641 // Return index of array with the minimum element. 642 // If more than one element is minimum returns first found. 643 return std::min_element(first, last); 644 } 645 646 template <typename T> 647 Long64_t TMath::LocMax(Long64_t n, const T *a) { 648 // Return index of array with the maximum element. 649 // If more than one element is maximum returns first found. 650 651 // Implement here since it is faster (see comment in LocMin function) 652 653 if (n <= 0 || !a) return -1; 654 T xmax = a[0]; 655 Long64_t loc = 0; 656 for (Long64_t i = 1; i < n; i++) { 657 if (xmax < a[i]) { 658 xmax = a[i]; 659 loc = i; 660 } 661 } 662 return loc; 663 } 664 665 template <typename Iterator> 666 Iterator TMath::LocMax(Iterator first, Iterator last) 667 { 668 // Return index of array with the maximum element. 669 // If more than one element is maximum returns first found. 670 671 return std::max_element(first, last); 672 } 673 674 template<typename T> 675 struct CompareDesc { 676 677 CompareDesc(T d) : fData(d) {} 678 679 template<typename Index> 680 bool operator()(Index i1, Index i2) { 681 return *(fData + i1) > *(fData + i2); 682 } 683 684 T fData; 685 }; 686 687 template<typename T> 688 struct CompareAsc { 689 690 CompareAsc(T d) : fData(d) {} 691 692 template<typename Index> 693 bool operator()(Index i1, Index i2) { 694 return *(fData + i1) < *(fData + i2); 695 } 696 697 T fData; 698 }; 699 700 template <typename Iterator> 701 Double_t TMath::Mean(Iterator first, Iterator last) 702 { 703 // Return the weighted mean of an array defined by the iterators. 704 705 Double_t sum = 0; 706 Double_t sumw = 0; 707 while ( first != last ) 708 { 709 sum += *first; 710 sumw += 1; 711 first++; 712 } 713 714 return sum/sumw; 715 } 716 717 template <typename Iterator, typename WeightIterator> 718 Double_t TMath::Mean(Iterator first, Iterator last, WeightIterator w) 719 { 720 // Return the weighted mean of an array defined by the first and 721 // last iterators. The w iterator should point to the first element 722 // of a vector of weights of the same size as the main array. 723 724 Double_t sum = 0; 725 Double_t sumw = 0; 726 int i = 0; 727 while ( first != last ) { 728 if ( *w < 0) { 729 ::Error("TMath::Mean","w[%d] = %.4e < 0 ?!",i,*w); 730 return 0; 731 } 732 sum += (*w) * (*first); 733 sumw += (*w) ; 734 ++w; 735 ++first; 736 ++i; 737 } 738 if (sumw <= 0) { 739 ::Error("TMath::Mean","sum of weights == 0 ?!"); 740 return 0; 741 } 742 743 return sum/sumw; 744 } 745 746 template <typename T> 747 Double_t TMath::Mean(Long64_t n, const T *a, const Double_t *w) 748 { 749 // Return the weighted mean of an array a with length n. 750 751 if (w) { 752 return TMath::Mean(a, a+n, w); 753 } else { 754 return TMath::Mean(a, a+n); 755 } 756 } 757 758 template <typename Iterator> 759 Double_t TMath::GeomMean(Iterator first, Iterator last) 760 { 761 // Return the geometric mean of an array defined by the iterators. 762 // geometric_mean = (Prod_i=0,n-1 |a[i]|)^1/n 763 764 Double_t logsum = 0.; 765 Long64_t n = 0; 766 while ( first != last ) { 767 if (*first == 0) return 0.; 768 Double_t absa = (Double_t) TMath::Abs(*first); 769 logsum += TMath::Log(absa); 770 ++first; 771 ++n; 772 } 773 774 return TMath::Exp(logsum/n); 775 } 776 777 template <typename T> 778 Double_t TMath::GeomMean(Long64_t n, const T *a) 779 { 780 // Return the geometric mean of an array a of size n. 781 // geometric_mean = (Prod_i=0,n-1 |a[i]|)^1/n 782 783 return TMath::GeomMean(a, a+n); 784 } 785 786 template <typename Iterator> 787 Double_t TMath::RMS(Iterator first, Iterator last) 788 { 789 // Return the Standard Deviation of an array defined by the iterators. 790 // Note that this function returns the sigma(standard deviation) and 791 // not the root mean square of the array. 792 793 // Use the two pass algorithm, which is slower (! a factor of 2) but much more 794 // precise. Since we have a vector the 2 pass algorithm is still faster than the 795 // Welford algorithm. (See also ROOT-5545) 796 797 Double_t n = 0; 798 799 Double_t tot = 0; 800 Double_t mean = TMath::Mean(first,last); 801 while ( first != last ) { 802 Double_t x = Double_t(*first); 803 tot += (x - mean)*(x - mean); 804 ++first; 805 ++n; 806 } 807 Double_t rms = (n > 1) ? TMath::Sqrt(tot/(n-1)) : 0.0; 808 return rms; 809 } 810 811 template <typename Iterator, typename WeightIterator> 812 Double_t TMath::RMS(Iterator first, Iterator last, WeightIterator w) 813 { 814 // Return the weighted Standard Deviation of an array defined by the iterators. 815 // Note that this function returns the sigma(standard deviation) and 816 // not the root mean square of the array. 817 818 // As in the unweighted case use the two pass algorithm 819 820 Double_t tot = 0; 821 Double_t sumw = 0; 822 Double_t sumw2 = 0; 823 Double_t mean = TMath::Mean(first,last,w); 824 while ( first != last ) { 825 Double_t x = Double_t(*first); 826 sumw += *w; 827 sumw2 += (*w) * (*w); 828 tot += (*w) * (x - mean)*(x - mean); 829 ++first; 830 ++w; 831 } 832 // use the correction neff/(neff -1) for the unbiased formula 833 Double_t rms = TMath::Sqrt(tot * sumw/ (sumw*sumw - sumw2) ); 834 return rms; 835 } 836 837 838 template <typename T> 839 Double_t TMath::RMS(Long64_t n, const T *a, const Double_t * w) 840 { 841 // Return the Standard Deviation of an array a with length n. 842 // Note that this function returns the sigma(standard deviation) and 843 // not the root mean square of the array. 844 845 return (w) ? TMath::RMS(a, a+n, w) : TMath::RMS(a, a+n); 846 } 847 848 template <typename Iterator, typename Element> 849 Iterator TMath::BinarySearch(Iterator first, Iterator last, Element value) 850 { 851 // Binary search in an array defined by its iterators. 852 // 853 // The values in the iterators range are supposed to be sorted 854 // prior to this call. If match is found, function returns 855 // position of element. If no match found, function gives nearest 856 // element smaller than value. 857 858 Iterator pind; 859 pind = std::lower_bound(first, last, value); 860 if ( (pind != last) && (*pind == value) ) 861 return pind; 862 else 863 return ( pind - 1); 864 } 865 866 867 template <typename T> Long64_t TMath::BinarySearch(Long64_t n, const T *array, T value) 868 { 869 // Binary search in an array of n values to locate value. 870 // 871 // Array is supposed to be sorted prior to this call. 872 // If match is found, function returns position of element. 873 // If no match found, function gives nearest element smaller than value. 874 875 const T* pind; 876 pind = std::lower_bound(array, array + n, value); 877 if ( (pind != array + n) && (*pind == value) ) 878 return (pind - array); 879 else 880 return ( pind - array - 1); 881 } 882 883 template <typename T> Long64_t TMath::BinarySearch(Long64_t n, const T **array, T value) 884 { 885 // Binary search in an array of n values to locate value. 886 // 887 // Array is supposed to be sorted prior to this call. 888 // If match is found, function returns position of element. 889 // If no match found, function gives nearest element smaller than value. 890 891 const T* pind; 892 pind = std::lower_bound(*array, *array + n, value); 893 if ( (pind != *array + n) && (*pind == value) ) 894 return (pind - *array); 895 else 896 return ( pind - *array - 1); 897 } 898 899 template <typename Iterator, typename IndexIterator> 900 void TMath::SortItr(Iterator first, Iterator last, IndexIterator index, Bool_t down) 901 { 902 // Sort the n1 elements of the Short_t array defined by its 903 // iterators. In output the array index contains the indices of 904 // the sorted array. If down is false sort in increasing order 905 // (default is decreasing order). 906 907 // NOTE that the array index must be created with a length bigger 908 // or equal than the main array before calling this function. 909 910 int i = 0; 911 912 IndexIterator cindex = index; 913 for ( Iterator cfirst = first; cfirst != last; ++cfirst ) 914 { 915 *cindex = i++; 916 ++cindex; 917 } 918 919 if ( down ) 920 std::sort(index, cindex, CompareDesc<Iterator>(first) ); 921 else 922 std::sort(index, cindex, CompareAsc<Iterator>(first) ); 923 } 924 925 template <typename Element, typename Index> void TMath::Sort(Index n, const Element* a, Index* index, Bool_t down) 926 { 927 // Sort the n elements of the array a of generic templated type Element. 928 // In output the array index of type Index contains the indices of the sorted array. 929 // If down is false sort in increasing order (default is decreasing order). 930 931 // NOTE that the array index must be created with a length >= n 932 // before calling this function. 933 // NOTE also that the size type for n must be the same type used for the index array 934 // (templated type Index) 935 936 for(Index i = 0; i < n; i++) { index[i] = i; } 937 if ( down ) 938 std::sort(index, index + n, CompareDesc<const Element*>(a) ); 939 else 940 std::sort(index, index + n, CompareAsc<const Element*>(a) ); 941 } 942 943 template <typename T> T *TMath::Cross(const T v1[3],const T v2[3], T out[3]) 944 { 945 // Calculate the Cross Product of two vectors: 946 // out = [v1 x v2] 947 948 out[0] = v1[1] * v2[2] - v1[2] * v2[1]; 949 out[1] = v1[2] * v2[0] - v1[0] * v2[2]; 950 out[2] = v1[0] * v2[1] - v1[1] * v2[0]; 951 952 return out; 953 } 954 955 template <typename T> T * TMath::Normal2Plane(const T p1[3],const T p2[3],const T p3[3], T normal[3]) 956 { 957 // Calculate a normal vector of a plane. 958 // 959 // Input: 960 // Float_t *p1,*p2,*p3 - 3 3D points belonged the plane to define it. 961 // 962 // Return: 963 // Pointer to 3D normal vector (normalized) 964 965 T v1[3], v2[3]; 966 967 v1[0] = p2[0] - p1[0]; 968 v1[1] = p2[1] - p1[1]; 969 v1[2] = p2[2] - p1[2]; 970 971 v2[0] = p3[0] - p1[0]; 972 v2[1] = p3[1] - p1[1]; 973 v2[2] = p3[2] - p1[2]; 974 975 NormCross(v1,v2,normal); 976 return normal; 977 } 978 979 template <typename T> Bool_t TMath::IsInside(T xp, T yp, Int_t np, T *x, T *y) 980 { 981 // Function which returns kTRUE if point xp,yp lies inside the 982 // polygon defined by the np points in arrays x and y, kFALSE otherwise. 983 // Note that the polygon may be open or closed. 984 985 Int_t i, j = np-1 ; 986 Bool_t oddNodes = kFALSE; 987 988 for (i=0; i<np; i++) { 989 if ((y[i]<yp && y[j]>=yp) || (y[j]<yp && y[i]>=yp)) { 990 if (x[i]+(yp-y[i])/(y[j]-y[i])*(x[j]-x[i])<xp) { 991 oddNodes = !oddNodes; 992 } 993 } 994 j=i; 995 } 996 997 return oddNodes; 998 } 999 1000 template <typename T> Double_t TMath::Median(Long64_t n, const T *a, const Double_t *w, Long64_t *work) 1001 { 1002 // Return the median of the array a where each entry i has weight w[i] . 1003 // Both arrays have a length of at least n . The median is a number obtained 1004 // from the sorted array a through 1005 // 1006 // median = (a[jl]+a[jh])/2. where (using also the sorted index on the array w) 1007 // 1008 // sum_i=0,jl w[i] <= sumTot/2 1009 // sum_i=0,jh w[i] >= sumTot/2 1010 // sumTot = sum_i=0,n w[i] 1011 // 1012 // If w=0, the algorithm defaults to the median definition where it is 1013 // a number that divides the sorted sequence into 2 halves. 1014 // When n is odd or n > 1000, the median is kth element k = (n + 1) / 2. 1015 // when n is even and n < 1000the median is a mean of the elements k = n/2 and k = n/2 + 1. 1016 // 1017 // If the weights are supplied (w not 0) all weights must be >= 0 1018 // 1019 // If work is supplied, it is used to store the sorting index and assumed to be 1020 // >= n . If work=0, local storage is used, either on the stack if n < kWorkMax 1021 // or on the heap for n >= kWorkMax . 1022 1023 const Int_t kWorkMax = 100; 1024 1025 if (n <= 0 || !a) return 0; 1026 Bool_t isAllocated = kFALSE; 1027 Double_t median; 1028 Long64_t *ind; 1029 Long64_t workLocal[kWorkMax]; 1030 1031 if (work) { 1032 ind = work; 1033 } else { 1034 ind = workLocal; 1035 if (n > kWorkMax) { 1036 isAllocated = kTRUE; 1037 ind = new Long64_t[n]; 1038 } 1039 } 1040 1041 if (w) { 1042 Double_t sumTot2 = 0; 1043 for (Int_t j = 0; j < n; j++) { 1044 if (w[j] < 0) { 1045 ::Error("TMath::Median","w[%d] = %.4e < 0 ?!",j,w[j]); 1046 if (isAllocated) delete [] ind; 1047 return 0; 1048 } 1049 sumTot2 += w[j]; 1050 } 1051 1052 sumTot2 /= 2.; 1053 1054 Sort(n, a, ind, kFALSE); 1055 1056 Double_t sum = 0.; 1057 Int_t jl; 1058 for (jl = 0; jl < n; jl++) { 1059 sum += w[ind[jl]]; 1060 if (sum >= sumTot2) break; 1061 } 1062 1063 Int_t jh; 1064 sum = 2.*sumTot2; 1065 for (jh = n-1; jh >= 0; jh--) { 1066 sum -= w[ind[jh]]; 1067 if (sum <= sumTot2) break; 1068 } 1069 1070 median = 0.5*(a[ind[jl]]+a[ind[jh]]); 1071 1072 } else { 1073 1074 if (n%2 == 1) 1075 median = KOrdStat(n, a,n/2, ind); 1076 else { 1077 median = 0.5*(KOrdStat(n, a, n/2 -1, ind)+KOrdStat(n, a, n/2, ind)); 1078 } 1079 } 1080 1081 if (isAllocated) 1082 delete [] ind; 1083 return median; 1084 } 1085 1086 1087 1088 1089 template <class Element, typename Size> 1090 Element TMath::KOrdStat(Size n, const Element *a, Size k, Size *work) 1091 { 1092 // Returns k_th order statistic of the array a of size n 1093 // (k_th smallest element out of n elements). 1094 // 1095 // C-convention is used for array indexing, so if you want 1096 // the second smallest element, call KOrdStat(n, a, 1). 1097 // 1098 // If work is supplied, it is used to store the sorting index and 1099 // assumed to be >= n. If work=0, local storage is used, either on 1100 // the stack if n < kWorkMax or on the heap for n >= kWorkMax. 1101 // Note that the work index array will not contain the sorted indices but 1102 // all indeces of the smaller element in arbitrary order in work[0,...,k-1] and 1103 // all indeces of the larger element in arbitrary order in work[k+1,..,n-1] 1104 // work[k] will contain instead the index of the returned element. 1105 // 1106 // Taken from "Numerical Recipes in C++" without the index array 1107 // implemented by Anna Khreshuk. 1108 // 1109 // See also the declarations at the top of this file 1110 1111 const Int_t kWorkMax = 100; 1112 1113 typedef Size Index; 1114 1115 Bool_t isAllocated = kFALSE; 1116 Size i, ir, j, l, mid; 1117 Index arr; 1118 Index *ind; 1119 Index workLocal[kWorkMax]; 1120 Index temp; 1121 1122 if (work) { 1123 ind = work; 1124 } else { 1125 ind = workLocal; 1126 if (n > kWorkMax) { 1127 isAllocated = kTRUE; 1128 ind = new Index[n]; 1129 } 1130 } 1131 1132 for (Size ii=0; ii<n; ii++) { 1133 ind[ii]=ii; 1134 } 1135 Size rk = k; 1136 l=0; 1137 ir = n-1; 1138 for(;;) { 1139 if (ir<=l+1) { //active partition contains 1 or 2 elements 1140 if (ir == l+1 && a[ind[ir]]<a[ind[l]]) 1141 {temp = ind[l]; ind[l]=ind[ir]; ind[ir]=temp;} 1142 Element tmp = a[ind[rk]]; 1143 if (isAllocated) 1144 delete [] ind; 1145 return tmp; 1146 } else { 1147 mid = (l+ir) >> 1; //choose median of left, center and right 1148 {temp = ind[mid]; ind[mid]=ind[l+1]; ind[l+1]=temp;}//elements as partitioning element arr. 1149 if (a[ind[l]]>a[ind[ir]]) //also rearrange so that a[l]<=a[l+1] 1150 {temp = ind[l]; ind[l]=ind[ir]; ind[ir]=temp;} 1151 1152 if (a[ind[l+1]]>a[ind[ir]]) 1153 {temp=ind[l+1]; ind[l+1]=ind[ir]; ind[ir]=temp;} 1154 1155 if (a[ind[l]]>a[ind[l+1]]) 1156 {temp = ind[l]; ind[l]=ind[l+1]; ind[l+1]=temp;} 1157 1158 i=l+1; //initialize pointers for partitioning 1159 j=ir; 1160 arr = ind[l+1]; 1161 for (;;){ 1162 do i++; while (a[ind[i]]<a[arr]); 1163 do j--; while (a[ind[j]]>a[arr]); 1164 if (j<i) break; //pointers crossed, partitioning complete 1165 {temp=ind[i]; ind[i]=ind[j]; ind[j]=temp;} 1166 } 1167 ind[l+1]=ind[j]; 1168 ind[j]=arr; 1169 if (j>=rk) ir = j-1; //keep active the partition that 1170 if (j<=rk) l=i; //contains the k_th element 1171 } 1172 } 1173 } 1174 1175 #endif 1176