LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
LMCAS::anonymous_namespace{transcendental_solver_substitution.cpp} 命名空间参考

类

struct  SubstNodeVisitor

函数

static void collect_transcendental_subexprs (const std::shared_ptr< const SymbolicNode > &node, const std::string &var, std::vector< std::shared_ptr< SymbolicExpr > > &candidates)
static void deduplicate_candidates (std::vector< std::shared_ptr< SymbolicExpr > > &candidates)
static BigInt extract_exp_multiplier (const std::shared_ptr< const SymbolicNode > &node, const std::string &var)
static bool function_candidate (const FunctionNode &function, const std::string &var)
static bool has_exp_k_var_terms (const std::shared_ptr< const SymbolicNode > &node, const std::string &var)
static Result< bool > is_substitution_polynomial (const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, const std::string &u_var)
static bool power_candidate (const PowerNode &power, const std::string &var)
static BigInt product_exp_multiplier (const MultiplyNode &product, const std::string &var)
static Result< bool > redundant_variable_candidate (const std::shared_ptr< SymbolicExpr > &candidate, const std::shared_ptr< SymbolicExpr > &expr, const std::string &var)
static std::shared_ptr< const SymbolicNode > rewrite_exp_as_u_power (const std::shared_ptr< const SymbolicNode > &node, const std::string &var, const std::string &u_var)

函数说明

◆ collect_transcendental_subexprs()

void LMCAS::anonymous_namespace{transcendental_solver_substitution.cpp}::collect_transcendental_subexprs ( const std::shared_ptr< const SymbolicNode > & node,
const std::string & var,
std::vector< std::shared_ptr< SymbolicExpr > > & candidates )
static

在文件 transcendental_solver_substitution.cpp 第 34 行定义.

37 {
38
39 if (!node) {
40 return;
41 }
42
43 if (auto func = std::dynamic_pointer_cast<const FunctionNode>(node)) {
44 if (function_candidate(*func, var)) {
45 candidates.push_back(LMCAS::detail::make_expression_ptr(node));
46 }
47
48 for (auto& arg : func->arguments()) {
49 collect_transcendental_subexprs(arg, var, candidates);
50 }
51 return;
52 }
53
54 if (auto pow = std::dynamic_pointer_cast<const PowerNode>(node)) {
55 if (power_candidate(*pow, var)) {
56 candidates.push_back(LMCAS::detail::make_expression_ptr(pow->base()));
57 }
58
59 collect_transcendental_subexprs(pow->base(), var, candidates);
60 collect_transcendental_subexprs(pow->exponent(), var, candidates);
61 return;
62 }
63
64 if (auto add = std::dynamic_pointer_cast<const AddNode>(node)) {
65 for (auto& op : add->operands()) {
66 collect_transcendental_subexprs(op, var, candidates);
67 }
68 return;
69 }
70
71 if (auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
72 for (auto& op : mul->operands()) {
73 collect_transcendental_subexprs(op, var, candidates);
74 }
75 return;
76 }
77}
static void collect_transcendental_subexprs(const std::shared_ptr< const SymbolicNode > &node, const std::string &var, std::vector< std::shared_ptr< SymbolicExpr > > &candidates)
static bool function_candidate(const FunctionNode &function, const std::string &var)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
ExprResult pow(const ExprPtr &base, const ExprPtr &exponent, ComputationContext &context)
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
const ExprPtr RelationOp op

引用了 LMCAS::add(), collect_transcendental_subexprs(), function_candidate(), LMCAS::detail::make_expression_ptr(), LMCAS::mul(), LMCAS::op, LMCAS::pow() , 以及 power_candidate().

被这些函数引用 collect_transcendental_subexprs().

函数调用图:
这是这个函数的调用关系图:

◆ deduplicate_candidates()

void LMCAS::anonymous_namespace{transcendental_solver_substitution.cpp}::deduplicate_candidates ( std::vector< std::shared_ptr< SymbolicExpr > > & candidates)
static

在文件 transcendental_solver_substitution.cpp 第 79 行定义.

79 {
80 std::vector<std::shared_ptr<SymbolicExpr>> unique;
81 std::vector<std::string> seen;
82 for (auto& c : candidates) {
83 std::string s = c->to_string();
84 bool found = false;
85 for (auto& existing : seen) {
86 if (existing == s) { found = true; break; }
87 }
88 if (!found) {
89 seen.push_back(s);
90 unique.push_back(c);
91 }
92 }
93 candidates = std::move(unique);
94}
const VectorField const VectorField & c

