Jpp  19.1.0
the software that should make you happy
JRange.hh
Go to the documentation of this file.
1 #ifndef __JTOOLS__JRANGE__
2 #define __JTOOLS__JRANGE__
3 
4 #include <cmath>
5 #include <utility>
6 #include <functional>
7 
8 #include "JLang/JClass.hh"
9 #include "JLang/JBool.hh"
10 #include "JLang/JEquals.hh"
11 #include "JLang/JVectorize.hh"
12 #include "JTools/JPair.hh"
13 #include "JMath/JMath.hh"
14 #include "JMath/JLimits.hh"
15 
16 
17 /**
18  * \file
19  *
20  * Auxiliary class to define a range between two values.
21  * \author mdejong
22  */
23 namespace JTOOLS {}
24 namespace JPP { using namespace JTOOLS; }
25 
26 namespace JTOOLS {
27 
28  using JLANG::JEquals;
29  using JLANG::array_type;
30  using JLANG::make_array;
31  using JMATH::JMath;
32 
33 
34  /**
35  * Range of values.
36  */
37  template<class T, class JComparator_t = std::less<T> >
38  class JRange :
39  public JPair<T,T>,
40  public JEquals< JRange<T> >,
41  public JMath < JRange<T> >
42  {
43  public:
44 
48 
49 
50  /**
51  * Default constructor.\n
52  * This range corresponds to the maximal possible range.
53  */
54  JRange() :
55  JPair<T,T>(getMinimum(), getMaximum())
56  {}
57 
58 
59  /**
60  * Constructor.
61  *
62  * \param pair pair
63  */
64  JRange(const pair_type& pair) :
65  JPair<T,T>(pair.first, pair.second)
66  {}
67 
68 
69  /**
70  * Constructor.
71  *
72  * \param x lower limit
73  * \param y upper limit
74  */
76  argument_type y) :
77  JPair<T,T>(x, y)
78  {}
79 
80 
81  /**
82  * Constructor.
83  *
84  * \param x lower and upper limit
85  */
87  JPair<T,T>(x, x)
88  {}
89 
90 
91  /**
92  * Constructor.\n
93  * The arguments could be values or iterators.
94  *
95  * \param first first
96  * \param second second
97  */
98  template<class R>
100  JPair<T,T>()
101  {
103  }
104 
105 
106  /**
107  * Constructor.
108  *
109  * \param buffer input data
110  */
111  template<class JElement_t, class JAllocator_t>
113  JPair<T,T>()
114  {
115  setRange(buffer);
116  }
117 
118 
119  /**
120  * Type conversion operator.
121  *
122  * \return piar
123  */
124  operator pair_type() const
125  {
127  }
128 
129 
130  /**
131  * Get range.
132  *
133  * \return range
134  */
135  const range_type& getRange() const
136  {
137  return static_cast<const range_type&>(*this);
138  }
139 
140 
141  /**
142  * Set range.
143  *
144  * \param range range
145  */
146  void setRange(const range_type& range)
147  {
148  static_cast<range_type&>(*this) = range;
149  }
150 
151 
152  /**
153  * Set lower and upper limit.
154  *
155  * \param x lower limit
156  * \param y upper limit
157  */
159  {
160  this->first = x;
161  this->second = y;
162  }
163 
164 
165  /**
166  * Set range.\n
167  * The arguments could be values or iterators.
168  *
169  * \param first first
170  * \param second second
171  */
172  template<class R>
173  void setRange(R first, R second)
174  {
175  using namespace JLANG;
176 
178  }
179 
180 
181  /**
182  * Set lower and upper limit according to input data.
183  *
184  * \param buffer input data
185  */
186  template<class JElement_t, class JAllocator_t>
188  {
190 
191  for (typename array_type<JElement_t, JAllocator_t>::const_iterator i = buffer.begin(); i != buffer.end(); ++i) {
192  include(*i);
193  }
194  }
195 
196 
197  /**
198  * Get lower limit.
199  *
200  * \return lower limit
201  */
202  T getLowerLimit() const
203  {
204  return this->first;
205  }
206 
207 
208  /**
209  * Get upper limit.
210  *
211  * \return upper limit
212  */
213  T getUpperLimit() const
214  {
215  return this->second;
216  }
217 
218 
219  /**
220  * Set lower limit.
221  *
222  * \param x lower limit
223  */
224  void setLowerLimit(argument_type x)
225  {
226  this->first = x;
227  }
228 
229 
230  /**
231  * Set upper limit.
232  *
233  * \param y upper limit
234  */
235  void setUpperLimit(argument_type y)
236  {
237  this->second = y;
238  }
239 
240 
241  /**
242  * Fix lower limit.
243  *
244  * The range is shifted to the given lower limit.
245  *
246  * \param x lower limit
247  */
248  void fixLowerLimit(argument_type x)
249  {
250  this->second += x - this->first;
251  this->first = x;
252  }
253 
254 
255  /**
256  * Fix upper limit.
257  *
258  * The range is shifted to the given upper limit.
259  *
260  * \param y upper limit
261  */
263  {
264  this->first += y - this->second;
265  this->second = y;
266  }
267 
268 
269  /**
270  * Equal method.
271  *
272  * \param range range
273  * \result true if this range is equal to given range; else false
274  */
275  inline bool equals(const range_type& range) const
276  {
277  return (!this->compare(this->getLowerLimit(), range.getLowerLimit()) &&
278  !this->compare(range.getLowerLimit(), this->getLowerLimit()) &&
279  !this->compare(this->getUpperLimit(), range.getUpperLimit()) &&
280  !this->compare(range.getUpperLimit(), this->getUpperLimit()));
281  }
282 
283 
284  /**
285  * Get length (difference between upper and lower limit).
286  *
287  * \return length
288  */
289  T getLength() const
290  {
291  return getUpperLimit() - getLowerLimit();
292  }
293 
294 
295  /**
296  * Set length (difference between upper and lower limit).
297  *
298  * \param length length
299  */
301  {
302  setUpperLimit(getLowerLimit() + length);
303  }
304 
305 
306  /**
307  * Check validity of range.
308  *
309  * \return true if lower limit less than or equal to upper limit; else false
310  */
311  bool is_valid() const
312  {
313  return !compare(getUpperLimit(), getLowerLimit());
314  }
315 
316 
317  /**
318  * Test whether value is inside range.
319  *
320  * \param x value
321  * \return true if lower limit <= value <= upper limit; else false
322  */
324  {
325  return (!compare(x, getLowerLimit()) &&
326  !compare(getUpperLimit(), x));
327  }
328 
329 
330  /**
331  * Test whether value is inside range.
332  *
333  * \param x value
334  * \return true if lower limit <= value <= upper limit; else false
335  */
337  {
338  return in_range(x);
339  }
340 
341 
342  /**
343  * Constrain value to range.\n
344  * This method returns the original value if it is in this range, else
345  * lower limit if value < lower limit or upper limit if value > upper limit.
346  *
347  * \param x value
348  * \return lower limit <= x <= upper limit
349  */
351  {
352  if (compare(x, getLowerLimit())) { return getLowerLimit(); }
353  if (compare(getUpperLimit(), x)) { return getUpperLimit(); }
354 
355  return x;
356  }
357 
358 
359  /**
360  * Modulo value with respect to range.\n
361  *
362  * \param x value
363  * \return lower limit <= x <= upper limit
364  */
365  T mod(argument_type x) const
366  {
367  if (compare(x, getLowerLimit()))
368  return x + getLength() * floor((getUpperLimit() - x) / getLength());
369  else if (compare(getUpperLimit(), x))
370  return x - getLength() * floor((x - getLowerLimit()) / getLength());
371  else
372  return x;
373  }
374 
375 
376  /**
377  * Test overlap with given range.\n
378  *
379  * \param range range
380  * \return true if there is a non-zero overlap; else false
381  */
382  bool overlap(const range_type& range) const
383  {
384  return (!compare(range.getUpperLimit(), getLowerLimit()) &&
385  !compare(getUpperLimit(), range.getLowerLimit()));
386  }
387 
388 
389  /**
390  * Include given value to range.\n
391  * The new lower limit is the minimim of the original lower limit and given value and\n
392  * the new upper limit is the maximum of the original upper limit and given value;
393  *
394  * \param x value
395  * \return range
396  */
398  {
399  if (compare(x, getLowerLimit())) { setLowerLimit(x); }
400  if (compare(getUpperLimit(), x)) { setUpperLimit(x); }
401 
402  return *this;
403  }
404 
405 
406  /**
407  * Join ranges.\n
408  * The new lower limit is the maximim of the two lower limits and\n
409  * the new upper limit is the minimum of the two upper limits.\n
410  * This operation results in an equal or smaller range and
411  * may result in an unphysical range (i.e.\ lower limit > upper limit).
412  *
413  * \param range range
414  */
415  range_type& join(const range_type& range)
416  {
417  if (compare(getLowerLimit(), range.getLowerLimit())) { setLowerLimit(range.getLowerLimit()); }
418  if (compare(range.getUpperLimit(), getUpperLimit())) { setUpperLimit(range.getUpperLimit()); }
419 
420  return *this;
421  }
422 
423 
424  /**
425  * Combine ranges.\n
426  * The new lower limit is the minimim of the two lower limits and\n
427  * the new upper limit is the maximum of the two upper limits.\n
428  * This operation results in an equal or larger range.
429  *
430  * \param range range
431  */
433  {
434  if (compare(range.getLowerLimit(), getLowerLimit())) { setLowerLimit(range.getLowerLimit()); }
435  if (compare(getUpperLimit(), range.getUpperLimit())) { setUpperLimit(range.getUpperLimit()); }
436 
437  return *this;
438  }
439 
440 
441  /**
442  * Add offset.
443  *
444  * \param x offset
445  */
447  {
448  this->first += x;
449  this->second += x;
450 
451  return *this;
452  }
453 
454 
455  /**
456  * Subtract offset.
457  *
458  * \param x offset
459  */
460  range_type& sub(argument_type x)
461  {
462  this->first -= x;
463  this->second -= x;
464 
465  return *this;
466  }
467 
468 
469  /**
470  * Add offsets.\n
471  * The new lower limit is the sum of the two lower limits and\n
472  * the new upper limit is the sum of the two upper limits.
473  *
474  * \param range offset
475  */
476  range_type& add(const range_type& range)
477  {
478  this->first += range.getLowerLimit();
479  this->second += range.getUpperLimit();
480 
481  return *this;
482  }
483 
484 
485  /**
486  * Subtract offsets.\n
487  * The new lower limit is the difference of the two lower limits and\n
488  * the new upper limit is the difference of the two upper limits.
489  *
490  * \param range offset
491  */
492  range_type& sub(const range_type& range)
493  {
494  this->first -= range.getLowerLimit();
495  this->second -= range.getUpperLimit();
496 
497  return *this;
498  }
499 
500 
501  /**
502  * Multiply range.
503  *
504  * \param factor factor
505  */
506  range_type& mul(const double factor)
507  {
508  this->first *= factor;
509  this->second *= factor;
510 
511  return *this;
512  }
513 
514 
515  /**
516  * Divide range.
517  *
518  * \param factor factor
519  */
520  range_type& div(const double factor)
521  {
522  this->first /= factor;
523  this->second /= factor;
524 
525  return *this;
526  }
527 
528 
529  /**
530  * Get minimum possible value.
531  *
532  * \return minimum possible value
533  */
534  static T getMinimum()
535  {
536  return JMATH::JLimits<T>::min();
537  }
538 
539 
540  /**
541  * Get maximum possible value.
542  *
543  * \return maximum possible value
544  */
545  static T getMaximum()
546  {
547  return JMATH::JLimits<T>::max();
548  }
549 
550 
551  /**
552  * Default range.
553  * This range corresponds to an unphysical range.
554  */
556  {
559  }
560 
561 
562  /**
563  * Function object for comparisons.
564  */
565  JComparator_t compare;
566 
567  protected:
568  /**
569  * Set range.
570  *
571  * \param first first
572  * \param second second
573  * \param option false
574  */
575  template<class R>
576  void setRange(R first, R second, const JLANG::JBool<false>& option)
577  {
579  }
580 
581 
582  /**
583  * Set range.
584  *
585  * \param first first
586  * \param second second
587  * \param option true
588  */
589  template<class R>
590  void setRange(R first, R second, const JLANG::JBool<true>& option)
591  {
593 
594  for (R i = first; i != second; ++i) {
595  include(*i);
596  }
597  }
598  };
599 
600 
601  /**
602  * Add ranges.\n
603  * The new lower limit is the sum of the two lower limits and\n
604  * the new upper limit is the sum of the two upper limits.
605  *
606  * \param first first range
607  * \param second second range
608  * \result range
609  */
610  template<class T, class JComparator_t>
612  {
614  }
615 
616 
617  /**
618  * Subtract ranges.\n
619  * The new lower limit is the difference of the two lower limits and
620  * the new upper limit is the difference of the two upper limits.
621  *
622  * \param first first range
623  * \param second second range
624  * \result range
625  */
626  template<class T, class JComparator_t>
628  {
630  }
631 
632 
633  /**
634  * Test overlap between ranges.
635  *
636  * \param first first range
637  * \param second second range
638  * \return true if there is a non-zero overlap; else false
639  */
640  template<class T, class JComparator_t>
642  {
643  return first.overlap(second);
644  }
645 
646 
647  /**
648  * Join ranges.\n
649  * The new lower limit is the maximim of the two lower limits and\n
650  * the new upper limit is the minimum of the two upper limits.\n
651  * This operation results in an equal or smaller range and
652  * may result in an unphysical range (i.e.\ lower limit > upper limit).
653  *
654  * \param first first range
655  * \param second second range
656  * \result range
657  */
658  template<class T, class JComparator_t>
660  {
662  }
663 
664 
665  /**
666  * Combine ranges.\n
667  * The new lower limit is the minimim of the two lower limits and\n
668  * the new upper limit is the maximum of the two upper limits.\n
669  * This operation results in an equal or larger range.
670  *
671  * \param first first range
672  * \param second second range
673  * \result range
674  */
675  template<class T, class JComparator_t>
677  {
679  }
680 
681 
682  /**
683  * Auxiliary method to create range of values.
684  *
685  * \param x lower limit
686  * \param y upper limit
687  * \return range
688  */
689  template<class T>
690  inline JRange<T> make_range(T x, T y)
691  {
692  return JRange<T>(x,y);
693  }
694 
695 
696  /**
697  * Get expected number of occurrences due to given rate within specified interval.
698  *
699  * \param range interval
700  * \param R rate
701  * \return expectation value
702  */
703  template<class T>
704  inline double getN(const JRange<T>& range, const double R)
705  {
706  return R * (range.getUpperLimit() - range.getLowerLimit());
707  }
708 }
709 
710 #endif
Definition of minimum and maximum values for any class.
Base class for data structures with artithmetic capabilities.
Auxiliary methods to convert data members or return values of member methods of a set of objects to a...
Vec operator-(const Vec &a, const Vec &b)
Subtract two vectors.
Definition: Vec.hh:346
Vec operator+(const Vec &a, const Vec &b)
Add two vectors.
Definition: Vec.hh:337
Template specialisation for a pair of values.
Definition: JPair.hh:29
Range of values.
Definition: JRange.hh:42
std::pair< T, T > pair_type
Definition: JRange.hh:45
range_type & join(const range_type &range)
Join ranges.
Definition: JRange.hh:415
range_type & include(argument_type x)
Include given value to range.
Definition: JRange.hh:397
void setUpperLimit(argument_type y)
Set upper limit.
Definition: JRange.hh:235
void setRange(const range_type &range)
Set range.
Definition: JRange.hh:146
JRange< T, JComparator_t > range_type
Definition: JRange.hh:46
bool is_valid() const
Check validity of range.
Definition: JRange.hh:311
JRange()
Default constructor.
Definition: JRange.hh:54
void setLength(argument_type length)
Set length (difference between upper and lower limit).
Definition: JRange.hh:300
range_type & div(const double factor)
Divide range.
Definition: JRange.hh:520
range_type & mul(const double factor)
Multiply range.
Definition: JRange.hh:506
range_type & sub(const range_type &range)
Subtract offsets.
Definition: JRange.hh:492
void setRange(R first, R second, const JLANG::JBool< true > &option)
Set range.
Definition: JRange.hh:590
void setRange(const array_type< JElement_t, JAllocator_t > &buffer)
Set lower and upper limit according to input data.
Definition: JRange.hh:187
T getLength() const
Get length (difference between upper and lower limit).
Definition: JRange.hh:289
void setRange(R first, R second)
Set range.
Definition: JRange.hh:173
const range_type & getRange() const
Get range.
Definition: JRange.hh:135
T constrain(argument_type x) const
Constrain value to range.
Definition: JRange.hh:350
bool overlap(const range_type &range) const
Test overlap with given range.
Definition: JRange.hh:382
range_type & add(argument_type x)
Add offset.
Definition: JRange.hh:446
T getLowerLimit() const
Get lower limit.
Definition: JRange.hh:202
void setLowerLimit(argument_type x)
Set lower limit.
Definition: JRange.hh:224
static JRange< T, JComparator_t > DEFAULT_RANGE()
Default range.
Definition: JRange.hh:555
void setRange(argument_type x, argument_type y)
Set lower and upper limit.
Definition: JRange.hh:158
T mod(argument_type x) const
Modulo value with respect to range.
Definition: JRange.hh:365
void setRange(R first, R second, const JLANG::JBool< false > &option)
Set range.
Definition: JRange.hh:576
JRange(R first, R second)
Constructor.
Definition: JRange.hh:99
JRange(const array_type< JElement_t, JAllocator_t > &buffer)
Constructor.
Definition: JRange.hh:112
bool in_range(argument_type x) const
Test whether value is inside range.
Definition: JRange.hh:323
bool operator()(argument_type x) const
Test whether value is inside range.
Definition: JRange.hh:336
range_type & combine(const range_type &range)
Combine ranges.
Definition: JRange.hh:432
void fixLowerLimit(argument_type x)
Fix lower limit.
Definition: JRange.hh:248
JRange(argument_type x, argument_type y)
Constructor.
Definition: JRange.hh:75
JRange(const pair_type &pair)
Constructor.
Definition: JRange.hh:64
JComparator_t compare
Function object for comparisons.
Definition: JRange.hh:565
void fixUpperLimit(argument_type y)
Fix upper limit.
Definition: JRange.hh:262
static T getMaximum()
Get maximum possible value.
Definition: JRange.hh:545
JRange(argument_type x)
Constructor.
Definition: JRange.hh:86
static T getMinimum()
Get minimum possible value.
Definition: JRange.hh:534
bool equals(const range_type &range) const
Equal method.
Definition: JRange.hh:275
JLANG::JClass< T >::argument_type argument_type
Definition: JRange.hh:47
range_type & sub(argument_type x)
Subtract offset.
Definition: JRange.hh:460
T getUpperLimit() const
Get upper limit.
Definition: JRange.hh:213
range_type & add(const range_type &range)
Add offsets.
Definition: JRange.hh:476
Auxiliary classes and methods for language specific functionality.
const array_type< JValue_t > & make_array(const JValue_t(&array)[N])
Method to create array of values.
Definition: JVectorize.hh:54
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for multi-dimensional interpolations and histograms.
JRange< T > make_range(T x, T y)
Auxiliary method to create range of values.
Definition: JRange.hh:690
double getN(const JRange< T > &range, const double R)
Get expected number of occurrences due to given rate within specified interval.
Definition: JRange.hh:704
Auxiliary template class for type bool.
Definition: JBool.hh:21
JArgument< T >::argument_type argument_type
Definition: JClass.hh:82
Template definition of auxiliary base class for comparison of data structures.
Definition: JEquals.hh:84
Auxiliary data structure for return type of make methods.
Definition: JVectorize.hh:28
Data structure to check whether given data type is an iterator.
Definition: JClass.hh:62
float min()
Get minimum possible value.
Definition: JLimits.hh:96
TTimeStamp max()
Get maximum possible value.
Auxiliary base class for aritmetic operations of derived class types.
Definition: JMath.hh:347