Jpp  15.0.4
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 expected number of occurances of given rate within this interval.
532  *
533  * \param R rate
534  * \return expectation value
535  */
536  T getN(const double R) const
537  {
538  return R * (getUpperLimit() - getLowerLimit());
539  }
540 
541 
542  /**
543  * Get minimum possible value.
544  *
545  * \return minimum possible value
546  */
547  static T getMinimum()
548  {
549  return JMATH::JLimits<T>::min();
550  }
551 
552 
553  /**
554  * Get maximum possible value.
555  *
556  * \return maximum possible value
557  */
558  static T getMaximum()
559  {
560  return JMATH::JLimits<T>::max();
561  }
562 
563 
564  /**
565  * Default range.
566  * This range corresponds to an unphysical range.
567  */
569 
570 
571  /**
572  * Function object.
573  *
574  * \param first first argument
575  * \param second second argument
576  * \return true if first < second; else false
577  */
578  JComparator_t compare;
579 
580  protected:
581  /**
582  * Set range.
583  *
584  * \param first first
585  * \param second second
586  * \param option false
587  */
588  template<class R>
589  void setRange(R first, R second, const JLANG::JBool<false>& option)
590  {
591  setRange((argument_type) first, (argument_type) second);
592  }
593 
594 
595  /**
596  * Set range.
597  *
598  * \param first first
599  * \param second second
600  * \param option true
601  */
602  template<class R>
603  void setRange(R first, R second, const JLANG::JBool<true>& option)
604  {
606 
607  for (R i = first; i != second; ++i) {
608  include(*i);
609  }
610  }
611  };
612 
613 
614  /**
615  * Default range.
616  * This range corresponds to an unphysical range.
617  */
618  template<class T, class JComparator_t>
621 
622 
623  /**
624  * Add ranges.\n
625  * The new lower limit is the sum of the two lower limits and\n
626  * the new upper limit is the sum of the two upper limits.
627  *
628  * \param first first range
629  * \param second second range
630  * \result range
631  */
632  template<class T, class JComparator_t>
634  {
635  return JRange<T, JComparator_t>(first).add(second);
636  }
637 
638 
639  /**
640  * Subtract ranges.\n
641  * The new lower limit is the difference of the two lower limits and
642  * the new upper limit is the difference of the two upper limits.
643  *
644  * \param first first range
645  * \param second second range
646  * \result range
647  */
648  template<class T, class JComparator_t>
650  {
651  return JRange<T, JComparator_t>(first).sub(second);
652  }
653 
654 
655  /**
656  * Test overlap between ranges.
657  *
658  * \param first first range
659  * \param second second range
660  * \return true if there is a non-zero overlap; else false
661  */
662  template<class T, class JComparator_t>
664  {
665  return first.overlap(second);
666  }
667 
668 
669  /**
670  * Join ranges.\n
671  * The new lower limit is the maximim of the two lower limits and\n
672  * the new upper limit is the minimum of the two upper limits.\n
673  * This operation results in an equal or smaller range and
674  * may result in an unphysical range (i.e.\ lower limit > upper limit).
675  *
676  * \param first first range
677  * \param second second range
678  * \result range
679  */
680  template<class T, class JComparator_t>
682  {
683  return JRange<T, JComparator_t>(first).join(second);
684  }
685 
686 
687  /**
688  * Combine ranges.\n
689  * The new lower limit is the minimim of the two lower limits and\n
690  * the new upper limit is the maximum of the two upper limits.\n
691  * This operation results in an equal or larger range.
692  *
693  * \param first first range
694  * \param second second range
695  * \result range
696  */
697  template<class T, class JComparator_t>
699  {
700  return JRange<T, JComparator_t>(first).combine(second);
701  }
702 
703 
704  /**
705  * Auxiliary method to create range of values.
706  *
707  * \param x lower limit
708  * \param y upper limit
709  * \return range
710  */
711  template<class T>
712  inline JRange<T> make_range(T x, T y)
713  {
714  return JRange<T>(x,y);
715  }
716 }
717 
718 #endif
static const JRange< T, JComparator_t > DEFAULT_RANGE
Default range.
Definition: JRange.hh:568
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
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:603
JComparator_t compare
Function object.
Definition: JRange.hh:578
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:589
T getN(const double R) const
Get expected number of occurances of given rate within this interval.
Definition: JRange.hh:536
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:547
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:712
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:558
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