引用了 LMCAS::c , 以及 deduplicate_candidates().

被这些函数引用 deduplicate_candidates().

函数调用图:
这是这个函数的调用关系图:

◆ extract_exp_multiplier()

BigInt LMCAS::anonymous_namespace{transcendental_solver_substitution.cpp}::extract_exp_multiplier ( const std::shared_ptr< const SymbolicNode > & node,
const std::string & var )
static

在文件 transcendental_solver_substitution.cpp 第 125 行定义.

125 {
126 auto func = std::dynamic_pointer_cast<const FunctionNode>(node);
127 if (!func || func->type() != FunctionNode::FuncType::Exp || func->arguments().size() != 1) {
128 return 0;
129 }
130
131 auto arg = func->arguments()[0];
132
133 if (auto v = std::dynamic_pointer_cast<const VariableNode>(arg)) {
134 if (!v->is_constant() && v->name() == var) {
135 return 1;
136 }
137 }
138
139 if (auto mul = std::dynamic_pointer_cast<const MultiplyNode>(arg)) {
140 return product_exp_multiplier(*mul, var);
141 }
142
143 return 0;
144}
static BigInt product_exp_multiplier(const MultiplyNode &product, const std::string &var)
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::string & v

引用了 LMCAS::FunctionNode::Exp, extract_exp_multiplier(), LMCAS::mul(), product_exp_multiplier() , 以及 LMCAS::v.

被这些函数引用 extract_exp_multiplier(), has_exp_k_var_terms() , 以及 rewrite_exp_as_u_power().

函数调用图:
这是这个函数的调用关系图:

◆ function_candidate()

bool LMCAS::anonymous_namespace{transcendental_solver_substitution.cpp}::function_candidate ( const FunctionNode & function,
const std::string & var )
static

在文件 transcendental_solver_substitution.cpp 第 13 行定义.

13 {
14 if (function.arguments().size() != 1 ||
15 !expression_depends_on_variable(function.arguments()[0], var)) {
16 return false;
17 }
18 using Type = FunctionNode::FuncType;
19 return function.type() == Type::Exp || function.type() == Type::Sin ||
20 function.type() == Type::Cos || function.type() == Type::Tan;
21}
bool expression_depends_on_variable(const detail::SymbolicNodePtr &expression, const std::string &variable, detail::RewriteBudget *budget)
ExprResult function(const std::string &name, std::vector< ExprPtr > arguments)

引用了 LMCAS::expression_depends_on_variable(), LMCAS::function() , 以及 function_candidate().

被这些函数引用 collect_transcendental_subexprs() , 以及 function_candidate().

函数调用图:
这是这个函数的调用关系图:

◆ has_exp_k_var_terms()

bool LMCAS::anonymous_namespace{transcendental_solver_substitution.cpp}::has_exp_k_var_terms ( const std::shared_ptr< const SymbolicNode > & node,
const std::string & var )
static

在文件 transcendental_solver_substitution.cpp 第 200 行定义.

200 {
201 if (!node) {
202 return false;
203 }
204
205 if (extract_exp_multiplier(node, var) > 0) {
206 return true;
207 }
208
209 if (auto add = std::dynamic_pointer_cast<const AddNode>(node)) {
210 for (auto& op : add->operands()) {
211 if (has_exp_k_var_terms(op, var)) {
212 return true;
213 }
214 }
215 }
216 if (auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
217 for (auto& op : mul->operands()) {
218 if (has_exp_k_var_terms(op, var)) {
219 return true;
220 }
221 }
222 }
223 if (auto pow = std::dynamic_pointer_cast<const PowerNode>(node)) {
224 if (has_exp_k_var_terms(pow->base(), var)) {
225 return true;
226 }
227 if (has_exp_k_var_terms(pow->exponent(), var)) {
228 return true;
229 }
230 }
231 if (auto func = std::dynamic_pointer_cast<const FunctionNode>(node)) {
232 for (auto& arg : func->arguments()) {
233 if (has_exp_k_var_terms(arg, var)) {
234 return true;
235 }
236 }
237 }
238
239 return false;
240}
static BigInt extract_exp_multiplier(const std::shared_ptr< const SymbolicNode > &node, const std::string &var)
static bool has_exp_k_var_terms(const std::shared_ptr< const SymbolicNode > &node, const std::string &var)

