Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JRange.hh
Go to the documentation of this file.
1 #ifndef __JTOOLS__JRANGE__
2 #define __JTOOLS__JRANGE__
3 
4 #include <cmath>
5 #include <functional>
6 
7 #include "JLang/JClass.hh"
8 #include "JLang/JEquals.hh"
9 #include "JTools/JPair.hh"
10 #include "JMath/JMath.hh"
11 #include "JMath/JLimits.hh"
12 
13 
14 /**
15  * \file
16  *
17  * Auxiliary class to define a range between two values.
18  * \author mdejong
19  */
20 namespace JTOOLS {}
21 namespace JPP { using namespace JTOOLS; }
22 
23 namespace JTOOLS {
24 
25  using JLANG::JEquals;
26  using JMATH::JMath;
27 
28 
29  /**
30  * Range of values.
31  */
32  template<class T, class JComparator_t = std::less<T> >
33  class JRange :
34  public JPair<T,T>,
35  public JEquals< JRange<T> >,
36  public JMath < JRange<T> >
37  {
38  public:
39 
42 
43 
44  /**
45  * Default constructor.
46  * This range corresponds to the maximal possible range.
47  */
48  JRange() :
49  JPair<T,T>(getMinimum(), getMaximum())
50  {}
51 
52 
53  /**
54  * Constructor.
55  *
56  * \param x lower limit
57  * \param y upper limit
58  */
60  argument_type y) :
61  JPair<T,T>(x, y)
62  {}
63 
64 
65  /**
66  * Constructor.
67  *
68  * \param x lower and upper limit
69  */
71  JPair<T,T>(x, x)
72  {}
73 
74 
75  /**
76  * Constructor.
77  *
78  * \param __begin begin of data
79  * \param __end end of data
80  * \param member pointer to data member
81  */
82  template<class iterator_type, class value_type, class result_type>
83  JRange(iterator_type __begin, iterator_type __end, result_type value_type::*member) :
84  JPair<T,T>(getMinimum(), getMaximum())
85  {
86  setRange(__begin, __end, member);
87  }
88 
89 
90  /**
91  * Constructor.
92  *
93  * \param __begin begin of data
94  * \param __end end of data
95  * \param function pointer to member method
96  */
97  template<class iterator_type, class value_type, class result_type>
98  JRange(iterator_type __begin, iterator_type __end, result_type (value_type::*function)() const) : JPair<T,T>(getMinimum(), getMaximum())
99  {
100  setRange(__begin, __end, function);
101  }
102 
103 
104  /**
105  * Get range.
106  *
107  * \return range
108  */
109  const range_type& getRange() const
110  {
111  return static_cast<const range_type&>(*this);
112  }
113 
114 
115  /**
116  * Set range.
117  *
118  * \param range range
119  */
120  void setRange(const range_type& range)
121  {
122  static_cast<range_type&>(*this) = range;
123  }
124 
125 
126  /**
127  * Set lower and uppper limit.
128  *
129  * \param x lower limit
130  * \param y upper limit
131  */
133  {
134  this->first = x;
135  this->second = y;
136  }
137 
138 
139  /**
140  * Set lower and uppper limit.
141  *
142  * \param __begin begin of data
143  * \param __end end of data
144  * \param member pointer to data member
145  */
146  template<class iterator_type, class value_type, class result_type>
147  void setRange(iterator_type __begin, iterator_type __end, result_type value_type::*member)
148  {
150 
151  for (iterator_type i = __begin; i != __end; ++i) {
152  include((*i).*member);
153  }
154  }
155 
156 
157  /**
158  * Set lower and uppper limit.
159  *
160  * \param __begin begin of data
161  * \param __end end of data
162  * \param function pointer to member method
163  */
164  template<class iterator_type, class value_type, class result_type>
165  void setRange(iterator_type __begin, iterator_type __end, result_type (value_type::*function)() const)
166  {
168 
169  for (iterator_type i = __begin; i != __end; ++i) {
170  include(((*i).*function)());
171  }
172  }
173 
174 
175  /**
176  * Get lower limit.
177  *
178  * \return lower limit
179  */
180  T getLowerLimit() const
181  {
182  return this->first;
183  }
184 
185 
186  /**
187  * Get upper limit.
188  *
189  * \return upper limit
190  */
191  T getUpperLimit() const
192  {
193  return this->second;
194  }
195 
196 
197  /**
198  * Set lower limit.
199  *
200  * \param x lower limit
201  */
203  {
204  this->first = x;
205  }
206 
207 
208  /**
209  * Set upper limit.
210  *
211  * \param y upper limit
212  */
214  {
215  this->second = y;
216  }
217 
218 
219  /**
220  * Fix lower limit.
221  *
222  * The range is shifted to the given lower limit.
223  *
224  * \param x lower limit
225  */
227  {
228  this->second += x - this->first;
229  this->first = x;
230  }
231 
232 
233  /**
234  * Fix upper limit.
235  *
236  * The range is shifted to the given upper limit.
237  *
238  * \param y upper limit
239  */
241  {
242  this->first += y - this->second;
243  this->second = y;
244  }
245 
246 
247  /**
248  * Equal method.
249  *
250  * \param range range
251  * \result true if this module range equal to given module range; else false
252  */
253  inline bool equals(const range_type& range) const
254  {
255  return (!this->compare(this->getLowerLimit(), range.getLowerLimit()) &&
256  !this->compare(range.getLowerLimit(), this->getLowerLimit()) &&
257  !this->compare(this->getUpperLimit(), range.getUpperLimit()) &&
258  !this->compare(range.getUpperLimit(), this->getUpperLimit()));
259  }
260 
261 
262  /**
263  * Get length (difference between upper and lower limit).
264  *
265  * \return length
266  */
267  T getLength() const
268  {
269  return getUpperLimit() - getLowerLimit();
270  }
271 
272 
273  /**
274  * Check validity of range.
275  *
276  * \return true if lower limit less than or equal to upper limit; else false
277  */
278  bool is_valid() const
279  {
280  return !compare(getUpperLimit(), getLowerLimit());
281  }
282 
283 
284  /**
285  * Test whether value is inside range.
286  *
287  * \param x value
288  * \return true if lower limit <= value <= upper limit; else false
289  */
290  bool operator()(argument_type x) const
291  {
292  return (!compare(x, getLowerLimit()) &&
293  !compare(getUpperLimit(), x));
294  }
295 
296 
297  /**
298  * Constrain value to range.
299  * This method returns the original value if it is in this range, else
300  * lower limit if value < lower limit or upper limit if value > upper limit.
301  *
302  * \param x value
303  * \return lower limit <= x <= upper limit
304  */
306  {
307  if (compare(x, getLowerLimit())) return getLowerLimit();
308  if (compare(getUpperLimit(), x)) return getUpperLimit();
309 
310  return x;
311  }
312 
313 
314  /**
315  * Test overlap with given range.
316  * The result is equivalent to join(range).is_valid().
317  *
318  * \param range range
319  * \return true if there is a non-zero overlap; else false
320  */
321  bool overlap(const range_type& range) const
322  {
323  return (compare(getLowerLimit(), range.getUpperLimit()) &&
324  compare(range.getLowerLimit(), getUpperLimit()));
325  }
326 
327 
328  /**
329  * Include given value to range.
330  * The new lower limit is the minimim of the original lower limit and given value and
331  * the new upper limit is the maximum of the original upper limit and given value;
332  *
333  * \param x value
334  * \return range
335  */
337  {
338  if (compare(x, getLowerLimit())) setLowerLimit(x);
339  if (compare(getUpperLimit(), x)) setUpperLimit(x);
340 
341  return *this;
342  }
343 
344 
345  /**
346  * Join ranges.
347  * The new lower limit is the maximim of the two lower limits and
348  * the new upper limit is the minimum of the two upper limits.
349  * This operation results in an equal or smaller range and
350  * may result in an unphysical range (i.e. lower limit > upper limit).
351  *
352  * \param range range
353  */
354  range_type& join(const range_type& range)
355  {
358 
359  return *this;
360  }
361 
362 
363  /**
364  * Combine ranges.
365  * The new lower limit is the minimim of the two lower limits and
366  * the new upper limit is the maximum of the two upper limits.
367  * This operation results in an equal or larger range.
368  *
369  * \param range range
370  */
372  {
375 
376  return *this;
377  }
378 
379 
380  /**
381  * Add offset.
382  *
383  * \param x offset
384  */
386  {
387  this->first += x;
388  this->second += x;
389 
390  return *this;
391  }
392 
393 
394  /**
395  * Subtract offset.
396  *
397  * \param x offset
398  */
400  {
401  this->first -= x;
402  this->second -= x;
403 
404  return *this;
405  }
406 
407 
408  /**
409  * Add offset.
410  * The new lower limit is the sum of the two lower limits and
411  * the new upper limit is the sum of the two upper limits.
412  *
413  * \param range offset
414  */
415  range_type& add(const range_type& range)
416  {
417  this->first += range.getLowerLimit();
418  this->second += range.getUpperLimit();
419 
420  return *this;
421  }
422 
423 
424  /**
425  * Subtract offset.
426  * The new lower limit is the difference of the two lower limits and
427  * the new upper limit is the difference of the two upper limits.
428  *
429  * \param range offset
430  */
431  range_type& sub(const range_type& range)
432  {
433  this->first -= range.getLowerLimit();
434  this->second -= range.getUpperLimit();
435 
436  return *this;
437  }
438 
439 
440  /**
441  * Multiply range.
442  *
443  * \param factor factor
444  */
445  range_type& mul(const double factor)
446  {
447  this->first *= factor;
448  this->second *= factor;
449 
450  return *this;
451  }
452 
453 
454  /**
455  * Divide range.
456  *
457  * \param factor factor
458  */
459  range_type& div(const double factor)
460  {
461  this->first /= factor;
462  this->second /= factor;
463 
464  return *this;
465  }
466 
467 
468  /**
469  * Get expected number of occurances of given rate within this interval.
470  *
471  * \param R rate
472  * \return expectation value
473  */
474  T getN(const double R) const
475  {
476  return R * (getUpperLimit() - getLowerLimit());
477  }
478 
479 
480  /**
481  * Get minimum possible value.
482  *
483  * \return minimum possible value
484  */
485  static T getMinimum()
486  {
487  return JMATH::JLimits<T>::min();
488  }
489 
490 
491  /**
492  * Get maximum possible value.
493  *
494  * \return maximum possible value
495  */
496  static T getMaximum()
497  {
498  return JMATH::JLimits<T>::max();
499  }
500 
501 
502  /**
503  * Default range.
504  * This range corresponds to an unphysical range.
505  */
507 
508 
509  /**
510  * Function object.
511  *
512  * \param first first argument
513  * \param second second argument
514  * \return true if first < second; else false
515  */
516  JComparator_t compare;
517  };
518 
519 
520  /**
521  * Default range.
522  * This range corresponds to an unphysical range.
523  */
524  template<class T, class JComparator_t>
527 
528 
529  /**
530  * Add ranges.
531  * The new lower limit is the sum of the two lower limits and
532  * the new upper limit is the sum of the two upper limits.
533  *
534  * \param first first range
535  * \param second second range
536  * \result range
537  */
538  template<class T, class JComparator_t>
540  {
541  return JRange<T, JComparator_t>(first).add(second);
542  }
543 
544 
545  /**
546  * Subtract ranges.
547  * The new lower limit is the difference of the two lower limits and
548  * the new upper limit is the difference of the two upper limits.
549  *
550  * \param first first range
551  * \param second second range
552  * \result range
553  */
554  template<class T, class JComparator_t>
556  {
557  return JRange<T, JComparator_t>(first).sub(second);
558  }
559 
560 
561  /**
562  * Join ranges.
563  * The new lower limit is the maximim of the two lower limits and
564  * the new upper limit is the minimum of the two upper limits.
565  * This operation results in an equal or smaller range and
566  * may result in an unphysical range (i.e. lower limit > upper limit).
567  *
568  * \param first first range
569  * \param second second range
570  * \result range
571  */
572  template<class T, class JComparator_t>
574  {
575  return JRange<T, JComparator_t>(first).join(second);
576  }
577 
578 
579  /**
580  * Combine ranges.
581  * The new lower limit is the minimim of the two lower limits and
582  * the new upper limit is the maximum of the two upper limits.
583  * This operation results in an equal or larger range.
584  *
585  * \param first first range
586  * \param second second range
587  * \result range
588  */
589  template<class T, class JComparator_t>
591  {
592  return JRange<T, JComparator_t>(first).combine(second);
593  }
594 
595 
596  /**
597  * Auxiliary method to create range of values.
598  *
599  * \param x lower limit
600  * \param y upper limit
601  * \return range
602  */
603  template<class T>
604  inline JRange<T> make_range(T x, T y)
605  {
606  return JRange<T>(x,y);
607  }
608 }
609 
610 #endif
static const JRange< T, JComparator_t > DEFAULT_RANGE
Default range.
Definition: JRange.hh:506
bool equals(const range_type &range) const
Equal method.
Definition: JRange.hh:253
T getLowerLimit() const
Get lower limit.
Definition: JRange.hh:180
range_type & mul(const double factor)
Multiply range.
Definition: JRange.hh:445
JRange()
Default constructor.
Definition: JRange.hh:48
Auxiliary base class for aritmetic operations of derived class types.
Definition: JMath.hh:26
range_type include(argument_type x)
Include given value to range.
Definition: JRange.hh:336
JRange< T, JComparator_t > join(const JRange< T, JComparator_t > &first, const JRange< T, JComparator_t > &second)
Join ranges.
Definition: JRange.hh:573
void setRange(iterator_type __begin, iterator_type __end, result_type value_type::*member)
Set lower and uppper limit.
Definition: JRange.hh:147
Definition of minimum and maximum values for any class.
JComparator_t compare
Function object.
Definition: JRange.hh:516
Auxiliary class for minimum and maximum values for any class.
Definition: JLimits.hh:21
range_type & combine(const range_type &range)
Combine ranges.
Definition: JRange.hh:371
T getN(const double R) const
Get expected number of occurances of given rate within this interval.
Definition: JRange.hh:474
void setUpperLimit(argument_type y)
Set upper limit.
Definition: JRange.hh:213
JRange(argument_type x)
Constructor.
Definition: JRange.hh:70
T getLength() const
Get length (difference between upper and lower limit).
Definition: JRange.hh:267
static T getMinimum()
Get minimum possible value.
Definition: JRange.hh:485
range_type & sub(argument_type x)
Subtract offset.
Definition: JRange.hh:399
range_type & sub(const range_type &range)
Subtract offset.
Definition: JRange.hh:431
Template specialisation for a pair of values.
Definition: JPair.hh:28
JArgument< T >::argument_type argument_type
Definition: JClass.hh:64
void fixUpperLimit(argument_type y)
Fix upper limit.
Definition: JRange.hh:240
JRange(argument_type x, argument_type y)
Constructor.
Definition: JRange.hh:59
JRange(iterator_type __begin, iterator_type __end, result_type value_type::*member)
Constructor.
Definition: JRange.hh:83
range_type & add(argument_type x)
Add offset.
Definition: JRange.hh:385
void setRange(const range_type &range)
Set range.
Definition: JRange.hh:120
JLANG::JClass< T >::argument_type argument_type
Definition: JRange.hh:41
void setRange(argument_type x, argument_type y)
Set lower and uppper limit.
Definition: JRange.hh:132
Template definition of auxiliary base class for comparison of data structures.
Definition: JEquals.hh:24
JRange< T > make_range(T x, T y)
Auxiliary method to create range of values.
Definition: JRange.hh:604
T getUpperLimit() const
Get upper limit.
Definition: JRange.hh:191
JRange< T, JComparator_t > operator-(const JRange< T, JComparator_t > &first, const JRange< T, JComparator_t > &second)
Subtract ranges.
Definition: JRange.hh:555
JSubscriptionList operator+(const JSubscription &first, const JSubscription &second)
Add operator.
bool operator()(argument_type x) const
Test whether value is inside range.
Definition: JRange.hh:290
static T getMaximum()
Get maximum possible value.
Definition: JRange.hh:496
T constrain(argument_type x) const
Constrain value to range.
Definition: JRange.hh:305
JRange(iterator_type __begin, iterator_type __end, result_type(value_type::*function)() const)
Constructor.
Definition: JRange.hh:98
const range_type & getRange() const
Get range.
Definition: JRange.hh:109
Range of values.
Definition: JRange.hh:33
JRange< T, JComparator_t > combine(const JRange< T, JComparator_t > &first, const JRange< T, JComparator_t > &second)
Combine ranges.
Definition: JRange.hh:590
range_type & add(const range_type &range)
Add offset.
Definition: JRange.hh:415
void setRange(iterator_type __begin, iterator_type __end, result_type(value_type::*function)() const)
Set lower and uppper limit.
Definition: JRange.hh:165
bool is_valid() const
Check validity of range.
Definition: JRange.hh:278
float min()
Definition: JLimits.hh:96
Base class for data structures with artithmetic capabilities.
JRange< T, JComparator_t > range_type
Definition: JRange.hh:40
bool overlap(const range_type &range) const
Test overlap with given range.
Definition: JRange.hh:321
range_type & div(const double factor)
Divide range.
Definition: JRange.hh:459
void setLowerLimit(argument_type x)
Set lower limit.
Definition: JRange.hh:202
void fixLowerLimit(argument_type x)
Fix lower limit.
Definition: JRange.hh:226
range_type & join(const range_type &range)
Join ranges.
Definition: JRange.hh:354