LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
LMCAS::detail::anonymous_namespace{exact_sturm.cpp} 命名空间参考

类

struct  PendingInterval

类型定义

using SturmSequence = std::vector<Polynomial<Rational>>

函数

Result< void > clear_isolation_endpoints (const Polynomial< Rational > &square_free, const SturmSequence &sequence, PendingInterval &interval, ComputationContext &context, const std::string &operation)
Result< std::size_t > count_open_roots (const Polynomial< Rational > &square_free, const SturmSequence &sequence, const Rational &lower, const Rational &upper, ComputationContext &context, const std::string &operation)
Result< std::vector< RationalInterval > > isolate_sturm_sequence (const Polynomial< Rational > &square_free, const SturmSequence &sequence, ComputationContext &context, const std::string &operation)
Result< SturmSequence > make_sturm_sequence (Polynomial< Rational > polynomial, ComputationContext &context, const std::string &operation)
int polynomial_sign_at (const Polynomial< Rational > &polynomial, const Rational &point)
int sign_changes (const std::vector< int > &signs)
Result< void > subdivide_isolation (const Polynomial< Rational > &square_free, const SturmSequence &sequence, const PendingInterval &current, std::vector< PendingInterval > &pending, std::vector< RationalInterval > &isolated, ComputationContext &context, const std::string &operation)
Result< int > variations_at (const SturmSequence &sequence, const Rational &point, ComputationContext &context, const std::string &operation)

类说明

◆ LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::PendingInterval

struct LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::PendingInterval

在文件 exact_sturm.cpp 第 137 行定义.

LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::PendingInterval 的协作图:
类成员
size_t count
Rational lower
Rational upper

类型定义说明

◆ SturmSequence

using LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::SturmSequence = std::vector<Polynomial<Rational>>

在文件 exact_sturm.cpp 第 9 行定义.

函数说明

◆ clear_isolation_endpoints()

Result< void > LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::clear_isolation_endpoints ( const Polynomial< Rational > & square_free,
const SturmSequence & sequence,
PendingInterval & interval,
ComputationContext & context,
const std::string & operation )

在文件 exact_sturm.cpp 第 143 行定义.