引用了 LMCAS::add(), extract_exp_multiplier(), has_exp_k_var_terms(), LMCAS::mul(), LMCAS::op , 以及 LMCAS::pow().

被这些函数引用 has_exp_k_var_terms().

函数调用图:
这是这个函数的调用关系图:

◆ is_substitution_polynomial()

Result< bool > LMCAS::anonymous_namespace{transcendental_solver_substitution.cpp}::is_substitution_polynomial ( const std::shared_ptr< SymbolicExpr > & expr,
const std::string & var,
const std::string & u_var )
static

在文件 transcendental_solver_substitution.cpp 第 306 行定义.

308 {
310 return false;
311 }
312 auto polynomial = symbolic_to_poly<SymbolicPolyCoeff>(expr, u_var);
313 if (!polynomial) {
314 if (polynomial.error().code == CasErrc::UnsupportedExpression) {
315 return false;
316 }
317 return Result<bool>::failure(polynomial.error());
318 }
319 return polynomial.value().degree() >= 2;
320}
static Result failure(CasErrc code, std::string message, std::string operation={})
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept

引用了 LMCAS::expression_depends_on_variable(), LMCAS::Result< T >::failure(), is_substitution_polynomial(), LMCAS::detail::node() , 以及 LMCAS::UnsupportedExpression.

被这些函数引用 is_substitution_polynomial().

函数调用图:
这是这个函数的调用关系图:

◆ power_candidate()

bool LMCAS::anonymous_namespace{transcendental_solver_substitution.cpp}::power_candidate ( const PowerNode & power,
const std::string & var )
static

在文件 transcendental_solver_substitution.cpp 第 23 行定义.

23 {
24 if (!expression_depends_on_variable(power.base(), var) ||
26 return false;
27 }
28 auto exponent = std::dynamic_pointer_cast<const NumberNode>(power.exponent());
29 BigInt value;
31}
const std::shared_ptr< const SymbolicNode > & exponent() const noexcept
const std::shared_ptr< const SymbolicNode > & base() const noexcept
bool try_get_integer_value(const std::shared_ptr< const NumberNode > &node, BigInt &value)
const ExprPtr & exponent
const std::string const ExprPtr & value

引用了 LMCAS::PowerNode::base(), LMCAS::exponent, LMCAS::PowerNode::exponent(), LMCAS::expression_depends_on_variable(), power_candidate(), LMCAS::try_get_integer_value() , 以及 LMCAS::value.

被这些函数引用 collect_transcendental_subexprs() , 以及 power_candidate().

函数调用图:
这是这个函数的调用关系图:

◆ product_exp_multiplier()

BigInt LMCAS::anonymous_namespace{transcendental_solver_substitution.cpp}::product_exp_multiplier ( const MultiplyNode & product,
const std::string & var )
static

在文件 transcendental_solver_substitution.cpp 第 96 行定义.

96 {
97 std::shared_ptr<const NumberNode> number;
98 bool has_variable = false;
99 bool has_other = false;
100 for (const auto& operand : product.operands()) {
101 if (auto numeric = std::dynamic_pointer_cast<const NumberNode>(operand)) {
102 if (!number) {
103 number = numeric;
104 } else {
105 has_other = true;
106 }
107 } else if (auto variable = std::dynamic_pointer_cast<const VariableNode>(operand)) {
108 if (!variable->is_constant() && variable->name() == var) {
109 has_variable = true;
110 } else {
111 has_other = true;
112 }
113 } else {
114 has_other = true;
115 }
116 }
117 BigInt value;
118 if (has_variable && number && !has_other &&
119 try_get_integer_value(number, value) && value > 0) {
120 return value;
121 }
122 return 0;
123}
const std::vector< std::shared_ptr< const SymbolicNode > > & operands() const noexcept
const std::string & variable

引用了 LMCAS::MultiplyNode::operands(), product_exp_multiplier(), LMCAS::try_get_integer_value(), LMCAS::value , 以及 LMCAS::variable.

被这些函数引用 extract_exp_multiplier() , 以及 product_exp_multiplier().

函数调用图:
这是这个函数的调用关系图:

◆ redundant_variable_candidate()

Result< bool > LMCAS::anonymous_namespace{transcendental_solver_substitution.cpp}::redundant_variable_candidate ( const std::shared_ptr< SymbolicExpr > & candidate,
const std::shared_ptr< SymbolicExpr > & expr,
const std::string & var )
static

在文件 transcendental_solver_substitution.cpp 第 289 行定义.

