Range.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 #include <utility>
5 #include "boca/units/Units.hh"
6 #include "boca/math/Math.hh"
7 
8 namespace boca
9 {
10 
15 template<typename Value_>
16 class Range
17 {
18 public:
19  Range() :
20  min_(InitialMin()),
21  max_(InitialMax())
22  {}
23 
24  Range(Value_ min, Value_ max) :
25  min_(min),
26  max_(max) {
27  ImposeHierachy();
28  }
29 
30  Range(Value_ degenerate) :
31  min_(degenerate),
32  max_(degenerate) {}
33 
34  template<typename Value_2_>
35  Range(Value_2_ min, Value_2_ max) :
36  min_(Value_(min)),
37  max_(Value_(max)) {
38  ImposeHierachy();
39  }
40 
41  template<typename Value_2_>
42  Range(Range<Value_2_> const& range) :
43  min_(Value_(range.Min())),
44  max_(Value_(range.Max())) {
45  ImposeHierachy();
46  }
47 
48  void SetMin(Value_ min) {
49  min_ = min;
50  ImposeHierachy();
51  }
52 
53  void SetMax(Value_ max) {
54  max_ = max;
55  ImposeHierachy();
56  }
57 
58  void Set(Value_ min, Value_ max) {
59  min_ = min;
60  max_ = max;
61  ImposeHierachy();
62  }
63 
64  void Set(std::pair<Value_, Value_> const pair) {
65  min_ = pair.first;
66  max_ = pair.second;
67  ImposeHierachy();
68  }
69 
70  void Widen(Range<Value_> const& bound) {
71  WidenMin(bound.Min());
72  WidenMax(bound.Max());
73  }
74 
75  void Widen(double factor) {
76  min_ /= factor;
77  max_ *= factor;
78  }
79 
80  void WidenMin(Value_ min) {
81  if (min > min_) return;
82  if (min == Value_(0)) return;
83  min_ = min;
84  }
85 
86  void WidenMax(Value_ max) {
87  if (max < max_) return;
88  max_ = max;
89  }
90 
91  Value_ Min() const {
92  return min_;
93  }
94 
95  Value_ Max() const {
96  return max_;
97  }
98 
99  Value_ Floor() const {
100  return FloorToDigits(min_);
101  }
102 
103  Value_ Ceil() const {
104  return CeilToDigits(max_);
105  }
106 
107  bool Inside(Value_ value) const {
108  return value > min_ && value < max_;
109  }
110 
111  bool Outside(Value_ value) const {
112  return value < min_ || value > max_;
113  }
114 
115  template<typename Value_2_>
116  Value_ Constrain(Value_2_ value) {
117  if (Value_(value) > Max()) value = Max();
118  if (Value_(value) < Min()) value = Min();
119  return value;
120  }
121 
122  Value_ Length() const {
123  return max_ - min_;
124  }
125 
126  Value_ Sum() const {
127  return max_ + min_;
128  }
129 
130  operator bool() const {
131  return min_ != InitialMin() && max_ != InitialMax();
132  }
133 
134  template<typename Value_2_>
135  Range<ValueProduct<Value_, Value_2_>> Scale(Value_2_ const& scalar) const {
136  return {Min()* scalar, Max()* scalar};
137  }
138 
139  template<typename Value_2_>
140  friend Range<ValueProduct<Value_, Value_2_>> operator*(Range const& range, Value_2_ const& scalar) {
141  return range.Scale(scalar);
142  }
143 
144  template<typename Value_2_>
145  friend Range<ValueQuotient<Value_, Value_2_>> operator/(Range const& range, Value_2_ const& scalar) {
146  return range.Scale(1. / scalar);
147  }
148 
149  void Log() {
150  if (min_ != Value_(0)) min_ = std::log10(min_);
151  if (max_ != Value_(0)) max_ = std::log10(max_);
152  }
153 
157  friend auto &operator<<(std::ostream &stream, Range const &range)
158  {
159  stream << Stream(range.min_) << Stream(range.max_);
160  return stream;
161  }
162 
163 private:
164  void ImposeHierachy() {
165  if (min_ != InitialMin() && max_ != InitialMax() && min_ > max_) std::swap(min_, max_);
166  }
167  Value_ InitialMin() const {
169  }
170  Value_ InitialMax() const {
171  return std::numeric_limits<Value_>::lowest();
172  }
173 
174  Value_ min_;
175  Value_ max_;
176 };
177 
178 template <typename Value_>
179 Range<Value_> MinMax(std::vector<Value_> const& vector)
180 {
181  auto minmax = std::minmax_element(vector.begin(), vector.end());
182  return {*minmax.first, *minmax.second};
183 }
184 
185 template <typename Iterator_, typename Value_>
186 Range<Value_> MinMax(Iterator_ begin, Iterator_ end)
187 {
188  auto minmax = std::minmax_element(begin, end);
189  return {*minmax.first, *minmax.second};
190 }
191 
192 }
friend auto & operator<<(std::ostream &stream, Range const &range)
Output stream operator.
Definition: Range.hh:157
Range between two values.
Definition: Range.hh:16
Value_ Min() const
Definition: Range.hh:91
Range< Value_ > MinMax(std::vector< Value_ > const &vector)
Definition: Range.hh:179
void Set(std::pair< Value_, Value_ > const pair)
Definition: Range.hh:64
double CeilToDigits(double value, int digits=2)
Ceiling to digits.
Definition: Math.cpp:28
std::string Stream(Value const &message, int width=20, bool right=false)
Definition: Debug.hh:48
bool Outside(Value_ value) const
Definition: Range.hh:111
void Widen(double factor)
Definition: Range.hh:75
Range< ValueProduct< Value_, Value_2_ > > Scale(Value_2_ const &scalar) const
Definition: Range.hh:135
Value_ Max() const
Definition: Range.hh:95
Value_ Floor() const
Definition: Range.hh:99
double FloorToDigits(double value, int digits=2)
Floor value to digits.
Definition: Math.cpp:22
Range(Value_2_ min, Value_2_ max)
Definition: Range.hh:35
Range(Range< Value_2_ > const &range)
Definition: Range.hh:42
Value_ Constrain(Value_2_ value)
Definition: Range.hh:116
Value_ Ceil() const
Definition: Range.hh:103
Range()
Definition: Range.hh:19
Value_ Length() const
Definition: Range.hh:122
void Widen(Range< Value_ > const &bound)
Definition: Range.hh:70
Boosted Collider Analysis.
Definition: Analysis.hh:15
friend Range< ValueProduct< Value_, Value_2_ > > operator*(Range const &range, Value_2_ const &scalar)
Definition: Range.hh:140
void Log()
Definition: Range.hh:149
void SetMin(Value_ min)
Definition: Range.hh:48
Range(Value_ min, Value_ max)
Definition: Range.hh:24
Value max(Value const &value_1, Value const &value_2)
Maximal value.
Definition: Units.hh:260
bool Inside(Value_ value) const
Definition: Range.hh:107
void SetMax(Value_ max)
Definition: Range.hh:53
void WidenMin(Value_ min)
Definition: Range.hh:80
friend Range< ValueQuotient< Value_, Value_2_ > > operator/(Range const &range, Value_2_ const &scalar)
Definition: Range.hh:145
Value_ Sum() const
Definition: Range.hh:126
void WidenMax(Value_ max)
Definition: Range.hh:86
Range(Value_ degenerate)
Definition: Range.hh:30
void Set(Value_ min, Value_ max)
Definition: Range.hh:58