LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
root_of_identity.cpp
浏览该文件的文档.
7
8namespace LMCAS {
9
11 const std::shared_ptr<SymbolicExpr>& polynomial,
12 const std::string& variable,
13 std::size_t index,
15 constexpr const char* operation = "rootof.construct";
16 if (!polynomial || !LMCAS::detail::node(polynomial) ||
17 variable.empty()) {
20 "RootOf requires a polynomial and named variable", operation);
21 }
22 auto recognized = recognize_rational_polynomial(
23 *polynomial, variable, context);
24 if (!recognized) {
25 return RootOfConstructionResult::failure(recognized.error());
26 }
27 if (!recognized.value()) {
30 "RootOf coefficients must be exact rational constants",
31 operation);
32 }
33 auto identity = detail::make_exact_root_id(
34 std::move(*recognized.value()), index, context, operation);
35 if (!identity) {
36 return RootOfConstructionResult::failure(identity.error());
37 }
41 std::move(identity.value()), variable)));
42}
43
45 const std::shared_ptr<SymbolicExpr>& polynomial,
46 const std::string& variable,
47 std::size_t index) {
49 return make_rootof_checked(polynomial, variable, index, context);
50}
51static std::shared_ptr<SymbolicExpr> symbolic_root_term(
52 const std::shared_ptr<SymbolicExpr>& coefficient,
53 const std::string& variable, int degree) {
54 if (degree == 0) return coefficient;
55 auto symbol = SymbolicExpr::variable(variable);
56 auto power = degree == 1
57 ? symbol : SymbolicExpr::power(symbol, SymbolicExpr::number(degree));
58 return coefficient->is_one()
59 ? power : SymbolicExpr::multiply(coefficient, power);
60}
61
62static std::shared_ptr<SymbolicExpr> symbolic_poly_to_expr(
64
65 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
66 (context).limits().max_ast_nodes, "transform");
67 if (poly.is_zero()) return SymbolicExpr::number(0);
68
69 std::vector<std::shared_ptr<SymbolicExpr>> terms;
70 for (int i = poly.degree(); i >= 0; --i) {
71 const auto& coeff = poly.coeffs[i];
72
73 auto coeff_expr = coeff.val;
74 if (coeff_expr) {
75 if (auto simplified = detail::make_expression_ptr(detail::normalize_node(detail::node(coeff_expr), transform_budget))) {
76 coeff_expr = simplified;
77 }
78 if (LMCAS::detail::node(coeff_expr) && coeff_expr->is_zero()) {
79 continue;
80 }
81 }
82 terms.push_back(symbolic_root_term(coeff_expr, poly.variable_name, i));
83 }
84
85 if (terms.empty()) return SymbolicExpr::number(0);
86 if (terms.size() == 1) return terms[0];
87
88 auto result = terms[0];
89 for (size_t i = 1; i < terms.size(); ++i) {
90 result = SymbolicExpr::add(result, terms[i]);
91 }
92 return result;
93}
94
95
96std::vector<std::shared_ptr<SymbolicExpr>> make_rootof_solutions(
98 const std::string& var) {
101}
102
103std::vector<std::shared_ptr<SymbolicExpr>> detail::make_rootof_solutions_impl(
105 const std::string& var, ComputationContext& context) {
106 if (poly.degree() <= 0) return {};
107 auto polynomial_expression = symbolic_poly_to_expr(poly, context);
108 auto recognized = recognize_rational_polynomial(
109 *polynomial_expression, var, context);
110 if (!recognized) throw recognized.error();
111 if (!recognized.value()) return {};
112 auto canonical = recognized.value()->square_free_part().make_monic();
113 canonical.variable_name = "_root";
114 std::vector<std::shared_ptr<SymbolicExpr>> solutions;
115 solutions.reserve(static_cast<std::size_t>(canonical.degree()));
116 for (int index = 0; index < canonical.degree(); ++index) {
117 solutions.push_back(LMCAS::detail::make_expression_ptr(
120 canonical, static_cast<std::size_t>(index)},
121 var)));
122 }
123 return solutions;
124}
125
126namespace {
127
128
130 const std::shared_ptr<SymbolicExpr>& rootof_expr,
132 const std::string& operation) {
133 if (!rootof_expr || !LMCAS::detail::node(rootof_expr)) {
135 CasErrc::InvalidArgument, "RootOf expression cannot be null", operation);
136 }
137 auto root = std::dynamic_pointer_cast<const RootOfNode>(
138 LMCAS::detail::node(rootof_expr));
139 if (!root) {
142 "expression is not a valid RootOf", operation);
143 }
144 auto access = context.consume_steps(1, operation);
145 if (!access) return Result<const RootOfNode*>::failure(access.error());
146 return Result<const RootOfNode*>::success(root.get());
147}
148
149
150}
151
153 const std::shared_ptr<SymbolicExpr>& rootof_expr,
155{
156 constexpr const char* operation = "rootof_evaluate";
157 auto request = parse_rootof_request(rootof_expr, context, operation);
158 if (!request) return RootOfEvaluationResult::failure(request.error());
159 auto evaluated = detail::evaluate_root_real(
160 request.value()->exact_id(),
162 if (!evaluated) {
163 return RootOfEvaluationResult::failure(evaluated.error());
164 }
165 return RootOfEvaluationResult::success(evaluated.value().value);
166}
167
169 const std::shared_ptr<SymbolicExpr>& rootof_expr) {
171 return rootof_evaluate_checked(rootof_expr, context);
172}
173
175 const std::shared_ptr<SymbolicExpr>& rootof_expr,
177 constexpr const char* operation = "rootof_evaluate_complex";
178 auto request = parse_rootof_request(rootof_expr, context, operation);
179 if (!request) {
180 return RootOfComplexEvaluationResult::failure(request.error());
181 }
183 request.value()->exact_id(),
185}
186
188 const std::shared_ptr<SymbolicExpr>& rootof_expr) {
190 return rootof_evaluate_complex_checked(rootof_expr, context);
191}
192
193}
一元多项式模板类
std::string variable_name
变量名
bool is_zero() const
判断是否为零多项式
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(std::shared_ptr< SymbolicExpr > value)
virtual bool is_zero() const
Result< const RootOfNode * > parse_rootof_request(const std::shared_ptr< SymbolicExpr > &rootof_expr, ComputationContext &context, const std::string &operation)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
Result< ExactRootId > make_exact_root_id(Polynomial< Rational > polynomial, std::size_t index, ComputationContext &context, const std::string &operation)
std::shared_ptr< const Node > make_node(Args &&... args)
Result< ApproxComplex > evaluate_root_complex(const ExactRootId &root, const NumericEvaluationOptions &options, ComputationContext &context)
Result< ApproxReal > evaluate_root_real(const ExactRootId &root, const NumericEvaluationOptions &options, ComputationContext &context)
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)
std::size_t std::size_t ComputationContext & context
std::vector< std::shared_ptr< SymbolicExpr > > make_rootof_solutions(const Polynomial< SymbolicPolyCoeff > &poly, const std::string &var)
const std::string & variable
RootOfComplexEvaluationResult rootof_evaluate_complex_checked(const std::shared_ptr< SymbolicExpr > &rootof_expr, ComputationContext &context)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
RootOfEvaluationResult rootof_evaluate_checked(const std::shared_ptr< SymbolicExpr > &rootof_expr, ComputationContext &context)
static std::shared_ptr< SymbolicExpr > symbolic_root_term(const std::shared_ptr< SymbolicExpr > &coefficient, const std::string &variable, int degree)
static std::shared_ptr< SymbolicExpr > symbolic_poly_to_expr(const Polynomial< SymbolicPolyCoeff > &poly, ComputationContext &context)
RootOfConstructionResult make_rootof_checked(const std::shared_ptr< SymbolicExpr > &polynomial, const std::string &variable, std::size_t index, ComputationContext &context)
Result< ApproxComplex > RootOfComplexEvaluationResult
Result< OptionalRationalPolynomial > recognize_rational_polynomial(const SymbolicExpr &expression, const std::string &variable, ComputationContext &context)
Result< std::shared_ptr< SymbolicExpr > > RootOfConstructionResult
Result< lmmc_real_t > RootOfEvaluationResult
符号表达式与一元多项式的转换。
精确 RootOf 标识构造及受检数值求值。
内部 AST 定义。