291 {
292 auto variable = std::dynamic_pointer_cast<const VariableNode>(LMCAS::detail::node(candidate));
293 if (!variable || variable->is_constant() || variable->name() != var) {
294 return false;
295 }
296 auto polynomial = symbolic_to_poly<SymbolicPolyCoeff>(expr, var);
297 if (!polynomial) {
298 if (polynomial.error().code == CasErrc::UnsupportedExpression) {
299 return false;
300 }
301 return Result<bool>::failure(polynomial.error());
302 }
303 return polynomial.value().degree() >= 2;
304}

引用了 LMCAS::Result< T >::failure(), LMCAS::detail::node(), redundant_variable_candidate(), LMCAS::UnsupportedExpression , 以及 LMCAS::variable.

被这些函数引用 redundant_variable_candidate().

函数调用图:
这是这个函数的调用关系图:

◆ rewrite_exp_as_u_power()

std::shared_ptr< const SymbolicNode > LMCAS::anonymous_namespace{transcendental_solver_substitution.cpp}::rewrite_exp_as_u_power ( const std::shared_ptr< const SymbolicNode > & node,
const std::string & var,
const std::string & u_var )
static

在文件 transcendental_solver_substitution.cpp 第 146 行定义.

149 {
150
151 if (!node) {
152 return node;
153 }
154
155 const BigInt k = extract_exp_multiplier(node, var);
156 if (k > 0) {
157 auto u_node = LMCAS::detail::make_node<VariableNode>(u_var);
158 if (k == 1) {
159 return u_node;
160 }
162 }
163
164 if (auto add = std::dynamic_pointer_cast<const AddNode>(node)) {
165 std::vector<std::shared_ptr<const SymbolicNode>> new_ops;
166 new_ops.reserve(add->operands().size());
167 for (auto& op : add->operands()) {
168 new_ops.push_back(rewrite_exp_as_u_power(op, var, u_var));
169 }
170 return SymbolicFactory::create_add(std::move(new_ops));
171 }
172
173 if (auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
174 std::vector<std::shared_ptr<const SymbolicNode>> new_ops;
175 new_ops.reserve(mul->operands().size());
176 for (auto& op : mul->operands()) {
177 new_ops.push_back(rewrite_exp_as_u_power(op, var, u_var));
178 }
179 return SymbolicFactory::create_multiply(std::move(new_ops));
180 }
181
182 if (auto pow = std::dynamic_pointer_cast<const PowerNode>(node)) {
183 auto new_base = rewrite_exp_as_u_power(pow->base(), var, u_var);
184 auto new_exp = rewrite_exp_as_u_power(pow->exponent(), var, u_var);
185 return SymbolicFactory::create_power(new_base, new_exp);
186 }
187
188 if (auto func = std::dynamic_pointer_cast<const FunctionNode>(node)) {
189 std::vector<std::shared_ptr<const SymbolicNode>> new_args;
190 new_args.reserve(func->arguments().size());
191 for (auto& arg : func->arguments()) {
192 new_args.push_back(rewrite_exp_as_u_power(arg, var, u_var));
193 }
194 return LMCAS::detail::make_node<FunctionNode>(func->type(), std::move(new_args));
195 }
196
197 return node;
198}
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_power(std::shared_ptr< const SymbolicNode > base, std::shared_ptr< const SymbolicNode > exponent)
创建幂运算节点,自动处理指数为 0/1 及底数为 0/1 的情况.
static std::shared_ptr< const SymbolicNode > create_multiply(std::vector< std::shared_ptr< const SymbolicNode > > ops, detail::RewriteBudget *budget=nullptr)
创建乘法节点,自动扁平化嵌套乘法并消除单位元.
static std::shared_ptr< const SymbolicNode > rewrite_exp_as_u_power(const std::shared_ptr< const SymbolicNode > &node, const std::string &var, const std::string &u_var)
std::shared_ptr< const Node > make_node(Args &&... args)

引用了 LMCAS::add(), LMCAS::SymbolicFactory::create_add(), LMCAS::SymbolicFactory::create_multiply(), LMCAS::SymbolicFactory::create_power(), extract_exp_multiplier(), LMCAS::detail::make_node(), LMCAS::mul(), LMCAS::op, LMCAS::pow() , 以及 rewrite_exp_as_u_power().

被这些函数引用 rewrite_exp_as_u_power().

函数调用图:
这是这个函数的调用关系图: