LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
LMCAS::anonymous_namespace{symbolic_gcd.cpp} 命名空间参考

类

class  RecursionFrame

函数

Result< void > check_term_budget (std::size_t lhs_terms, std::size_t rhs_terms, ComputationContext &context)
Result< void > collect_polynomial_operands (const std::vector< std::shared_ptr< const SymbolicNode > > &operands, std::set< std::string > &variables, ComputationContext &context)
Result< void > collect_polynomial_variables (const std::shared_ptr< const SymbolicNode > &node, std::set< std::string > &variables, ComputationContext &context)
MultiPoly make_monic (const MultiPoly &polynomial)
Result< MultiPoly > multiply_checked (const MultiPoly &lhs, const MultiPoly &rhs, ComputationContext &context)
Result< std::shared_ptr< SymbolicExpr > > multivariate_polynomial_to_expression (const MultiPoly &polynomial, detail::RewriteBudget &budget)
Result< MultiPoly > node_to_multivariate_polynomial (const std::shared_ptr< const SymbolicNode > &node, const std::vector< std::string > &variables, ComputationContext &context)
Result< std::size_t > polynomial_exponent (const std::shared_ptr< const SymbolicNode > &node)
Result< std::shared_ptr< SymbolicExpr > > polynomial_term_to_expression (const Monomial &monomial, const Rational &coefficient, const MultiPoly &polynomial, detail::RewriteBudget &budget)
Result< MultiPoly > power_to_polynomial (const std::shared_ptr< const PowerNode > &power, const std::vector< std::string > &variables, ComputationContext &context)
Result< MultiPoly > sum_to_polynomial (const std::shared_ptr< const AddNode > &addition, const std::vector< std::string > &variables, ComputationContext &context)
Result< void > verify_gcd_candidate (const MultiPoly &lhs, const MultiPoly &rhs, const MultiPoly &gcd)

变量

constexpr const char * kOperation = "symbolic_polynomial_gcd"

函数说明

◆ check_term_budget()

Result< void > LMCAS::anonymous_namespace{symbolic_gcd.cpp}::check_term_budget ( std::size_t lhs_terms,
std::size_t rhs_terms,
ComputationContext & context )

在文件 symbolic_gcd.cpp 第 133 行定义.

135 {
136 const std::size_t limit = context.limits().max_expansion_terms;
137 if (lhs_terms != 0 && rhs_terms > limit / lhs_terms) {
140 "polynomial expansion term budget exhausted", kOperation);
141 }
142 return context.consume_steps(lhs_terms * rhs_terms + 1, kOperation);
143}
static Result failure(CasErrc code, std::string message, std::string operation={})
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context

引用了 check_term_budget(), LMCAS::context, LMCAS::Result< T >::failure(), kOperation , 以及 LMCAS::ResourceLimit.

被这些函数引用 check_term_budget() , 以及 multiply_checked().

函数调用图:
这是这个函数的调用关系图:

◆ collect_polynomial_operands()

Result< void > LMCAS::anonymous_namespace{symbolic_gcd.cpp}::collect_polynomial_operands ( const std::vector< std::shared_ptr< const SymbolicNode > > & operands,
std::set< std::string > & variables,
ComputationContext & context )

在文件 symbolic_gcd.cpp 第 43 行定义.

45 {
46 for (const auto& operand : operands) {
47 auto result = collect_polynomial_variables(operand, variables, context);
48 if (!result) { return result; }
49 }
50 return Result<void>::success();
51}
static Result success(T value)
Result< void > collect_polynomial_variables(const std::shared_ptr< const SymbolicNode > &node, std::set< std::string > &variables, ComputationContext &context)

引用了 collect_polynomial_operands(), collect_polynomial_variables(), LMCAS::context , 以及 LMCAS::Result< T >::success().

被这些函数引用 collect_polynomial_operands() , 以及 collect_polynomial_variables().

函数调用图:
这是这个函数的调用关系图:

◆ collect_polynomial_variables()

Result< void > LMCAS::anonymous_namespace{symbolic_gcd.cpp}::collect_polynomial_variables ( const std::shared_ptr< const SymbolicNode > & node,
std::set< std::string > & variables,
ComputationContext & context )

在文件 symbolic_gcd.cpp 第 53 行定义.

