Jpp  15.0.3
the software that should make you happy
 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 <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() :
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  {
102  setRange(first, second);
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>
174  {
175  using namespace JLANG;
176 
177  setRange(first, second, JBool<is_iterator<R>::value>());
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  */
225  {
226  this->first = x;
227  }
228 
229 
230  /**
231  * Set upper limit.
232  *
233  * \param y upper limit
234  */
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  */
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 module range equal to given module 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  */
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  * The result is equivalent to join(range).is_valid().
379  *
380  * \param range range
381  * \return true if there is a non-zero overlap; else false
382  */
383  bool overlap(const range_type& range) const
384  {
385  return (compare(getLowerLimit(), range.getUpperLimit()) &&
386  compare(range.getLowerLimit(), getUpperLimit()));
387  }
388 
389 
390  /**
391  * Include given value to range.\n
392  * The new lower limit is the minimim of the original lower limit and given value and\n
393  * the new upper limit is the maximum of the original upper limit and given value;
394  *
395  * \param x value
396  * \return range
397  */
399  {
400  if (compare(x, getLowerLimit())) { setLowerLimit(x); }
401  if (compare(getUpperLimit(), x)) { setUpperLimit(x); }
402 
403  return *this;
404  }
405 
406 
407  /**
408  * Join ranges.\n
409  * The new lower limit is the maximim of the two lower limits and\n
410  * the new upper limit is the minimum of the two upper limits.\n
411  * This operation results in an equal or smaller range and
412  * may result in an unphysical range (i.e.\ lower limit > upper limit).
413  *
414  * \param range range
415  */
417  {
418  if (compare(getLowerLimit(), range.getLowerLimit())) { setLowerLimit(range.getLowerLimit()); }
419  if (compare(range.getUpperLimit(), getUpperLimit())) { setUpperLimit(range.getUpperLimit()); }
420 
421  return *this;
422  }
423 
424 
425  /**
426  * Combine ranges.\n
427  * The new lower limit is the minimim of the two lower limits and\n
428  * the new upper limit is the maximum of the two upper limits.\n
429  * This operation results in an equal or larger range.
430  *
431  * \param range range
432  */
434  {
435  if (compare(range.getLowerLimit(), getLowerLimit())) { setLowerLimit(range.getLowerLimit()); }
436  if (compare(getUpperLimit(), range.getUpperLimit())) { setUpperLimit(range.getUpperLimit()); }
437 
438  return *this;
439  }
440 
441 
442  /**
443  * Add offset.
444  *
445  * \param x offset
446  */
448  {
449  this->first += x;
450  this->second += x;
451 
452  return *this;
453  }
454 
455 
456  /**
457  * Subtract offset.
458  *
459  * \param x offset
460  */
462  {
463  this->first -= x;
464  this->second -= x;
465 
466  return *this;
467  }
468 
469 
470  /**
471  * Add offsets.\n
472  * The new lower limit is the sum of the two lower limits and\n
473  * the new upper limit is the sum of the two upper limits.
474  *
475  * \param range offset
476  */
478  {
479  this->first += range.getLowerLimit();
480  this->second += range.getUpperLimit();
481 
482  return *this;
483  }
484 
485 
486  /**
487  * Subtract offsets.\n
488  * The new lower limit is the difference of the two lower limits and\n
489  * the new upper limit is the difference of the two upper limits.
490  *
491  * \param range offset
492  */
494  {
495  this->first -= range.getLowerLimit();
496  this->second -= range.getUpperLimit();
497 
498  return *this;
499  }
500 
501 
502  /**
503  * Multiply range.
504  *
505  * \param factor factor
506  */
507  range_type& mul(const double factor)
508  {
509  this->first *= factor;
510  this->second *= factor;
511 
512  return *this;
513  }
514 
515 
516  /**
517  * Divide range.
518  *
519  * \param factor factor
520  */
521  range_type& div(const double factor)
522  {
523  this->first /= factor;
524  this->second /= factor;
525 
526  return *this;
527  }
528 
529 
530  /**
531  * Get minimum possible value.
532  *
533  * \return minimum possible value
534  */
535  static T getMinimum()
536  {
537  return JMATH::JLimits<T>::min();
538  }
539 
540 
541  /**
542  * Get maximum possible value.
543  *
544  * \return maximum possible value
545  */
546  static T getMaximum()
547  {
548  return JMATH::JLimits<T>::max();
549  }
550 
551 
552  /**
553  * Default range.
554  * This range corresponds to an unphysical range.
555  */
557 
558 
559  /**
560  * Function object.
561  *
562  * \param first first argument
563  * \param second second argument
564  * \return true if first < second; else false
565  */
566  JComparator_t compare;
567 
568  protected:
569  /**
570  * Set range.
571  *
572  * \param first first
573  * \param second second
574  * \param option false
575  */
576  template<class R>
577  void setRange(R first, R second, const JLANG::JBool<false>& option)
578  {
579  setRange((argument_type) first, (argument_type) second);
580  }
581 
582 
583  /**
584  * Set range.
585  *
586  * \param first first
587  * \param second second
588  * \param option true
589  */
590  template<class R>
591  void setRange(R first, R second, const JLANG::JBool<true>& option)
592  {
594 
595  for (R i = first; i != second; ++i) {
596  include(*i);
597  }
598  }
599  };
600 
601 
602  /**
603  * Default range.
604  * This range corresponds to an unphysical range.
605  */
606  template<class T, class JComparator_t>
609 
610 
611  /**
612  * Add ranges.\n
613  * The new lower limit is the sum of the two lower limits and\n
614  * the new upper limit is the sum of the two upper limits.
615  *
616  * \param first first range
617  * \param second second range
618  * \result range
619  */
620  template<class T, class JComparator_t>
622  {
623  return JRange<T, JComparator_t>(first).add(second);
624  }
625 
626 
627  /**
628  * Subtract ranges.\n
629  * The new lower limit is the difference of the two lower limits and
630  * the new upper limit is the difference of the two upper limits.
631  *
632  * \param first first range
633  * \param second second range
634  * \result range
635  */
636  template<class T, class JComparator_t>
638  {
639  return JRange<T, JComparator_t>(first).sub(second);
640  }
641 
642 
643  /**
644  * Test overlap between ranges.
645  *
646  * \param first first range
647  * \param second second range
648  * \return true if there is a non-zero overlap; else false
649  */
650  template<class T, class JComparator_t>
652  {
653  return first.overlap(second);
654  }
655 
656 
657  /**
658  * Join ranges.\n
659  * The new lower limit is the maximim of the two lower limits and\n
660  * the new upper limit is the minimum of the two upper limits.\n
661  * This operation results in an equal or smaller range and
662  * may result in an unphysical range (i.e.\ lower limit > upper limit).
663  *
664  * \param first first range
665  * \param second second range
666  * \result range
667  */
668  template<class T, class JComparator_t>
670  {
671  return JRange<T, JComparator_t>(first).join(second);
672  }
673 
674 
675  /**
676  * Combine ranges.\n
677  * The new lower limit is the minimim of the two lower limits and\n
678  * the new upper limit is the maximum of the two upper limits.\n
679  * This operation results in an equal or larger range.
680  *
681  * \param first first range
682  * \param second second range
683  * \result range
684  */
685  template<class T, class JComparator_t>
687  {
688  return JRange<T, JComparator_t>(first).combine(second);
689  }
690 
691 
692  /**
693  * Auxiliary method to create range of values.
694  *
695  * \param x lower limit
696  * \param y upper limit
697  * \return range
698  */
699  template<class T>
700  inline JRange<T> make_range(T x, T y)
701  {
702  return JRange<T>(x,y);
703  }
704 
705 
706  /**
707  * Get expected number of occurrences due to given rate within specified interval.
708  *
709  * \param range interval
710  * \param R rate
711  * \return expectation value
712  */
713  template<class T>
714  inline double getN(const JRange<T>& range, const double R)
715  {
716  return R * (range.getUpperLimit() - range.getLowerLimit());
717  }
718 }
719 
720 #endif
static const JRange< T, JComparator_t > DEFAULT_RANGE
Default range.
Definition: JRange.hh:556
bool equals(const range_type &range) const
Equal method.
Definition: JRange.hh:275
Vec operator-(const Vec &a, const Vec &b)
Subtract two vectors.
Definition: Vec.hh:346
T getLowerLimit() const
Get lower limit.
Definition: JRange.hh:202
std::pair< T, T > pair_type
Definition: JRange.hh:45
range_type & mul(const double factor)
Multiply range.
Definition: JRange.hh:507
JRange()
Default constructor.
Definition: JRange.hh:54
double getN(const JRange< T > &range, const double R)
Get expected number of occurrences due to given rate within specified interval.
Definition: JRange.hh:714
Auxiliary base class for aritmetic operations of derived class types.
Definition: JMath.hh:110
range_type & include(argument_type x)
Include given value to range.
Definition: JRange.hh:398
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:300
void setRange(R first, R second, const JLANG::JBool< true > &option)
Set range.
Definition: JRange.hh:591
JComparator_t compare
Function object.
Definition: JRange.hh:566
range_type & combine(const range_type &range)
Combine ranges.
Definition: JRange.hh:433
void setRange(R first, R second, const JLANG::JBool< false > &option)
Set range.
Definition: JRange.hh:577
JRange(const pair_type &pair)
Constructor.
Definition: JRange.hh:64
void setUpperLimit(argument_type y)
Set upper limit.
Definition: JRange.hh:235
JRange(argument_type x)
Constructor.
Definition: JRange.hh:86
T getLength() const
Get length (difference between upper and lower limit).
Definition: JRange.hh:289
static T getMinimum()
Get minimum possible value.
Definition: JRange.hh:535
range_type & sub(argument_type x)
Subtract offset.
Definition: JRange.hh:461
range_type & sub(const range_type &range)
Subtract offsets.
Definition: JRange.hh:493
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:262
JRange(argument_type x, argument_type y)
Constructor.
Definition: JRange.hh:75
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:447
const array_type< JValue_t > & make_array(const JValue_t(&array)[N])
Method to create array of values.
Definition: JVectorize.hh:54
void setRange(const range_type &range)
Set range.
Definition: JRange.hh:146
JLANG::JClass< T >::argument_type argument_type
Definition: JRange.hh:47
do set_variable OUTPUT_DIRECTORY $WORKDIR T
void setRange(argument_type x, argument_type y)
Set lower and upper limit.
Definition: JRange.hh:158
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:700
T getUpperLimit() const
Get upper limit.
Definition: JRange.hh:213
JRange(const array_type< JElement_t, JAllocator_t > &buffer)
Constructor.
Definition: JRange.hh:112
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:546
T constrain(argument_type x) const
Constrain value to range.
Definition: JRange.hh:350
const range_type & getRange() const
Get range.
Definition: JRange.hh:135
Auxiliary methods to convert data members or return values of member methods of a set of objects to a...
JRange(R first, R second)
Constructor.
Definition: JRange.hh:99
then usage $script[distance] fi case set_variable R
Definition: JDrawLED.sh:43
bool in_range(argument_type x) const
Test whether value is inside range.
Definition: JRange.hh:323
Range of values.
Definition: JRange.hh:38
range_type & add(const range_type &range)
Add offsets.
Definition: JRange.hh:477
void setRange(const array_type< JElement_t, JAllocator_t > &buffer)
Set lower and upper limit according to input data.
Definition: JRange.hh:187
Vec operator+(const Vec &a, const Vec &b)
Add two vectors.
Definition: Vec.hh:337
z range($ZMAX-$ZMIN)< $MINIMAL_DZ." fi fi typeset -Z 4 STRING typeset -Z 2 FLOOR JPlot1D -f $
bool is_valid() const
Check validity of range.
Definition: JRange.hh:311
float min()
Definition: JLimits.hh:96
void setRange(R first, R second)
Set range.
Definition: JRange.hh:173
Base class for data structures with artithmetic capabilities.
JRange< T, JComparator_t > range_type
Definition: JRange.hh:46
bool overlap(const range_type &range) const
Test overlap with given range.
Definition: JRange.hh:383
T mod(argument_type x) const
Modulo value with respect to range.
Definition: JRange.hh:365
range_type & div(const double factor)
Divide range.
Definition: JRange.hh:521
Auxiliary data structure for return type of make methods.
Definition: JVectorize.hh:26
void setLowerLimit(argument_type x)
Set lower limit.
Definition: JRange.hh:224
void fixLowerLimit(argument_type x)
Fix lower limit.
Definition: JRange.hh:248
range_type & join(const range_type &range)
Join ranges.
Definition: JRange.hh:416