LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
root_of_utils.cpp
浏览该文件的文档.
2#include "root_of_utils.hpp"
6
7namespace LMCAS {
8
9
10
11
12
13
14static std::vector<std::shared_ptr<SymbolicExpr>> solve_closed_form_from_poly(
16 const std::string& var, ComputationContext& context)
17{
18
19 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
20 (context).limits().max_ast_nodes, "transform");
21 int deg = poly.degree();
22 if (deg <= 0) return {};
23
24 auto get_coeff = [&](int d) -> std::shared_ptr<SymbolicExpr> {
25 if (d < 0 || d > deg) return SymbolicExpr::number(0);
26 return poly.coeffs[d].val ? poly.coeffs[d].val : SymbolicExpr::number(0);
27 };
28
29 if (deg == 1) {
30
31 auto a = get_coeff(1);
32 auto b = get_coeff(0);
33 auto neg_b = SymbolicExpr::multiply(b, SymbolicExpr::number(-1));
34 return { detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(neg_b, a)), transform_budget)) };
35 } else if (deg == 2) {
36 auto a = get_coeff(2);
37 auto b = get_coeff(1);
38 auto c = get_coeff(0);
39
40 auto b2 = SymbolicExpr::power(b, SymbolicExpr::number(2));
41 auto four_ac = SymbolicExpr::multiply(SymbolicExpr::number(4), SymbolicExpr::multiply(a, c));
42 auto delta = SymbolicExpr::add(b2, SymbolicExpr::multiply(four_ac, SymbolicExpr::number(-1)));
43 auto sqrt_delta = SymbolicExpr::sqrt(delta);
44 auto neg_b = SymbolicExpr::multiply(b, SymbolicExpr::number(-1));
45 auto two_a = SymbolicExpr::multiply(SymbolicExpr::number(2), a);
46
47 auto x1 = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(SymbolicExpr::add(neg_b, sqrt_delta), two_a)), transform_budget));
48 auto x2 = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(SymbolicExpr::add(neg_b, SymbolicExpr::multiply(sqrt_delta, SymbolicExpr::number(-1))), two_a)), transform_budget));
49 return { x1, x2 };
50 } else if (deg == 3) {
51 auto a = get_coeff(3);
52 auto b = get_coeff(2);
53 auto c = get_coeff(1);
54 auto d = get_coeff(0);
55 return solve_cubic(a, b, c, d, var);
56 } else if (deg == 4) {
57 auto a = get_coeff(4);
58 auto b = get_coeff(3);
59 auto c = get_coeff(2);
60 auto d = get_coeff(1);
61 auto e = get_coeff(0);
62 return solve_quartic(a, b, c, d, e, var);
63 }
64
65 return {};
66}
67
68
69
70
71std::shared_ptr<SymbolicExpr> rootof_simplify(
72 const std::shared_ptr<SymbolicExpr>& rootof_expr)
73{
75 if (!rootof_expr || !LMCAS::detail::node(rootof_expr)) return rootof_expr;
76
77 auto root = std::dynamic_pointer_cast<const RootOfNode>(
78 LMCAS::detail::node(rootof_expr));
79 if (!root) return rootof_expr;
80
81 const std::string& var = root->variable();
82 const int k = static_cast<int>(root->index());
83 std::vector<SymbolicPolyCoeff> coefficients;
84 coefficients.reserve(root->exact_id().polynomial.coeffs.size());
85 for (const auto& coefficient : root->exact_id().polynomial.coeffs) {
86 coefficients.emplace_back(SymbolicExpr::number(coefficient));
87 }
88 Polynomial<SymbolicPolyCoeff> sym_poly(coefficients, var);
89
90 int degree = sym_poly.degree();
91 if (degree <= 0) return rootof_expr;
92
93 if (k < 0 || k >= degree) {
94 return rootof_expr;
95 }
96
97 if (degree == 1) {
98 auto roots = solve_closed_form_from_poly(sym_poly, var, context);
99 return roots.size() == 1 ? roots.front() : rootof_expr;
100 }
101 if (degree == 2) {
102 auto roots = solve_closed_form_from_poly(sym_poly, var, context);
103 if (roots.size() != 2) return rootof_expr;
104 return roots[static_cast<std::size_t>(1 - k)];
105 }
106
107 return rootof_expr;
108}
109
110}
一元多项式模板类
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::shared_ptr< SymbolicExpr > rootof_simplify(const std::shared_ptr< SymbolicExpr > &rootof_expr)
ExprResult e()
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
std::vector< std::shared_ptr< SymbolicExpr > > solve_quartic(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)
const VectorField const VectorField & c
static std::vector< std::shared_ptr< SymbolicExpr > > solve_closed_form_from_poly(const Polynomial< SymbolicPolyCoeff > &poly, const std::string &var, ComputationContext &context)
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)
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)
RootOf 恒等关系、求值及代数闭式化简。
内部 AST 定义。