npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
Interval.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_INTERVAL_HH_
2 #define NPSTAT_INTERVAL_HH_
3 
4 /*!
5 // \file Interval.hh
6 //
7 // \brief Template to represent intervals in one dimension
8 //
9 // Author: I. Volobouev
10 //
11 // March 2010
12 */
13 
14 #include <stdexcept>
15 #include <algorithm>
16 #include <utility>
17 
19 
20 namespace npstat {
21  /**
22  // Representation of 1-d intervals. The following invariant
23  // is maintained: min() will not exceed max().
24  //
25  // See BoxND class for rectangles, boxes, and hyperboxes.
26  */
27  template <typename Numeric>
28  class Interval
29  {
30  public:
31  typedef Numeric value_type;
32 
33  /** Both lower and upper interval bounds are set to Numeric() */
34  inline Interval() : min_(Numeric()), max_(Numeric()) {}
35 
36  /**
37  // Minimum is set to Numeric(), maximum to the given argument.
38  // An exception is thrown if the argument is smaller than Numeric().
39  */
40  inline explicit Interval(const Numeric max)
41  : min_(Numeric()), max_(max)
42  {
43  if (min_ > max_) throw std::invalid_argument(
44  "In npstat::Interval constructor: invalid limits");
45  }
46 
47  /**
48  // Constructor from both bounds. Set "swapIfOutOfOrder" argument
49  // to "true" if the minimum can be larger than the maximum (in this
50  // case the bounds will be swapped internally).
51  */
52  inline Interval(const Numeric min, const Numeric max,
53  const bool swapIfOutOfOrder = false)
54  : min_(min), max_(max)
55  {
56  if (min_ > max_)
57  {
58  if (swapIfOutOfOrder)
59  std::swap(min_, max_);
60  else
61  throw std::invalid_argument(
62  "In npstat::Interval constructor: invalid limits");
63  }
64  }
65 
66  /** Set the lower interval bound */
67  inline void setMin(const Numeric value)
68  {
69  if (value > max_) throw std::invalid_argument(
70  "In npstat::Interval::setMin: argument above max");
71  min_ = value;
72  }
73 
74  /** Set the upper interval bound */
75  inline void setMax(const Numeric value)
76  {
77  if (value < min_) throw std::invalid_argument(
78  "In npstat::Interval::setMax: argument below min");
79  max_ = value;
80  }
81 
82  /** Set both interval bounds */
83  inline void setBounds(const Numeric minval, const Numeric maxval,
84  const bool swapIfOutOfOrder = false)
85  {
86  if (maxval < minval && !swapIfOutOfOrder)
87  throw std::invalid_argument(
88  "In npstat::Interval::setBounds: invalid limits");
89  min_ = minval;
90  max_ = maxval;
91  if (swapIfOutOfOrder && min_ > max_)
92  std::swap(min_, max_);
93  }
94 
95  /** Return the lower bound */
96  inline const Numeric min() const {return min_;}
97 
98  /** Return the upper bound */
99  inline const Numeric max() const {return max_;}
100 
101  /** Return both bounds */
102  inline void getBounds(Numeric* pmin, Numeric* pmax) const
103  {*pmin = min_; *pmax = max_;}
104 
105  /** Interval length */
106  inline Numeric length() const {return max_ - min_;}
107 
108  /** The middle point of the interval */
109  inline Numeric midpoint() const
110  {return static_cast<Numeric>((max_ + min_)*0.5);}
111 
112  /** Is the point inside the interval or on the lower boundary? */
113  inline bool isInsideLower(const Numeric value) const
114  {return value >= min_ && value < max_;}
115 
116  /** Is the point inside the interval or on the upper boundary? */
117  inline bool isInsideUpper(const Numeric value) const
118  {return value > min_ && value <= max_;}
119 
120  /** Is the point inside the interval or on one of the boundaries? */
121  inline bool isInsideWithBounds(const Numeric value) const
122  {return value >= min_ && value <= max_;}
123 
124  /**
125  // Is the point completely inside the interval
126  // (and does not coincide with any bound)?
127  */
128  inline bool isInside(const Numeric value) const
129  {return value > min_ && value < max_;}
130 
131  /**
132  // Is the point inside the interval with the given boundary
133  // inclusion handling?
134  */
135  bool isInside(Numeric value, BoundaryInclusion bi) const;
136 
137  //@{
138  /**
139  // Scaling of both the minimum and the maximum by a constant.
140  // Minimum and maximum will be swapped internally in case the
141  // constant is negative.
142  */
143  Interval& operator*=(double r);
144  Interval& operator/=(double r);
145  //@}
146 
147  //@{
148  /** Shift both interval bounds by a constant */
149  Interval& operator+=(const Numeric value);
150  Interval& operator-=(const Numeric value);
151  //@}
152 
153  /** Move the interval so that the midpoint ends up at 0 */
155 
156  //@{
157  /**
158  // Scaling the bounds by a constant in such a way
159  // that the midpoint remains unchanged
160  */
161  Interval& expand(double r);
162  //@}
163 
164  /**
165  // The following function returns default-constructed empty interval
166  // in case this interval and the argument interval do not overlap
167  */
168  Interval overlap(const Interval& r) const;
169 
170  /** Same as overlap.length() but a tad faster */
171  Numeric overlapLength(const Interval& r) const;
172 
173  /** Same as overlapLength(r)/length() but a tad faster */
174  double overlapFraction(const Interval& r) const;
175 
176  /**
177  // Which points are inside this interval but outside the argument
178  // interval? The result can have 0, 1, or 2 intervals. The default
179  // constructed empty interval will be substituted for the absence
180  // of the first and/or the second interval in the result.
181  */
182  std::pair<Interval,Interval> logicalDifference(const Interval& r) const;
183 
184  /**
185  // Derive the coefficients a and b such that the linear
186  // mapping y = a*x + b maps the lower limit of this interval
187  // into the lower limit of the argument interval and the
188  // upper limit of this interval into the upper limit of the
189  // argument interval
190  */
191  template <typename Num2>
192  void linearMap(const Interval<Num2> &r, double* a, double* b) const;
193 
194  private:
195  Numeric min_;
196  Numeric max_;
197  };
198 }
199 
200 //@{
201 /** Binary comparison for equality */
202 template <typename Numeric>
204 
205 template <typename Numeric>
206 bool operator!=(const npstat::Interval<Numeric>& l,const npstat::Interval<Numeric>& r);
207 //@}
208 
209 #include "npstat/nm/Interval.icc"
210 
211 #endif // NPSTAT_INTERVAL_HH_
Enumeration of possible boundary inclusions for an interval.
bool operator==(const npstat::Interval< Numeric > &l, const npstat::Interval< Numeric > &r)
Definition: Interval.hh:29
Numeric length() const
Definition: Interval.hh:106
Interval overlap(const Interval &r) const
void setMax(const Numeric value)
Definition: Interval.hh:75
Interval & moveMidpointTo0()
void getBounds(Numeric *pmin, Numeric *pmax) const
Definition: Interval.hh:102
Interval & expand(double r)
std::pair< Interval, Interval > logicalDifference(const Interval &r) const
bool isInside(Numeric value, BoundaryInclusion bi) const
double overlapFraction(const Interval &r) const
const Numeric max() const
Definition: Interval.hh:99
bool isInsideWithBounds(const Numeric value) const
Definition: Interval.hh:121
Interval()
Definition: Interval.hh:34
Interval & operator*=(double r)
bool isInsideLower(const Numeric value) const
Definition: Interval.hh:113
Interval(const Numeric min, const Numeric max, const bool swapIfOutOfOrder=false)
Definition: Interval.hh:52
void setMin(const Numeric value)
Definition: Interval.hh:67
void setBounds(const Numeric minval, const Numeric maxval, const bool swapIfOutOfOrder=false)
Definition: Interval.hh:83
Interval & operator+=(const Numeric value)
void linearMap(const Interval< Num2 > &r, double *a, double *b) const
Numeric midpoint() const
Definition: Interval.hh:109
bool isInsideUpper(const Numeric value) const
Definition: Interval.hh:117
Numeric overlapLength(const Interval &r) const
const Numeric min() const
Definition: Interval.hh:96
bool isInside(const Numeric value) const
Definition: Interval.hh:128
Interval(const Numeric max)
Definition: Interval.hh:40
Definition: AbsArrayProjector.hh:14