7 const std::shared_ptr<const SymbolicNode>&
right) {
13 const bool left_number = std::dynamic_pointer_cast<const NumberNode>(left) !=
nullptr;
14 const bool right_number = std::dynamic_pointer_cast<const NumberNode>(
right) !=
nullptr;
15 if (left_number != right_number) {
18 return left->compare(*
right) < 0;
22 const std::shared_ptr<const SymbolicNode>& term,
24 if (coefficient->is_one()) {
27 std::vector<std::shared_ptr<const SymbolicNode>> operands;
28 std::size_t nodes = 0;
30 if (
const auto multiply = std::dynamic_pointer_cast<const MultiplyNode>(term)) {
31 for (
const auto& child : multiply->operands()) {
63 node.real()->accept(*
this);
65 node.imag()->accept(*
this);
71 std::vector<std::shared_ptr<const SymbolicNode>>& operands) {
72 std::vector<std::shared_ptr<const SymbolicNode>>
real;
73 std::vector<std::shared_ptr<const SymbolicNode>>
imag;
74 std::vector<std::shared_ptr<const SymbolicNode>> remaining;
75 std::size_t real_nodes = 0, imag_nodes = 0, remaining_nodes = 0;
76 bool has_complex =
false;
77 for (
const auto& operand : operands) {
78 if (
const auto complex = std::dynamic_pointer_cast<const ComplexNode>(operand)) {
82 }
else if (std::dynamic_pointer_cast<const NumberNode>(operand)) {
96 real_sum->accept(visitor);
98 imag_sum->accept(visitor);
101 if (!merged->is_zero()) {
104 operands = std::move(remaining);
108 std::shared_ptr<const SymbolicNode>& term) {
110 const auto multiply = std::dynamic_pointer_cast<const MultiplyNode>(term);
111 if (!multiply || multiply->operands().empty()) {
114 const auto& operands = multiply->operands();
115 auto number = std::dynamic_pointer_cast<const NumberNode>(operands.front());
116 std::size_t index = 0;
118 number = std::dynamic_pointer_cast<const NumberNode>(operands.back());
119 index = operands.size() - 1;
124 coefficient = number;
125 if (operands.size() == 2) {
126 term = operands[index == 0 ? 1 : 0];
129 std::vector<std::shared_ptr<const SymbolicNode>> rest;
130 std::size_t nodes = 0;
132 rest.reserve(operands.size() - 1);
133 for (std::size_t k = 0; k < operands.size(); ++k) {
140 rest_product->accept(visitor);
146 const std::vector<std::shared_ptr<const SymbolicNode>>& operands) {
149 std::shared_ptr<const NumberNode> coefficient;
150 std::vector<std::shared_ptr<const SymbolicNode>> originals;
153 std::map<std::shared_ptr<const SymbolicNode>, TermAccum,
NodeCompare> terms;
154 for (
const auto& operand : operands) {
155 if (
const auto number = std::dynamic_pointer_cast<const NumberNode>(operand)) {
161 auto found = terms.find(term);
162 if (found == terms.end()) {
164 terms.emplace(term, TermAccum{coefficient, {operand}, nodes});
166 found->second.coefficient =
add_numbers(found->second.coefficient, coefficient);
170 std::vector<std::shared_ptr<const SymbolicNode>> collected;
171 std::size_t nodes = 0;
172 if (!constant->is_zero()) {
175 for (
const auto& [term, accumulated] : terms) {
176 if (!accumulated.coefficient->is_zero()) {
180 for (
const auto& original : accumulated.originals) {
185 if (collected.empty()) {
188 if (collected.size() == 1) {
189 return collected.front();
192 std::sort(collected.begin(), collected.end(), sum_term_less);
197 std::vector<std::shared_ptr<const SymbolicNode>> operands;
198 std::size_t nodes = 0;
199 for (
const auto& operand : node.operands()) {
200 operand->accept(*
this);
201 if (
const auto add = std::dynamic_pointer_cast<const AddNode>(
result)) {
202 for (
const auto& child :
add->operands()) {
void visit(const NumberNode &node) override
std::shared_ptr< const NumberNode > extract_term_coefficient(std::shared_ptr< const SymbolicNode > &term)
NormalizationVisitor(detail::RewriteBudget &budget, const FactsQuery &facts, Domain domain)
void set_result(std::shared_ptr< const SymbolicNode > candidate)
std::shared_ptr< const SymbolicNode > collect_sum(const std::vector< std::shared_ptr< const SymbolicNode > > &operands)
const FactsQuery & facts_
std::shared_ptr< const SymbolicNode > result
bool normalize_matrix_sum(const std::vector< std::shared_ptr< const SymbolicNode > > &operands)
ComputationContext & context_
void merge_complex_terms(std::vector< std::shared_ptr< const SymbolicNode > > &operands)
std::shared_ptr< const SymbolicNode > get_result() const
static std::shared_ptr< const SymbolicNode > create_add(std::vector< std::shared_ptr< const SymbolicNode > > ops, detail::RewriteBudget *budget=nullptr)
创建加法节点,自动扁平化嵌套加法并消除零项.
static std::shared_ptr< const SymbolicNode > create_complex(std::shared_ptr< const SymbolicNode > real, std::shared_ptr< const SymbolicNode > imag)
创建复数节点,自动简化(若虚部为 0,则返回实部).
static std::shared_ptr< const SymbolicNode > create_number(const ::LMCAS::BigInt &v)
std::size_t measure(const std::shared_ptr< const SymbolicNode > &node)
void require_nodes(std::size_t nodes) const
std::size_t measure_result(const std::shared_ptr< const SymbolicNode > &node)
RewriteBudget * rewrite_budget() const noexcept
bool sum_term_less(const std::shared_ptr< const SymbolicNode > &left, const std::shared_ptr< const SymbolicNode > &right)
std::shared_ptr< const SymbolicNode > weighted_term(const std::shared_ptr< const SymbolicNode > &term, const std::shared_ptr< const NumberNode > &coefficient, detail::RewriteBudget *budget)
std::shared_ptr< const Node > make_node(Args &&... args)
std::shared_ptr< const NumberNode > add_numbers(const std::shared_ptr< const NumberNode > &left, const std::shared_ptr< const NumberNode > &right)
两个数值节点相加
ExprResult real(const ExprPtr &expression, ComputationContext &context)
bool normalization_can_discard(const std::shared_ptr< const SymbolicNode > &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
std::size_t normalization_check_arithmetic(detail::RewriteBudget *budget, std::size_t extra_nodes, const std::shared_ptr< const Nodes > &... children)
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
std::size_t normalization_check_count(detail::RewriteBudget *budget, std::size_t rows, std::size_t cols=1, bool wrapped=true)
ExprResult complex(ExprPtr real, ExprPtr imag)
__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
void normalization_check_children(detail::RewriteBudget *budget, std::size_t roots, const std::shared_ptr< const Nodes > &... children)
BigInt get_node_degree_helper(const std::shared_ptr< const SymbolicNode > &node)
计算 AST 节点的多项式次数
std::shared_ptr< const SymbolicNode > make_normalized_multiply_node(const std::vector< std::shared_ptr< const SymbolicNode > > &operands, detail::RewriteBudget *budget=nullptr)
void normalization_append(detail::RewriteBudget *budget, std::size_t &nodes, std::vector< std::shared_ptr< const SymbolicNode > > &children, std::shared_ptr< const SymbolicNode > child)