LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
solve_polynomial.cpp
浏览该文件的文档.
4#include <algorithm>
5#include <cmath>
6#include <limits>
7#include <stdexcept>
8
9#include "root_of_utils.hpp"
10
11namespace LMCAS {
12using namespace polynomial_solver_detail;
13
14static std::vector<std::shared_ptr<SymbolicExpr>> solve_closed_form_poly(
16 const std::string& var, ComputationContext& context)
17{
18 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
19 (context).limits().max_ast_nodes, "transform");
20 int deg = poly.degree();
21 if (deg <= 0) return {};
22
23 auto get_coeff = [&](int d) -> std::shared_ptr<SymbolicExpr> {
24 if (d < 0 || d > deg) return SymbolicExpr::number(0);
25 return poly.coeffs[d].val ? poly.coeffs[d].val : SymbolicExpr::number(0);
26 };
27
28 if (deg == 1) {
29 auto a = get_coeff(1);
30 auto b = get_coeff(0);
31 auto neg_b = SymbolicExpr::multiply(b, SymbolicExpr::number(-1));
32 return { detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(neg_b, a)), transform_budget)) };
33 } else if (deg == 2) {
35 } else if (deg == 3) {
37 } else if (deg == 4) {
39 }
40
41 return {};
42}
43
45 const Polynomial<Rational>& rat_poly)
46{
47 std::vector<SymbolicPolyCoeff> sym_coeffs;
48 sym_coeffs.reserve(rat_poly.coeffs.size());
49 for (const auto& c : rat_poly.coeffs) {
50 sym_coeffs.push_back(SymbolicPolyCoeff(SymbolicExpr::number(c)));
51 }
52 return Polynomial<SymbolicPolyCoeff>(sym_coeffs, rat_poly.variable_name);
53}
54
55static void append_factor_solutions(const Polynomial<Rational>& factor, int multiplicity,
56 const std::string& var, std::vector<std::shared_ptr<SymbolicExpr>>& results,
58 if (factor.degree() <= 0) { return; }
59 auto symbolic = rational_to_symbolic_poly(factor);
60 auto solutions = factor.degree() <= 4 ?
61 solve_closed_form_poly(symbolic, var, context) :
63 for (int copy = 0; copy < multiplicity; ++copy) {
64 results.insert(results.end(), solutions.begin(), solutions.end());
65 }
66}
67
68std::vector<std::shared_ptr<SymbolicExpr>> polynomial_solver_detail::solve_by_factoring_impl(
70 const std::string& var, ComputationContext& context) {
71
72 if (poly.is_zero() || poly.degree() < 1) { return {}; }
73
74 if (poly.degree() <= 2) {
75 return solve_closed_form_poly(poly, var, context);
76 }
77
78 std::vector<std::shared_ptr<SymbolicExpr>> results;
79
80 Polynomial<Rational> rat_poly;
81 if (!convert_to_rational_poly(poly, rat_poly, context)) {
82 if (poly.degree() <= 4) {
83 return solve_closed_form_poly(poly, var, context);
84 }
86 }
87
88 // Keep rational boundaries exact before cubic/quartic floating formulas.
89 auto rational_roots = bounded_rational_root_search(rat_poly) ?
90 find_rational_roots(rat_poly) : std::vector<Rational>{};
91
92 for (const auto& r : rational_roots) {
93 results.push_back(SymbolicExpr::number(r));
94 }
95
96 Polynomial<Rational> quotient = rat_poly;
97 for (const auto& r : rational_roots) {
98 Polynomial<Rational> linear_factor({-r, Rational(1)}, var);
99 auto [q, rem] = quotient.div_mod(linear_factor);
100 if (!rem.is_zero()) { throw std::logic_error("solve_by_factoring: inexact root division"); }
101 quotient = q;
102 }
103
104 if (quotient.degree() <= 0) {
105 return results;
106 }
107
108 if (quotient.degree() <= 4) {
109 auto sym_quotient = rational_to_symbolic_poly(quotient);
110 auto factor_roots = solve_closed_form_poly(sym_quotient, var, context);
111 results.insert(results.end(), factor_roots.begin(), factor_roots.end());
112 return results;
113 }
114
115 auto sqfree_factors = square_free_factorization(quotient);
116
117 for (const auto& [factor, multiplicity] : sqfree_factors) {
118 append_factor_solutions(factor, multiplicity, var, results, context);
119 }
120
121 return results;
122}
123
124std::vector<std::shared_ptr<SymbolicExpr>> solve_by_factoring(
125 const Polynomial<SymbolicPolyCoeff>& poly, const std::string& variable) {
128}
129
130}
一元多项式模板类
std::pair< Polynomial, Polynomial > div_mod(const Polynomial &other) const
多项式带余除法
Polynomial(const std::string &var="x")
构造零多项式
std::string variable_name
变量名
bool is_zero() const
判断是否为零多项式
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
int degree() const
获取多项式的次数
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)
std::vector< std::shared_ptr< SymbolicExpr > > make_rootof_solutions_impl(const Polynomial< SymbolicPolyCoeff > &polynomial, const std::string &variable, ComputationContext &context)
bool bounded_rational_root_search(const Polynomial< Rational > &polynomial)
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 > > solve_by_factoring_impl(const Polynomial< SymbolicPolyCoeff > &polynomial, const std::string &variable, ComputationContext &context)
std::vector< std::shared_ptr< SymbolicExpr > > solve_quartic_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::shared_ptr< SymbolicExpr > &e, const std::string &variable, ComputationContext &context)
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
std::vector< std::pair< Polynomial< Rational >, int > > square_free_factorization(const Polynomial< Rational > &poly)
__attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std std::shared_ptr< SymbolicExpr > r
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
std::vector< std::shared_ptr< SymbolicExpr > > solve_by_factoring(const Polynomial< SymbolicPolyCoeff > &poly, const std::string &variable)
const VectorField const VectorField & c
const MultiPoly & b
__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::shared_ptr< SymbolicExpr > get_coeff(const Polynomial< SymbolicPolyCoeff > &p, int deg)
std::vector< Rational > find_rational_roots(const Polynomial< Rational > &poly)
static std::vector< std::shared_ptr< SymbolicExpr > > solve_closed_form_poly(const Polynomial< SymbolicPolyCoeff > &poly, const std::string &var, ComputationContext &context)
static Polynomial< SymbolicPolyCoeff > rational_to_symbolic_poly(const Polynomial< Rational > &rat_poly)
static void append_factor_solutions(const Polynomial< Rational > &factor, int multiplicity, const std::string &var, std::vector< std::shared_ptr< SymbolicExpr > > &results, ComputationContext &context)
RootOf 恒等关系、求值及代数闭式化简。