carl  24.04
Computer ARithmetic Library
operators.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Interval.h"
4 
5 namespace carl {
6 
7 /**
8  * Operators for LowerBound and UpperBound.
9  */
10 template<typename Number>
11 inline bool operator<(const LowerBound<Number>& lhs, const LowerBound<Number>& rhs) {
12  if (rhs.bound_type == BoundType::INFTY) return false;
13  switch (lhs.bound_type) {
14  case BoundType::INFTY:
15  return true;
16  case BoundType::STRICT:
17  return lhs.number < rhs.number;
18  case BoundType::WEAK:
19  if (lhs.number < rhs.number) return true;
20  return rhs.bound_type == BoundType::STRICT && lhs.number == rhs.number;
21  default:
22  assert(false);
23  return false;
24  }
25 }
26 
27 template<typename Number>
28 inline bool operator<=(const LowerBound<Number>& lhs, const LowerBound<Number>& rhs) {
29  return !(rhs < lhs);
30 }
31 
32 template<typename Number>
33 inline bool operator<(const UpperBound<Number>& lhs, const LowerBound<Number>& rhs) {
34  if (lhs.bound_type == BoundType::INFTY) return false;
35  if (rhs.bound_type == BoundType::INFTY) return false;
37  return lhs.number <= rhs.number;
38  }
39  return lhs.number < rhs.number;
40 }
41 
42 template<typename Number>
43 inline bool operator<=(const LowerBound<Number>& lhs, const UpperBound<Number>& rhs) {
44  return !(rhs < lhs);
45 }
46 
47 template<typename Number>
48 inline bool operator<(const UpperBound<Number>& lhs, const UpperBound<Number>& rhs) {
49  if (lhs.bound_type == BoundType::INFTY) return false;
50  switch (rhs.bound_type) {
51  case BoundType::INFTY:
52  return true;
53  case BoundType::STRICT:
54  return lhs.number < rhs.number;
55  case BoundType::WEAK:
56  if (lhs.number < rhs.number) return true;
57  if (lhs.bound_type == BoundType::STRICT) return lhs.number == rhs.number;
58  return false;
59  default:
60  assert(false);
61  return false;
62  }
63 }
64 
65 template<typename Number>
66 inline bool operator<=(const UpperBound<Number>& lhs, const UpperBound<Number>& rhs) {
67  return !(rhs < lhs);
68 }
69 
70 /**
71  * Check whether the two bounds connect, for example as for ...3),[3...
72  */
73 template<typename Number>
74 inline bool bounds_connect(const UpperBound<Number>& lhs, const LowerBound<Number>& rhs) {
75  if (lhs.bound_type == BoundType::INFTY) return false;
76  if (rhs.bound_type == BoundType::INFTY) return false;
77  if (lhs.bound_type == rhs.bound_type) return false;
78  return lhs.number == rhs.number;
79 }
80 
81 /**
82  * Operator for the comparison of two intervals.
83  * @param lhs Lefthand side.
84  * @param rhs Righthand side.
85  * @return True if both intervals are equal.
86  */
87 template<typename Number>
88 inline bool operator==(const Interval<Number>& lhs, const Interval<Number>& rhs) {
89  return std::forward_as_tuple(lhs.lower_bound_type(), lhs.upper_bound_type(), lhs.lower(), lhs.upper())
90  == std::forward_as_tuple(rhs.lower_bound_type(), rhs.upper_bound_type(), rhs.lower(), rhs.upper());
91 }
92 
93 template<>
94 inline bool operator==(const Interval<double>& lhs, const Interval<double>& rhs) {
95  if(!AlmostEqual2sComplement(lhs.lower(),rhs.lower()) ||
96  !AlmostEqual2sComplement(lhs.upper(),rhs.upper())) {
97  return false;
98  }
99  return std::forward_as_tuple(lhs.lower_bound_type(), lhs.upper_bound_type())
100  == std::forward_as_tuple(rhs.lower_bound_type(), rhs.upper_bound_type());
101 }
102 
103 template<typename Number>
104 inline bool operator==(const Interval<Number>& lhs, const Number& rhs) {
105  return lhs.is_point_interval() && lhs.lower() == rhs;
106 }
107 template<typename Number>
108 inline bool operator==(const Number& lhs, const Interval<Number>& rhs) {
109  return rhs == lhs;
110 }
111 
112 /**
113  * Operator for the comparison of two intervals.
114  * @param lhs Lefthand side.
115  * @param rhs Righthand side.
116  * @return True if both intervals are unequal.
117  */
118 template<typename Number>
119 inline bool operator!=(const Interval<Number>& lhs, const Interval<Number>& rhs) {
120  return !(lhs == rhs);
121 }
122 template<typename Number>
123 inline bool operator!=(const Interval<Number>& lhs, const Number& rhs) {
124  return !(lhs == rhs);
125 }
126 template<typename Number>
127 inline bool operator!=(const Number& lhs, const Interval<Number>& rhs) {
128  return !(lhs == rhs);
129 }
130 
131 /**
132  * Operator for the comparison of two intervals.
133  * @param lhs Lefthand side.
134  * @param rhs Righthand side.
135  * @return True if the lefthand side is smaller than the righthand side.
136  */
137 template<typename Number>
138 inline bool operator<(const Interval<Number>& lhs, const Interval<Number>& rhs) {
139  if (lhs.upper_bound() < rhs.lower_bound()) return true;
140  if (lhs.upper() == rhs.lower()) {
141  switch (lhs.upper_bound_type()) {
142  case BoundType::STRICT:
143  return rhs.lower_bound_type() != BoundType::INFTY;
144  case BoundType::WEAK:
145  return rhs.lower_bound_type() == BoundType::STRICT;
146  default:
147  return false;
148  }
149  }
150  return false;
151 }
152 template<typename Number>
153 inline bool operator<(const Interval<Number>& lhs, const Number& rhs) {
154  switch (lhs.upper_bound_type()) {
155  case BoundType::STRICT:
156  return lhs.upper() <= rhs;
157  case BoundType::WEAK:
158  return lhs.upper() < rhs;
159  case BoundType::INFTY:
160  return false;
161  default:
162  assert(false);
163  return false;
164  }
165 }
166 template<typename Number>
167 inline bool operator<(const Number& lhs, const Interval<Number>& rhs) {
168  switch (rhs.lower_bound_type()) {
169  case BoundType::STRICT:
170  return lhs <= rhs.lower();
171  case BoundType::WEAK:
172  return lhs < rhs.lower();
173  case BoundType::INFTY:
174  return false;
175  default:
176  assert(false);
177  return false;
178  }
179 }
180 
181 /**
182  * Operator for the comparison of two intervals.
183  * @param lhs Lefthand side.
184  * @param rhs Righthand side.
185  * @return True if the lefthand side is larger than the righthand side.
186  */
187 template<typename Number>
188 inline bool operator>(const Interval<Number>& lhs, const Interval<Number>& rhs) {
189  return rhs < lhs;
190 }
191 template<typename Number>
192 inline bool operator>(const Interval<Number>& lhs, const Number& rhs) {
193  return rhs < lhs;
194 }
195 template<typename Number>
196 inline bool operator>(const Number& lhs, const Interval<Number>& rhs) {
197  return rhs < lhs;
198 }
199 
200 
201 /**
202  * Operator for the comparison of two intervals.
203  * @param lhs Lefthand side.
204  * @param rhs Righthand side.
205  * @return True if the righthand side has maximal one intersection with the lefthand side
206  * at the upper bound of lhs.
207  */
208 template<typename Number>
209 inline bool operator<=(const Interval<Number>& lhs, const Interval<Number>& rhs) {
210  if (lhs.upper_bound() < rhs.lower_bound()) return true;
211  if (lhs.upper() == rhs.lower()) {
212  switch (lhs.upper_bound_type()) {
213  case BoundType::STRICT:
214  case BoundType::WEAK:
215  return rhs.lower_bound_type() != BoundType::INFTY;
216  default:
217  return false;
218  }
219  }
220  return false;
221 }
222 template<typename Number>
223 inline bool operator<=(const Interval<Number>& lhs, const Number& rhs) {
224  if (lhs.upper_bound_type() == BoundType::INFTY) return false;
225  return lhs.upper() <= rhs;
226 }
227 template<typename Number>
228 inline bool operator<=(const Number& lhs, const Interval<Number>& rhs) {
229  if (rhs.lower_bound_type() == BoundType::INFTY) return false;
230  return rhs.lower() >= lhs;
231 }
232 
233 /**
234  * Operator for the comparison of two intervals.
235  * @param lhs Lefthand side.
236  * @param rhs Righthand side.
237  * @return True if the lefthand side has maximal one intersection with the righthand side
238  * at the lower bound of lhs.
239  */
240 template<typename Number>
241 inline bool operator>=(const Interval<Number>& lhs, const Interval<Number>& rhs) {
242  return rhs <= lhs;
243 }
244 template<typename Number>
245 inline bool operator>=(const Interval<Number>& lhs, const Number& rhs) {
246  return rhs <= lhs;
247 }
248 template<typename Number>
249 inline bool operator>=(const Number& lhs, const Interval<Number>& rhs) {
250  return rhs <= lhs;
251 }
252 
253 
254 /**
255  * Operator for the addition of two intervals.
256  * @param lhs Lefthand side.
257  * @param rhs Righthand side.
258  * @return Resulting interval.
259  */
260 template<typename Number>
262  return lhs.add(rhs);
263 }
264 
265 /**
266  * Operator for the addition of an interval and a number.
267  * @param lhs Lefthand side.
268  * @param rhs Righthand side.
269  * @return Resulting interval.
270  */
271 template<typename Number>
272 inline Interval<Number> operator+(const Interval<Number>& lhs, const Number& rhs) {
273  return Interval<Number>(lhs.content() + rhs, lhs.lower_bound_type(), lhs.upper_bound_type());
274 }
275 
276 /**
277  * Operator for the addition of an interval and a number.
278  * @param lhs Lefthand side.
279  * @param rhs Righthand side.
280  * @return Resulting interval.
281  */
282 template<typename Number>
283 inline Interval<Number> operator+(const Number& lhs, const Interval<Number>& rhs) {
284  return rhs + lhs;
285 }
286 
287 
288 /**
289  * Operator for the addition of an interval and a number with assignment.
290  * @param lhs Lefthand side.
291  * @param rhs Righthand side.
292  * @return Resulting interval.
293  */
294 template<typename Number>
296  lhs.add_assign(rhs);
297  return lhs;
298 }
299 
300 /**
301  * Operator for the addition of an interval and a number with assignment.
302  * @param lhs Lefthand side.
303  * @param rhs Righthand side.
304  * @return Resulting interval.
305  */
306 template<typename Number>
307 inline Interval<Number>& operator+=(Interval<Number>& lhs, const Number& rhs) {
308  lhs.content() += rhs;
309  return lhs;
310 }
311 
312 /**
313  * Unary minus.
314  * @param rhs The operand.
315  * @return Resulting interval.
316  */
317 template<typename Number>
319  return rhs.inverse();
320 }
321 
322 /**
323  * Operator for the subtraction of two intervals.
324  * @param lhs Lefthand side.
325  * @param rhs Righthand side.
326  * @return Resulting interval.
327  */
328 template<typename Number>
330  return lhs.sub(rhs);
331 }
332 
333 /**
334  * Operator for the subtraction of an interval and a number.
335  * @param lhs Lefthand side.
336  * @param rhs Righthand side.
337  * @return Resulting interval.
338  */
339 template<typename Number>
340 inline Interval<Number> operator-(const Interval<Number>& lhs, const Number& rhs) {
341  return Interval<Number>(lhs.content() - rhs, lhs.lower_bound_type(), lhs.upper_bound_type());
342 }
343 
344 /**
345  * Operator for the subtraction of an interval and a number.
346  * @param lhs Lefthand side.
347  * @param rhs Righthand side.
348  * @return Resulting interval.
349  */
350 template<typename Number>
351 inline Interval<Number> operator-(const Number& lhs, const Interval<Number>& rhs) {
352  return (-rhs) + lhs;
353 }
354 
355 /**
356  * Operator for the subtraction of two intervals with assignment.
357  * @param lhs Lefthand side.
358  * @param rhs Righthand side.
359  * @return Resulting interval.
360  */
361 template<typename Number>
363  lhs.sub_assign(rhs);
364  return lhs;
365 }
366 
367 /**
368  * Operator for the subtraction of an interval and a number with assignment.
369  * @param lhs Lefthand side.
370  * @param rhs Righthand side.
371  * @return Resulting interval.
372  */
373 template<typename Number>
374 inline Interval<Number>& operator-=(Interval<Number>& lhs, const Number& rhs) {
375  lhs.content() -= rhs;
376  return lhs;
377 }
378 
379 /**
380  * Operator for the multiplication of two intervals.
381  * @param lhs Lefthand side.
382  * @param rhs Righthand side.
383  * @return Resulting interval.
384  */
385 template<typename Number>
387  return lhs.mul(rhs);
388 }
389 
390 /**
391  * Operator for the multiplication of an interval and a number.
392  * @param lhs Lefthand side.
393  * @param rhs Righthand side.
394  * @return Resulting interval.
395  */
396 template<typename Number>
397 inline Interval<Number> operator*(const Interval<Number>& lhs, const Number& rhs) {
398  if (rhs > 0 || lhs.is_empty()) {
399  return Interval<Number>(lhs.content() * rhs, lhs.lower_bound_type(), lhs.upper_bound_type());
400  } else if (rhs < 0) {
401  return Interval<Number>(lhs.content() * rhs, lhs.upper_bound_type(), lhs.lower_bound_type());
402  } else {
403  return Interval<Number>{0};
404  }
405 }
406 
407 /**
408  * Operator for the multiplication of an interval and a number.
409  * @param lhs Lefthand side.
410  * @param rhs Righthand side.
411  * @return Resulting interval.
412  */
413 template<typename Number>
414 inline Interval<Number> operator*(const Number& lhs, const Interval<Number>& rhs) {
415  return rhs * lhs;
416 }
417 
418 /**
419  * Operator for the multiplication of an interval and a number with assignment.
420  * @param lhs Lefthand side.
421  * @param rhs Righthand side.
422  * @return Resulting interval.
423  */
424 template<typename Number>
426  lhs.mul_assign(rhs);
427  return lhs;
428 }
429 
430 /**
431  * Operator for the multiplication of an interval and a number with assignment.
432  * @param lhs Lefthand side.
433  * @param rhs Righthand side.
434  * @return Resulting interval.
435  */
436 template<typename Number>
437 inline Interval<Number>& operator*=(Interval<Number>& lhs, const Number& rhs) {
438  if (carl::is_zero(rhs) && !lhs.is_empty()) {
439  lhs = Interval<Number>{0};
440  return lhs;
441  }
442  lhs.content() *= rhs;
443  return lhs;
444 }
445 
446 /**
447  * Operator for the division of an interval and a number.
448  * @param lhs Lefthand side.
449  * @param rhs Righthand side.
450  * @return Resulting interval.
451  */
452 template<typename Number>
453 inline Interval<Number> operator/(const Interval<Number>& lhs, const Number& rhs) {
454  assert(!carl::is_zero(rhs));
455  if (rhs >= 0) {
456  return Interval<Number>(lhs.content() / rhs, lhs.lower_bound_type(), lhs.upper_bound_type());
457  } else {
458  return Interval<Number>(lhs.content() / rhs, lhs.upper_bound_type(), lhs.lower_bound_type());
459  }
460 }
461 
462 /**
463  * Operator for the division of an interval and a number with assignment.
464  * @param lhs Lefthand side.
465  * @param rhs Righthand side.
466  * @return Resulting interval.
467  */
468 template<typename Number>
469 inline Interval<Number>& operator/=(Interval<Number>& lhs, const Number& rhs) {
470  return lhs = lhs / rhs;
471 }
472 
473 }
carl is the main namespace for the library.
bool operator>(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
Interval< Number > operator/(const Interval< Number > &lhs, const Number &rhs)
Operator for the division of an interval and a number.
Definition: operators.h:453
bool AlmostEqual2sComplement(const Number &A, const Number &B, unsigned=128)
Definition: FLOAT_T.h:83
Interval< Number > operator+(const Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the addition of two intervals.
Definition: operators.h:261
bool operator<(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
Definition: Interval.h:1453
Interval< Number > operator*(const Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the multiplication of two intervals.
Definition: operators.h:386
Interval< Number > & operator*=(Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the multiplication of an interval and a number with assignment.
Definition: operators.h:425
Interval< Number > & operator/=(Interval< Number > &lhs, const Number &rhs)
Operator for the division of an interval and a number with assignment.
Definition: operators.h:469
Interval< Number > & operator+=(Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the addition of an interval and a number with assignment.
Definition: operators.h:295
Interval< Number > operator-(const Interval< Number > &rhs)
Unary minus.
Definition: operators.h:318
bool operator!=(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
bool operator<=(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
bool operator==(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
bool operator>=(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
Interval< Number > & operator-=(Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the subtraction of two intervals with assignment.
Definition: operators.h:362
@ WEAK
the given bound is compared by a weak ordering relation
@ STRICT
the given bound is compared by a strict ordering relation
@ INFTY
the given bound is interpreted as minus or plus infinity depending on whether it is the left or the r...
bool bounds_connect(const UpperBound< Number > &lhs, const LowerBound< Number > &rhs)
Check whether the two bounds connect, for example as for ...3),[3...
Definition: operators.h:74
The class which contains the interval arithmetic including trigonometric functions.
Definition: Interval.h:134
Interval< Number > inverse() const
Calculates the additive inverse of an interval with respect to natural interval arithmetic.
bool is_empty() const
Function which determines, if the interval is empty.
Definition: Interval.h:1056
BoundType lower_bound_type() const
The getter for the lower bound type of the interval.
Definition: Interval.h:883
const BoostInterval & content() const
Returns a reference to the included boost interval.
Definition: Interval.h:865
const Number & upper() const
The getter for the upper boundary of the interval.
Definition: Interval.h:849
void mul_assign(const Interval< Number > &rhs)
auto lower_bound() const
Definition: Interval.h:854
void add_assign(const Interval< Number > &rhs)
void sub_assign(const Interval< Number > &rhs)
const Number & lower() const
The getter for the lower boundary of the interval.
Definition: Interval.h:840
bool is_point_interval() const
Function which determines, if the interval is a pointinterval.
Definition: Interval.h:1071
Interval< Number > mul(const Interval< Number > &rhs) const
Multiplies two intervals according to natural interval arithmetic.
Interval< Number > sub(const Interval< Number > &rhs) const
Subtracts two intervals according to natural interval arithmetic.
BoundType upper_bound_type() const
The getter for the upper bound type of the interval.
Definition: Interval.h:892
Interval< Number > add(const Interval< Number > &rhs) const
Adds two intervals according to natural interval arithmetic.
auto upper_bound() const
Definition: Interval.h:857
BoundType bound_type
Definition: Interval.h:98
const Number & number
Definition: Interval.h:97
BoundType bound_type
Definition: Interval.h:108
const Number & number
Definition: Interval.h:107