dlinear  0.0.1
Delta-complete SMT solver for linear programming
Loading...
Searching...
No Matches
Interval.cpp
1
6#include "Interval.h"
7
8#include <iostream>
9
10#include "dlinear/util/RoundingModeGuard.hpp"
11#include "dlinear/util/exception.h"
12
13namespace dlinear {
14
15Interval::Interval(const mpq_class &lb, const mpq_class &ub) : lb_(lb), ub_(ub) {
16 DLINEAR_ASSERT(lb <= ub, "Interval: lb > ub");
17}
18
19std::pair<Interval, Interval> Interval::bisect(const mpq_class &p) const {
20 mpq_class midpoint{lb_ + p * (ub_ - lb_)};
21 return std::make_pair(Interval(lb_, midpoint), Interval(midpoint, ub_));
22}
23
24Interval &Interval::operator+=(const Interval &o) {
25 lb_ += o.lb_;
26 ub_ += o.ub_;
27 return *this;
28}
29Interval &Interval::operator-=(const Interval &o) {
30 lb_ -= o.ub_;
31 ub_ -= o.lb_;
32 return *this;
33}
34Interval &Interval::operator*=(const Interval &o) {
35 const std::initializer_list<mpq_class> products{lb_ * o.lb_, lb_ * o.ub_, ub_ * o.lb_, ub_ * o.ub_};
36 const mpq_class lb{std::min(products)};
37 const mpq_class ub{std::max(products)};
38 lb_ = lb;
39 ub_ = ub;
40 return *this;
41}
42Interval &Interval::operator/=(const Interval &o) {
43 if (o.is_degenerated() && o.lb() == 0) DLINEAR_RUNTIME_ERROR("Division by zero");
44
45 const std::initializer_list<mpq_class> quotients{lb_ / o.lb_, lb_ / o.ub_, ub_ / o.lb_, ub_ / o.ub_};
46 const mpq_class lb{std::min(quotients)};
47 const mpq_class ub{std::max(quotients)};
48 lb_ = lb;
49 ub_ = ub;
50 return *this;
51}
52Interval &Interval::operator+=(const mpq_class &o) {
53 lb_ += o;
54 ub_ += o;
55 return *this;
56}
57Interval &Interval::operator-=(const mpq_class &o) {
58 lb_ -= o;
59 ub_ -= o;
60 return *this;
61}
62Interval &Interval::operator*=(const mpq_class &o) {
63 const std::initializer_list<mpq_class> products{lb_ * o, lb_ * o, ub_ * o, ub_ * o};
64 const mpq_class lb{std::min(products)};
65 const mpq_class ub{std::max(products)};
66 lb_ = lb;
67 ub_ = ub;
68 return *this;
69}
70Interval &Interval::operator/=(const mpq_class &o) {
71 if (o == 0) DLINEAR_RUNTIME_ERROR("Division by zero");
72
73 const std::initializer_list<mpq_class> quotients{lb_ / o, lb_ / o, ub_ / o, ub_ / o};
74 const mpq_class lb{std::min(quotients)};
75 const mpq_class ub{std::max(quotients)};
76 lb_ = lb;
77 ub_ = ub;
78 return *this;
79}
80
81std::ostream &Interval::PrintToStream(std::ostream &os, const mpq_class &ninfinity, const mpq_class &infinity) const {
82 if (is_empty()) return os << "[ empty ]";
83 if (lb() <= ninfinity && ub() >= infinity) return os << "[ ENTIRE ]";
84
85 os << "[";
86 if (lb() <= ninfinity) {
87 os << "-inf";
88 } else {
89 os << lb();
90 }
91 os << ", ";
92 if (ub() >= infinity) {
93 os << "inf";
94 } else {
95 os << ub();
96 }
97 return os << "]";
98}
99
100std::ostream &operator<<(std::ostream &os, const Interval &iv) {
101 if (iv.is_empty()) return os << "[ empty ]";
102 return os << "[" << iv.lb() << ", " << iv.ub() << "]";
103}
104
105Interval Interval::FromString(const std::string &s) {
106 RoundingModeGuard guard(FE_UPWARD);
107 const double ub{stod(s)};
108 double lb = s[0] == '-' ? -stod(s.substr(1)) : -stod("-" + s); // TODO: shouldn't this be -stod(s) or even -ub?
109 return Interval{lb, ub};
110}
111
112} // namespace dlinear
Global namespace for the dlinear library.