56 {
57 auto entered = context.enter_recursion(kOperation);
58 if (!entered) { return entered; }
59 RecursionFrame frame(context);
60
61 if (!node) {
63 CasErrc::InternalInvariant, "polynomial contains a null node",
65 }
66 if (std::dynamic_pointer_cast<const NumberNode>(node)) {
67 return Result<void>::success();
68 }
69 if (auto variable = std::dynamic_pointer_cast<const VariableNode>(node)) {
70 if (variable->is_constant()) {
72 "mathematical constants are not rational polynomial variables",
74 }
75 variables.insert(variable->name());
76 return Result<void>::success();
77 }
78 if (auto addition = std::dynamic_pointer_cast<const AddNode>(node)) {
79 return collect_polynomial_operands(addition->operands(), variables, context);
80 }
81 if (auto product = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
82 return collect_polynomial_operands(product->operands(), variables, context);
83 }
84 if (auto power = std::dynamic_pointer_cast<const PowerNode>(node)) {
85 auto exponent = std::dynamic_pointer_cast<const NumberNode>(power->exponent());
86 if (!exponent) {
89 "polynomial exponents must be exact nonnegative integers",
91 }
92 return collect_polynomial_variables(power->base(), variables, context);
93 }
96 "expression is outside the exact rational polynomial domain",
98}
Result< void > collect_polynomial_operands(const std::vector< std::shared_ptr< const SymbolicNode > > &operands, std::set< std::string > &variables, ComputationContext &context)
const std::string & variable
const ExprPtr & exponent

引用了 collect_polynomial_operands(), collect_polynomial_variables(), LMCAS::context, LMCAS::exponent, LMCAS::Result< T >::failure(), LMCAS::InternalInvariant, kOperation, LMCAS::Result< T >::success(), LMCAS::UnsupportedExpression , 以及 LMCAS::variable.

被这些函数引用 collect_polynomial_operands() , 以及 collect_polynomial_variables().

函数调用图:
这是这个函数的调用关系图:

◆ make_monic()

MultiPoly LMCAS::anonymous_namespace{symbolic_gcd.cpp}::make_monic ( const MultiPoly & polynomial)

在文件 symbolic_gcd.cpp 第 285 行定义.

285 {
286 if (polynomial.is_zero()) { return polynomial; }
287 const Rational leading = polynomial.terms().front().second;
288 return polynomial * (Rational(1) / leading);
289}

引用了 make_monic().

被这些函数引用 make_monic() , 以及 verify_gcd_candidate().

函数调用图:
这是这个函数的调用关系图:

◆ multiply_checked()

Result< MultiPoly > LMCAS::anonymous_namespace{symbolic_gcd.cpp}::multiply_checked ( const MultiPoly & lhs,
const MultiPoly & rhs,
ComputationContext & context )

在文件 symbolic_gcd.cpp 第 145 行定义.

147 {
148 auto budget = check_term_budget(
149 static_cast<std::size_t>(lhs.num_terms()),
150 static_cast<std::size_t>(rhs.num_terms()), context);
151 if (!budget) { return Result<MultiPoly>::failure(budget.error()); }
152 MultiPoly result = lhs * rhs;
153 if (static_cast<std::size_t>(result.num_terms()) >
154 context.limits().max_expansion_terms) {
157 "polynomial expansion term budget exhausted", kOperation);
158 }
159 return Result<MultiPoly>::success(std::move(result));
160}
Result< void > check_term_budget(std::size_t lhs_terms, std::size_t rhs_terms, ComputationContext &context)
const ExprPtr & rhs

引用了 check_term_budget(), LMCAS::context, LMCAS::Result< T >::failure(), kOperation, multiply_checked(), LMCAS::ResourceLimit, LMCAS::rhs , 以及 LMCAS::Result< T >::success().

被这些函数引用 multiply_checked(), node_to_multivariate_polynomial() , 以及 power_to_polynomial().

函数调用图:
这是这个函数的调用关系图:

◆ multivariate_polynomial_to_expression()

Result< std::shared_ptr< SymbolicExpr > > LMCAS::anonymous_namespace{symbolic_gcd.cpp}::multivariate_polynomial_to_expression ( const MultiPoly & polynomial,
detail::RewriteBudget & budget )

在文件 symbolic_gcd.cpp 第 291 行定义.

