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

类

struct  CancellationFraction

类型定义

using CancellationExpr = std::shared_ptr<SymbolicExpr>
using CancellationNode = std::shared_ptr<const SymbolicNode>

函数

static CancellationExpr build_product (const std::vector< CancellationNode > &factors)
template<typename Coefficient>
static void cancel_polynomial_gcd (const Polynomial< Coefficient > &numerator, const Polynomial< Coefficient > &denominator, CancellationExpr &cur_num, CancellationExpr &cur_den, ComputationContext &context)
static CancellationExpr cancel_variable (CancellationExpr &cur_num, CancellationExpr &cur_den, const std::string &var, const CancellationExpr &simp, ComputationContext &context)
static void classify_fraction_factor (const CancellationNode &factor, std::vector< CancellationNode > &numerator, std::vector< CancellationNode > &denominator)
static bool collect_fraction_terms (const AddNode &addition, std::vector< CancellationFraction > &terms, ComputationContext &context)
static CancellationFraction combine_fraction_terms (const std::vector< CancellationFraction > &terms, ComputationContext &context)
static CancellationExpr distinct_denominator_product (const std::vector< CancellationFraction > &terms, ComputationContext &context)
static CancellationExpr finish_cancellation (const CancellationExpr &cur_num, const CancellationExpr &cur_den, ComputationContext &context)
static CancellationNode positive_denominator_exponent (const NumberNode &exponent)
static CancellationExpr reduce_fraction (CancellationFraction fraction, const CancellationExpr &simp, bool from_sum, ComputationContext &context)
static bool same_denominators (const std::vector< CancellationFraction > &terms)
static void separate_num_den (const CancellationNode &node, std::vector< CancellationNode > &numerator, std::vector< CancellationNode > &denominator)

类说明

◆ LMCAS::anonymous_namespace{symbolic_cancel.cpp}::CancellationFraction

struct LMCAS::anonymous_namespace{symbolic_cancel.cpp}::CancellationFraction

在文件 symbolic_cancel.cpp 第 64 行定义.

LMCAS::anonymous_namespace{symbolic_cancel.cpp}::CancellationFraction 的协作图:
类成员
CancellationExpr denominator
CancellationExpr numerator

类型定义说明

◆ CancellationExpr

using LMCAS::anonymous_namespace{symbolic_cancel.cpp}::CancellationExpr = std::shared_ptr<SymbolicExpr>

在文件 symbolic_cancel.cpp 第 13 行定义.

◆ CancellationNode

using LMCAS::anonymous_namespace{symbolic_cancel.cpp}::CancellationNode = std::shared_ptr<const SymbolicNode>

在文件 symbolic_cancel.cpp 第 12 行定义.

函数说明

◆ build_product()

CancellationExpr LMCAS::anonymous_namespace{symbolic_cancel.cpp}::build_product ( const std::vector< CancellationNode > & factors)
static

在文件 symbolic_cancel.cpp 第 58 行定义.

58 {
59 if (factors.empty()) { return SymbolicExpr::number(1); }
60 if (factors.size() == 1) { return detail::make_expression_ptr(factors[0]); }
62}
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
std::shared_ptr< const Node > make_node(Args &&... args)

引用了 build_product(), LMCAS::detail::make_expression_ptr() , 以及 LMCAS::detail::make_node().

被这些函数引用 build_product() , 以及 collect_fraction_terms().

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

◆ cancel_polynomial_gcd()

template<typename Coefficient>
void LMCAS::anonymous_namespace{symbolic_cancel.cpp}::cancel_polynomial_gcd ( const Polynomial< Coefficient > & numerator,
const Polynomial< Coefficient > & denominator,
CancellationExpr & cur_num,
CancellationExpr & cur_den,
ComputationContext & context )
static

在文件 symbolic_cancel.cpp 第 152 行定义.

