LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
interval_normalization.cpp
浏览该文件的文档.
2#include <utility>
3
4namespace LMCAS {
8
9namespace {
10
11constexpr const char* kCheckedIntervalOperation = "normalize_intervals";
12
14 std::vector<Interval> intervals, ComputationContext& context) {
15 std::vector<CheckedInterval> checked;
16 checked.reserve(intervals.size());
17 for (auto& interval : intervals) {
20 if (!lower) return Result<std::vector<CheckedInterval>>::failure(lower.error());
23 if (!upper) return Result<std::vector<CheckedInterval>>::failure(upper.error());
24 auto comparison =
26 if (!comparison) {
27 return Result<std::vector<CheckedInterval>>::failure(comparison.error());
28 }
29 const bool empty = comparison.value() > 0 ||
30 (comparison.value() == 0 &&
31 (interval.lower.is_open || interval.upper.is_open));
32 if (!empty) {
33 checked.push_back(CheckedInterval{
34 std::move(interval), std::move(lower.value()), std::move(upper.value())});
35 }
36 }
37 return Result<std::vector<CheckedInterval>>::success(std::move(checked));
38}
39
41 std::vector<CheckedInterval>& checked, ComputationContext& context) {
42 for (std::size_t i = 1; i < checked.size(); ++i) {
43 std::size_t position = i;
44 while (position > 0) {
45 auto comparison = compare_comparable(
46 checked[position - 1].lower, checked[position].lower, context);
47 if (!comparison) {
48 return Result<void>::failure(comparison.error());
49 }
50 const bool out_of_order = comparison.value() > 0 ||
51 (comparison.value() == 0 &&
52 checked[position - 1].interval.lower.is_open &&
53 !checked[position].interval.lower.is_open);
54 if (!out_of_order) break;
55 std::swap(checked[position - 1], checked[position]);
56 --position;
57 }
58 }
59 return Result<void>::success();
60}
61
63 std::vector<CheckedInterval> checked, ComputationContext& context) {
64 std::vector<CheckedInterval> merged;
65 merged.reserve(checked.size());
66 for (auto& next : checked) {
67 if (merged.empty()) {
68 merged.push_back(std::move(next));
69 continue;
70 }
71
72 CheckedInterval& current = merged.back();
73 auto boundary =
74 compare_comparable(current.upper, next.lower, context);
75 if (!boundary) {
76 return Result<std::vector<Interval>>::failure(boundary.error());
77 }
78 const bool overlaps = boundary.value() > 0 ||
79 (boundary.value() == 0 &&
80 (!current.interval.upper.is_open || !next.interval.lower.is_open));
81 if (!overlaps) {
82 merged.push_back(std::move(next));
83 continue;
84 }
85
86 auto upper_comparison =
87 compare_comparable(current.upper, next.upper, context);
88 if (!upper_comparison) {
89 return Result<std::vector<Interval>>::failure(upper_comparison.error());
90 }
91 if (upper_comparison.value() < 0 ||
92 (upper_comparison.value() == 0 && current.interval.upper.is_open &&
93 !next.interval.upper.is_open)) {
94 current.interval.upper = std::move(next.interval.upper);
95 current.upper = std::move(next.upper);
96 }
97 }
98
99 std::vector<Interval> result;
100 result.reserve(merged.size());
101 for (auto& interval : merged) {
102 result.push_back(std::move(interval.interval));
103 }
104 return Result<std::vector<Interval>>::success(std::move(result));
105}
106
107}
108
110 std::vector<Interval> intervals,
112 auto checked = collect_nonempty_intervals(std::move(intervals), context);
113 if (!checked) return Result<std::vector<Interval>>::failure(checked.error());
114 auto sorted = sort_checked_intervals(checked.value(), context);
115 if (!sorted) return Result<std::vector<Interval>>::failure(sorted.error());
116 return merge_checked_intervals(std::move(checked.value()), context);
117}
118
120 std::vector<Interval> intervals) {
122 return normalize_intervals_checked(std::move(intervals), context);
123}
124
125}
CasError & error()
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
Result< std::vector< Interval > > merge_checked_intervals(std::vector< CheckedInterval > checked, ComputationContext &context)
Result< void > sort_checked_intervals(std::vector< CheckedInterval > &checked, ComputationContext &context)
Result< std::vector< CheckedInterval > > collect_nonempty_intervals(std::vector< Interval > intervals, ComputationContext &context)
Result< ComparableEndpoint > comparable_endpoint(const Endpoint &endpoint, ComputationContext &context, const std::string &operation)
Result< int > compare_comparable(const ComparableEndpoint &left, const ComparableEndpoint &right, ComputationContext &context)
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)
const ExprPtr & lower
Result< std::vector< Interval > > normalize_intervals_checked(std::vector< Interval > intervals, ComputationContext &context)
Result< int > compare_comparable(const ComparableEndpoint &left, const ComparableEndpoint &right, ComputationContext &context)