293 {
294 if (polynomial.is_zero()) {
295 budget.require_nodes(1);
297 SymbolicExpr::number(0));
298 }
299
300 std::vector<std::shared_ptr<SymbolicExpr>> terms;
301 terms.reserve(polynomial.terms().size());
302 std::size_t nodes = 0;
303 for (const auto& [monomial, coefficient] : polynomial.terms()) {
305 monomial, coefficient, polynomial, budget);
306 if (!term) { return term; }
307 nodes = budget.append_size(nodes, budget.measure(detail::node(term.value())));
308 terms.push_back(std::move(term.value()));
309 }
310
311 auto expression = terms.front();
312 for (std::size_t index = 1; index < terms.size(); ++index) {
313 expression = SymbolicExpr::add(expression, terms[index]);
314 budget.measure(detail::node(expression));
315 }
316 return Result<std::shared_ptr<SymbolicExpr>>::success(std::move(expression));
317}
std::size_t measure(const std::shared_ptr< const SymbolicNode > &node)
void require_nodes(std::size_t nodes) const
std::size_t append_size(std::size_t current, std::size_t child)
Result< std::shared_ptr< SymbolicExpr > > polynomial_term_to_expression(const Monomial &monomial, const Rational &coefficient, const MultiPoly &polynomial, detail::RewriteBudget &budget)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept

引用了 LMCAS::detail::RewriteBudget::append_size(), LMCAS::detail::RewriteBudget::measure(), multivariate_polynomial_to_expression(), LMCAS::detail::node(), polynomial_term_to_expression() , 以及 LMCAS::detail::RewriteBudget::require_nodes().

被这些函数引用 multivariate_polynomial_to_expression().

函数调用图:
这是这个函数的调用关系图:

◆ node_to_multivariate_polynomial()

Result< MultiPoly > LMCAS::anonymous_namespace{symbolic_gcd.cpp}::node_to_multivariate_polynomial ( const std::shared_ptr< const SymbolicNode > & node,
const std::vector< std::string > & variables,
ComputationContext & context )

在文件 symbolic_gcd.cpp 第 236 行定义.

239 {
240 auto entered = context.enter_recursion(kOperation);
241 if (!entered) { return Result<MultiPoly>::failure(entered.error()); }
242 RecursionFrame frame(context);
243
244 if (auto number = std::dynamic_pointer_cast<const NumberNode>(node)) {
246 MultiPoly(exact_number_as_rational(*number), variables));
247 }
248 if (auto variable = std::dynamic_pointer_cast<const VariableNode>(node)) {
249 Monomial monomial(variables.size(), 0);
250 auto position = std::find(variables.begin(), variables.end(),
251 variable->name());
252 if (position == variables.end()) {
255 "polynomial variable collection is inconsistent", kOperation);
256 }
257 monomial[static_cast<std::size_t>(position - variables.begin())] = 1;
258 return Result<MultiPoly>::success(MultiPoly(
259 {{std::move(monomial), Rational(1)}}, variables));
260 }
261 if (auto addition = std::dynamic_pointer_cast<const AddNode>(node)) {
262 return sum_to_polynomial(addition, variables, context);
263 }
264 if (auto product = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
265 MultiPoly result(Rational(1), variables);
266 for (const auto& operand : product->operands()) {
267 auto converted = node_to_multivariate_polynomial(
268 operand, variables, context);
269 if (!converted) { return converted; }
270 auto multiplied = multiply_checked(result, converted.value(), context);
271 if (!multiplied) { return multiplied; }
272 result = std::move(multiplied.value());
273 }
274 return Result<MultiPoly>::success(std::move(result));
275 }
276 if (auto power = std::dynamic_pointer_cast<const PowerNode>(node)) {
277 return power_to_polynomial(power, variables, context);
278 }
281 "expression is outside the exact rational polynomial domain",
282 kOperation);
283}
Result< MultiPoly > node_to_multivariate_polynomial(const std::shared_ptr< const SymbolicNode > &node, const std::vector< std::string > &variables, ComputationContext &context)
Result< MultiPoly > sum_to_polynomial(const std::shared_ptr< const AddNode > &addition, const std::vector< std::string > &variables, ComputationContext &context)
Result< MultiPoly > multiply_checked(const MultiPoly &lhs, const MultiPoly &rhs, ComputationContext &context)
Result< MultiPoly > power_to_polynomial(const std::shared_ptr< const PowerNode > &power, const std::vector< std::string > &variables, ComputationContext &context)
std::vector< int > Monomial
单项式类型,以整数向量表示各变量的指数
@ Rational
Rational numbers
Rational exact_number_as_rational(const NumberNode &node)

引用了 LMCAS::context, LMCAS::exact_number_as_rational(), LMCAS::Result< T >::failure(), LMCAS::InternalInvariant, kOperation, multiply_checked(), node_to_multivariate_polynomial(), power_to_polynomial(), LMCAS::Result< T >::success(), sum_to_polynomial(), LMCAS::UnsupportedExpression , 以及 LMCAS::variable.

