LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
normalization_powers.cpp
浏览该文件的文档.
3
4namespace LMCAS {
5
7 const std::shared_ptr<const SymbolicNode>& base,
8 const std::shared_ptr<const SymbolicNode>& exponent) {
9 if (exponent->is_zero()) {
14 } else {
17 }
18 return true;
19 }
20 if (exponent->is_one()) {
21 set_result(base);
22 return true;
23 }
24 if (base->is_zero()) {
28 } else {
31 }
32 return true;
33 }
34 if (!base->is_one() || !normalization_can_discard(exponent, facts_, domain_, context_)) {
35 return false;
36 }
38 return true;
39}
40
42 const MultiplyNode& base, const std::shared_ptr<const SymbolicNode>& exponent) {
43 for (const auto& operand : base.operands()) {
44 const auto* power = dynamic_cast<const PowerNode*>(operand.get());
45 if (dynamic_cast<const MatrixNode*>(operand.get()) ||
46 (power && dynamic_cast<const MatrixNode*>(power->base().get()))) {
47 return false;
48 }
49 }
50 BigInt integer;
51 if (!try_get_integer_value(std::dynamic_pointer_cast<const NumberNode>(exponent), integer)) {
53 return false;
54 }
56 for (const auto& operand : base.operands()) {
57 if (!normalization_proved(positive
60 return false;
61 }
62 }
63 } else if (integer.is_zero()) {
64 return false;
65 }
67 return true;
68}
69
71 const MultiplyNode& base, const std::shared_ptr<const SymbolicNode>& exponent) {
72 std::vector<std::shared_ptr<const SymbolicNode>> operands;
73 std::size_t nodes = 0;
74 normalization_check_count(rewrite_budget(), base.operands().size(), 1, false);
75 for (const auto& operand : base.operands()) {
77 detail::make_node<PowerNode>(operand, exponent)->accept(*this);
78 if (const auto multiply = std::dynamic_pointer_cast<const MultiplyNode>(result)) {
79 for (const auto& child : multiply->operands()) {
80 normalization_append(rewrite_budget(), nodes, operands, child);
81 }
82 } else {
83 normalization_append(rewrite_budget(), nodes, operands, result);
84 }
85 }
86 make_normalized_multiply_node(operands, rewrite_budget())->accept(*this);
87}
88
90 const PowerNode& base, const std::shared_ptr<const NumberNode>& exponent) {
91 BigInt integer;
93 return false;
94 }
95 const auto inner_base = std::dynamic_pointer_cast<const NumberNode>(base.base());
96 if (!inner_base || !inner_base->is_negative_one()) {
97 return false;
98 }
99 const auto inner_exponent = std::dynamic_pointer_cast<const NumberNode>(base.exponent());
100 if (!inner_exponent) {
101 return false;
102 }
103 const auto* rational = std::get_if<Rational>(&inner_exponent->value());
104 if (!rational || *rational != Rational(1, 2)) {
105 return false;
106 }
108 return true;
109}
110
112 const PowerNode& base, const std::shared_ptr<const SymbolicNode>& exponent) {
113 const auto numeric = std::dynamic_pointer_cast<const NumberNode>(exponent);
114 if (normalize_nested_imaginary_power(base, numeric)) {
115 return true;
116 }
117 if (!can_combine_nested_power(base, numeric)) {
118 return false;
119 }
122 detail::make_node<PowerNode>(base.base(), result)->accept(*this);
123 return true;
124}
125
127 std::shared_ptr<const SymbolicNode> base;
128 if (try_normalize_squared_norm(node, base)) {
129 return;
130 }
131 if (!base) {
132 node.base()->accept(*this);
133 base = result;
134 }
135 node.exponent()->accept(*this);
136 auto exponent = result;
138 return;
139 }
140 const auto base_number = std::dynamic_pointer_cast<const NumberNode>(base);
141 const auto exponent_number = std::dynamic_pointer_cast<const NumberNode>(exponent);
142 if (base_number && exponent_number &&
144 if (auto folded = normalization_numeric_power(base_number, exponent_number, rewrite_budget())) {
145 set_result(std::move(folded));
146 return;
147 }
148 }
149 if (const auto multiply = std::dynamic_pointer_cast<const MultiplyNode>(base)) {
150 if (normalize_product_power(*multiply, exponent)) {
151 return;
152 }
153 }
154 if (const auto power = std::dynamic_pointer_cast<const PowerNode>(base)) {
155 if (normalize_nested_power(*power, exponent)) {
156 return;
157 }
158 }
161}
162
163bool NormalizationVisitor::is_positive_integer_number(const std::shared_ptr<const NumberNode>& node) {
164 BigInt value;
165 return try_get_integer_value(node, value) && value > BigInt(0);
166 }
168 const PowerNode& inner,
169 const std::shared_ptr<const NumberNode>& outer_exponent) const {
170 if (!is_positive_integer_number(outer_exponent)) {
171 return false;
172 }
173 auto exponent = std::dynamic_pointer_cast<const NumberNode>(inner.exponent());
175 return true;
176 }
177 if (!exponent) {
178 return false;
179 }
180 const auto* rational = std::get_if<Rational>(&exponent->value());
181 if (!rational || rational->get_numerator() <= BigInt(0)) {
182 return false;
183 }
185}
186
187}
矩阵节点,支持稠密和稀疏两种存储方式。
乘法节点,表示多个操作数的乘积。
const std::vector< std::shared_ptr< const SymbolicNode > > & operands() const noexcept
bool can_combine_nested_power(const PowerNode &inner, const std::shared_ptr< const NumberNode > &outer_exponent) const
bool try_normalize_squared_norm(const SymbolicNode &node, std::shared_ptr< const SymbolicNode > &argument)
bool normalize_nested_imaginary_power(const PowerNode &base, const std::shared_ptr< const NumberNode > &exponent)
void visit(const NumberNode &node) override
bool normalize_nested_power(const PowerNode &base, const std::shared_ptr< const SymbolicNode > &exponent)
void set_result(std::shared_ptr< const SymbolicNode > candidate)
std::shared_ptr< const SymbolicNode > result
bool normalize_product_power(const MultiplyNode &base, const std::shared_ptr< const SymbolicNode > &exponent)
void distribute_power(const MultiplyNode &base, const std::shared_ptr< const SymbolicNode > &exponent)
static bool is_positive_integer_number(const std::shared_ptr< const NumberNode > &node)
bool normalize_power_identity(const std::shared_ptr< const SymbolicNode > &base, const std::shared_ptr< const SymbolicNode > &exponent)
幂运算节点,表示 base^exponent。
const std::shared_ptr< const SymbolicNode > & exponent() const noexcept
const std::shared_ptr< const SymbolicNode > & base() const noexcept
RewriteBudget * rewrite_budget() const noexcept
Result< Tribool > query_nonzero_value(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
std::shared_ptr< const Node > make_node(Args &&... args)
Result< Tribool > query_real_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
Result< Tribool > query_nonnegative_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
Result< Tribool > query_positive_value(const Node &node, const FactsQuery &facts, ComputationContext &context)
ExprResult integer(Integer)=delete
bool try_get_integer_value(const std::shared_ptr< const NumberNode > &node, BigInt &value)
bool normalization_can_discard(const std::shared_ptr< const SymbolicNode > &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
@ Complex
Complex numbers (default, least specific)
std::shared_ptr< const SymbolicNode > normalization_imaginary_power(const BigInt &exponent, detail::RewriteBudget *budget=nullptr)
std::size_t normalization_check_count(detail::RewriteBudget *budget, std::size_t rows, std::size_t cols=1, bool wrapped=true)
const ExprPtr & exponent
void normalization_check_children(detail::RewriteBudget *budget, std::size_t roots, const std::shared_ptr< const Nodes > &... children)
std::shared_ptr< const SymbolicNode > normalization_numeric_power(const std::shared_ptr< const NumberNode > &base, const std::shared_ptr< const NumberNode > &exponent, detail::RewriteBudget *budget=nullptr)
const std::string const ExprPtr & value
bool normalization_proved(const Result< Tribool > &result)
std::shared_ptr< const SymbolicNode > make_normalized_multiply_node(const std::vector< std::shared_ptr< const SymbolicNode > > &operands, detail::RewriteBudget *budget=nullptr)
ExprResult rational(const Rational &value)
void normalization_append(detail::RewriteBudget *budget, std::size_t &nodes, std::vector< std::shared_ptr< const SymbolicNode > > &children, std::shared_ptr< const SymbolicNode > child)
符号规范化访问器接口。