libmonaa 0.5.2
Loading...
Searching...
No Matches
interval.hh
Go to the documentation of this file.
1#pragma once
8#include <cmath>
9
10#include "zone.hh"
11
15struct Interval {
17 Bounds lowerBound;
19 Bounds upperBound;
20
27 upperBound = Bounds{std::numeric_limits<double>::infinity(), false};
28 lowerBound = {0, true};
29 }
30
36 Interval(int lower) {
37 upperBound = Bounds{std::numeric_limits<double>::infinity(), false};
38 lowerBound = {lower, false};
39 }
40
47 Interval(int lower, int upper) {
48 upperBound = {upper, false};
49 lowerBound = {lower, false};
50 }
51
52 Interval(Bounds lower, Bounds upper) : lowerBound(lower), upperBound(upper) {}
53
70 inline void plus(std::vector<std::shared_ptr<Interval>> &plusIntervals) {
71 plusIntervals.clear();
72 if (std::isinf(upperBound.first)) {
73 plusIntervals = {std::make_shared<Interval>(lowerBound, upperBound)};
74 return;
75 }
76 const int m = ceil(double(lowerBound.first) /
77 double(upperBound.first - lowerBound.first));
78 plusIntervals.reserve(m + 1);
79 for (int i = 1; i < m; i++) {
80 plusIntervals.emplace_back(std::make_shared<Interval>(
81 Bounds{lowerBound.first * i, lowerBound.second},
82 Bounds{upperBound.first * i, upperBound.second}));
83 }
84 plusIntervals.emplace_back(std::make_shared<Interval>(
85 Bounds{lowerBound.first * m, lowerBound.second},
86 Bounds{std::numeric_limits<double>::infinity(), false}));
87 }
88
89 inline bool contain(double value) const {
90 return (lowerBound.second ? lowerBound.first <= value
91 : lowerBound.first < value) and
92 (upperBound.second ? value <= upperBound.first
93 : value < upperBound.first);
94 }
95};
96
98inline static Interval operator&&(const Interval &left, const Interval &right) {
99 Interval ret = Interval{std::max(left.lowerBound, right.lowerBound),
100 std::min(left.upperBound, right.upperBound)};
101 return ret;
102}
103
118inline static void land(std::vector<std::shared_ptr<Interval>> &left,
119 const Interval &right) {
120 for (auto interval : left) {
121 (*interval) = (*interval) && right;
122 }
123 left.erase(std::remove_if(left.begin(), left.end(),
124 [](std::shared_ptr<Interval> interval) {
125 return interval->lowerBound >
126 interval->upperBound;
127 }),
128 left.end());
129}
130
145inline static void land(std::vector<std::shared_ptr<Interval>> &left,
146 const std::vector<std::shared_ptr<Interval>> &right) {
147 std::vector<std::shared_ptr<Interval>> tmp;
148 for (auto interval : right) {
149 std::vector<std::shared_ptr<Interval>> tmpL = left;
150 for (auto &ptr : tmpL) {
151 ptr = std::make_shared<Interval>(*ptr);
152 }
153 land(tmpL, *interval);
154 tmp.insert(tmp.end(), tmpL.begin(), tmpL.end());
155 }
156
157#ifdef DEBUG
158 assert(left.size() * right.size() == tmp.size());
159#endif
160 left = tmp;
161}
162
168inline static Interval operator+(Interval left, const Interval &right) {
169 left.lowerBound += right.lowerBound;
170 left.upperBound += right.upperBound;
171 return left;
172}
173
188inline static void
189operator+=(std::vector<std::shared_ptr<Interval>> &left,
190 const std::vector<std::shared_ptr<Interval>> &right) {
191 std::vector<std::shared_ptr<Interval>> ans;
192 ans.reserve(left.size() * right.size());
193 for (auto intervalLeft : left) {
194 for (auto intervalRight : right) {
195 ans.emplace_back(
196 std::make_shared<Interval>(*intervalLeft + *intervalRight));
197 }
198 }
199 left = std::move(ans);
200}
201
203inline void plus(std::vector<std::shared_ptr<Interval>> &intervals) {
204 if (intervals.size() >= 32) {
205 throw "too large expression";
206 }
207 std::vector<std::vector<std::shared_ptr<Interval>>> plusIntervals;
208 plusIntervals.resize(intervals.size());
209 for (std::size_t i = 0; i < intervals.size(); i++) {
210 if (std::isinf(intervals[i]->upperBound.first)) {
211 plusIntervals[i] = {intervals[i]};
212 } else {
213 intervals[i]->plus(plusIntervals[i]);
214 }
215 }
216 if (plusIntervals.size() == 1) {
217 intervals = std::move(plusIntervals[0]);
218 return;
219 }
220
221 std::vector<std::shared_ptr<Interval>> ansIntervals;
222 const uint32_t subsetSize = 1 << intervals.size();
223 for (uint32_t i = 1; i < subsetSize; i++) {
224 std::vector<const std::vector<std::shared_ptr<Interval>> *> subSetVec;
225 subSetVec.reserve(intervals.size());
226 for (std::size_t j = 0; j < intervals.size(); j++) {
227 if ((1 << j) & i) {
228 subSetVec.emplace_back(&(plusIntervals[j]));
229 }
230 }
231 std::vector<std::shared_ptr<Interval>> tmpIntervals = {
232 std::make_shared<Interval>(Bounds{0, true}, Bounds{0, true})};
233 for (const auto &intervals : subSetVec) {
234 tmpIntervals += *intervals;
235 }
236 ansIntervals.insert(ansIntervals.end(), tmpIntervals.begin(),
237 tmpIntervals.end());
238 }
239 intervals = std::move(ansIntervals);
240}
241
242// inline static std::vector<shared_ptr<Interval>>
243// operator&&( const Interval &&left, const Interval &&right) {
244// Interval ret = Interval{std::max(left.lowerBound, right.lowerBound),
245// std::min(left.upperBound, right.upperBound)};
246// return ret;
247// }
248
249inline static std::ostream &operator<<(std::ostream &stream,
250 const Interval &interval) {
251 stream << '(' << interval.lowerBound << ',' << interval.upperBound << ')';
252 return stream;
253}
static void operator+=(std::vector< std::shared_ptr< Interval > > &left, const std::vector< std::shared_ptr< Interval > > &right)
The sum of two sets of intervals.
Definition interval.hh:189
void plus(std::vector< std::shared_ptr< Interval > > &intervals)
Definition interval.hh:203
static Interval operator+(Interval left, const Interval &right)
The sum of two intervals. The formal definition is as follows.
Definition interval.hh:168
static Interval operator&&(const Interval &left, const Interval &right)
The intersection of two intervals.
Definition interval.hh:98
static void land(std::vector< std::shared_ptr< Interval > > &left, const Interval &right)
The intersection of a set of intervals and an interval.
Definition interval.hh:118
Class for an interval.
Definition interval.hh:15
Interval(int lower, int upper)
Constructor returning the interval (lower, upper)
Definition interval.hh:47
Bounds lowerBound
the lower bound of the interval
Definition interval.hh:17
Bounds upperBound
the upper bound of the interval
Definition interval.hh:19
Interval(int lower)
Constructor returning the interval (lower, ∞)
Definition interval.hh:36
void plus(std::vector< std::shared_ptr< Interval > > &plusIntervals)
The Kleene plus operator on intervals in [Dima'00].
Definition interval.hh:70
Interval()
Defail constructor.
Definition interval.hh:26