154 {
155
156 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
157 (context).limits().max_ast_nodes, "transform");
158 if (denominator.is_zero()) return;
159 auto gcd = Polynomial<Coefficient>::gcd(numerator, denominator);
160 if (gcd.degree() >= 1) {
161 auto [q_num, r_num] = numerator.div_mod(gcd);
162 auto [q_den, r_den] = denominator.div_mod(gcd);
163 if (!r_num.is_zero() || !r_den.is_zero()) return;
164 cur_num = detail::make_expression_ptr(detail::normalize_node(detail::node(poly_to_symbolic(q_num)), transform_budget));
165 cur_den = detail::make_expression_ptr(detail::normalize_node(detail::node(poly_to_symbolic(q_den)), transform_budget));
166 }
167}
static Polynomial gcd(Polynomial a, Polynomial b)
计算两个多项式的最大公因式
std::pair< Polynomial, Polynomial > div_mod(const Polynomial &other) const
多项式带余除法
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
const ExprPtr & denominator

引用了 cancel_polynomial_gcd(), LMCAS::context, LMCAS::denominator, LMCAS::Polynomial< CoeffType >::div_mod(), LMCAS::Polynomial< CoeffType >::gcd(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::node() , 以及 LMCAS::detail::normalize_node().

被这些函数引用 cancel_polynomial_gcd() , 以及 cancel_variable().

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

◆ cancel_variable()

CancellationExpr LMCAS::anonymous_namespace{symbolic_cancel.cpp}::cancel_variable ( CancellationExpr & cur_num,
CancellationExpr & cur_den,
const std::string & var,
const CancellationExpr & simp,
ComputationContext & context )
static

在文件 symbolic_cancel.cpp 第 169 行定义.

170 {
171
172 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
173 (context).limits().max_ast_nodes, "transform");
174 auto num_expanded = detail::make_expression_ptr(detail::expand_node(detail::node(cur_num), transform_budget));
175 auto den_expanded = detail::make_expression_ptr(detail::expand_node(detail::node(cur_den), transform_budget));
176 auto rational_num = symbolic_to_poly<Rational>(num_expanded, var);
177 auto rational_den = symbolic_to_poly<Rational>(den_expanded, var);
178 if (rational_num && rational_den) {
179 if (rational_den.value().is_zero()) { return simp; }
180 if (rational_num.value().is_zero()) { return SymbolicExpr::number(0); }
181 cancel_polynomial_gcd(rational_num.value(), rational_den.value(), cur_num, cur_den, context);
182 return nullptr;
183 }
184 auto symbolic_num = symbolic_to_poly<SymbolicPolyCoeff>(num_expanded, var);
185 auto symbolic_den = symbolic_to_poly<SymbolicPolyCoeff>(den_expanded, var);
186 if (!symbolic_num || !symbolic_den) { return nullptr; }
187 if (symbolic_den.value().is_zero()) { return simp; }
188 if (symbolic_num.value().is_zero()) { return SymbolicExpr::number(0); }
189 cancel_polynomial_gcd(symbolic_num.value(), symbolic_den.value(), cur_num, cur_den, context);
190 return nullptr;
191}
static void cancel_polynomial_gcd(const Polynomial< Coefficient > &numerator, const Polynomial< Coefficient > &denominator, CancellationExpr &cur_num, CancellationExpr &cur_den, ComputationContext &context)
SymbolicNodePtr expand_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)

引用了 cancel_polynomial_gcd(), cancel_variable(), LMCAS::context, LMCAS::detail::expand_node(), LMCAS::detail::make_expression_ptr() , 以及 LMCAS::detail::node().

被这些函数引用 cancel_variable() , 以及 reduce_fraction().

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

◆ classify_fraction_factor()

void LMCAS::anonymous_namespace{symbolic_cancel.cpp}::classify_fraction_factor ( const CancellationNode & factor,
std::vector< CancellationNode > & numerator,
std::vector< CancellationNode > & denominator )
static

在文件 symbolic_cancel.cpp 第 28 行定义.

