Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TMathBase.h
Go to the documentation of this file.
1 // @(#)root/base:
2 // Authors: Rene Brun, 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_TMathBase
13 #define ROOT_TMathBase
14 
15 
16 //////////////////////////////////////////////////////////////////////////
17 // //
18 // TMath Base functions //
19 // //
20 // Define the functions Min, Max, Abs, Sign, Range for all types. //
21 // NB: These functions are unfortunately not available in a portable //
22 // way in std::. //
23 // //
24 // More functions are defined in TMath.h. TMathBase.h is designed to be //
25 // a stable file and used in place of TMath.h in the ROOT miniCore. //
26 // //
27 //////////////////////////////////////////////////////////////////////////
28 
29 #include "Rtypes.h"
30 
31 #include <cstdlib>
32 #include <cmath>
33 #include <algorithm>
34 
35 namespace TMath {
36 
37  // Abs
38  inline Short_t Abs(Short_t d);
39  inline Int_t Abs(Int_t d);
40  inline Long_t Abs(Long_t d);
41  inline Long64_t Abs(Long64_t d);
42  inline Float_t Abs(Float_t d);
43  inline Double_t Abs(Double_t d);
44  inline LongDouble_t Abs(LongDouble_t d);
45 
46  // Even/Odd
47  inline Bool_t Even(Long_t a);
48  inline Bool_t Odd(Long_t a);
49 
50  // SignBit
51  template<typename Integer>
52  inline Bool_t SignBit(Integer a);
53  inline Bool_t SignBit(Float_t a);
54  inline Bool_t SignBit(Double_t a);
55  inline Bool_t SignBit(LongDouble_t a);
56 
57  // Sign
58  template<typename T1, typename T2>
59  inline T1 Sign( T1 a, T2 b);
60  inline Float_t Sign(Float_t a, Float_t b);
61  inline Double_t Sign(Double_t a, Double_t b);
62  inline LongDouble_t Sign(LongDouble_t a, LongDouble_t b);
63 
64  // Min, Max of two scalars
65  inline Short_t Min(Short_t a, Short_t b);
66  inline UShort_t Min(UShort_t a, UShort_t b);
67  inline Int_t Min(Int_t a, Int_t b);
68  inline UInt_t Min(UInt_t a, UInt_t b);
69  inline Long_t Min(Long_t a, Long_t b);
70  inline ULong_t Min(ULong_t a, ULong_t b);
71  inline Long64_t Min(Long64_t a, Long64_t b);
72  inline ULong64_t Min(ULong64_t a, ULong64_t b);
73  inline Float_t Min(Float_t a, Float_t b);
74  inline Double_t Min(Double_t a, Double_t b);
75 
76  inline Short_t Max(Short_t a, Short_t b);
77  inline UShort_t Max(UShort_t a, UShort_t b);
78  inline Int_t Max(Int_t a, Int_t b);
79  inline UInt_t Max(UInt_t a, UInt_t b);
80  inline Long_t Max(Long_t a, Long_t b);
81  inline ULong_t Max(ULong_t a, ULong_t b);
82  inline Long64_t Max(Long64_t a, Long64_t b);
83  inline ULong64_t Max(ULong64_t a, ULong64_t b);
84  inline Float_t Max(Float_t a, Float_t b);
85  inline Double_t Max(Double_t a, Double_t b);
86 
87  // Range
88  inline Short_t Range(Short_t lb, Short_t ub, Short_t x);
89  inline Int_t Range(Int_t lb, Int_t ub, Int_t x);
90  inline Long_t Range(Long_t lb, Long_t ub, Long_t x);
91  inline ULong_t Range(ULong_t lb, ULong_t ub, ULong_t x);
92  inline Double_t Range(Double_t lb, Double_t ub, Double_t x);
93 
94  //NextPrime is used by the Core classes.
95  Long_t NextPrime(Long_t x); // Least prime number greater than x
96 
97  // Binary search
98  template <typename T> Long64_t BinarySearch(Long64_t n, const T *array, T value);
99  template <typename T> Long64_t BinarySearch(Long64_t n, const T **array, T value);
100  template <typename Iterator, typename Element> Iterator BinarySearch(Iterator first, Iterator last, Element value);
101 
102  // Sorting
103  template <typename Element, typename Index>
104  void Sort(Index n, const Element* a, Index* index, Bool_t down=kTRUE);
105  template <typename Iterator, typename IndexIterator>
106  void SortItr(Iterator first, Iterator last, IndexIterator index, Bool_t down=kTRUE);
107 }
108 
109 
110 //---- Even/odd ----------------------------------------------------------------
111 
112 inline Bool_t TMath::Even(Long_t a)
113  { return ! (a & 1); }
114 
115 inline Bool_t TMath::Odd(Long_t a)
116  { return (a & 1); }
117 
118 //---- Abs ---------------------------------------------------------------------
119 
120 inline Short_t TMath::Abs(Short_t d)
121 { return (d >= 0) ? d : Short_t(-d); }
122 
123 inline Int_t TMath::Abs(Int_t d)
124 { return std::abs(d); }
125 
126 inline Long_t TMath::Abs(Long_t d)
127 { return std::labs(d); }
128 
129 inline Long64_t TMath::Abs(Long64_t d)
130 #if __cplusplus >= 201103
131 { return std::llabs(d); }
132 #else
133 { return (d >= 0) ? d : -d; }
134 #endif
135 
136 inline Float_t TMath::Abs(Float_t d)
137 { return std::abs(d); }
138 
139 inline Double_t TMath::Abs(Double_t d)
140 { return std::abs(d); }
141 
142 inline LongDouble_t TMath::Abs(LongDouble_t d)
143 { return std::abs(d); }
144 
145 
146 //---- Sign Bit--------------------------------------------------------------------
147 
148 template<typename Integer>
149 inline Bool_t TMath::SignBit( Integer a)
150  { return (a < 0); }
151 
152 inline Bool_t TMath::SignBit(Float_t a)
153  { return std::signbit(a); }
154 
155 inline Bool_t TMath::SignBit(Double_t a)
156  { return std::signbit(a); }
157 
158 inline Bool_t TMath::SignBit(LongDouble_t a)
159  { return std::signbit(a); }
160 
161 
162 //---- Sign --------------------------------------------------------------------
163 
164 template<typename T1, typename T2>
165 inline T1 TMath::Sign( T1 a, T2 b)
166  { return (SignBit(b)) ? - Abs(a) : Abs(a); }
167 
168 inline Float_t TMath::Sign(Float_t a, Float_t b)
169  { return std::copysign(a,b); }
170 
171 inline Double_t TMath::Sign(Double_t a, Double_t b)
172  { return std::copysign(a,b); }
173 
174 inline LongDouble_t TMath::Sign(LongDouble_t a, LongDouble_t b)
175  { return std::copysign(a,b); }
176 
177 
178 //---- Min ---------------------------------------------------------------------
179 
180 inline Short_t TMath::Min(Short_t a, Short_t b)
181  { return a <= b ? a : b; }
182 
183 inline UShort_t TMath::Min(UShort_t a, UShort_t b)
184  { return a <= b ? a : b; }
185 
186 inline Int_t TMath::Min(Int_t a, Int_t b)
187  { return a <= b ? a : b; }
188 
189 inline UInt_t TMath::Min(UInt_t a, UInt_t b)
190  { return a <= b ? a : b; }
191 
192 inline Long_t TMath::Min(Long_t a, Long_t b)
193  { return a <= b ? a : b; }
194 
195 inline ULong_t TMath::Min(ULong_t a, ULong_t b)
196  { return a <= b ? a : b; }
197 
198 inline Long64_t TMath::Min(Long64_t a, Long64_t b)
199  { return a <= b ? a : b; }
200 
201 inline ULong64_t TMath::Min(ULong64_t a, ULong64_t b)
202  { return a <= b ? a : b; }
203 
204 inline Float_t TMath::Min(Float_t a, Float_t b)
205  { return a <= b ? a : b; }
206 
207 inline Double_t TMath::Min(Double_t a, Double_t b)
208  { return a <= b ? a : b; }
209 
210 //---- Max ---------------------------------------------------------------------
211 
212 inline Short_t TMath::Max(Short_t a, Short_t b)
213  { return a >= b ? a : b; }
214 
215 inline UShort_t TMath::Max(UShort_t a, UShort_t b)
216  { return a >= b ? a : b; }
217 
218 inline Int_t TMath::Max(Int_t a, Int_t b)
219  { return a >= b ? a : b; }
220 
221 inline UInt_t TMath::Max(UInt_t a, UInt_t b)
222  { return a >= b ? a : b; }
223 
224 inline Long_t TMath::Max(Long_t a, Long_t b)
225  { return a >= b ? a : b; }
226 
227 inline ULong_t TMath::Max(ULong_t a, ULong_t b)
228  { return a >= b ? a : b; }
229 
230 inline Long64_t TMath::Max(Long64_t a, Long64_t b)
231  { return a >= b ? a : b; }
232 
233 inline ULong64_t TMath::Max(ULong64_t a, ULong64_t b)
234  { return a >= b ? a : b; }
235 
236 inline Float_t TMath::Max(Float_t a, Float_t b)
237  { return a >= b ? a : b; }
238 
239 inline Double_t TMath::Max(Double_t a, Double_t b)
240  { return a >= b ? a : b; }
241 
242 //---- Range -------------------------------------------------------------------
243 
244 inline Short_t TMath::Range(Short_t lb, Short_t ub, Short_t x)
245  { return x < lb ? lb : (x > ub ? ub : x); }
246 
247 inline Int_t TMath::Range(Int_t lb, Int_t ub, Int_t x)
248  { return x < lb ? lb : (x > ub ? ub : x); }
249 
250 inline Long_t TMath::Range(Long_t lb, Long_t ub, Long_t x)
251  { return x < lb ? lb : (x > ub ? ub : x); }
252 
253 inline ULong_t TMath::Range(ULong_t lb, ULong_t ub, ULong_t x)
254  { return x < lb ? lb : (x > ub ? ub : x); }
255 
256 inline Double_t TMath::Range(Double_t lb, Double_t ub, Double_t x)
257  { return x < lb ? lb : (x > ub ? ub : x); }
258 
259 template <typename Iterator, typename Element>
260 Iterator TMath::BinarySearch(Iterator first, Iterator last, Element value)
261 {
262  // Binary search in an array defined by its iterators.
263  //
264  // The values in the iterators range are supposed to be sorted
265  // prior to this call. If match is found, function returns
266  // position of element. If no match found, function gives nearest
267  // element smaller than value.
268 
269  Iterator pind;
270  pind = std::lower_bound(first, last, value);
271  if ( (pind != last) && (*pind == value) )
272  return pind;
273  else
274  return ( pind - 1);
275 }
276 
277 
278 template <typename T> Long64_t TMath::BinarySearch(Long64_t n, const T *array, T value)
279 {
280  // Binary search in an array of n values to locate value.
281  //
282  // Array is supposed to be sorted prior to this call.
283  // If match is found, function returns position of element.
284  // If no match found, function gives nearest element smaller than value.
285 
286  const T* pind;
287  pind = std::lower_bound(array, array + n, value);
288  if ( (pind != array + n) && (*pind == value) )
289  return (pind - array);
290  else
291  return ( pind - array - 1);
292 }
293 
294 template <typename T> Long64_t TMath::BinarySearch(Long64_t n, const T **array, T value)
295 {
296  // Binary search in an array of n values to locate value.
297  //
298  // Array is supposed to be sorted prior to this call.
299  // If match is found, function returns position of element.
300  // If no match found, function gives nearest element smaller than value.
301 
302  const T* pind;
303  pind = std::lower_bound(*array, *array + n, value);
304  if ( (pind != *array + n) && (*pind == value) )
305  return (pind - *array);
306  else
307  return ( pind - *array - 1);
308 }
309 
310 template<typename T>
311 struct CompareDesc {
312 
313  CompareDesc(T d) : fData(d) {}
314 
315  template<typename Index>
316  bool operator()(Index i1, Index i2) {
317  return *(fData + i1) > *(fData + i2);
318  }
319 
320  T fData;
321 };
322 
323 template<typename T>
324 struct CompareAsc {
325 
326  CompareAsc(T d) : fData(d) {}
327 
328  template<typename Index>
329  bool operator()(Index i1, Index i2) {
330  return *(fData + i1) < *(fData + i2);
331  }
332 
333  T fData;
334 };
335 
336 template <typename Iterator, typename IndexIterator>
337 void TMath::SortItr(Iterator first, Iterator last, IndexIterator index, Bool_t down)
338 {
339  // Sort the n1 elements of the Short_t array defined by its
340  // iterators. In output the array index contains the indices of
341  // the sorted array. If down is false sort in increasing order
342  // (default is decreasing order).
343 
344  // NOTE that the array index must be created with a length bigger
345  // or equal than the main array before calling this function.
346 
347  int i = 0;
348 
349  IndexIterator cindex = index;
350  for ( Iterator cfirst = first; cfirst != last; ++cfirst )
351  {
352  *cindex = i++;
353  ++cindex;
354  }
355 
356  if ( down )
357  std::sort(index, cindex, CompareDesc<Iterator>(first) );
358  else
359  std::sort(index, cindex, CompareAsc<Iterator>(first) );
360 }
361 
362 template <typename Element, typename Index> void TMath::Sort(Index n, const Element* a, Index* index, Bool_t down)
363 {
364  // Sort the n elements of the array a of generic templated type Element.
365  // In output the array index of type Index contains the indices of the sorted array.
366  // If down is false sort in increasing order (default is decreasing order).
367 
368  // NOTE that the array index must be created with a length >= n
369  // before calling this function.
370  // NOTE also that the size type for n must be the same type used for the index array
371  // (templated type Index)
372 
373  for(Index i = 0; i < n; i++) { index[i] = i; }
374  if ( down )
375  std::sort(index, index + n, CompareDesc<const Element*>(a) );
376  else
377  std::sort(index, index + n, CompareAsc<const Element*>(a) );
378 }
379 
380 #endif