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  public:
28  inline Interval() : min_(Numeric()), max_(Numeric()) {}
29 
34  inline explicit Interval(const Numeric max) : min_(Numeric()), max_(max) {
35  if (min_ > max_)
36  throw npstat::NpstatInvalidArgument("In npstat::Interval constructor: invalid limits");
37  }
38 
44  inline Interval(const Numeric min, const Numeric max, const bool swapIfOutOfOrder = false) : min_(min), max_(max) {
45  if (min_ > max_) {
46  if (swapIfOutOfOrder)
48  else
49  throw npstat::NpstatInvalidArgument("In npstat::Interval constructor: invalid limits");
50  }
51  }
52 
54  inline void setMin(const Numeric value) {
55  if (value > max_)
56  throw npstat::NpstatInvalidArgument("In npstat::Interval::setMin: argument above max");
57  min_ = value;
58  }
59 
61  inline void setMax(const Numeric value) {
62  if (value < min_)
63  throw npstat::NpstatInvalidArgument("In npstat::Interval::setMax: argument below min");
64  max_ = value;
65  }
66 
68  inline void setBounds(const Numeric minval, const Numeric maxval, const bool swapIfOutOfOrder = false) {
69  if (maxval < minval && !swapIfOutOfOrder)
70  throw npstat::NpstatInvalidArgument("In npstat::Interval::setBounds: invalid limits");
71  min_ = minval;
72  max_ = maxval;
73  if (swapIfOutOfOrder && min_ > max_)
75  }
76 
78  inline const Numeric min() const { return min_; }
79 
81  inline const Numeric max() const { return max_; }
82 
84  inline void getBounds(Numeric* pmin, Numeric* pmax) const {
85  *pmin = min_;
86  *pmax = max_;
87  }
88 
90  inline Numeric length() const { return max_ - min_; }
91 
93  inline Numeric midpoint() const { return static_cast<Numeric>((max_ + min_) * 0.5); }
94 
96  inline bool isInsideLower(const Numeric value) const { return value >= min_ && value < max_; }
97 
99  inline bool isInsideUpper(const Numeric value) const { return value > min_ && value <= max_; }
100 
102  inline bool isInsideWithBounds(const Numeric value) const { return value >= min_ && value <= max_; }
103 
108  inline bool isInside(const Numeric value) const { return value > min_ && value < max_; }
109 
111 
116  Interval& operator*=(double r);
117  Interval& operator/=(double r);
119 
121 
122  Interval& operator+=(const Numeric value);
123  Interval& operator-=(const Numeric value);
125 
128 
130 
134  Interval& expand(double r);
136 
141  Interval overlap(const Interval& r) const;
142 
144  Numeric overlapLength(const Interval& r) const;
145 
147  double overlapFraction(const Interval& r) const;
148 
156  template <typename Num2>
157  void linearMap(const Interval<Num2>& r, double* a, double* b) const;
158 
159  private:
160  Numeric min_;
161  Numeric max_;
162  };
163 } // namespace npstat
164 
166 
167 template <typename Numeric>
169 
170 template <typename Numeric>
173 
174 #include <cmath>
175 #include <cassert>
176 
177 namespace npstat {
178  template <typename Numeric>
180  Interval<Numeric> over;
181  if (max_ == r.min_)
182  over.setBounds(max_, max_);
183  else if (r.max_ == min_)
184  over.setBounds(min_, min_);
185  else if (max_ > r.min_ && r.max_ > min_) {
186  over.min_ = min_ < r.min_ ? r.min_ : min_;
187  over.max_ = max_ < r.max_ ? max_ : r.max_;
188  }
189  return over;
190  }
191 
192  template <typename Numeric>
193  inline Numeric Interval<Numeric>::overlapLength(const Interval& r) const {
194  if (max_ > r.min_ && r.max_ > min_) {
195  const Numeric mn = min_ < r.min_ ? r.min_ : min_;
196  const Numeric mx = max_ < r.max_ ? max_ : r.max_;
197  return mx - mn;
198  } else
199  return Numeric();
200  }
201 
202  template <typename Numeric>
203  inline double Interval<Numeric>::overlapFraction(const Interval& r) const {
204  if (max_ > r.min_ && r.max_ > min_) {
205  const Numeric mn = min_ < r.min_ ? r.min_ : min_;
206  const Numeric mx = max_ < r.max_ ? max_ : r.max_;
207  return (mx - mn) * 1.0 / (max_ - min_);
208  } else
209  return 0.0;
210  }
211 
212  template <typename Numeric>
214  min_ *= r;
215  max_ *= r;
216  if (max_ < min_)
217  std::swap(min_, max_);
218  return *this;
219  }
220 
221  template <typename Numeric>
223  const Numeric len = max_ - min_;
224  max_ = len / static_cast<Numeric>(2);
225  min_ = -max_;
226  return *this;
227  }
228 
229  template <typename Numeric>
230  inline Interval<Numeric>& Interval<Numeric>::expand(const double ir) {
231  const double r = fabs(ir);
232  if (r != 1.0) {
233  const Numeric center(static_cast<Numeric>((max_ + min_) * 0.5));
234  min_ = center + (min_ - center) * r;
235  max_ = center + (max_ - center) * r;
236  }
237  return *this;
238  }
239 
240  template <typename Numeric>
242  if (!r)
243  throw npstat::NpstatDomainError("In npstat::Interval::operator/=: division by zero");
244  min_ /= r;
245  max_ /= r;
246  if (max_ < min_)
247  std::swap(min_, max_);
248  return *this;
249  }
250 
251  template <typename Numeric>
253  min_ += r;
254  max_ += r;
255  return *this;
256  }
257 
258  template <typename Numeric>
260  min_ -= r;
261  max_ -= r;
262  return *this;
263  }
264 
265  template <typename Numeric>
266  template <typename Num2>
267  void Interval<Numeric>::linearMap(const Interval<Num2>& r, double* a, double* b) const {
268  if (max_ == min_)
269  throw npstat::NpstatDomainError("In npstat::Interval::linearMap: zero length interval");
270  assert(a);
271  assert(b);
272  const Num2 rmax(r.max());
273  const Num2 rmin(r.min());
274  *a = static_cast<double>((rmax - rmin) * 1.0 / (max_ - min_));
275  *b = static_cast<double>((rmax + rmin) - *a * (max_ + min_)) / 2.0;
276  }
277 } // namespace npstat
278 
279 template <typename Numeric>
281  return r.min() == l.min() && r.max() == l.max();
282 }
283 
284 template <typename Numeric>
286  return !(l == r);
287 }
288 
289 #endif // NPSTAT_INTERVAL_HH_
Numeric min_
Definition: Interval.h:160
Interval(const Numeric min, const Numeric max, const bool swapIfOutOfOrder=false)
Definition: Interval.h:44
Interval & moveMidpointTo0()
Definition: Interval.h:222
Interval & operator+=(const Numeric value)
Definition: Interval.h:252
Interval & operator-=(const Numeric value)
Definition: Interval.h:259
Numeric overlapLength(const Interval &r) const
Definition: Interval.h:193
bool isInside(const Numeric value) const
Definition: Interval.h:108
const Numeric max() const
Definition: Interval.h:81
Numeric length() const
Definition: Interval.h:90
void setBounds(const Numeric minval, const Numeric maxval, const bool swapIfOutOfOrder=false)
Definition: Interval.h:68
double overlapFraction(const Interval &r) const
Definition: Interval.h:203
void setMax(const Numeric value)
Definition: Interval.h:61
assert(be >=bs)
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:112
Exceptions for the npstat namespace.
Numeric midpoint() const
Definition: Interval.h:93
bool operator!=(const npstat::Interval< Numeric > &l, const npstat::Interval< Numeric > &r)
Definition: Interval.h:285
void getBounds(Numeric *pmin, Numeric *pmax) const
Definition: Interval.h:84
Definition: value.py:1
void setMin(const Numeric value)
Definition: Interval.h:54
Interval & expand(double r)
Definition: Interval.h:230
const Numeric min() const
Definition: Interval.h:78
Numeric max_
Definition: Interval.h:161
Interval & operator*=(double r)
Definition: Interval.h:213
Interval(const Numeric max)
Definition: Interval.h:34
double b
Definition: hdecay.h:120
bool isInsideLower(const Numeric value) const
Definition: Interval.h:96
bool operator==(const npstat::Interval< Numeric > &l, const npstat::Interval< Numeric > &r)
Definition: Interval.h:280
double a
Definition: hdecay.h:121
void linearMap(const Interval< Num2 > &r, double *a, double *b) const
Definition: Interval.h:267
Interval & operator/=(double r)
Definition: Interval.h:241
bool isInsideUpper(const Numeric value) const
Definition: Interval.h:99
Interval overlap(const Interval &r) const
Definition: Interval.h:179
bool isInsideWithBounds(const Numeric value) const
Definition: Interval.h:102