29 {
30 auto power = std::dynamic_pointer_cast<const PowerNode>(factor);
31 if (power) {
32 auto exponent = std::dynamic_pointer_cast<const NumberNode>(power->exponent());
33 auto positive = exponent ? positive_denominator_exponent(*exponent) : nullptr;
34 if (positive) {
35 auto number = std::dynamic_pointer_cast<const NumberNode>(positive);
36 if (number && number->is_one()) {
37 denominator.push_back(power->base());
38 } else {
39 denominator.push_back(detail::make_node<PowerNode>(power->base(), positive));
40 }
41 return;
42 }
43 }
44 numerator.push_back(factor);
45}
static CancellationNode positive_denominator_exponent(const NumberNode &exponent)
const ExprPtr & exponent

引用了 classify_fraction_factor(), LMCAS::denominator, LMCAS::exponent, LMCAS::detail::make_node() , 以及 positive_denominator_exponent().

被这些函数引用 classify_fraction_factor() , 以及 separate_num_den().

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

◆ collect_fraction_terms()

bool LMCAS::anonymous_namespace{symbolic_cancel.cpp}::collect_fraction_terms ( const AddNode & addition,
std::vector< CancellationFraction > & terms,
ComputationContext & context )
static

在文件 symbolic_cancel.cpp 第 69 行定义.

70 {
71
72 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
73 (context).limits().max_ast_nodes, "transform");
74 bool has_denominator = false;
75 for (const auto& term : addition.operands()) {
76 std::vector<CancellationNode> numerator, denominator;
77 separate_num_den(term, numerator, denominator);
78 auto num_expr = detail::make_expression_ptr(detail::normalize_node(detail::node(build_product(numerator)), transform_budget));
80 if (!den_expr->is_one()) { has_denominator = true; }
81 terms.push_back({num_expr, den_expr});
82 }
83 return has_denominator;
84}
const std::vector< std::shared_ptr< const SymbolicNode > > & operands() const noexcept
static CancellationExpr build_product(const std::vector< CancellationNode > &factors)
static void separate_num_den(const CancellationNode &node, std::vector< CancellationNode > &numerator, std::vector< CancellationNode > &denominator)

引用了 build_product(), collect_fraction_terms(), LMCAS::context, LMCAS::denominator, LMCAS::detail::make_expression_ptr(), LMCAS::detail::node(), LMCAS::detail::normalize_node(), LMCAS::AddNode::operands() , 以及 separate_num_den().

被这些函数引用 collect_fraction_terms().

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

◆ combine_fraction_terms()

CancellationFraction LMCAS::anonymous_namespace{symbolic_cancel.cpp}::combine_fraction_terms ( const std::vector< CancellationFraction > & terms,
ComputationContext & context )
static

在文件 symbolic_cancel.cpp 第 118 行定义.

119 {
120
121 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
122 (context).limits().max_ast_nodes, "transform");
123 const bool same = same_denominators(terms);
124 auto denominator = same ? terms[0].denominator : distinct_denominator_product(terms, context);
125 std::vector<CancellationNode> operands;
126 for (const auto& term : terms) {
127 auto numerator = term.numerator;
128 if (!same) {
129 const auto& total_node = detail::node(denominator);
130 const auto& term_node = detail::node(term.denominator);
131 auto factor = total_node && term_node &&
132 total_node->compare(*term_node) == 0
133 ? SymbolicExpr::number(1)
134 : detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(
135 denominator, term.denominator)), transform_budget));
136 numerator = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::multiply(
137 term.numerator, factor)), transform_budget));
138 }
139 if (numerator && detail::node(numerator)) {
140 operands.push_back(detail::node(numerator));
141 }
142 }
143 if (operands.empty()) { return {SymbolicExpr::number(0), nullptr}; }
144 auto numerator = operands.size() == 1 ? detail::make_expression_ptr(operands[0])
145 : detail::make_expression_ptr(detail::make_node<AddNode>(operands));
146 numerator = same ? detail::make_expression_ptr(detail::normalize_node(detail::node(numerator), transform_budget)) : detail::make_expression_ptr(detail::expand_node(detail::node(numerator), transform_budget));
147 return {numerator, denominator};
148}
static bool same_denominators(const std::vector< CancellationFraction > &terms)
static CancellationExpr distinct_denominator_product(const std::vector< CancellationFraction > &terms, ComputationContext &context)
多元 Hensel 提升(单变量步)

引用了 combine_fraction_terms(), LMCAS::SymbolicNode::compare(), LMCAS::context, LMCAS::denominator, distinct_denominator_product(), LMCAS::detail::expand_node(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::make_node(), LMCAS::detail::node(), LMCAS::detail::normalize_node() , 以及 same_denominators().

被这些函数引用 combine_fraction_terms().

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

◆ distinct_denominator_product()

CancellationExpr LMCAS::anonymous_namespace{symbolic_cancel.cpp}::distinct_denominator_product ( const std::vector< CancellationFraction > & terms,
ComputationContext & context )
static

在文件 symbolic_cancel.cpp 第 94 行定义.

95 {
96
97 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
98 (context).limits().max_ast_nodes, "transform");
99 auto total_den = SymbolicExpr::number(1);
100 std::vector<CancellationExpr> unique_dens;
101 for (const auto& term : terms) {
102 if (term.denominator->is_one()) { continue; }
103 bool found = false;
104 for (const auto& denominator : unique_dens) {
105 if (denominator->to_string() == term.denominator->to_string()) {
106 found = true;
107 break;
108 }
109 }
110 if (!found) { unique_dens.push_back(term.denominator); }
111 }
112 for (const auto& denominator : unique_dens) {
113 total_den = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::multiply(total_den, denominator)), transform_budget));
114 }
115 return total_den;
116}

引用了 LMCAS::context, LMCAS::denominator, distinct_denominator_product(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::node() , 以及 LMCAS::detail::normalize_node().

被这些函数引用 combine_fraction_terms() , 以及 distinct_denominator_product().

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

◆ finish_cancellation()

CancellationExpr LMCAS::anonymous_namespace{symbolic_cancel.cpp}::finish_cancellation ( const CancellationExpr & cur_num,
const CancellationExpr & cur_den,
ComputationContext & context )
static

在文件 symbolic_cancel.cpp 第 193 行定义.

194 {
195
196 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
197 (context).limits().max_ast_nodes, "transform");
198 if (cur_den->is_one()) { return cur_num; }
199 if (detail::node(cur_den)) {
201 SymbolicExpr::number(-1))), transform_budget));
202 if (diff->is_zero()) {
203 return detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::multiply(SymbolicExpr::number(-1), cur_num)), transform_budget));
204 }
205 }
206 return detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(cur_num, cur_den)), transform_budget));
207}

引用了 LMCAS::context, finish_cancellation(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::node() , 以及 LMCAS::detail::normalize_node().

被这些函数引用 finish_cancellation() , 以及 reduce_fraction().

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

◆ positive_denominator_exponent()

CancellationNode LMCAS::anonymous_namespace{symbolic_cancel.cpp}::positive_denominator_exponent ( const NumberNode & exponent)
static

在文件 symbolic_cancel.cpp 第 15 行定义.

15 {
16 const auto& value = exponent.value();
17 if (std::holds_alternative<BigInt>(value)) {
18 const auto& integer = std::get<BigInt>(value);
19 if (!integer.is_negative()) { return nullptr; }
20 return detail::make_node<NumberNode>(BigInt(0) - integer);
21 }
22 const auto& rational = std::get<Rational>(value);
23 if (!rational.get_numerator().is_negative()) { return nullptr; }
25 BigInt(0) - rational.get_numerator(), rational.get_denominator()));
26}
ExprResult integer(Integer)=delete
@ Rational
Rational numbers
const std::string const ExprPtr & value
ExprResult rational(const Rational &value)

