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