19 if (polynomial.
is_zero())
return polynomial;
20 const Rational leading = polynomial.
lead_coeff();
21 for (
auto& coefficient : polynomial.
coeffs) coefficient = coefficient / leading;
31bool overlaps(
const Rational& lhs_lower,
const Rational& lhs_upper,
32 const Rational& rhs_lower,
const Rational& rhs_upper) {
33 return !(lhs_upper < rhs_lower) && !(rhs_upper < lhs_lower);
37 if (
value < Rational(0))
return -1;
38 if (
value > Rational(0))
return 1;
46 if (common.degree() < 1) {
50 common,
context,
"exact_algebraic.equal");
70 if (polynomial.
degree() < 1) {
73 "an algebraic value requires a non-constant polynomial",
79 "algebraic root multiplicity must be positive",
82 auto step =
context.consume_steps(1, kOperation);
86 polynomial = monic(std::move(polynomial));
88 std::sort(rational_roots.begin(), rational_roots.end());
90 std::unique(rational_roots.begin(), rational_roots.end()),
91 rational_roots.end());
92 if (rational_roots.size() ==
93 static_cast<std::size_t
>(polynomial.
degree())) {
97 "real algebraic root index is out of range",
101 std::move(polynomial), rational_roots[
root_index],
105 polynomial,
context, kOperation);
109 const auto& intervals = isolated.value();
113 "real algebraic root index is out of range",
117 std::move(polynomial), intervals[
root_index].first,
119 }
catch (
const std::bad_alloc&) {
122 "algebraic root isolation allocation failed",
124 }
catch (
const std::exception& error) {
135 if (!step)
return step;
138 const Rational lower_value =
value.polynomial.eval(
value.lower);
139 if (lower_value == Rational(0)) {
143 const Rational upper_value =
value.polynomial.eval(
value.upper);
144 if (upper_value == Rational(0)) {
149 const Rational midpoint = (
value.lower +
value.upper) / Rational(2);
150 const Rational midpoint_value =
value.polynomial.eval(midpoint);
151 if (midpoint_value == Rational(0)) {
152 value.lower = midpoint;
153 value.upper = midpoint;
157 if (sign(lower_value) != sign(midpoint_value)) {
158 value.upper = midpoint;
160 value.lower = midpoint;
170 auto step =
context.consume_steps(1,
"exact_algebraic.equal");
181 const Rational overlap_lower =
183 const Rational overlap_upper =
185 if (overlap_lower == overlap_upper &&
187 rhs.polynomial.eval(overlap_lower) != Rational(0))) {
192 return common_root_in_enclosures(lhs,
rhs,
context);
193 }
catch (
const std::bad_alloc&) {
196 "algebraic equality allocation failed",
197 "exact_algebraic.equal");
198 }
catch (
const std::exception& error) {
202 "exact_algebraic.equal");
225 const double lhs_width = (lhs.
upper - lhs.
lower).to_double();
226 const double rhs_width = (
rhs.upper -
rhs.lower).to_double();
227 const double width = std::max(lhs_width, rhs_width);
228 if (!(width > 0.0) || !std::isfinite(width)) {
231 "distinct algebraic values retained an inseparable enclosure",
232 "exact_algebraic.compare");
234 if (lhs_width > 0.0) {
237 "exact_algebraic.compare");
242 if (rhs_width > 0.0) {
245 "exact_algebraic.compare");
static Polynomial gcd(Polynomial a, Polynomial b)
计算两个多项式的最大公因式
CoeffType eval(const CoeffType &val) const
对多项式求值(Horner 法)
std::string variable_name
变量名
bool is_zero() const
判断是否为零多项式
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
CoeffType lead_coeff() const
获取首项系数
int degree() const
获取多项式的次数
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
bool overlaps(const Rational &lhs_lower, const Rational &lhs_upper, const Rational &rhs_lower, const Rational &rhs_upper)
int sign(const Rational &value)
Polynomial< Rational > monic(Polynomial< Rational > polynomial)
constexpr const char * kOperation
bool same_polynomial(const Polynomial< Rational > &lhs, const Polynomial< Rational > &rhs)
Result< bool > common_root_in_enclosures(const ExactRealAlgebraic &lhs, const ExactRealAlgebraic &rhs, ComputationContext &context)
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)
Result< int > compare_exact_real_algebraic(ExactRealAlgebraic lhs, ExactRealAlgebraic rhs, ComputationContext &context)
std::size_t std::size_t multiplicity
Result< void > refine_exact_real_algebraic(ExactRealAlgebraic &value, ComputationContext &context, const std::string &operation)
ComputationContext const std::string & operation
Result< ExactRealAlgebraic > ExactRealAlgebraicResult
ExactRealAlgebraicResult make_exact_real_algebraic(Polynomial< Rational > polynomial, std::size_t root_index, std::size_t multiplicity, ComputationContext &context)
std::size_t std::size_t ComputationContext & context
Result< bool > equal_exact_real_algebraic(ExactRealAlgebraic lhs, ExactRealAlgebraic rhs, ComputationContext &context)
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
std::vector< Rational > find_rational_roots(const Polynomial< Rational > &poly)
const std::string const ExprPtr & value
Polynomial< Rational > polynomial