LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
interval.cpp
浏览该文件的文档.
2#include <utility>
3
4namespace LMCAS {
9
10Endpoint Endpoint::neg_inf() {
11 return Endpoint{nullptr, true, true, false};
12}
13
14Endpoint Endpoint::pos_inf() {
15 return Endpoint{nullptr, true, false, true};
16}
17
18Endpoint Endpoint::closed(std::shared_ptr<SymbolicExpr> val) {
19 return Endpoint{std::move(val), false, false, false};
20}
21
22Endpoint Endpoint::open(std::shared_ptr<SymbolicExpr> val) {
23 return Endpoint{std::move(val), true, false, false};
24}
25
26bool Interval::contains(double value) const {
27 auto result = interval_contains_checked(*this, value);
28 return result ? result.value() : false;
29}
30
31bool Interval::is_empty() const {
32 auto result = interval_is_empty_checked(*this);
33 return result ? result.value() : false;
34}
35
36bool Interval::is_entire_line() const {
37 return lower.is_neg_infinity && upper.is_pos_infinity;
38}
39
40Interval Interval::empty() {
41
42 return Interval{Endpoint::open(SymbolicExpr::number(1)), Endpoint::open(SymbolicExpr::number(0))};
43}
44
45Interval Interval::entire_line() {
46 return Interval{Endpoint::neg_inf(), Endpoint::pos_inf()};
47}
48
49Interval Interval::point(std::shared_ptr<SymbolicExpr> val) {
50 return Interval{Endpoint::closed(val), Endpoint::closed(val)};
51}
52
53IntervalUnion::IntervalUnion() : intervals_() {}
54
55IntervalUnion::IntervalUnion(std::vector<Interval> intervals) : intervals_(std::move(intervals)) {
56 normalize();
57}
58
59IntervalUnion IntervalUnion::from_single(const Interval& iv) {
60 return IntervalUnion(std::vector<Interval>{iv});
61}
62
63Result<IntervalUnion> IntervalUnion::from_intervals_checked(
64 std::vector<Interval> intervals,
65 ComputationContext& context) {
66 auto normalized = normalize_intervals_checked(std::move(intervals), context);
67 if (!normalized) {
68 return Result<IntervalUnion>::failure(normalized.error());
69 }
70 return Result<IntervalUnion>::success(
71 from_checked_normalized(std::move(normalized.value())));
72}
73
74Result<IntervalUnion> IntervalUnion::from_intervals_checked(
75 std::vector<Interval> intervals) {
76 ComputationContext context;
77 return from_intervals_checked(std::move(intervals), context);
78}
79
80IntervalUnion IntervalUnion::empty() {
81 return IntervalUnion();
82}
83
84IntervalUnion IntervalUnion::entire_line() {
85 return IntervalUnion::from_single(Interval::entire_line());
86}
87
88bool IntervalUnion::contains(double value) const {
89 for (const auto& iv : intervals_) {
90 if (iv.contains(value)) {
91 return true;
92 }
93 }
94 return false;
95}
96
97bool IntervalUnion::is_empty() const {
98 return intervals_.empty();
99}
100
101bool IntervalUnion::is_entire_line() const {
102 return intervals_.size() == 1 && intervals_[0].is_entire_line();
103}
104
105const std::vector<Interval>& IntervalUnion::intervals() const {
106 return intervals_;
107}
108
109IntervalUnion IntervalUnion::from_checked_normalized(std::vector<Interval> intervals) {
110 IntervalUnion result;
111 result.intervals_ = std::move(intervals);
112 return result;
113}
114
115void IntervalUnion::normalize() {
116 auto normalized = normalize_intervals_checked(intervals_);
117 if (normalized) {
118 intervals_ = std::move(normalized.value());
119 }
120}
121
123 const Interval& interval,
124 double value,
126 constexpr const char* operation = "interval_contains";
127 auto point_step = context.consume_steps(1, operation);
128 if (!point_step) {
129 return Result<bool>::failure(point_step.error());
130 }
131 auto point = exact_double_rational(value, context, operation);
132 if (!point) {
133 return Result<bool>::failure(point.error());
134 }
135 const ComparableEndpoint point_key{
136 0, std::move(point.value()), Rational(0), Rational(0)};
137
138 auto lower = comparable_endpoint(interval.lower, context, operation);
139 if (!lower) {
140 return Result<bool>::failure(lower.error());
141 }
142 auto upper = comparable_endpoint(interval.upper, context, operation);
143 if (!upper) {
145 }
146
147 auto lower_cmp = compare_comparable(point_key, lower.value(), context);
148 if (!lower_cmp) {
149 return Result<bool>::failure(lower_cmp.error());
150 }
151 if (lower_cmp.value() < 0 ||
152 (lower_cmp.value() == 0 && interval.lower.is_open)) {
153 return Result<bool>::success(false);
154 }
155 auto upper_cmp = compare_comparable(point_key, upper.value(), context);
156 if (!upper_cmp) {
157 return Result<bool>::failure(upper_cmp.error());
158 }
159 if (upper_cmp.value() > 0 ||
160 (upper_cmp.value() == 0 && interval.upper.is_open)) {
161 return Result<bool>::success(false);
162 }
163 return Result<bool>::success(true);
164}
165
172
174 const Interval& interval,
176 constexpr const char* operation = "interval_is_empty";
177 auto lower = comparable_endpoint(interval.lower, context, operation);
178 if (!lower) {
179 return Result<bool>::failure(lower.error());
180 }
181 auto upper = comparable_endpoint(interval.upper, context, operation);
182 if (!upper) {
184 }
185 auto comparison = compare_comparable(lower.value(), upper.value(), context);
186 if (!comparison) {
187 return Result<bool>::failure(comparison.error());
188 }
190 comparison.value() > 0 ||
191 (comparison.value() == 0 &&
192 (interval.lower.is_open || interval.upper.is_open)));
193}
194
199
200IntervalUnion IntervalUnion::intersect(const IntervalUnion& other) const {
201 auto result = intersect_checked(other);
202 return result ? result.value() : IntervalUnion::empty();
203}
204
205IntervalUnion IntervalUnion::unite(const IntervalUnion& other) const {
206 auto result = unite_checked(other);
207 return result ? result.value() : IntervalUnion::empty();
208}
209
210IntervalUnion IntervalUnion::complement() const {
211 auto result = complement_checked();
212 return result ? result.value() : IntervalUnion::empty();
213}
214
215}
CasError & error()
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
ExpressionResult normalize(const Node &value, ComputationContext &context)
Result< ComparableEndpoint > comparable_endpoint(const Endpoint &endpoint, ComputationContext &context, const std::string &operation)
Result< Rational > exact_double_rational(double value, ComputationContext &context, const std::string &operation)
Result< int > compare_comparable(const ComparableEndpoint &left, const ComparableEndpoint &right, ComputationContext &context)
const std::string const LimitExprPtr & point
Result< ComparableEndpoint > comparable_endpoint(const Endpoint &endpoint, ComputationContext &context, const std::string &operation)
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
Result< bool > interval_is_empty_checked(const Interval &interval, ComputationContext &context)
const ExprPtr & lower
Result< Rational > exact_double_rational(double value, ComputationContext &context, const std::string &operation)
Result< std::vector< Interval > > normalize_intervals_checked(std::vector< Interval > intervals, ComputationContext &context)
Result< bool > interval_contains_checked(const Interval &interval, double value, ComputationContext &context)
const std::string const ExprPtr & value
Result< int > compare_comparable(const ComparableEndpoint &left, const ComparableEndpoint &right, ComputationContext &context)