LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
normalization_norms.cpp
浏览该文件的文档.
4
5namespace LMCAS {
6namespace {
7bool numeric_norm_operands(const NumberNode* first, const NumberNode* second,
8 const std::shared_ptr<const SymbolicNode>& second_node) {
9 return first && (!second_node || second);
10}
11
12bool retain_first_square(const std::shared_ptr<const SymbolicNode>& first,
13 const std::shared_ptr<const SymbolicNode>& second) {
14 if (!first->is_zero()) {
15 return true;
16 }
17 if (!second) {
18 return true;
19 }
20 return second->is_zero();
21}
22
23bool complex_norm_operand(const std::shared_ptr<const SymbolicNode>& first,
24 const std::shared_ptr<const SymbolicNode>& second) {
25 return dynamic_cast<const ComplexNode*>(first.get()) ||
26 dynamic_cast<const ComplexNode*>(second.get());
27}
28
29std::shared_ptr<const SymbolicNode> normalized_norm_argument(
30 const std::shared_ptr<const SymbolicNode>& first,
31 const std::shared_ptr<const SymbolicNode>& second,
32 const std::array<const PowerNode*, 2>& squares, detail::RewriteBudget* budget) {
33 std::vector<std::shared_ptr<const SymbolicNode>> terms;
34 std::size_t nodes = 0;
35 terms.reserve(second ? 2 : 1);
36 if (retain_first_square(first, second)) {
37 normalization_check_children(budget, 1, first, squares[0]->exponent());
38 normalization_append(budget, nodes, terms,
39 detail::make_node<PowerNode>(first, squares[0]->exponent()));
40 }
41 if (second && !second->is_zero()) {
42 normalization_check_children(budget, 1, second, squares[1]->exponent());
43 normalization_append(budget, nodes, terms,
44 detail::make_node<PowerNode>(second, squares[1]->exponent()));
45 }
46 if (terms.size() == 1) {
47 return terms.front();
48 }
49 normalization_check_arithmetic<AddNode>(budget, terms, nodes);
50 return detail::make_node<AddNode>(std::move(terms));
51}
52}
53
55 const SymbolicNode& node, std::shared_ptr<const SymbolicNode>& argument) {
56 const auto squares = detail::squared_norm_terms(node);
57 if (!squares[0]) {
58 return false;
59 }
60 squares[0]->base()->accept(*this);
61 auto first = result;
62 std::shared_ptr<const SymbolicNode> second;
63 if (squares[1]) {
64 squares[1]->base()->accept(*this);
65 second = result;
66 }
67 const auto* a = dynamic_cast<const NumberNode*>(first.get());
68 const auto* b = dynamic_cast<const NumberNode*>(second.get());
69 const bool numeric = numeric_norm_operands(a, b, second);
70 argument = normalized_norm_argument(first, second, squares, rewrite_budget());
71 if (numeric) {
72 argument->accept(*this);
73 const auto* number = dynamic_cast<const NumberNode*>(result.get());
74 if (number) {
75 if (auto root = normalization_exact_square_root(*number)) {
76 set_result(std::move(root));
77 return true;
78 }
79 }
80 return finish_squared_norm(node, argument, false);
81 }
82 return finish_squared_norm(node, argument, complex_norm_operand(first, second));
83}
84
86 const SymbolicNode& node, std::shared_ptr<const SymbolicNode>& argument, bool normalize_argument) {
87 if (normalize_argument) {
88 argument->accept(*this);
89 argument = result;
90 return false;
91 }
92 if (const auto* power = dynamic_cast<const PowerNode*>(&node)) {
93 normalization_check_children(rewrite_budget(), 1, argument, power->exponent());
94 set_result(detail::make_node<PowerNode>(argument, power->exponent()));
95 } else {
98 std::vector<std::shared_ptr<const SymbolicNode>>{argument});
99 auto simplified = try_assumption_simplify(norm);
100 set_result(simplified ? simplified : norm);
101 }
102 return true;
103}
104}
复数节点,表示 real + imag * i。
@ Sqrt
对数、绝对值、平方根。
bool try_normalize_squared_norm(const SymbolicNode &node, std::shared_ptr< const SymbolicNode > &argument)
std::shared_ptr< const SymbolicNode > try_assumption_simplify(const std::shared_ptr< const SymbolicNode > &node)
bool finish_squared_norm(const SymbolicNode &node, std::shared_ptr< const SymbolicNode > &argument, bool normalize_argument)
void set_result(std::shared_ptr< const SymbolicNode > candidate)
std::shared_ptr< const SymbolicNode > result
幂运算节点,表示 base^exponent。
RewriteBudget * rewrite_budget() const noexcept
std::shared_ptr< const SymbolicNode > normalized_norm_argument(const std::shared_ptr< const SymbolicNode > &first, const std::shared_ptr< const SymbolicNode > &second, const std::array< const PowerNode *, 2 > &squares, detail::RewriteBudget *budget)
bool retain_first_square(const std::shared_ptr< const SymbolicNode > &first, const std::shared_ptr< const SymbolicNode > &second)
bool numeric_norm_operands(const NumberNode *first, const NumberNode *second, const std::shared_ptr< const SymbolicNode > &second_node)
bool complex_norm_operand(const std::shared_ptr< const SymbolicNode > &first, const std::shared_ptr< const SymbolicNode > &second)
std::array< const PowerNode *, 2 > squared_norm_terms(const SymbolicNode &root)
Recognize real-numeric norm forms without evaluating their squares.
std::shared_ptr< const Node > make_node(Args &&... args)
std::size_t normalization_check_arithmetic(detail::RewriteBudget *budget, std::size_t extra_nodes, const std::shared_ptr< const Nodes > &... children)
const MultiPoly & b
std::shared_ptr< const NumberNode > normalization_exact_square_root(const NumberNode &number)
const ExprPtr & exponent
__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)
void normalization_append(detail::RewriteBudget *budget, std::size_t &nodes, std::vector< std::shared_ptr< const SymbolicNode > > &children, std::shared_ptr< const SymbolicNode > child)
符号规范化访问器接口。