cgv
interval.h
1 #pragma once
2 
3 #include <cgv/type/traits/min.h>
4 #include <cgv/type/traits/max.h>
5 #include <iostream>
6 #include <algorithm>
7 
8 namespace cgv {
9  namespace math {
10 
24 template <typename T>
25 class interval
26 {
27 protected:
28  T lb, ub;
29 public:
32  interval() : lb(1), ub(0) {}
39  interval(bool) : lb(type::traits::min_fct<T>::get_value()), ub(type::traits::max_fct<T>::get_value()) {}
41  interval(const interval<T>& I) : lb(I.get_lower_bound()), ub(I.get_upper_bound()) {}
43  interval(const T& _lb, const T& _ub) : lb(std::min(_lb,_ub)), ub(std::max(_lb,_ub)) {}
45  bool is_empty() const { return ub < lb; }
47  void clear() { ub = 0; lb = 1; }
49  bool contains(const T& v) const { return lb <= v && v <= ub; }
51  void set_lower_bound(const T& _lb) { lb = _lb; }
53  void set_upper_bound(const T& _ub) { ub = _ub; }
55  const T& get_lower_bound() const { return lb; }
57  const T& get_upper_bound() const { return ub; }
59  T get_center() const { return (lb+ub)/2; }
61  T get_size() const { return is_empty() ? 0 : ub-lb; }
64  lb = std::max(lb, I.get_lower_bound());
65  ub = std::min(ub, I.get_upper_bound());
66  return *this;
67  }
69  interval<T> intersection(const interval<T>& I) const { interval J(*this); return J.intersect(I); }
71  interval<T>& extend(const T& v) {
72  if (is_empty())
73  lb=ub=v;
74  else {
75  lb = std::min(lb,v);
76  ub = std::max(ub,v);
77  }
78  return *this;
79  }
81  interval<T>& extension(const T& v) { interval<T> I(*this); return I.extend(v); }
84  if (!I.is_empty()) {
85  extend(I.get_lower_bound());
86  extend(I.get_upper_bound());
87  }
88  return *this;
89  }
91  interval<T>& extend(const T& v0, const T& v1, const T& v2, const T& v3) {
92  extend(v0); extend(v1); extend(v2); extend(v3);
93  return *this;
94  }
96  interval<T>& extension(const interval<T>& J) { interval<T> I(*this); return I.extend(J); }
98 
101  interval<T>& operator *= (const T& s) { lb *= s; ub *= s; return *this; }
104  interval<T> operator * (const T& s) const { interval I(*this); return I *= s; }
106  interval<T>& operator /= (const T& s) { return *this *= 1/s; }
108  interval<T> operator / (const T& s) const { return *this * (1/s); }
110  interval<T>& operator += (const T& s) { lb += s; ub += s; return *this; }
112  interval<T> operator + (const T& s) const { interval I(*this); return I += s; }
114  interval<T>& operator -= (const T& s) { lb -= s; ub -= s; return *this; }
116  interval<T> operator - (const T& s) const { interval I(*this); return I -= s; }
118 
121  interval<T>& operator *= (const interval<T>& I) {
123  if (is_empty() || I.is_empty())
124  *this = interval<T>();
125  else
126  extend(lb*I.get_lower_bound(), lb*I.get_upper_bound(),
127  ub*I.get_lower_bound(), ub*I.get_upper_bound());
128  return *this;
129  }
131  interval<T> operator * (const interval<T>& J) const { interval I(*this); return I *= J; }
137  if (is_empty() || I.is_empty())
138  *this = interval<T>();
139  else {
140  if (I.contains(0))
141  *this = interval<T>(true);
142  else
143  extend(lb/I.get_lower_bound(), lb/I.get_upper_bound(),
144  ub/I.get_lower_bound(), ub/I.get_upper_bound());
145  }
146  return *this;
147  }
149  interval<T> operator / (const interval<T>& J) const { interval I(*this); return I /= J; }
151  interval<T> operator - () const { if (is_empty()) return *this; else return interval<T>(-ub,-lb); }
154  if (is_empty() || I.is_empty())
155  *this = interval<T>();
156  else {
157  extend(lb+I.get_lower_bound(), lb+I.get_upper_bound(),
158  ub+I.get_lower_bound(), ub+I.get_upper_bound());
159  }
160  return *this;
161  }
163  interval<T> operator + (const interval<T>& J) const { interval I(*this); return I += J; }
165  interval<T>& operator -= (const interval<T>& I) { return *this += -I; }
167  interval<T> operator - (const interval<T>& J) const { interval I(*this); return I -= J; }
169 
172  bool operator == (const interval<T>& I) const {
174  return is_empty() && I.is_empty() ||
175  lb == I.get_lower_bound() && ub == I.get_upper_bound();
176  }
178  bool operator != (const interval<T>& I) const {
179  return !(*this == I);
180  }
182  bool operator < (const interval<T>& I) const {
183  return !is_empty() && !I.is_empty() && ub < I.get_lower_bound();
184  }
186  bool operator > (const interval<T>& I) const {
187  return !is_empty() && !I.is_empty() && lb > I.get_upper_bound();
188  }
190 
191 };
192 
193 template <typename T> inline interval<T> operator + (const T& s, const interval<T>& I) { return I+s; }
194 template <typename T> inline interval<T> operator - (const T& s, const interval<T>& I) { return -I+s; }
195 template <typename T> inline interval<T> operator * (const T& s, const interval<T>& I) { return I*s; }
196 template <typename T> inline interval<T> operator / (const T& s, const interval<T>& I) { return interval<T>(s,s)/I; }
197 
198 template <typename T>
199 std::ostream& operator << (std::ostream& os, const interval<T>& I) {
200  return os << '[' << I.get_lower_bound() << ',' << I.get_upper_bound() << ']';
201 }
202 
203  }
204 }
cgv::math::interval
Definition: interval.h:26
cgv::math::interval::get_upper_bound
const T & get_upper_bound() const
return the upper bound
Definition: interval.h:57
cgv::math::interval::operator!=
bool operator!=(const interval< T > &I) const
check for inequality of two intervals
Definition: interval.h:178
cgv::math::interval::operator/=
interval< T > & operator/=(const T &s)
divide the interval
Definition: interval.h:106
cgv::math::interval::extend
interval< T > & extend(const T &v0, const T &v1, const T &v2, const T &v3)
extend by four values
Definition: interval.h:91
cgv::math::interval::intersect
interval< T > & intersect(const interval< T > &I)
set interval to intersection with given interval and return reference to this interval
Definition: interval.h:63
cgv::math::interval::operator-
interval< T > operator-() const
unary minus operator reflects interval at zero value
Definition: interval.h:151
cgv::math::interval::contains
bool contains(const T &v) const
check if given value is contained in interval
Definition: interval.h:49
cgv::math::interval::get_size
T get_size() const
return the size of the interval
Definition: interval.h:61
cgv::math::interval::operator+=
interval< T > & operator+=(const T &s)
right shift interval by adding scalar to both bounds
Definition: interval.h:110
cgv::math::interval::operator*
interval< T > operator*(const T &s) const
return scaled the interval
Definition: interval.h:104
cgv::math::interval::operator-=
interval< T > & operator-=(const T &s)
left shift interval by subtracting scalar from both bounds
Definition: interval.h:114
cgv::math::interval::operator>
bool operator>(const interval< T > &I) const
only returns true if both intervals are not empty and the operator holds for all values in both inter...
Definition: interval.h:186
cgv::math::interval::interval
interval(const T &_lb, const T &_ub)
contruct interval from bounds, sort bounds if necessary. To construct empty interval call the standar...
Definition: interval.h:43
cgv::math::interval::extension
interval< T > & extension(const T &v)
return extension of interval that it includes the given value
Definition: interval.h:81
cgv::math::interval::is_empty
bool is_empty() const
check if interval is empty
Definition: interval.h:45
cgv::math::operator<<
std::ostream & operator<<(std::ostream &out, const diag_mat< T > &m)
output of a diagonal matrix onto an ostream
Definition: diag_mat.h:442
cgv::math::interval::extension
interval< T > & extension(const interval< T > &J)
return extension of interval that it includes the given interval
Definition: interval.h:96
cgv::math::interval::get_lower_bound
const T & get_lower_bound() const
return the lower bound
Definition: interval.h:55
cgv::math::interval::interval
interval()
construct empty interval
Definition: interval.h:33
cgv::math::interval::operator+
interval< T > operator+(const T &s) const
return right shifted interval
Definition: interval.h:112
cgv::math::interval::interval
interval(const interval< T > &I)
copy constructor
Definition: interval.h:41
cgv::math::interval::operator<
bool operator<(const interval< T > &I) const
only returns true if both intervals are not empty and the operator holds for all values in both inter...
Definition: interval.h:182
cgv::math::interval::set_lower_bound
void set_lower_bound(const T &_lb)
set the lower bound
Definition: interval.h:51
cgv::math::interval::operator*=
interval< T > & operator*=(const T &s)
scale the interval
Definition: interval.h:102
cgv::math::interval::intersection
interval< T > intersection(const interval< T > &I) const
return intersection interval
Definition: interval.h:69
cgv::math::interval::operator==
bool operator==(const interval< T > &I) const
check for equality of two intervals
Definition: interval.h:173
cgv::math::interval::extend
interval< T > & extend(const interval< T > &I)
extend interval such that it includes the given interval
Definition: interval.h:83
cgv::math::interval::extend
interval< T > & extend(const T &v)
extend interval such that it includes the given value
Definition: interval.h:71
cgv::math::interval::clear
void clear()
set to empty interval
Definition: interval.h:47
cgv
the cgv namespace
Definition: vr_calib.cxx:9
cgv::math::interval::interval
interval(bool)
Definition: interval.h:39
cgv::math::interval::operator/
interval< T > operator/(const T &s) const
return divided the interval
Definition: interval.h:108
cgv::math::interval::set_upper_bound
void set_upper_bound(const T &_ub)
set the upper bound
Definition: interval.h:53
cgv::math::interval::get_center
T get_center() const
return the center value, which is only valid if the interval is not empty
Definition: interval.h:59