14static std::shared_ptr<SymbolicExpr>
cbrt_expr(
const std::shared_ptr<SymbolicExpr>& x) {
15 return SymbolicExpr::power(x, SymbolicExpr::number(Rational(1, 3)));
19 const std::shared_ptr<SymbolicExpr>&
b,
const std::shared_ptr<SymbolicExpr>&
c,
22 (
context).limits().max_ast_nodes,
"transform");
30 if (constant->get_number_value_is_zero()) {
31 throw std::invalid_argument(
32 "solve_cubic: identically zero equation has no finite root list");
35 throw std::invalid_argument(
36 "solve_cubic: equation is independent of the requested variable");
40 const std::shared_ptr<SymbolicExpr>&
a,
const std::shared_ptr<SymbolicExpr>&
b,
44 (
context).limits().max_ast_nodes,
"transform");
45 auto a2 = SymbolicExpr::power(
a,
num(2));
46 auto a3 = SymbolicExpr::power(
a,
num(3));
47 auto b2 = SymbolicExpr::power(
b,
num(2));
48 auto b3 = SymbolicExpr::power(
b,
num(3));
49 auto three_ac = SymbolicExpr::multiply(
50 num(3), SymbolicExpr::multiply(
a,
c));
51 auto p_num =
sub(three_ac, b2);
52 auto p_den = SymbolicExpr::multiply(
num(3), a2);
54 auto two_b3 = SymbolicExpr::multiply(
num(2), b3);
55 auto nine_abc = SymbolicExpr::multiply(
56 num(9), SymbolicExpr::multiply(
57 a, SymbolicExpr::multiply(
b,
c)));
58 auto twentyseven_a2d = SymbolicExpr::multiply(
59 num(27), SymbolicExpr::multiply(a2, d));
60 auto q_num = SymbolicExpr::add(
61 sub(two_b3, nine_abc), twentyseven_a2d);
62 auto q_den = SymbolicExpr::multiply(
num(27), a3);
65 b, SymbolicExpr::multiply(
num(3),
a))), transform_budget));
68 auto q_half = SymbolicExpr::divide(q,
num(2));
69 auto p_third = SymbolicExpr::divide(p,
num(3));
71 SymbolicExpr::power(q_half,
num(2)),
72 SymbolicExpr::power(p_third,
num(3)))), transform_budget));
75 auto sqrt_D = SymbolicExpr::sqrt(D_expr);
80 auto t1 = SymbolicExpr::add(
u,
v);
83 auto neg_half_sum = SymbolicExpr::divide(
negate(SymbolicExpr::add(
u,
v)),
num(2));
84 auto diff_uv =
sub(
u,
v);
85 auto sqrt3_half = SymbolicExpr::divide(SymbolicExpr::sqrt(
num(3)),
num(2));
86 auto imag_coeff = SymbolicExpr::multiply(sqrt3_half, diff_uv);
88 auto i_unit = SymbolicExpr::sqrt(
num(-1));
97 if (polynomial.
degree() <= 1)
return true;
101 BigInt denominator_lcm(1);
102 for (
const auto& coefficient : polynomial.
coeffs) {
103 denominator_lcm = BigInt::lcm(
104 denominator_lcm, coefficient.get_denominator());
105 if (denominator_lcm.bit_length() > 32)
return false;
112 for (
const auto& coefficient : polynomial.
coeffs) {
113 if (coefficient != Rational(0)) {
114 return (coefficient * Rational(denominator_lcm))
115 .get_numerator().bit_length() <= 32;
124 std::vector<std::shared_ptr<SymbolicExpr>>
roots;
125 while (polynomial.
degree() >= 3 && polynomial.
coeffs[0] == Rational(0)) {
126 roots.push_back(SymbolicExpr::number(0));
129 if (polynomial.
degree() >= 3) {
134 auto [quotient, remainder] = polynomial.
div_mod(linear);
135 if (!remainder.is_zero()) {
136 throw std::logic_error(
"polynomial solver: inexact rational root division");
138 roots.push_back(SymbolicExpr::number(root));
139 polynomial = std::move(quotient);
143 if (polynomial.
degree() == 1) {
144 roots.push_back(SymbolicExpr::number(
146 }
else if (polynomial.
degree() == 2) {
148 SymbolicExpr::number(polynomial.
coeffs[2]),
149 SymbolicExpr::number(polynomial.
coeffs[1]),
151 roots.insert(
roots.end(), quadratic.begin(), quadratic.end());
152 }
else if (polynomial.
degree() == 4 &&
153 polynomial.
coeffs[3] == Rational(0) &&
154 polynomial.
coeffs[1] == Rational(0)) {
156 SymbolicExpr::number(polynomial.
coeffs[4]),
157 SymbolicExpr::number(polynomial.
coeffs[2]),
158 SymbolicExpr::number(polynomial.
coeffs[0]),
160 roots.insert(
roots.end(), biquadratic.begin(), biquadratic.end());
161 }
else if (polynomial.
degree() >= 3) {
162 auto expression = poly_to_symbolic(polynomial);
163 for (
int index = 0; index < polynomial.
degree(); ++index) {
165 static_cast<std::size_t
>(index),
context);
166 if (!root)
throw root.error();
167 roots.push_back(std::move(root.value()));
176 throw std::invalid_argument(
177 "polynomial solver: identically zero equation has no finite root list");
179 std::vector<std::shared_ptr<SymbolicExpr>>
roots;
180 for (
const auto& [factor, multiplicity] :
183 for (
int repeat = 0; repeat < multiplicity; ++repeat) {
184 roots.insert(
roots.end(), factor_roots.begin(), factor_roots.end());
191 const std::shared_ptr<SymbolicExpr>&
a,
192 const std::shared_ptr<SymbolicExpr>&
b,
193 const std::shared_ptr<SymbolicExpr>&
c,
194 const std::shared_ptr<SymbolicExpr>& d,
197 (
context).limits().max_ast_nodes,
"transform");
212 const std::shared_ptr<SymbolicExpr>&
a,
213 const std::shared_ptr<SymbolicExpr>&
b,
214 const std::shared_ptr<SymbolicExpr>&
c,
215 const std::shared_ptr<SymbolicExpr>& d,
std::pair< Polynomial, Polynomial > div_mod(const Polynomial &other) const
多项式带余除法
std::string variable_name
变量名
bool is_zero() const
判断是否为零多项式
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
CoeffType lead_coeff() const
获取首项系数
int degree() const
获取多项式的次数
Polynomial make_monic() const
首一化(使首项系数为 1)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
bool bounded_rational_root_search(const Polynomial< Rational > &polynomial)
std::shared_ptr< SymbolicExpr > num(int value)
std::vector< std::shared_ptr< SymbolicExpr > > solve_cubic_impl(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, const std::shared_ptr< SymbolicExpr > &d, const std::string &variable, ComputationContext &context)
bool convert_to_rational_poly(const Polynomial< SymbolicPolyCoeff > &poly, Polynomial< Rational > &output, ComputationContext &context)
std::vector< std::shared_ptr< SymbolicExpr > > exact_polynomial_roots(const Polynomial< Rational > &polynomial, ComputationContext &context)
std::vector< std::shared_ptr< SymbolicExpr > > solve_biquadratic_impl(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, const std::string &variable, ComputationContext &context)
std::shared_ptr< SymbolicExpr > negate(const std::shared_ptr< SymbolicExpr > &expr)
bool is_purely_numeric(const std::shared_ptr< SymbolicExpr > &expr)
std::vector< std::shared_ptr< SymbolicExpr > > solve_quadratic_internal(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, ComputationContext &context)
const std::string & variable
static std::vector< std::shared_ptr< SymbolicExpr > > solve_degenerate_cubic(const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, const std::shared_ptr< SymbolicExpr > &d, ComputationContext &context)
std::vector< std::pair< Polynomial< Rational >, int > > square_free_factorization(const Polynomial< Rational > &poly)
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::string & v
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult sub(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
const VectorField const VectorField & c
RootOfConstructionResult make_rootof_checked(const std::shared_ptr< SymbolicExpr > &polynomial, const std::string &variable, std::size_t index, ComputationContext &context)
static std::shared_ptr< SymbolicExpr > cbrt_expr(const std::shared_ptr< SymbolicExpr > &x)
__attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::shared_ptr< SymbolicExpr > & a
std::vector< Rational > find_rational_roots(const Polynomial< Rational > &poly)
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)
std::vector< std::shared_ptr< SymbolicExpr > > solve_cubic(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, const std::shared_ptr< SymbolicExpr > &d, const std::string &variable)
static std::vector< std::shared_ptr< SymbolicExpr > > exact_factor_roots(Polynomial< Rational > polynomial, ComputationContext &context)
static std::vector< std::shared_ptr< SymbolicExpr > > symbolic_cubic_roots(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, const std::shared_ptr< SymbolicExpr > &d, ComputationContext &context)
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string & u