00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef ROOT_TMath
00013 #define ROOT_TMath
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
00052 inline Double_t E() { return 2.71828182845904523536; }
00053
00054
00055 inline Double_t Ln10() { return 2.30258509299404568402; }
00056
00057
00058 inline Double_t LogE() { return 0.43429448190325182765; }
00059
00060
00061 inline Double_t C() { return 2.99792458e8; }
00062 inline Double_t Ccgs() { return 100.0 * C(); }
00063 inline Double_t CUncertainty() { return 0.0; }
00064
00065
00066 inline Double_t G() { return 6.673e-11; }
00067 inline Double_t Gcgs() { return G() / 1000.0; }
00068 inline Double_t GUncertainty() { return 0.010e-11; }
00069
00070
00071 inline Double_t GhbarC() { return 6.707e-39; }
00072 inline Double_t GhbarCUncertainty() { return 0.010e-39; }
00073
00074
00075 inline Double_t Gn() { return 9.80665; }
00076 inline Double_t GnUncertainty() { return 0.0; }
00077
00078
00079 inline Double_t H() { return 6.62606876e-34; }
00080 inline Double_t Hcgs() { return 1.0e7 * H(); }
00081 inline Double_t HUncertainty() { return 0.00000052e-34; }
00082
00083
00084 inline Double_t Hbar() { return 1.054571596e-34; }
00085 inline Double_t Hbarcgs() { return 1.0e7 * Hbar(); }
00086 inline Double_t HbarUncertainty() { return 0.000000082e-34; }
00087
00088
00089 inline Double_t HC() { return H() * C(); }
00090 inline Double_t HCcgs() { return Hcgs() * Ccgs(); }
00091
00092
00093 inline Double_t K() { return 1.3806503e-23; }
00094 inline Double_t Kcgs() { return 1.0e7 * K(); }
00095 inline Double_t KUncertainty() { return 0.0000024e-23; }
00096
00097
00098 inline Double_t Sigma() { return 5.6704e-8; }
00099 inline Double_t SigmaUncertainty() { return 0.000040e-8; }
00100
00101
00102 inline Double_t Na() { return 6.02214199e+23; }
00103 inline Double_t NaUncertainty() { return 0.00000047e+23; }
00104
00105
00106
00107 inline Double_t R() { return K() * Na(); }
00108 inline Double_t RUncertainty() { return R()*((KUncertainty()/K()) + (NaUncertainty()/Na())); }
00109
00110
00111
00112
00113 inline Double_t MWair() { return 28.9644; }
00114
00115
00116
00117 inline Double_t Rgair() { return (1000.0 * R()) / MWair(); }
00118
00119
00120 inline Double_t EulerGamma() { return 0.577215664901532860606512090082402431042; }
00121
00122
00123 inline Double_t Qe() { return 1.602176462e-19; }
00124 inline Double_t QeUncertainty() { return 0.000000063e-19; }
00125
00126
00127
00128
00129
00130
00131
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
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
00170 Long_t Hypot(Long_t x, Long_t y);
00171
00172
00173 inline Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon) {
00174
00175 return TMath::Abs(af-bf) < epsilon;
00176 }
00177 inline Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec) {
00178
00179 return TMath::Abs(af-bf) <= 0.5*relPrec*(TMath::Abs(af)+TMath::Abs(bf));
00180 }
00181
00182
00183
00184
00185
00186
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
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
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
00202 ULong_t Hash(const void *txt, Int_t ntxt);
00203 ULong_t Hash(const char *str);
00204
00205
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);
00215
00216
00217
00218
00219
00220
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
00225 template <typename T> Bool_t IsInside(T xp, T yp, Int_t np, T *x, T *y);
00226
00227
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]);
00231 Double_t Normalize(Double_t v[3]);
00232
00233
00234 template <typename T> inline T NormCross(const T v1[3],const T v2[3],T out[3]);
00235
00236
00237 template <typename T> T *Normal2Plane(const T v1[3],const T v2[3],const T v3[3], T normal[3]);
00238
00239
00240
00241
00242
00243 Bool_t RootsCubic(const Double_t coef[4],Double_t &a, Double_t &b, Double_t &c);
00244
00245
00246
00247
00248
00249 Double_t Binomial(Int_t n,Int_t 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
00277
00278
00279
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
00294 template <class Element, typename Size> Element KOrdStat(Size n, const Element *a, Size k, Size *work = 0);
00295
00296
00297
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
00307 Double_t BesselI(Int_t n,Double_t x);
00308 Double_t BesselK(Int_t n,Double_t x);
00309 Double_t BesselI0(Double_t x);
00310 Double_t BesselK0(Double_t x);
00311 Double_t BesselI1(Double_t x);
00312 Double_t BesselK1(Double_t x);
00313 Double_t BesselJ0(Double_t x);
00314 Double_t BesselJ1(Double_t x);
00315 Double_t BesselY0(Double_t x);
00316 Double_t BesselY1(Double_t x);
00317 Double_t StruveH0(Double_t x);
00318 Double_t StruveH1(Double_t x);
00319 Double_t StruveL0(Double_t x);
00320 Double_t StruveL1(Double_t x);
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
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
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
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
00473 { return isfinite(x); }
00474 #else
00475
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
00486 { return isnan(x); }
00487 #else
00488
00489 { return std::isnan(x); }
00490 #endif
00491 #else
00492 { return isnan(x); }
00493 #endif
00494
00495
00496
00497 template <typename T> inline T TMath::NormCross(const T v1[3],const T v2[3],T out[3])
00498 {
00499
00500 return Normalize(Cross(v1,v2,out));
00501 }
00502
00503 template <typename T>
00504 T TMath::MinElement(Long64_t n, const T *a) {
00505
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
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
00520
00521
00522
00523
00524
00525
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
00542
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
00549
00550
00551
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
00569
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
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
00621
00622
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
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
00662
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
00681
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
00690
00691
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
00712
00713
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
00722
00723
00724
00725
00726
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
00740
00741
00742
00743
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
00756
00757
00758
00759
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
00773
00774
00775
00776
00777
00778
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
00798
00799
00800
00801
00802
00803
00804
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
00816
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
00828
00829
00830
00831
00832
00833
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
00852
00853
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
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
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
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
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) {
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;
01014 {temp = ind[mid]; ind[mid]=ind[l+1]; ind[l+1]=temp;}
01015 if (a[ind[l]]>a[ind[ir]])
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;
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;
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;
01036 if (j<=rk) l=i;
01037 }
01038 }
01039 }
01040
01041 #endif