7 std::shared_ptr<const NumberNode>
exponent;
8 std::vector<std::shared_ptr<const SymbolicNode>>
originals;
13 const std::shared_ptr<const SymbolicNode>& factor,
17 const auto power = std::dynamic_pointer_cast<const PowerNode>(factor);
19 const auto numeric = std::dynamic_pointer_cast<const NumberNode>(power->exponent());
33 bool add_number(
const std::shared_ptr<const SymbolicNode>& factor) {
34 const auto number = std::dynamic_pointer_cast<const NumberNode>(factor);
42 void add_base(
const std::shared_ptr<const SymbolicNode>& factor,
43 const std::shared_ptr<const SymbolicNode>& base,
45 auto it =
bases_.find(base);
47 const auto nodes = budget ? budget->
measure(factor) : 0;
55 std::shared_ptr<const SymbolicNode>
finish(
60 std::vector<std::shared_ptr<const SymbolicNode>> operands;
61 std::size_t nodes = 0;
65 std::vector<std::shared_ptr<const SymbolicNode>> variables;
66 std::size_t variable_nodes = 0;
72 operands.insert(operands.end(), variables.begin(), variables.end());
73 if (expanding && operands.size() > 1 &&
74 std::dynamic_pointer_cast<const NumberNode>(operands.back())) {
75 std::rotate(operands.begin(), operands.end() - 1, operands.end());
83 std::vector<std::shared_ptr<const SymbolicNode>>& variables,
85 for (
const auto& [base, accumulated] :
bases_) {
86 const auto&
exponent = accumulated.exponent;
92 for (
const auto& original : accumulated.originals) {
106 for (
const auto& [base, accumulated] :
bases_) {
107 for (
const auto& original : accumulated.originals) {
119 for (
const auto& operand : operands) {
120 if (std::dynamic_pointer_cast<const MatrixNode>(operand)) {
123 const auto power = std::dynamic_pointer_cast<const PowerNode>(operand);
124 if (power && std::dynamic_pointer_cast<const MatrixNode>(power->base())) {
133 const std::vector<std::shared_ptr<const SymbolicNode>>& operands) {
134 ProductAccumulator accumulated;
135 for (
const auto& operand : operands) {
136 if (accumulated.add_number(operand)) {
141 if (base == operand) {
142 const auto power = std::dynamic_pointer_cast<const PowerNode>(operand);
144 base = power->base();
145 exponent = std::dynamic_pointer_cast<const NumberNode>(power->exponent());
154 std::vector<std::shared_ptr<const SymbolicNode>> operands;
155 std::size_t nodes = 0;
156 for (
const auto& operand : node.operands()) {
157 operand->accept(*
this);
158 if (
const auto multiply = std::dynamic_pointer_cast<const MultiplyNode>(
result)) {
159 for (
const auto& child : multiply->operands()) {
166 if (has_matrix_factor(operands)) {
174 const std::shared_ptr<const SymbolicNode>& lhs,
175 const std::shared_ptr<const SymbolicNode>&
rhs) {
176 const auto left = std::dynamic_pointer_cast<const ComplexNode>(lhs);
177 const auto right = std::dynamic_pointer_cast<const ComplexNode>(
rhs);
178 if (!left && !
right) {
181 std::shared_ptr<const SymbolicNode>
real;
182 std::shared_ptr<const SymbolicNode>
imag;
199 real->accept(visitor);
201 imag->accept(visitor);
207 const std::shared_ptr<const SymbolicNode>& lhs,
208 const std::shared_ptr<const SymbolicNode>&
rhs) {
213 const auto left = std::dynamic_pointer_cast<const AddNode>(lhs);
214 const auto right = std::dynamic_pointer_cast<const AddNode>(
rhs);
222 const std::shared_ptr<const SymbolicNode>& lhs,
223 const std::shared_ptr<const SymbolicNode>&
rhs) {
224 const auto left = std::dynamic_pointer_cast<const AddNode>(lhs);
225 const auto right = std::dynamic_pointer_cast<const AddNode>(
rhs);
226 std::size_t left_count = 1, right_count = 1;
228 left_count = left->operands().size();
231 right_count =
right->operands().size();
234 std::vector<std::shared_ptr<const SymbolicNode>> terms;
235 std::size_t nodes = 0;
236 for (std::size_t i = 0; i < left_count; ++i) {
237 const auto&
a = left ? left->operands()[i] : lhs;
238 for (std::size_t j = 0; j < right_count; ++j) {
248 const std::shared_ptr<const SymbolicNode>& lhs,
249 const std::shared_ptr<const SymbolicNode>&
rhs) {
250 ProductAccumulator accumulated;
251 const auto process = [&](
const std::shared_ptr<const SymbolicNode>& factor) {
252 if (accumulated.add_number(factor)) {
259 for (
const auto* node : {&lhs, &
rhs}) {
260 const auto multiply = std::dynamic_pointer_cast<const MultiplyNode>(*node);
265 for (
const auto& operand : multiply->operands()) {
bool can_combine_nested_power(const PowerNode &inner, const std::shared_ptr< const NumberNode > &outer_exponent) const
void visit(const NumberNode &node) override
std::shared_ptr< const SymbolicNode > collect_product(const std::vector< std::shared_ptr< const SymbolicNode > > &operands)
std::shared_ptr< const SymbolicNode > distribute_product(const std::shared_ptr< const SymbolicNode > &lhs, const std::shared_ptr< const SymbolicNode > &rhs)
std::shared_ptr< const SymbolicNode > expand_product(const std::shared_ptr< const SymbolicNode > &lhs, const std::shared_ptr< const SymbolicNode > &rhs)
std::shared_ptr< const SymbolicNode > expand_complex_product(const std::shared_ptr< const SymbolicNode > &lhs, const std::shared_ptr< const SymbolicNode > &rhs)
NormalizationVisitor(detail::RewriteBudget &budget, const FactsQuery &facts, Domain domain)
void set_result(std::shared_ptr< const SymbolicNode > candidate)
std::shared_ptr< const SymbolicNode > collect_expanded_product(const std::shared_ptr< const SymbolicNode > &lhs, const std::shared_ptr< const SymbolicNode > &rhs)
const FactsQuery & facts_
std::shared_ptr< const SymbolicNode > result
ComputationContext & context_
std::shared_ptr< const SymbolicNode > normalize_matrix_product(const 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,则返回实部).
bool add_number(const std::shared_ptr< const SymbolicNode > &factor)
std::shared_ptr< const NumberNode > constant_
void add_base(const std::shared_ptr< const SymbolicNode > &factor, const std::shared_ptr< const SymbolicNode > &base, const std::shared_ptr< const NumberNode > &exponent, detail::RewriteBudget *budget)
void collect_variables(const FactsQuery &facts, Domain domain, detail::RewriteBudget *budget, std::vector< std::shared_ptr< const SymbolicNode > > &variables, std::size_t &nodes, ComputationContext &context) const
std::map< std::shared_ptr< const SymbolicNode >, FactorAccum, NodeCompare > bases_
bool factors_defined(const FactsQuery &facts, Domain domain, ComputationContext &context) const
std::shared_ptr< const SymbolicNode > finish(const FactsQuery &facts, Domain domain, ComputationContext &context, bool expanding, detail::RewriteBudget *budget) const
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)
RewriteBudget * rewrite_budget() const noexcept
bool has_matrix_factor(const std::vector< std::shared_ptr< const SymbolicNode > > &operands)
std::shared_ptr< const NumberNode > collectable_power_exponent(const std::shared_ptr< const SymbolicNode > &factor, std::shared_ptr< const SymbolicNode > &base, const FactsQuery &facts, Domain domain, ComputationContext &context)
Result< Tribool > query_nonzero_value(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
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)
两个数值节点相加
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult integer(Integer)=delete
bool try_get_integer_value(const std::shared_ptr< const NumberNode > &node, BigInt &value)
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)
Domain
Mathematical domain hierarchy (least specific → most specific). Complex ⊃ Real ⊃ Algebraic ⊃ Rational...
@ Complex
Complex numbers (default, least specific)
std::size_t normalization_check_arithmetic(detail::RewriteBudget *budget, std::size_t extra_nodes, const std::shared_ptr< const Nodes > &... children)
std::size_t normalization_check_count(detail::RewriteBudget *budget, std::size_t rows, std::size_t cols=1, bool wrapped=true)
std::shared_ptr< const NumberNode > multiply_numbers(const std::shared_ptr< const NumberNode > &left, const std::shared_ptr< const NumberNode > &right)
两个数值节点相乘
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)
const NumberDomainSet & domain
bool normalization_proved(const Result< Tribool > &result)
bool normalization_factor_less(const std::shared_ptr< const SymbolicNode > &left, const std::shared_ptr< const SymbolicNode > &right)
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)
std::vector< std::shared_ptr< const SymbolicNode > > originals
std::shared_ptr< const NumberNode > exponent