146 {
147 while (polynomial_sign_at(square_free, interval.lower) == 0 ||
148 polynomial_sign_at(square_free, interval.upper) == 0) {
149 const Rational midpoint = (interval.lower + interval.upper) / Rational(2);
150 if (polynomial_sign_at(square_free, midpoint) == 0) {
151 interval.lower = midpoint;
152 interval.upper = midpoint;
153 break;
154 }
155 const bool lower_is_root = polynomial_sign_at(square_free, interval.lower) == 0;
156 auto half = lower_is_root
157 ? count_open_roots(square_free, sequence, midpoint, interval.upper,
159 : count_open_roots(square_free, sequence, interval.lower, midpoint,
161 if (!half) return Result<void>::failure(half.error());
162 if (lower_is_root == (half.value() == 1)) {
163 interval.lower = midpoint;
164 } else {
165 interval.upper = midpoint;
166 }
167 }
168 return Result<void>::success();
169}
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
Result< std::size_t > count_open_roots(const Polynomial< Rational > &square_free, const SturmSequence &sequence, const Rational &lower, const Rational &upper, ComputationContext &context, const std::string &operation)
int polynomial_sign_at(const Polynomial< Rational > &polynomial, const Rational &point)
ComputationContext const std::string & operation
std::size_t std::size_t ComputationContext & context
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
const ExprPtr & lower

引用了 clear_isolation_endpoints(), LMCAS::detail::context, count_open_roots(), LMCAS::Result< T >::failure(), LMCAS::interval(), LMCAS::detail::operation, polynomial_sign_at() , 以及 LMCAS::Result< T >::success().

被这些函数引用 clear_isolation_endpoints() , 以及 isolate_sturm_sequence().

函数调用图:
这是这个函数的调用关系图:

◆ count_open_roots()

Result< std::size_t > LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::count_open_roots ( const Polynomial< Rational > & square_free,
const SturmSequence & sequence,
const Rational & lower,
const Rational & upper,
ComputationContext & context,
const std::string & operation )

在文件 exact_sturm.cpp 第 107 行定义.

113 {
114 if (!(lower < upper) || sequence.empty()) {
116 }
117 auto lower_variations = variations_at(sequence, lower, context, operation);
118 if (!lower_variations) {
119 return Result<std::size_t>::failure(lower_variations.error());
120 }
121 auto upper_variations = variations_at(sequence, upper, context, operation);
122 if (!upper_variations) {
123 return Result<std::size_t>::failure(upper_variations.error());
124 }
125 int count = lower_variations.value() - upper_variations.value();
126 if (polynomial_sign_at(square_free, upper) == 0) --count;
127 if (count < 0) {
130 "Sturm variation produced a negative open-interval count",
131 operation);
132 }
133 return Result<std::size_t>::success(static_cast<std::size_t>(count));
134}
Result< int > variations_at(const SturmSequence &sequence, const Rational &point, 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

引用了 LMCAS::detail::context, count_open_roots(), LMCAS::Result< T >::failure(), LMCAS::InternalInvariant, LMCAS::lower, LMCAS::detail::operation, polynomial_sign_at(), LMCAS::Result< T >::success(), LMCAS::upper , 以及 variations_at().

被这些函数引用 clear_isolation_endpoints(), count_open_roots(), isolate_sturm_sequence() , 以及 subdivide_isolation().

函数调用图:
这是这个函数的调用关系图:

◆ isolate_sturm_sequence()

Result< std::vector< RationalInterval > > LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::isolate_sturm_sequence ( const Polynomial< Rational > & square_free,
const SturmSequence & sequence,
ComputationContext & context,
const std::string & operation )

在文件 exact_sturm.cpp 第 201 行定义.

203 {
204 const Rational bound = strict_cauchy_root_bound(square_free);
205 auto total = count_open_roots(square_free, sequence, -bound, bound, context, operation);
206 if (!total) return Result<std::vector<RationalInterval>>::failure(total.error());
207 std::vector<PendingInterval> pending;
208 std::vector<RationalInterval> isolated;
209 if (total.value() != 0) pending.push_back({-bound, bound, total.value()});
210 isolated.reserve(total.value());
211 while (!pending.empty()) {
212 auto step = context.consume_steps(1, operation);
213 if (!step) return Result<std::vector<RationalInterval>>::failure(step.error());
214 PendingInterval current = std::move(pending.back());
215 pending.pop_back();
216 if (current.count == 1) {
217 auto cleared = clear_isolation_endpoints(
218 square_free, sequence, current, context, operation);
219 if (!cleared) return Result<std::vector<RationalInterval>>::failure(cleared.error());
220 isolated.emplace_back(current.lower, current.upper);
221 continue;
222 }
223 auto subdivided = subdivide_isolation(
224 square_free, sequence, current, pending, isolated, context, operation);
225 if (!subdivided) return Result<std::vector<RationalInterval>>::failure(subdivided.error());
226 }
227 std::sort(isolated.begin(), isolated.end(),
228 [](const RationalInterval& left, const RationalInterval& right) {
229 if (left.first != right.first) return left.first < right.first;
230 return left.second < right.second;
231 });
232 if (isolated.size() != total.value()) {
233 return Result<std::vector<RationalInterval>>::failure(
235 "Sturm isolation lost a distinct real root", operation);
236 }
237 return Result<std::vector<RationalInterval>>::success(std::move(isolated));
238}
Result< void > clear_isolation_endpoints(const Polynomial< Rational > &square_free, const SturmSequence &sequence, PendingInterval &interval, ComputationContext &context, const std::string &operation)
Result< void > subdivide_isolation(const Polynomial< Rational > &square_free, const SturmSequence &sequence, const PendingInterval &current, std::vector< PendingInterval > &pending, std::vector< RationalInterval > &isolated, ComputationContext &context, const std::string &operation)
std::pair< Rational, Rational > RationalInterval
Rational strict_cauchy_root_bound(const Polynomial< Rational > &polynomial)
const ExprPtr & right

引用了 clear_isolation_endpoints(), LMCAS::detail::context, LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::PendingInterval::count, count_open_roots(), LMCAS::InternalInvariant, isolate_sturm_sequence(), LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::PendingInterval::lower, LMCAS::detail::operation, LMCAS::right, LMCAS::detail::strict_cauchy_root_bound(), subdivide_isolation() , 以及 LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::PendingInterval::upper.

被这些函数引用 isolate_sturm_sequence().

函数调用图:
这是这个函数的调用关系图:

◆ make_sturm_sequence()

Result< SturmSequence > LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::make_sturm_sequence ( Polynomial< Rational > polynomial,
ComputationContext & context,
const std::string & operation )

在文件 exact_sturm.cpp 第 60 行定义.

63 {
64 auto step = context.consume_steps(1, operation);
65 if (!step) return Result<SturmSequence>::failure(step.error());
66
67 polynomial.trim();
68 if (polynomial.degree() <= 0) {
70 }
71 polynomial = polynomial.square_free_part().make_monic();
72
73 SturmSequence sequence;
74 sequence.push_back(polynomial);
75 sequence.push_back(polynomial.differentiate());
76 while (!sequence.back().is_zero()) {
77 step = context.consume_steps(1, operation);
78 if (!step) return Result<SturmSequence>::failure(step.error());
79 const auto& dividend = sequence[sequence.size() - 2];
80 const auto& divisor = sequence.back();
81 auto division = dividend.div_mod(divisor);
82 auto remainder = std::move(division.second);
83 if (remainder.is_zero()) break;
84 for (auto& coefficient : remainder.coeffs) coefficient = -coefficient;
85 remainder.trim();
86 sequence.push_back(std::move(remainder));
87 }
88 if (!sequence.empty() && sequence.back().is_zero()) sequence.pop_back();
89 return Result<SturmSequence>::success(std::move(sequence));
90}
Polynomial differentiate() const
求导
Polynomial square_free_part() const
计算无平方因子部分
int degree() const
获取多项式的次数
Polynomial make_monic() const
首一化(使首项系数为 1)
void trim()
去除高次零系数
std::vector< Polynomial< Rational > > SturmSequence

引用了 LMCAS::detail::context, LMCAS::Polynomial< CoeffType >::degree(), LMCAS::Polynomial< CoeffType >::differentiate(), LMCAS::Result< T >::failure(), LMCAS::Polynomial< CoeffType >::make_monic(), make_sturm_sequence(), LMCAS::detail::operation, LMCAS::Polynomial< CoeffType >::square_free_part(), LMCAS::Result< T >::success() , 以及 LMCAS::Polynomial< CoeffType >::trim().

被这些函数引用 make_sturm_sequence().

函数调用图:
这是这个函数的调用关系图:

◆ polynomial_sign_at()

int LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::polynomial_sign_at ( const Polynomial< Rational > & polynomial,
const Rational & point )

在文件 exact_sturm.cpp 第 22 行定义.

24 {
25 if (polynomial.is_zero()) return 0;
26 const int degree = polynomial.degree();
27 const BigInt numerator = point.get_numerator();
28 const BigInt denominator = point.get_denominator();
29 BigInt coefficient_denominator(1);
30 for (const auto& coefficient : polynomial.coeffs) {
31 coefficient_denominator *= coefficient.get_denominator();
32 }
33 std::vector<BigInt> numerator_powers(
34 static_cast<std::size_t>(degree) + 1, BigInt(1));
35 std::vector<BigInt> denominator_powers(
36 static_cast<std::size_t>(degree) + 1, BigInt(1));
37 for (int exponent = 1; exponent <= degree; ++exponent) {
38 numerator_powers[static_cast<std::size_t>(exponent)] =
39 numerator_powers[static_cast<std::size_t>(exponent - 1)] *
40 numerator;
41 denominator_powers[static_cast<std::size_t>(exponent)] =
42 denominator_powers[static_cast<std::size_t>(exponent - 1)] *
44 }
45 BigInt value(0);
46 for (int exponent = 0; exponent <= degree; ++exponent) {
47 const auto& coefficient =
48 polynomial.coeffs[static_cast<std::size_t>(exponent)];
49 if (coefficient == Rational(0)) continue;
50 value += coefficient.get_numerator() *
51 (coefficient_denominator / coefficient.get_denominator()) *
52 numerator_powers[static_cast<std::size_t>(exponent)] *
53 denominator_powers[
54 static_cast<std::size_t>(degree - exponent)];
55 }
56 if (value == BigInt(0)) return 0;
57 return value < BigInt(0) ? -1 : 1;
58}
bool is_zero() const
判断是否为零多项式
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
const std::string const LimitExprPtr & point
const ExprPtr & exponent
const std::string const ExprPtr & value
const ExprPtr & denominator

引用了 LMCAS::Polynomial< CoeffType >::coeffs, LMCAS::Polynomial< CoeffType >::degree(), LMCAS::denominator, LMCAS::exponent, LMCAS::Polynomial< CoeffType >::is_zero(), LMCAS::point, polynomial_sign_at() , 以及 LMCAS::value.

被这些函数引用 clear_isolation_endpoints(), count_open_roots(), polynomial_sign_at(), subdivide_isolation() , 以及 variations_at().

函数调用图:
这是这个函数的调用关系图:

◆ sign_changes()

int LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::sign_changes ( const std::vector< int > & signs)

在文件 exact_sturm.cpp 第 11 行定义.

11 {
12 int changes = 0;
13 int previous = 0;
14 for (const int current : signs) {
15 if (current == 0) continue;
16 if (previous != 0 && current != previous) ++changes;
17 previous = current;
18 }
19 return changes;
20}

引用了 sign_changes().

被这些函数引用 sign_changes() , 以及 variations_at().

函数调用图:
这是这个函数的调用关系图:

◆ subdivide_isolation()

Result< void > LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::subdivide_isolation ( const Polynomial< Rational > & square_free,
const SturmSequence & sequence,
const PendingInterval & current,
std::vector< PendingInterval > & pending,
std::vector< RationalInterval > & isolated,
ComputationContext & context,
const std::string & operation )

在文件 exact_sturm.cpp 第 171 行定义.

175 {
176 const Rational midpoint = (current.lower + current.upper) / Rational(2);
177 const bool midpoint_is_root = polynomial_sign_at(square_free, midpoint) == 0;
178 auto left = count_open_roots(
179 square_free, sequence, current.lower, midpoint, context, operation);
180 if (!left) return Result<void>::failure(left.error());
181 auto right = count_open_roots(
182 square_free, sequence, midpoint, current.upper, context, operation);
183 if (!right) return Result<void>::failure(right.error());
184 const std::size_t accounted = left.value() + right.value() +
185 (midpoint_is_root ? 1U : 0U);
186 if (accounted != current.count) {
189 "Sturm subdivision did not preserve the root count", operation);
190 }
191 if (right.value() != 0) {
192 pending.push_back({midpoint, current.upper, right.value()});
193 }
194 if (midpoint_is_root) isolated.emplace_back(midpoint, midpoint);
195 if (left.value() != 0) {
196 pending.push_back({current.lower, midpoint, left.value()});
197 }
198 return Result<void>::success();
199}

引用了 LMCAS::detail::context, LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::PendingInterval::count, count_open_roots(), LMCAS::Result< T >::failure(), LMCAS::InternalInvariant, LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::PendingInterval::lower, LMCAS::detail::operation, polynomial_sign_at(), LMCAS::right, subdivide_isolation(), LMCAS::Result< T >::success() , 以及 LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::PendingInterval::upper.

被这些函数引用 isolate_sturm_sequence() , 以及 subdivide_isolation().

函数调用图:
这是这个函数的调用关系图:

◆ variations_at()

Result< int > LMCAS::detail::anonymous_namespace{exact_sturm.cpp}::variations_at ( const SturmSequence & sequence,
const Rational & point,
ComputationContext & context,
const std::string & operation )

在文件 exact_sturm.cpp 第 92 行定义.

96 {
97 auto step = context.consume_steps(sequence.size() + 1, operation);
98 if (!step) return Result<int>::failure(step.error());
99 std::vector<int> signs;
100 signs.reserve(sequence.size());
101 for (const auto& member : sequence) {
102 signs.push_back(polynomial_sign_at(member, point));
103 }
104 return Result<int>::success(sign_changes(signs));
105}
int sign_changes(const std::vector< int > &signs)
ExprResult member(const ExprPtr &element, const ExprPtr &set, ComputationContext &context)

引用了 LMCAS::detail::context, LMCAS::Result< T >::failure(), LMCAS::member(), LMCAS::detail::operation, LMCAS::point, polynomial_sign_at(), sign_changes(), LMCAS::Result< T >::success() , 以及 variations_at().

被这些函数引用 count_open_roots() , 以及 variations_at().

函数调用图:
这是这个函数的调用关系图: