Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-31 09:59:53

0001 // @(#)root/base:
0002 // Authors: Rene Brun, Fons Rademakers   29/07/95
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOT_TMathBase
0013 #define ROOT_TMathBase
0014 
0015 
0016 //////////////////////////////////////////////////////////////////////////
0017 //                                                                      //
0018 // TMath Base functions                                                 //
0019 //                                                                      //
0020 // Define the functions Min, Max, Abs, Sign, Range for all types.       //
0021 // NB: These functions are unfortunately not available in a portable    //
0022 // way in std::.                                                        //
0023 //                                                                      //
0024 // More functions are defined in TMath.h. TMathBase.h is designed to be //
0025 // a stable file and used in place of TMath.h in the ROOT miniCore.     //
0026 //                                                                      //
0027 //////////////////////////////////////////////////////////////////////////
0028 
0029 #include "RtypesCore.h"
0030 
0031 #include <cstdlib>
0032 #include <cmath>
0033 #include <algorithm>
0034 
0035 namespace TMath {
0036 
0037    // Abs
0038    inline Short_t  Abs(Short_t d);
0039    inline Int_t    Abs(Int_t d);
0040    inline Long_t   Abs(Long_t d);
0041    inline Long64_t Abs(Long64_t d);
0042    inline Float_t  Abs(Float_t d);
0043    inline Double_t Abs(Double_t d);
0044    inline LongDouble_t Abs(LongDouble_t d);
0045 
0046    // Even/Odd
0047    inline Bool_t   Even(Long_t a);
0048    inline Bool_t   Odd(Long_t a);
0049 
0050    // SignBit
0051    template<typename Integer>
0052    inline Bool_t SignBit(Integer a);
0053    inline Bool_t SignBit(Float_t a);
0054    inline Bool_t SignBit(Double_t a);
0055    inline Bool_t SignBit(LongDouble_t a);
0056 
0057    // Sign
0058    template<typename T1, typename T2>
0059    inline T1 Sign( T1 a, T2 b);
0060    inline Float_t  Sign(Float_t a, Float_t b);
0061    inline Double_t Sign(Double_t a, Double_t b);
0062    inline LongDouble_t Sign(LongDouble_t a, LongDouble_t b);
0063 
0064    // Min, Max of two scalars
0065    inline Short_t   Min(Short_t a, Short_t b);
0066    inline UShort_t  Min(UShort_t a, UShort_t b);
0067    inline Int_t     Min(Int_t a, Int_t b);
0068    inline UInt_t    Min(UInt_t a, UInt_t b);
0069    inline Long_t    Min(Long_t a, Long_t b);
0070    inline ULong_t   Min(ULong_t a, ULong_t b);
0071    inline Long64_t  Min(Long64_t a, Long64_t b);
0072    inline ULong64_t Min(ULong64_t a, ULong64_t b);
0073    inline Float_t   Min(Float_t a, Float_t b);
0074    inline Double_t  Min(Double_t a, Double_t b);
0075 
0076    inline Short_t   Max(Short_t a, Short_t b);
0077    inline UShort_t  Max(UShort_t a, UShort_t b);
0078    inline Int_t     Max(Int_t a, Int_t b);
0079    inline UInt_t    Max(UInt_t a, UInt_t b);
0080    inline Long_t    Max(Long_t a, Long_t b);
0081    inline ULong_t   Max(ULong_t a, ULong_t b);
0082    inline Long64_t  Max(Long64_t a, Long64_t b);
0083    inline ULong64_t Max(ULong64_t a, ULong64_t b);
0084    inline Float_t   Max(Float_t a, Float_t b);
0085    inline Double_t  Max(Double_t a, Double_t b);
0086 
0087    // Range
0088    inline Short_t   Range(Short_t lb, Short_t ub, Short_t x);
0089    inline Int_t     Range(Int_t lb, Int_t ub, Int_t x);
0090    inline Long_t    Range(Long_t lb, Long_t ub, Long_t x);
0091    inline ULong_t   Range(ULong_t lb, ULong_t ub, ULong_t x);
0092    inline Double_t  Range(Double_t lb, Double_t ub, Double_t x);
0093 
0094    //NextPrime is used by the Core classes.
0095    Long_t   NextPrime(Long_t x);   // Least prime number greater than x
0096 
0097    // Binary search
0098    template <typename T> Long64_t BinarySearch(Long64_t n, const T  *array, T value);
0099    template <typename T> Long64_t BinarySearch(Long64_t n, const T **array, T value);
0100    template <typename Iterator, typename Element> Iterator BinarySearch(Iterator first, Iterator last, Element value)
0101        R__DEPRECATED(6,40, "Undefined behavior in case \"value\" is smaller than the first element. Use STL algorithms instead, e.g. std::lower_bound(v.rbegin(), v.rend(), value, std::greater{}).");
0102 
0103    // Sorting
0104    template <typename Element, typename Index>
0105    void Sort(Index n, const Element* a, Index* index, Bool_t down=kTRUE);
0106    template <typename Iterator, typename IndexIterator>
0107    void SortItr(Iterator first, Iterator last, IndexIterator index, Bool_t down=kTRUE);
0108 }
0109 
0110 
0111 //---- Even/odd ----------------------------------------------------------------
0112 
0113 /// Returns `true` if `a` is even.
0114 inline Bool_t TMath::Even(Long_t a)
0115    { return ! (a & 1); }
0116 
0117 /// Returns `true` if `a` is odd.
0118 inline Bool_t TMath::Odd(Long_t a)
0119    { return (a & 1); }
0120 
0121 //---- Abs ---------------------------------------------------------------------
0122 
0123 /// Returns the absolute value of parameter `Short_t d`.
0124 inline Short_t TMath::Abs(Short_t d)
0125 { return (d >= 0) ? d : Short_t(-d);  }
0126 
0127 /// Returns the absolute value of parameter `Int_t d`.
0128 inline Int_t TMath::Abs(Int_t d)
0129 { return std::abs(d); }
0130 
0131 /// Returns the absolute value of parameter `Long_t d`.
0132 inline Long_t TMath::Abs(Long_t d)
0133 { return std::labs(d); }
0134 
0135 /// Returns the absolute value of parameter `Long64_t d`.
0136 inline Long64_t TMath::Abs(Long64_t d)
0137 { return std::llabs(d); }
0138 
0139 /// Returns the absolute value of parameter `Float_t d`.
0140 inline Float_t TMath::Abs(Float_t d)
0141 { return std::abs(d); }
0142 
0143 /// Returns the absolute value of parameter `Double_t d`.
0144 inline Double_t TMath::Abs(Double_t d)
0145 { return std::abs(d); }
0146 
0147 /// Returns the absolute value of parameter `LongDouble_t d`.
0148 inline LongDouble_t TMath::Abs(LongDouble_t d)
0149 { return std::abs(d); }
0150 
0151 
0152 //---- Sign Bit--------------------------------------------------------------------
0153 
0154 /// Returns whether the sign of `Integer a` is negative.
0155 template<typename Integer>
0156 inline Bool_t TMath::SignBit( Integer a)
0157    { return (a < 0); }
0158 
0159 /// Returns whether the sign of `Float_t a` is negative.
0160 inline Bool_t TMath::SignBit(Float_t a)
0161    { return std::signbit(a);  }
0162 
0163 /// Returns whether the sign of `Double_t a` is negative.
0164 inline Bool_t TMath::SignBit(Double_t a)
0165    { return std::signbit(a);  }
0166 
0167 /// Returns whether the sign of `LongDouble_t a` is negative.
0168 inline Bool_t TMath::SignBit(LongDouble_t a)
0169    { return std::signbit(a);  }
0170 
0171 
0172 //---- Sign --------------------------------------------------------------------
0173 
0174 /// Returns a value with the magnitude of `a` and the sign of `b`.
0175 template<typename T1, typename T2>
0176 inline T1 TMath::Sign( T1 a, T2 b)
0177    { return (SignBit(b)) ? - Abs(a) : Abs(a); }
0178 
0179 /// Returns a value with the magnitude of `a` and the sign of `b`.
0180 /// `a`and `b` are `Short_t`.
0181 inline Float_t TMath::Sign(Float_t a, Float_t b)
0182    { return std::copysign(a,b);  }
0183 
0184 /// Returns a value with the magnitude of `a` and the sign of `b`.
0185 /// `a`and `b` are `Double_t`.
0186 inline Double_t TMath::Sign(Double_t a, Double_t b)
0187    { return std::copysign(a,b);  }
0188 
0189 /// Returns a value with the magnitude of `a` and the sign of `b`.
0190 /// `a`and `b` are `LongDouble_t`.
0191 inline LongDouble_t TMath::Sign(LongDouble_t a, LongDouble_t b)
0192    { return std::copysign(a,b);  }
0193 
0194 
0195 //---- Min ---------------------------------------------------------------------
0196 
0197 /// Returns the smallest of `a` and `b`. If both are equivalent, `a` is returned.
0198 /// `a`and `b` are `Short_t`.
0199 inline Short_t TMath::Min(Short_t a, Short_t b)
0200    { return a <= b ? a : b; }
0201 
0202 /// Returns the smallest of `a` and `b`. If both are equivalent, `a` is returned.
0203 /// `a`and `b` are `UShort_t`.
0204 inline UShort_t TMath::Min(UShort_t a, UShort_t b)
0205    { return a <= b ? a : b; }
0206 
0207 /// Returns the smallest of `a` and `b`. If both are equivalent, `a` is returned.
0208 /// `a`and `b` are `Int_t`.
0209 inline Int_t TMath::Min(Int_t a, Int_t b)
0210    { return a <= b ? a : b; }
0211 
0212 /// Returns the smallest of `a` and `b`. If both are equivalent, `a` is returned.
0213 /// `a`and `b` are `Short_t`.
0214 inline UInt_t TMath::Min(UInt_t a, UInt_t b)
0215    { return a <= b ? a : b; }
0216 
0217 /// Returns the smallest of `a` and `b`. If both are equivalent, `a` is returned.
0218 /// `a`and `b` are `Long_t`.
0219 inline Long_t TMath::Min(Long_t a, Long_t b)
0220    { return a <= b ? a : b; }
0221 
0222 /// Returns the smallest of `a` and `b`. If both are equivalent, `a` is returned.
0223 /// `a`and `b` are `ULong_t`.
0224 inline ULong_t TMath::Min(ULong_t a, ULong_t b)
0225    { return a <= b ? a : b; }
0226 
0227 /// Returns the smallest of `a` and `b`. If both are equivalent, `a` is returned.
0228 /// `a`and `b` are `Long64_t`.
0229 inline Long64_t TMath::Min(Long64_t a, Long64_t b)
0230    { return a <= b ? a : b; }
0231 
0232 /// Returns the smallest of `a` and `b`. If both are equivalent, `a` is returned.
0233 /// `a`and `b` are `ULong64_t`.
0234 inline ULong64_t TMath::Min(ULong64_t a, ULong64_t b)
0235    { return a <= b ? a : b; }
0236 
0237 /// Returns the smallest of `a` and `b`. If both are equivalent, `a` is returned.
0238 /// `a`and `b` are `Float_t`.
0239 inline Float_t TMath::Min(Float_t a, Float_t b)
0240    { return a <= b ? a : b; }
0241 
0242 /// Returns the smallest of `a` and `b`. If both are equivalent, `a` is returned.
0243 /// `a`and `b` are `Double_t`.
0244 inline Double_t TMath::Min(Double_t a, Double_t b)
0245    { return a <= b ? a : b; }
0246 
0247 //---- Max ---------------------------------------------------------------------
0248 
0249 /// Returns the largest of `a` and `b`. If both are equivalent, `a` is returned.
0250 /// `a`and `b` are `Short_t`.
0251 inline Short_t TMath::Max(Short_t a, Short_t b)
0252    { return a >= b ? a : b; }
0253 
0254 /// Returns the largest of `a` and `b`. If both are equivalent, `a` is returned.
0255 /// `a`and `b` are `UShort_t`.
0256 inline UShort_t TMath::Max(UShort_t a, UShort_t b)
0257    { return a >= b ? a : b; }
0258 
0259 /// Returns the largest of `a` and `b`. If both are equivalent, `a` is returned.
0260 /// `a`and `b` are `Int_t`.
0261 inline Int_t TMath::Max(Int_t a, Int_t b)
0262    { return a >= b ? a : b; }
0263 
0264 /// Returns the largest of `a` and `b`. If both are equivalent, `a` is returned.
0265 /// `a`and `b` are `UInt_t`.
0266 inline UInt_t TMath::Max(UInt_t a, UInt_t b)
0267    { return a >= b ? a : b; }
0268 
0269 /// Returns the largest of `a` and `b`. If both are equivalent, `a` is returned.
0270 /// `a`and `b` are `Long_t`.
0271 inline Long_t TMath::Max(Long_t a, Long_t b)
0272    { return a >= b ? a : b; }
0273 
0274 /// Returns the largest of `a` and `b`. If both are equivalent, `a` is returned.
0275 /// `a`and `b` are `ULong_t`.
0276 inline ULong_t TMath::Max(ULong_t a, ULong_t b)
0277    { return a >= b ? a : b; }
0278 
0279 /// Returns the largest of `a` and `b`. If both are equivalent, `a` is returned.
0280 /// `a`and `b` are `Long64_t`.
0281 inline Long64_t TMath::Max(Long64_t a, Long64_t b)
0282    { return a >= b ? a : b; }
0283 
0284 /// Returns the largest of `a` and `b`. If both are equivalent, `a` is returned.
0285 /// `a`and `b` are `ULong64_t`.
0286 inline ULong64_t TMath::Max(ULong64_t a, ULong64_t b)
0287    { return a >= b ? a : b; }
0288 
0289 /// Returns the largest of `a` and `b`. If both are equivalent, `a` is returned.
0290 /// `a`and `b` are `Float_t`.
0291 inline Float_t TMath::Max(Float_t a, Float_t b)
0292    { return a >= b ? a : b; }
0293 
0294 /// Returns the largest of `a` and `b`. If both are equivalent, `a` is returned.
0295 /// `a`and `b` are `Double_t`.
0296 inline Double_t TMath::Max(Double_t a, Double_t b)
0297    { return a >= b ? a : b; }
0298 
0299 //---- Range -------------------------------------------------------------------
0300 
0301 /// Returns `x` if `lb < x < up`, `lb` if `x < lb` and `ub` if `x > ub`.
0302 /// `lb`, `ub` and `x` are `Short_t`.
0303 inline Short_t TMath::Range(Short_t lb, Short_t ub, Short_t x)
0304    { return x < lb ? lb : (x > ub ? ub : x); }
0305 
0306 /// Returns `x` if `lb < x < up`, `lb` if `x < lb` and `ub` if `x > ub`.
0307 /// `lb`, `ub` and `x` are `Int_t`.
0308 inline Int_t TMath::Range(Int_t lb, Int_t ub, Int_t x)
0309    { return x < lb ? lb : (x > ub ? ub : x); }
0310 
0311 /// Returns `x` if `lb < x < up`, `lb` if `x < lb` and `ub` if `x > ub`.
0312 /// `lb`, `ub` and `x` are `Long_t`.
0313 inline Long_t TMath::Range(Long_t lb, Long_t ub, Long_t x)
0314    { return x < lb ? lb : (x > ub ? ub : x); }
0315 
0316 /// Returns `x` if `lb < x < up`, `lb` if `x < lb` and `ub` if `x > ub`.
0317 /// `lb`, `ub` and `x` are `ULong_t`.
0318 inline ULong_t TMath::Range(ULong_t lb, ULong_t ub, ULong_t x)
0319    { return x < lb ? lb : (x > ub ? ub : x); }
0320 
0321 /// Returns `x` if `lb < x < up`, `lb` if `x < lb` and `ub` if `x > ub`.
0322 /// `lb`, `ub` and `x` are `Double_t`.
0323 inline Double_t TMath::Range(Double_t lb, Double_t ub, Double_t x)
0324    { return x < lb ? lb : (x > ub ? ub : x); }
0325 
0326 /// Binary search in an array defined by its iterators.
0327 ///
0328 /// The values in the iterators range are supposed to be sorted
0329 /// prior to this call.  If match is found, function returns
0330 /// position of element.  If no match found, function gives nearest
0331 /// element smaller than value.
0332 template <typename Iterator, typename Element>
0333 Iterator TMath::BinarySearch(Iterator first, Iterator last, Element value)
0334 {
0335    Iterator pind;
0336    pind = std::lower_bound(first, last, value);
0337    if ( (pind != last) && (*pind == value) )
0338       return pind;
0339    else
0340       return ( pind - 1);
0341 }
0342 
0343 /// Binary search in an array of n values to locate value.
0344 ///
0345 /// Array is supposed  to be sorted prior to this call.
0346 /// If match is found, function returns position of element.
0347 /// If no match found, function gives nearest element smaller than value.
0348 template <typename T> Long64_t TMath::BinarySearch(Long64_t n, const T  *array, T value)
0349 {
0350    const T* pind;
0351    pind = std::lower_bound(array, array + n, value);
0352    if ( (pind != array + n) && (*pind == value) )
0353       return (pind - array);
0354    else
0355       return ( pind - array - 1);
0356 }
0357 
0358 /// Binary search in an array of n values to locate value.
0359 ///
0360 /// Array is supposed  to be sorted prior to this call.
0361 /// If match is found, function returns position of element.
0362 /// If no match found, function gives nearest element smaller than value.
0363 template <typename T> Long64_t TMath::BinarySearch(Long64_t n, const T **array, T value)
0364 {
0365    const T* pind;
0366    pind = std::lower_bound(*array, *array + n, value);
0367    if ( (pind != *array + n) && (*pind == value) )
0368       return (pind - *array);
0369    else
0370       return ( pind - *array - 1);
0371 }
0372 
0373 template<typename T>
0374 struct CompareDesc {
0375 
0376    CompareDesc(T d) : fData(d) {}
0377 
0378    template<typename Index>
0379    bool operator()(Index i1, Index i2) {
0380       return *(fData + i1) > *(fData + i2);
0381    }
0382 
0383    T fData;
0384 };
0385 
0386 template<typename T>
0387 struct CompareAsc {
0388 
0389    CompareAsc(T d) : fData(d) {}
0390 
0391    template<typename Index>
0392    bool operator()(Index i1, Index i2) {
0393       return *(fData + i1) < *(fData + i2);
0394    }
0395 
0396    T fData;
0397 };
0398 
0399 /// Sort the n1 elements of the Short_t array defined by its
0400 /// iterators.  In output the array index contains the indices of
0401 /// the sorted array.  If down is false sort in increasing order
0402 /// (default is decreasing order).
0403 ///
0404 /// NOTE that the array index must be created with a length bigger
0405 /// or equal than the main array before calling this function.
0406 template <typename Iterator, typename IndexIterator>
0407 void TMath::SortItr(Iterator first, Iterator last, IndexIterator index, Bool_t down)
0408 {
0409    int i = 0;
0410 
0411    IndexIterator cindex = index;
0412    for ( Iterator cfirst = first; cfirst != last; ++cfirst )
0413    {
0414       *cindex = i++;
0415       ++cindex;
0416    }
0417 
0418    if ( down )
0419       std::sort(index, cindex, CompareDesc<Iterator>(first) );
0420    else
0421       std::sort(index, cindex, CompareAsc<Iterator>(first) );
0422 }
0423 
0424 /// Sort the n elements of the  array a of generic templated type Element.
0425 /// In output the array index of type Index contains the indices of the sorted array.
0426 /// If down is false sort in increasing order (default is decreasing order).
0427 ///
0428 /// NOTE that the array index must be created with a length >= n
0429 /// before calling this function.
0430 /// NOTE also that the size type for n must be the same type used for the index array
0431 /// (templated type Index)
0432 template <typename Element, typename Index> void TMath::Sort(Index n, const Element* a, Index* index, Bool_t down)
0433 {
0434    for(Index i = 0; i < n; i++) { index[i] = i; }
0435    if ( down )
0436       std::sort(index, index + n, CompareDesc<const Element*>(a) );
0437    else
0438       std::sort(index, index + n, CompareAsc<const Element*>(a) );
0439 }
0440 
0441 #endif