20 }
catch (
const std::invalid_argument&) {
32 std::vector<detail::SymbolicNodePtr> operands;
34 operands.reserve(
add.operands().size());
35 for (
const auto& operand :
add.operands()) {
46 for (
const auto& operand : operands) {
60 if (std::dynamic_pointer_cast<const ComplexNode>(
detail::node(base))) {
62 auto result = SymbolicExpr::number(1);
63 for (
int index = 0; index < *
exponent; ++index) {
67 *SymbolicExpr::multiply(result, base), budget);
84 if (
auto complex = std::dynamic_pointer_cast<const ComplexNode>(
92 factor_imag = SymbolicExpr::number(0);
96 auto ac = SymbolicExpr::multiply(
real, factor_real);
99 auto bd = SymbolicExpr::multiply(
imag, factor_imag);
102 auto ad = SymbolicExpr::multiply(
real, factor_imag);
105 auto bc = SymbolicExpr::multiply(
imag, factor_real);
106 const auto negative_size = budget.
append_size(1, bd_size);
109 ac, SymbolicExpr::multiply(SymbolicExpr::number(-1), bd)), budget);
112 real = std::move(next_real);
113 imag = std::move(next_imag);
120 std::vector<ExprPtr> factors;
121 bool changed =
false;
122 bool saw_complex =
false;
123 factors.reserve(multiply.operands().size());
124 for (
const auto& operand : multiply.operands()) {
127 changed = changed ||
detail::node(canonical) != operand;
128 saw_complex = saw_complex ||
129 static_cast<bool>(std::dynamic_pointer_cast<const ComplexNode>(
131 factors.push_back(std::move(canonical));
133 if (!changed && !saw_complex) {
138 std::vector<detail::SymbolicNodePtr> operands;
139 std::size_t size = 0;
140 operands.reserve(factors.size());
141 for (
const auto& factor : factors) {
149 for (
const auto& factor : factors) {
161 if (
auto add = std::dynamic_pointer_cast<const AddNode>(node)) {
162 return canonicalize_sum(*
add, node, budget);
164 if (
auto power = std::dynamic_pointer_cast<const PowerNode>(node)) {
165 return canonicalize_power(*power, node, budget);
167 if (
auto complex = std::dynamic_pointer_cast<const ComplexNode>(node)) {
174 if (
auto multiply = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
175 return canonicalize_product(*multiply, node, budget);
const std::shared_ptr< const SymbolicNode > & exponent() const noexcept
const std::shared_ptr< const SymbolicNode > & base() const noexcept
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_multiply(std::vector< std::shared_ptr< const SymbolicNode > > ops, detail::RewriteBudget *budget=nullptr)
创建乘法节点,自动扁平化嵌套乘法并消除单位元.
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)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::shared_ptr< const SymbolicNode > SymbolicNodePtr
ExprPtr canonicalize_power(const PowerNode &power, const detail::SymbolicNodePtr &original, detail::RewriteBudget &budget)
ExprPtr canonicalize_product(const MultiplyNode &multiply, const detail::SymbolicNodePtr &original, detail::RewriteBudget &budget)
ExprPtr canonicalize_sum(const AddNode &add, const detail::SymbolicNodePtr &original, detail::RewriteBudget &budget)
ExprPtr normalize_equivalence(const ExprPtr &expression, detail::RewriteBudget &budget)
ExprPtr canonicalize_complex_product(const SymbolicExpr &expression, detail::RewriteBudget &budget)
ExprPtr rewritten_complex(const ExprPtr &real, const ExprPtr &imag, const detail::SymbolicNodePtr &original, detail::RewriteBudget &budget)
ExprResult real(const ExprPtr &expression, 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)
ExprResult complex(ExprPtr real, ExprPtr imag)
std::optional< int > exact_small_integer_node(const detail::SymbolicNodePtr &node, int min_value, int max_value)
std::shared_ptr< SymbolicExpr > ExprPtr
const std::string const ExprPtr & value
void accumulate(const ExprPtr &factor, detail::RewriteBudget &budget)