CMS 3D CMS Logo

Interval.h
Go to the documentation of this file.
1 #ifndef NPSTAT_INTERVAL_HH_
2 #define NPSTAT_INTERVAL_HH_
3 
15 #include <algorithm>
16 
17 namespace npstat {
24  template <typename Numeric>
25  class Interval
26  {
27  public:
29  inline Interval() : min_(Numeric()), max_(Numeric()) {}
30 
35  inline explicit Interval(const Numeric max)
36  : min_(Numeric()), max_(max)
37  {
39  "In npstat::Interval constructor: invalid limits");
40  }
41 
47  inline Interval(const Numeric min, const Numeric max,
48  const bool swapIfOutOfOrder = false)
49  : min_(min), max_(max)
50  {
51  if (min_ > max_)
52  {
53  if (swapIfOutOfOrder)
55  else
57  "In npstat::Interval constructor: invalid limits");
58  }
59  }
60 
62  inline void setMin(const Numeric value)
63  {
64  if (value > max_) throw npstat::NpstatInvalidArgument(
65  "In npstat::Interval::setMin: argument above max");
66  min_ = value;
67  }
68 
70  inline void setMax(const Numeric value)
71  {
72  if (value < min_) throw npstat::NpstatInvalidArgument(
73  "In npstat::Interval::setMax: argument below min");
74  max_ = value;
75  }
76 
78  inline void setBounds(const Numeric minval, const Numeric maxval,
79  const bool swapIfOutOfOrder = false)
80  {
81  if (maxval < minval && !swapIfOutOfOrder)
83  "In npstat::Interval::setBounds: invalid limits");
84  min_ = minval;
85  max_ = maxval;
86  if (swapIfOutOfOrder && min_ > max_)
88  }
89 
91  inline const Numeric min() const {return min_;}
92 
94  inline const Numeric max() const {return max_;}
95 
97  inline void getBounds(Numeric* pmin, Numeric* pmax) const
98  {*pmin = min_; *pmax = max_;}
99 
101  inline Numeric length() const {return max_ - min_;}
102 
104  inline Numeric midpoint() const
105  {return static_cast<Numeric>((max_ + min_)*0.5);}
106 
108  inline bool isInsideLower(const Numeric value) const
109  {return value >= min_ && value < max_;}
110 
112  inline bool isInsideUpper(const Numeric value) const
113  {return value > min_ && value <= max_;}
114 
116  inline bool isInsideWithBounds(const Numeric value) const
117  {return value >= min_ && value <= max_;}
118 
123  inline bool isInside(const Numeric value) const
124  {return value > min_ && value < max_;}
125 
127 
132  Interval& operator*=(double r);
133  Interval& operator/=(double r);
135 
137 
138  Interval& operator+=(const Numeric value);
139  Interval& operator-=(const Numeric value);
141 
144 
146 
150  Interval& expand(double r);
152 
157  Interval overlap(const Interval& r) const;
158 
160  Numeric overlapLength(const Interval& r) const;
161 
163  double overlapFraction(const Interval& r) const;
164 
172  template <typename Num2>
173  void linearMap(const Interval<Num2> &r, double* a, double* b) const;
174 
175  private:
176  Numeric min_;
177  Numeric max_;
178  };
179 }
180 
182 
183 template <typename Numeric>
185 
186 template <typename Numeric>
189 
190 #include <cmath>
191 #include <cassert>
192 
193 namespace npstat {
194  template <typename Numeric>
196  const Interval<Numeric>& r) const
197  {
198  Interval<Numeric> over;
199  if (max_ == r.min_)
200  over.setBounds(max_, max_);
201  else if (r.max_ == min_)
202  over.setBounds(min_, min_);
203  else if (max_ > r.min_ && r.max_ > min_)
204  {
205  over.min_ = min_ < r.min_ ? r.min_ : min_;
206  over.max_ = max_ < r.max_ ? max_ : r.max_;
207  }
208  return over;
209  }
210 
211  template <typename Numeric>
212  inline Numeric Interval<Numeric>::overlapLength(const Interval& r) const
213  {
214  if (max_ > r.min_ && r.max_ > min_)
215  {
216  const Numeric mn = min_ < r.min_ ? r.min_ : min_;
217  const Numeric mx = max_ < r.max_ ? max_ : r.max_;
218  return mx - mn;
219  }
220  else
221  return Numeric();
222  }
223 
224  template <typename Numeric>
225  inline double Interval<Numeric>::overlapFraction(const Interval& r) const
226  {
227  if (max_ > r.min_ && r.max_ > min_)
228  {
229  const Numeric mn = min_ < r.min_ ? r.min_ : min_;
230  const Numeric mx = max_ < r.max_ ? max_ : r.max_;
231  return (mx - mn)*1.0/(max_ - min_);
232  }
233  else
234  return 0.0;
235  }
236 
237  template <typename Numeric>
239  {
240  min_ *= r;
241  max_ *= r;
242  if (max_ < min_)
243  std::swap(min_, max_);
244  return *this;
245  }
246 
247  template <typename Numeric>
249  {
250  const Numeric len = max_ - min_;
251  max_ = len/static_cast<Numeric>(2);
252  min_ = -max_;
253  return *this;
254  }
255 
256  template <typename Numeric>
258  {
259  const double r = fabs(ir);
260  if (r != 1.0)
261  {
262  const Numeric center(static_cast<Numeric>((max_ + min_)*0.5));
263  min_ = center + (min_ - center)*r;
264  max_ = center + (max_ - center)*r;
265  }
266  return *this;
267  }
268 
269  template <typename Numeric>
271  {
272  if (!r) throw npstat::NpstatDomainError(
273  "In npstat::Interval::operator/=: division by zero");
274  min_ /= r;
275  max_ /= r;
276  if (max_ < min_)
277  std::swap(min_, max_);
278  return *this;
279  }
280 
281  template <typename Numeric>
283  {
284  min_ += r;
285  max_ += r;
286  return *this;
287  }
288 
289  template <typename Numeric>
291  {
292  min_ -= r;
293  max_ -= r;
294  return *this;
295  }
296 
297  template <typename Numeric>
298  template <typename Num2>
300  const Interval<Num2> &r, double* a, double* b) const
301  {
302  if (max_ == min_) throw npstat::NpstatDomainError(
303  "In npstat::Interval::linearMap: zero length interval");
304  assert(a);
305  assert(b);
306  const Num2 rmax(r.max());
307  const Num2 rmin(r.min());
308  *a = static_cast<double>((rmax - rmin)*1.0/(max_ - min_));
309  *b = static_cast<double>((rmax + rmin) - *a*(max_ + min_))/2.0;
310  }
311 }
312 
313 template <typename Numeric>
315 {
316  return r.min() == l.min() && r.max() == l.max();
317 }
318 
319 template <typename Numeric>
321 {
322  return !(l == r);
323 }
324 
325 
326 #endif // NPSTAT_INTERVAL_HH_
327 
Numeric min_
Definition: Interval.h:176
Interval(const Numeric min, const Numeric max, const bool swapIfOutOfOrder=false)
Definition: Interval.h:47
Interval overlap(const Interval &r) const
Definition: Interval.h:195
Interval & moveMidpointTo0()
Definition: Interval.h:248
Interval & operator+=(const Numeric value)
Definition: Interval.h:282
Interval & operator-=(const Numeric value)
Definition: Interval.h:290
bool isInside(const Numeric value) const
Definition: Interval.h:123
void getBounds(Numeric *pmin, Numeric *pmax) const
Definition: Interval.h:97
void setBounds(const Numeric minval, const Numeric maxval, const bool swapIfOutOfOrder=false)
Definition: Interval.h:78
void linearMap(const Interval< Num2 > &r, double *a, double *b) const
Definition: Interval.h:299
void setMax(const Numeric value)
Definition: Interval.h:70
const Numeric max() const
Definition: Interval.h:94
bool isInsideUpper(const Numeric value) const
Definition: Interval.h:112
Exceptions for the npstat namespace.
Numeric overlapLength(const Interval &r) const
Definition: Interval.h:212
double overlapFraction(const Interval &r) const
Definition: Interval.h:225
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
Numeric length() const
Definition: Interval.h:101
Definition: value.py:1
void setMin(const Numeric value)
Definition: Interval.h:62
Interval & expand(double r)
Definition: Interval.h:257
Numeric midpoint() const
Definition: Interval.h:104
Numeric max_
Definition: Interval.h:177
bool operator==(const npstat::Interval< Numeric > &l, const npstat::Interval< Numeric > &r)
Definition: Interval.h:314
Interval & operator*=(double r)
Definition: Interval.h:238
Interval(const Numeric max)
Definition: Interval.h:35
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121
bool isInsideLower(const Numeric value) const
Definition: Interval.h:108
const Numeric min() const
Definition: Interval.h:91
Interval & operator/=(double r)
Definition: Interval.h:270
bool operator!=(const npstat::Interval< Numeric > &l, const npstat::Interval< Numeric > &r)
Definition: Interval.h:320
bool isInsideWithBounds(const Numeric value) const
Definition: Interval.h:116