10 const Poly& polynomial,
11 const Rational& real_start,
12 const Rational& imaginary_start,
13 const Rational& real_delta,
14 const Rational& imaginary_delta) {
16 std::vector<Rational>{real_start, real_delta},
"t");
17 const Poly imaginary_line(
18 std::vector<Rational>{imaginary_start, imaginary_delta},
"t");
21 for (std::size_t position = polynomial.
coeffs.size(); position-- > 0;) {
22 Poly next_real =
real * real_line - imaginary * imaginary_line;
23 Poly next_imaginary =
real * imaginary_line + imaginary * real_line;
24 if (next_real.
coeffs.empty()) next_real.
coeffs.resize(1, Rational(0));
27 real = std::move(next_real);
28 imaginary = std::move(next_imaginary);
30 return {std::move(
real), std::move(imaginary)};
34 const Poly& polynomial,
37 const Rational height =
39 std::vector<std::pair<Poly, Poly>> edges;
46 Rational(0), height));
49 -width, Rational(0)));
52 Rational(0), -height));
58 const Poly& imaginary,
61 if (
real.eval(Rational(0)) == Rational(0) &&
62 imaginary.
eval(Rational(0)) == Rational(0)) {
65 if (
real.eval(Rational(1)) == Rational(0) &&
66 imaginary.
eval(Rational(1)) == Rational(0)) {
88 numerator_roots.value() == 0 &&
128 Rational left_sample = root / Rational(2);
135 if (count.value() == 1 &&
denominator.eval(left_sample) != Rational(0))
break;
136 left_sample = (left_sample + root) / Rational(2);
148 Rational numerator_sample;
149 Rational left_sample;
151 const Rational root =
interval.first;
153 numerator_sample = root;
156 left_sample = std::move(sample.value());
163 if (denominator_left_sign == 0 || numerator_sign == 0) {
166 "Cauchy-index pole sign could not be certified",
operation);
186 if (!contribution)
return contribution;
187 index += contribution.value();
194 const Rational& shear) {
195 for (
const auto& [
real, imaginary] : edges) {
199 denominator.eval(Rational(1)) == Rational(0))
return false;
205 const std::vector<std::pair<Poly, Poly>>& edges,
const Rational& shear,
208 for (
const auto& [
real, imaginary] : edges) {
213 total_index += edge_index.value();
215 if ((total_index & 1) != 0) {
218 "argument-principle Cauchy index was odd",
operation);
220 const int count = total_index / 2;
221 if (count < 0 || count > degree) {
224 "argument-principle root count was outside polynomial degree",
operation);
237 const auto edges = rectangle_edges(polynomial, rectangle);
238 for (
const auto& [
real, imaginary] : edges) {
241 if (!clear.value()) {
245 BigInt shear_magnitude(0);
246 int shear_direction = 1;
250 auto bits =
context.require_integer_bits(shear_magnitude.bit_length(),
operation);
252 const Rational shear(shear_direction > 0 ? shear_magnitude : -shear_magnitude);
253 if (shear_is_valid(edges, shear)) {
256 if (shear_direction > 0) {
257 shear_direction = -1;
258 if (shear_magnitude.is_zero()) shear_magnitude = BigInt(1);
261 shear_magnitude += BigInt(1);
static Polynomial gcd(Polynomial a, Polynomial b)
CoeffType eval(const CoeffType &val) const
对多项式求值(Horner 法)
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
int degree() const
获取多项式的次数
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
Result< bool > pole_interval_is_clear(const Poly &denominator, const Poly &numerator, const RationalInterval &interval, ComputationContext &context, const std::string &operation)
Result< int > cauchy_index_on_edge(const Poly &denominator, const Poly &numerator, ComputationContext &context, const std::string &operation)
std::vector< std::pair< Poly, Poly > > rectangle_edges(const Poly &polynomial, const RationalRectangle &rectangle)
std::pair< Poly, Poly > edge_image(const Poly &polynomial, const Rational &real_start, const Rational &imaginary_start, const Rational &real_delta, const Rational &imaginary_delta)
Result< RectangleCount > count_sheared_edges(const std::vector< std::pair< Poly, Poly > > &edges, const Rational &shear, int degree, ComputationContext &context, const std::string &operation)
Result< bool > edge_is_clear(const Poly &real, const Poly &imaginary, ComputationContext &context, const std::string &operation)
Result< int > pole_index(const Poly &denominator, const Poly &numerator, const RationalInterval &interval, ComputationContext &context, const std::string &operation)
Result< Rational > left_pole_sample(const Poly &denominator, const Rational &root, ComputationContext &context, const std::string &operation)
Result< void > refine_pole_interval(const Poly &factor, const Poly &denominator, const Poly &numerator, RationalInterval &interval, ComputationContext &context, const std::string &operation)
bool shear_is_valid(const std::vector< std::pair< Poly, Poly > > &edges, const Rational &shear)
int rational_sign(const Rational &value)
Polynomial< Rational > Poly
Result< RectangleCount > count_rectangle_roots(const Poly &polynomial, const RationalRectangle &rectangle, ComputationContext &context, const std::string &operation)
Poly scale_poly(Poly polynomial, const Rational &scalar)
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< std::size_t > count_real_roots_exact(const Polynomial< Rational > &polynomial, const Rational &lower, const Rational &upper, ComputationContext &context, const std::string &operation)
std::size_t std::size_t multiplicity
ComputationContext const std::string & operation
std::pair< Rational, Rational > RationalInterval
std::size_t std::size_t ComputationContext & context
std::vector< std::pair< Polynomial< Rational >, int > > square_free_factorization(const Polynomial< Rational > &poly)
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
ExprResult real(const ExprPtr &expression, ComputationContext &context)
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)
const ExprPtr & denominator