引用了 LMCAS::exponent, LMCAS::integer, LMCAS::detail::make_node(), positive_denominator_exponent(), LMCAS::rational() , 以及 LMCAS::value.

被这些函数引用 classify_fraction_factor() , 以及 positive_denominator_exponent().

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

◆ reduce_fraction()

CancellationExpr LMCAS::anonymous_namespace{symbolic_cancel.cpp}::reduce_fraction ( CancellationFraction fraction,
const CancellationExpr & simp,
bool from_sum,
ComputationContext & context )
static

在文件 symbolic_cancel.cpp 第 209 行定义.

210 {
211
212 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
213 (context).limits().max_ast_nodes, "transform");
214 auto rational_variables = free_variables(detail::node(fraction.numerator));
215 const auto denominator_variables = free_variables(detail::node(fraction.denominator));
216 rational_variables.insert(denominator_variables.begin(), denominator_variables.end());
217 if (!from_sum && rational_variables.empty()) {
218 return detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(fraction.numerator, fraction.denominator)), transform_budget));
219 }
220 for (const auto& var : rational_variables) {
221 try {
222 auto terminal = cancel_variable(
223 fraction.numerator, fraction.denominator, var, simp, context);
224 if (terminal) { return terminal; }
225 } catch (const std::invalid_argument&) {
226 continue;
227 } catch (const std::out_of_range&) {
228 continue;
229 } catch (const std::runtime_error&) {
230 continue;
231 }
232 }
233 return finish_cancellation(fraction.numerator, fraction.denominator, context);
234}
static CancellationExpr cancel_variable(CancellationExpr &cur_num, CancellationExpr &cur_den, const std::string &var, const CancellationExpr &simp, ComputationContext &context)
static CancellationExpr finish_cancellation(const CancellationExpr &cur_num, const CancellationExpr &cur_den, ComputationContext &context)
std::set< std::string > free_variables(const detail::SymbolicNodePtr &expression, detail::RewriteBudget *budget)

引用了 cancel_variable(), LMCAS::context, LMCAS::anonymous_namespace{symbolic_cancel.cpp}::CancellationFraction::denominator, finish_cancellation(), LMCAS::free_variables(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::node(), LMCAS::detail::normalize_node(), LMCAS::anonymous_namespace{symbolic_cancel.cpp}::CancellationFraction::numerator , 以及 reduce_fraction().

被这些函数引用 reduce_fraction().

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

◆ same_denominators()

bool LMCAS::anonymous_namespace{symbolic_cancel.cpp}::same_denominators ( const std::vector< CancellationFraction > & terms)
static

在文件 symbolic_cancel.cpp 第 86 行定义.

86 {
87 auto first = terms[0].denominator->to_string();
88 for (size_t i = 1; i < terms.size(); ++i) {
89 if (terms[i].denominator->to_string() != first) { return false; }
90 }
91 return true;
92}

引用了 LMCAS::denominator , 以及 same_denominators().

被这些函数引用 combine_fraction_terms() , 以及 same_denominators().

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

◆ separate_num_den()

void LMCAS::anonymous_namespace{symbolic_cancel.cpp}::separate_num_den ( const CancellationNode & node,
std::vector< CancellationNode > & numerator,
std::vector< CancellationNode > & denominator )
static

在文件 symbolic_cancel.cpp 第 47 行定义.

48 {
49 if (auto product = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
50 for (const auto& operand : product->operands()) {
51 classify_fraction_factor(operand, numerator, denominator);
52 }
53 } else {
54 classify_fraction_factor(node, numerator, denominator);
55 }
56}
static void classify_fraction_factor(const CancellationNode &factor, std::vector< CancellationNode > &numerator, std::vector< CancellationNode > &denominator)

引用了 classify_fraction_factor(), LMCAS::denominator , 以及 separate_num_den().

被这些函数引用 collect_fraction_terms() , 以及 separate_num_den().

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