被这些函数引用 node_to_multivariate_polynomial(), power_to_polynomial() , 以及 sum_to_polynomial().

函数调用图:
这是这个函数的调用关系图:

◆ polynomial_exponent()

Result< std::size_t > LMCAS::anonymous_namespace{symbolic_gcd.cpp}::polynomial_exponent ( const std::shared_ptr< const SymbolicNode > & node)

在文件 symbolic_gcd.cpp 第 100 行定义.

101 {
102 auto number = std::dynamic_pointer_cast<const NumberNode>(node);
103 if (!number) {
106 "polynomial exponents must be exact nonnegative integers",
107 kOperation);
108 }
109
110 BigInt integer;
111 if (std::holds_alternative<BigInt>(number->value())) {
112 integer = std::get<BigInt>(number->value());
113 } else {
114 const Rational& rational = std::get<Rational>(number->value());
115 if (!rational.is_integer()) {
118 "polynomial exponents must be integers", kOperation);
119 }
120 integer = rational.to_bigint();
121 }
122
123 const auto value = integer.try_to_int64();
124 if (!value || *value < 0) {
127 "polynomial exponents must be representable nonnegative integers",
128 kOperation);
129 }
130 return Result<std::size_t>::success(static_cast<std::size_t>(*value));
131}
ExprResult integer(Integer)=delete
const std::string const ExprPtr & value
ExprResult rational(const Rational &value)

引用了 LMCAS::Result< T >::failure(), LMCAS::integer, kOperation, polynomial_exponent(), LMCAS::rational(), LMCAS::Result< T >::success(), LMCAS::UnsupportedExpression , 以及 LMCAS::value.

被这些函数引用 polynomial_exponent() , 以及 power_to_polynomial().

函数调用图:
这是这个函数的调用关系图:

◆ polynomial_term_to_expression()

Result< std::shared_ptr< SymbolicExpr > > LMCAS::anonymous_namespace{symbolic_gcd.cpp}::polynomial_term_to_expression ( const Monomial & monomial,
const Rational & coefficient,
const MultiPoly & polynomial,
detail::RewriteBudget & budget )

在文件 symbolic_gcd.cpp 第 219 行定义.

221 {
222 auto step = budget.context().consume_steps(1, kOperation);
223 if (!step) { return Result<std::shared_ptr<SymbolicExpr>>::failure(step.error()); }
224
225 auto factors = detail::multipoly_term_factors(
226 monomial, coefficient, polynomial.variables());
227 std::size_t nodes = 0;
228 for (const auto& factor : factors) {
229 nodes = budget.append_size(nodes, budget.measure(detail::node(factor)));
230 }
231 auto result = detail::multiply_expression_factors(factors);
232 budget.measure(detail::node(result));
233 return Result<std::shared_ptr<SymbolicExpr>>::success(std::move(result));
234}
Result< void > consume_steps(std::size_t amount=1, const std::string &operation={})
ComputationContext & context() const noexcept
std::vector< std::shared_ptr< SymbolicExpr > > multipoly_term_factors(const Monomial &monomial, const Rational &coefficient, const std::vector< std::string > &variables)
std::shared_ptr< SymbolicExpr > multiply_expression_factors(const std::vector< std::shared_ptr< SymbolicExpr > > &factors)

引用了 LMCAS::detail::RewriteBudget::append_size(), LMCAS::ComputationContext::consume_steps(), LMCAS::detail::RewriteBudget::context(), kOperation, LMCAS::detail::RewriteBudget::measure(), LMCAS::detail::multiply_expression_factors(), LMCAS::detail::multipoly_term_factors(), LMCAS::detail::node() , 以及 polynomial_term_to_expression().

被这些函数引用 multivariate_polynomial_to_expression() , 以及 polynomial_term_to_expression().

函数调用图:
这是这个函数的调用关系图:

◆ power_to_polynomial()

Result< MultiPoly > LMCAS::anonymous_namespace{symbolic_gcd.cpp}::power_to_polynomial ( const std::shared_ptr< const PowerNode > & power,
const std::vector< std::string > & variables,
ComputationContext & context )

在文件 symbolic_gcd.cpp 第 191 行定义.

