9 if (
value < Rational(0))
return -1;
10 if (
value > Rational(0))
return 1;
15 const Poly& polynomial,
20 if (!step)
return step;
22 const Rational midpoint =
24 const Rational middle_value = polynomial.
eval(midpoint);
25 if (middle_value == Rational(0)) {
30 if (lower_sign == 0) {
52 std::size_t index, std::size_t
round,
60 if (!refined)
return refined;
66 const Poly& projection, std::vector<RationalInterval>& intervals,
69 bool separated =
false;
70 std::size_t
round = 0;
73 for (std::size_t index = 1; index < intervals.size(); ++index) {
74 if (intervals[index - 1].second < intervals[index].first)
continue;
78 if (!left)
return left;
89 const std::vector<RationalInterval>& intervals,
90 const Rational& bound) {
91 std::vector<RationalInterval> bands;
92 bands.reserve(intervals.size());
93 for (std::size_t index = 0; index < intervals.size(); ++index) {
94 const Rational
lower = index == 0
96 : (intervals[index - 1].second + intervals[index].first) /
98 const Rational
upper = index + 1 == intervals.size()
100 : (intervals[index].second + intervals[index + 1].first) /
117 projections.value().imaginary,
context,
operation +
".projection.imaginary");
123 projections.value().imaginary, imaginary.value(),
context,
125 if (!imaginary_separated) {
129 std::move(projections.value()), std::move(
real.
value()),
130 std::move(imaginary.value()), {}, {}});
138 if (projection.
eval(Rational(0)) == Rational(0)) {
139 interval = {Rational(0), Rational(0)};
143 if (!refined)
return refined;
151 bool have_positive =
false;
152 bool have_negative =
false;
156 if (!separated)
return separated;
157 if (
interval.first > Rational(0)) have_positive =
true;
158 if (
interval.second < Rational(0)) have_negative =
true;
160 if (!have_positive || !have_negative || (complex_count & 1U) != 0) {
163 "non-real roots lacked conjugate imaginary projections",
operation);
170 std::size_t real_index, std::size_t imaginary_index) {
171 const auto& real_interval = grid.
real_roots[real_index];
172 const auto& imaginary_interval = grid.
imaginary_roots[imaginary_index];
177 real_interval.first, real_interval.second, real_index, 1},
179 imaginary_interval.first, imaginary_interval.second, imaginary_index, 1}};
186 for (std::size_t imaginary_index = 0;
198 if (!count.value().boundary_clear || count.value().count > 1) {
201 "projection-band rectangle was not a clear one-root cell",
operation);
203 if (count.value().count == 0)
continue;
212 const Poly& polynomial, std::size_t complex_count,
216 auto& grid = prepared.value();
217 auto conjugate = certify_conjugate_projections(grid, complex_count,
context,
operation);
220 grid.real_bands = projection_bands(grid.real_roots, bound);
221 grid.imaginary_bands = projection_bands(grid.imaginary_roots, bound);
222 std::vector<ComplexIsolation>
roots;
223 roots.reserve(complex_count);
224 for (std::size_t real_index = 0; real_index < grid.real_bands.size(); ++real_index) {
228 if (
roots.size() != complex_count) {
231 "projection-band rectangles did not cover every non-real root",
operation);
235 if (left.real_projection.root_index != right.real_projection.root_index) {
236 return left.real_projection.root_index < right.real_projection.root_index;
266 if (!imaginary)
return imaginary;
CoeffType eval(const CoeffType &val) const
对多项式求值(Horner 法)
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
std::vector< RationalInterval > real_bands
Result< void > refine_projection_interval(const Poly &projection, RationalInterval &interval, std::size_t index, std::size_t round, ComputationContext &context, const std::string &operation)
CoordinateProjections projections
Result< void > isolate_grid_row(const Poly &polynomial, const ProjectionGrid &grid, std::size_t real_index, std::vector< ComplexIsolation > &roots, ComputationContext &context, const std::string &operation)
Result< void > separate_projection_intervals(const Poly &projection, std::vector< RationalInterval > &intervals, ComputationContext &context, const std::string &operation)
std::vector< RationalInterval > imaginary_bands
Result< void > certify_conjugate_projections(ProjectionGrid &grid, std::size_t complex_count, ComputationContext &context, const std::string &operation)
std::vector< RationalInterval > projection_bands(const std::vector< RationalInterval > &intervals, const Rational &bound)
std::vector< RationalInterval > real_roots
ComplexIsolation make_cell_isolation(const ProjectionGrid &grid, const RationalRectangle &rectangle, std::size_t real_index, std::size_t imaginary_index)
std::vector< RationalInterval > imaginary_roots
Result< ProjectionGrid > prepare_projection_grid(const Poly &polynomial, ComputationContext &context, const std::string &operation)
Result< void > separate_imaginary_axis(const Poly &projection, RationalInterval &interval, ComputationContext &context, const std::string &operation)
int rational_sign(const Rational &value)
Polynomial< Rational > Poly
Result< CoordinateProjections > coordinate_projections(const Poly &polynomial, ComputationContext &context, const std::string &operation)
Result< std::vector< ComplexIsolation > > isolate_nonreal_roots(const Poly &polynomial, std::size_t complex_count, ComputationContext &context, const std::string &operation)
Result< RectangleCount > count_rectangle_roots(const Poly &polynomial, const RationalRectangle &rectangle, ComputationContext &context, const std::string &operation)
Result< void > refine_interval(const Poly &polynomial, RationalInterval &interval, ComputationContext &context, const std::string &operation)
Result< std::vector< RationalInterval > > isolate_real_roots_exact(const Polynomial< Rational > &polynomial, ComputationContext &context, const std::string &operation)
Result< void > refine_exact_real_algebraic_to_tolerance(ExactRealAlgebraic &value, double absolute_tolerance, double relative_tolerance, ComputationContext &context, const std::string &operation)
ComputationContext const std::string & operation
ExactRealAlgebraic imaginary_projection
ExactRealAlgebraic real_projection
std::pair< Rational, Rational > RationalInterval
std::size_t std::size_t ComputationContext & context
Rational strict_cauchy_root_bound(const Polynomial< Rational > &polynomial)
Result< void > refine_complex_isolation(const Polynomial< Rational > &, ComplexIsolation &isolation, const NumericEvaluationOptions &options, ComputationContext &context, const std::string &operation)
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
ExprResult real(const ExprPtr &expression, ComputationContext &context)
const std::string ComputationContext const SolveOptions & options
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)
const std::string const ExprPtr & value
ExprResult round(const ExprPtr &expression, ComputationContext &context)