193 {
194 auto exponent = polynomial_exponent(power->exponent());
195 if (!exponent) { return Result<MultiPoly>::failure(exponent.error()); }
197 power->base(), variables, context);
198 if (!base) { return base; }
199
200 MultiPoly result(Rational(1), variables);
201 MultiPoly factor = std::move(base.value());
202 std::size_t remaining = exponent.value();
203 while (remaining != 0) {
204 if ((remaining & 1U) != 0) {
205 auto multiplied = multiply_checked(result, factor, context);
206 if (!multiplied) { return multiplied; }
207 result = std::move(multiplied.value());
208 }
209 remaining >>= 1U;
210 if (remaining != 0) {
211 auto squared = multiply_checked(factor, factor, context);
212 if (!squared) { return squared; }
213 factor = std::move(squared.value());
214 }
215 }
216 return Result<MultiPoly>::success(std::move(result));
217}
Result< std::size_t > polynomial_exponent(const std::shared_ptr< const SymbolicNode > &node)

引用了 LMCAS::context, LMCAS::exponent, LMCAS::Result< T >::failure(), multiply_checked(), node_to_multivariate_polynomial(), polynomial_exponent(), power_to_polynomial() , 以及 LMCAS::Result< T >::success().

被这些函数引用 node_to_multivariate_polynomial() , 以及 power_to_polynomial().

函数调用图:
这是这个函数的调用关系图:

◆ sum_to_polynomial()

Result< MultiPoly > LMCAS::anonymous_namespace{symbolic_gcd.cpp}::sum_to_polynomial ( const std::shared_ptr< const AddNode > & addition,
const std::vector< std::string > & variables,
ComputationContext & context )

在文件 symbolic_gcd.cpp 第 167 行定义.

169 {
170 MultiPoly result(Rational(0), variables);
171 for (const auto& operand : addition->operands()) {
172 auto converted = node_to_multivariate_polynomial(
173 operand, variables, context);
174 if (!converted) { return converted; }
175 auto step = context.consume_steps(
176 static_cast<std::size_t>(result.num_terms() +
177 converted.value().num_terms()) + 1,
178 kOperation);
179 if (!step) { return Result<MultiPoly>::failure(step.error()); }
180 result = result + converted.value();
181 if (static_cast<std::size_t>(result.num_terms()) >
182 context.limits().max_expansion_terms) {
185 "polynomial expansion term budget exhausted", kOperation);
186 }
187 }
188 return Result<MultiPoly>::success(std::move(result));
189}

引用了 LMCAS::context, LMCAS::Result< T >::failure(), kOperation, node_to_multivariate_polynomial(), LMCAS::ResourceLimit, LMCAS::Result< T >::success() , 以及 sum_to_polynomial().

被这些函数引用 node_to_multivariate_polynomial() , 以及 sum_to_polynomial().

函数调用图:
这是这个函数的调用关系图:

◆ verify_gcd_candidate()

Result< void > LMCAS::anonymous_namespace{symbolic_gcd.cpp}::verify_gcd_candidate ( const MultiPoly & lhs,
const MultiPoly & rhs,
const MultiPoly & gcd )

在文件 symbolic_gcd.cpp 第 318 行定义.

319 {
320 if (gcd.is_zero()) { return Result<void>::success(); }
321 MultiPoly lhs_quotient;
322 MultiPoly rhs_quotient;
323 try {
324 lhs_quotient = lhs.exact_div(gcd);
325 rhs_quotient = rhs.exact_div(gcd);
326 } catch (const std::bad_alloc&) {
329 "symbolic GCD verification allocation failed", kOperation);
330 } catch (const std::runtime_error&) {
333 "GCD candidate failed exact divisibility verification",
334 kOperation);
335 } catch (const std::exception& error) {
338 }
339 MultiPoly residual = make_monic(multivariate_gcd(
340 lhs_quotient, rhs_quotient));
341 if (!residual.is_constant()) {
344 "GCD candidate is not maximal", kOperation);
345 }
346 return Result<void>::success();
347}
MultiPoly make_monic(const MultiPoly &polynomial)
MultiPoly multivariate_gcd(const MultiPoly &a, const MultiPoly &b)

引用了 LMCAS::Result< T >::failure(), LMCAS::Inconclusive, LMCAS::InternalInvariant, kOperation, make_monic(), LMCAS::multivariate_gcd(), LMCAS::ResourceLimit, LMCAS::rhs, LMCAS::Result< T >::success() , 以及 verify_gcd_candidate().

被这些函数引用 verify_gcd_candidate().

函数调用图:
这是这个函数的调用关系图:

变量说明

◆ kOperation

const char* LMCAS::anonymous_namespace{symbolic_gcd.cpp}::kOperation = "symbolic_polynomial_gcd"
constexpr