LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
LMCAS::solver_detail 命名空间参考

命名空间

namespace  anonymous_namespace{solver_imaginary.cpp}

函数

bool collect_denominator_factors (const std::shared_ptr< const SymbolicNode > &node, std::vector< std::shared_ptr< const SymbolicNode > > &denominator_factors, std::vector< std::shared_ptr< SymbolicExpr > > &denominator_constraints)
bool contains_imaginary (const std::shared_ptr< SymbolicExpr > &expression)
lmmc_real_t finite_midpoint (lmmc_real_t lower, lmmc_real_t upper)
bool is_polynomial_node (const std::shared_ptr< const SymbolicNode > &node)
std::shared_ptr< SymbolicExpr > multiply_no_expand (const std::shared_ptr< const SymbolicNode > &term, const std::vector< std::shared_ptr< const SymbolicNode > > &denominator_factors)
std::map< std::string, SymbolicExpr > project_unconditional_linear_system (const std::vector< SymbolicExpr > &equations, const std::vector< std::string > &variables, ComputationContext &context)
std::map< std::string, SymbolicExpr > solve_linear_system_impl (const std::vector< SymbolicExpr > &equations, const std::vector< std::string > &variables, ComputationContext &context)
bool solver_number_value (const NumberNode &number, double &value)
std::shared_ptr< SymbolicExpr > to_ptr (const SymbolicExpr &expression)

函数说明

◆ collect_denominator_factors()

bool LMCAS::solver_detail::collect_denominator_factors ( const std::shared_ptr< const SymbolicNode > & node,
std::vector< std::shared_ptr< const SymbolicNode > > & denominator_factors,
std::vector< std::shared_ptr< SymbolicExpr > > & denominator_constraints )

在文件 solver_linear.cpp 第 225 行定义.

229 {
230 if (!node) {
231 return false;
232 }
233
234 if (std::dynamic_pointer_cast<const NumberNode>(node) || std::dynamic_pointer_cast<const VariableNode>(node)) {
235 return true;
236 }
237
238 if (auto add = std::dynamic_pointer_cast<const AddNode>(node)) {
239 return collect_operand_denominators(add->operands(), den_factors, den_constraints);
240 }
241
242 if (auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
243 return collect_operand_denominators(mul->operands(), den_factors, den_constraints);
244 }
245
246 if (auto pow = std::dynamic_pointer_cast<const PowerNode>(node)) {
247 return collect_power_denominators(*pow, den_factors, den_constraints);
248 }
249
250 if (auto func = std::dynamic_pointer_cast<const FunctionNode>(node)) {
251 return collect_operand_denominators(func->arguments(), den_factors, den_constraints);
252 }
253
254 return false;
255}
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)
static bool collect_power_denominators(const PowerNode &power, std::vector< std::shared_ptr< const SymbolicNode > > &den_factors, std::vector< std::shared_ptr< SymbolicExpr > > &den_constraints)
static bool collect_operand_denominators(const std::vector< std::shared_ptr< const SymbolicNode > > &operands, std::vector< std::shared_ptr< const SymbolicNode > > &den_factors, std::vector< std::shared_ptr< SymbolicExpr > > &den_constraints)

引用了 LMCAS::add(), LMCAS::collect_operand_denominators(), LMCAS::collect_power_denominators(), LMCAS::mul() , 以及 LMCAS::pow().

被这些函数引用 LMCAS::anonymous_namespace{solver_groebner_system.cpp}::clear_denominators(), LMCAS::collect_operand_denominators() , 以及 LMCAS::collect_power_denominators().

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

◆ contains_imaginary()

bool LMCAS::solver_detail::contains_imaginary ( const std::shared_ptr< SymbolicExpr > & expression)

在文件 solver_imaginary.cpp 第 226 行定义.

226 {
227 if (!expr || !LMCAS::detail::node(expr)) {
228 return false;
229 }
230 ContainsImaginaryVisitor visitor;
231 LMCAS::detail::node(expr)->accept(visitor);
232 return visitor.found;
233}
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept

引用了 contains_imaginary() , 以及 LMCAS::detail::node().

被这些函数引用 contains_imaginary() , 以及 LMCAS::solution_is_excluded().

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

◆ finite_midpoint()

lmmc_real_t LMCAS::solver_detail::finite_midpoint ( lmmc_real_t lower,
lmmc_real_t upper )
inline

在文件 solver_support.hpp 第 9 行定义.

9 {
10 if (lower < 0.0 && upper > 0.0) {
11 return lower * 0.5 + upper * 0.5;
12 }
13 return lower + (upper - lower) * 0.5;
14}
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
const ExprPtr & lower

引用了 finite_midpoint(), LMCAS::lower , 以及 LMCAS::upper.

被这些函数引用 finite_midpoint(), LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::midpoint() , 以及 LMCAS::anonymous_namespace{newton_raphson.cpp}::solve_isolated_polynomial().

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

◆ is_polynomial_node()

bool LMCAS::solver_detail::is_polynomial_node ( const std::shared_ptr< const SymbolicNode > & node)

在文件 solver_linear.cpp 第 141 行定义.

141 {
142 if (!node) {
143 return false;
144 }
145 if (std::dynamic_pointer_cast<const NumberNode>(node)) {
146 return true;
147 }
148 if (std::dynamic_pointer_cast<const VariableNode>(node)) {
149 return true;
150 }
151
152 if (auto add = std::dynamic_pointer_cast<const AddNode>(node)) {
153 for (const auto& op : add->operands()) {
154 if (!is_polynomial_node(op)) {
155 return false;
156 }
157 }
158 return true;
159 }
160
161 if (auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
162 for (const auto& op : mul->operands()) {
163 if (!is_polynomial_node(op)) {
164 return false;
165 }
166 }
167 return true;
168 }
169
170 if (auto pow = std::dynamic_pointer_cast<const PowerNode>(node)) {
171 BigInt exp(0);
172 if (!get_integer_value(pow->exponent(), exp)) {
173 return false;
174 }
175 if (exp < 0) {
176 return false;
177 }
178 return is_polynomial_node(pow->base());
179 }
180
181 return false;
182}
bool is_polynomial_node(const std::shared_ptr< const SymbolicNode > &node)
ExprResult exp(const ExprPtr &expression, ComputationContext &context)
const ExprPtr RelationOp op
static bool get_integer_value(const std::shared_ptr< const SymbolicNode > &node, BigInt &value)

引用了 LMCAS::add(), LMCAS::exp(), LMCAS::get_integer_value(), is_polynomial_node(), LMCAS::mul(), LMCAS::op , 以及 LMCAS::pow().

被这些函数引用 LMCAS::anonymous_namespace{solver_groebner_system.cpp}::clear_denominators(), LMCAS::collect_power_denominators() , 以及 is_polynomial_node().

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

◆ multiply_no_expand()

std::shared_ptr< SymbolicExpr > LMCAS::solver_detail::multiply_no_expand ( const std::shared_ptr< const SymbolicNode > & term,
const std::vector< std::shared_ptr< const SymbolicNode > > & denominator_factors )

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

82 {
83 std::vector<std::shared_ptr<const SymbolicNode>> factors;
84 if (auto mul = std::dynamic_pointer_cast<const MultiplyNode>(term)) {
85 factors.insert(factors.end(), mul->operands().begin(), mul->operands().end());
86 } else if (term) {
87 factors.push_back(term);
88 }
89 factors.insert(factors.end(), den_factors.begin(), den_factors.end());
90
91 std::shared_ptr<const NumberNode> const_acc =
93 std::map<std::shared_ptr<const SymbolicNode>, std::shared_ptr<const NumberNode>, NodeLess> bases;
94
95 for (const auto& op : factors) {
96 if (!op) {
97 continue;
98 }
99 if (auto num = std::dynamic_pointer_cast<const NumberNode>(op)) {
100 const_acc = multiply_number_nodes(const_acc, num);
101 continue;
102 }
103
104 std::shared_ptr<const SymbolicNode> base = op;
105 std::shared_ptr<const NumberNode> exp = LMCAS::detail::make_node<NumberNode>(BigInt(1));
106 if (auto pow = std::dynamic_pointer_cast<const PowerNode>(op)) {
107 base = pow->base();
108 if (auto e_num = std::dynamic_pointer_cast<const NumberNode>(pow->exponent())) {
109 exp = e_num;
110 }
111 }
112
113 auto it = bases.find(base);
114 if (it == bases.end()) {
115 bases[base] = exp;
116 } else {
117 bases[base] = add_number_nodes(it->second, exp);
118 }
119 }
120
121 std::vector<std::shared_ptr<const SymbolicNode>> final_ops;
122 if (!const_acc->is_one()) final_ops.push_back(const_acc);
123
124 for (const auto& [base, exp] : bases) {
125 if (exp->is_zero()) {
126 continue;
127 }
128 if (exp->is_one()) final_ops.push_back(base);
129 else final_ops.push_back(LMCAS::detail::make_node<PowerNode>(base, exp));
130 }
131
132 if (final_ops.empty()) {
133 return SymbolicExpr::number(1);
134 }
135 if (final_ops.size() == 1) {
136 return LMCAS::detail::make_expression_ptr(final_ops[0]);
137 }
139}
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
std::shared_ptr< const Node > make_node(Args &&... args)
std::shared_ptr< SymbolicExpr > num(int value)
static std::shared_ptr< const NumberNode > multiply_number_nodes(const std::shared_ptr< const NumberNode > &a, const std::shared_ptr< const NumberNode > &b)
static std::shared_ptr< const NumberNode > add_number_nodes(const std::shared_ptr< const NumberNode > &a, const std::shared_ptr< const NumberNode > &b)

引用了 LMCAS::add_number_nodes(), LMCAS::exp(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::make_node(), LMCAS::mul(), LMCAS::multiply_number_nodes(), LMCAS::polynomial_solver_detail::num(), LMCAS::op , 以及 LMCAS::pow().

被这些函数引用 LMCAS::anonymous_namespace{solver_groebner_system.cpp}::clear_denominators().

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

◆ project_unconditional_linear_system()

std::map< std::string, SymbolicExpr > LMCAS::solver_detail::project_unconditional_linear_system ( const std::vector< SymbolicExpr > & equations,
const std::vector< std::string > & variables,
ComputationContext & context )

在文件 solver_linear.cpp 第 298 行定义.

300 {
301 try {
302 return solve_linear_system_impl(equations, variables, context);
303 } catch (const CasError& error) {
304 // 容器接口以空映射表示求解未决;受检算法保留内部错误分类。
305 if (error.code == CasErrc::Inconclusive ||
307 return {};
308 }
309 throw;
310 }
311}
std::map< std::string, SymbolicExpr > solve_linear_system_impl(const std::vector< SymbolicExpr > &equations, const std::vector< std::string > &variables, ComputationContext &context)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context

引用了 LMCAS::CasError::code, LMCAS::context, LMCAS::Inconclusive, solve_linear_system_impl() , 以及 LMCAS::UnsupportedExpression.

函数调用图:

◆ solve_linear_system_impl()

std::map< std::string, SymbolicExpr > LMCAS::solver_detail::solve_linear_system_impl ( const std::vector< SymbolicExpr > & equations,
const std::vector< std::string > & variables,
ComputationContext & context )

在文件 solver_linear.cpp 第 313 行定义.

315 {
316 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
317 context.limits().max_ast_nodes, "solve_linear_system");
318
319 size_t num_vars = variables.size();
320 size_t num_eqs = equations_in.size();
321
322 std::vector<std::vector<std::shared_ptr<SymbolicExpr>>> matrix(num_eqs, std::vector<std::shared_ptr<SymbolicExpr>>(num_vars + 1));
323
324 for (size_t i = 0; i < num_eqs; ++i) {
325 SymbolicExpr current_eq = equations_in[i];
326
327 SymbolicExpr constant_part = current_eq;
328
329 for (size_t j = 0; j < num_vars; ++j) {
330 auto [coeff, remainder] = isolate_linear_coeff(constant_part, variables[j], context);
331 matrix[i][j] = LMCAS::detail::make_expression_ptr(coeff);
332
333 constant_part = remainder;
334 }
335
336 std::vector<std::shared_ptr<const SymbolicNode>> ops;
337 ops.push_back(SymbolicFactory::create_number(BigInt(-1)));
338 ops.push_back(LMCAS::detail::node(constant_part));
339 auto neg_const = SymbolicFactory::create_multiply(ops);
340 matrix[i][num_vars] = LMCAS::detail::make_expression_ptr(neg_const);
341 }
342
343 detail::ExactMatrixData augmented{
344 num_eqs, num_vars + 1, {}};
345 augmented.entries.reserve(num_eqs * (num_vars + 1));
346 for (const auto& row : matrix) {
347 augmented.entries.insert(
348 augmented.entries.end(), row.begin(), row.end());
349 }
350
351 auto solved = detail::solve_linear_exact(
352 std::move(augmented), num_vars, context,
353 "solve_linear_system");
354 if (!solved) throw solved.error();
355 if (std::holds_alternative<detail::InconsistentLinearSolution>(solved.value())) {
356 return {};
357 }
358
359 std::vector<std::shared_ptr<SymbolicExpr>> values;
360 if (auto* unique =
361 std::get_if<detail::UniqueLinearSolution>(&solved.value())) {
362 values = std::move(unique->values);
363 } else {
364 auto& parametric =
365 std::get<detail::ParametricLinearSolution>(solved.value());
366 values = parametric.particular;
367 for (std::size_t parameter = 0;
368 parameter < parametric.free_columns.size(); ++parameter) {
369 auto free_variable = SymbolicExpr::variable(
370 variables[parametric.free_columns[parameter]]);
371 for (std::size_t column = 0; column < num_vars; ++column) {
372 auto term = SymbolicExpr::multiply(
373 parametric.nullspace_basis[parameter][column],
374 free_variable);
375 values[column] = detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::add(
376 values[column], term)), transform_budget));
377 }
378 }
379 }
380
381 std::map<std::string, SymbolicExpr> solution;
382 for (std::size_t column = 0; column < num_vars; ++column) {
383 solution.insert_or_assign(
384 variables[column], *values[column]);
385 }
386 return solution;
387}
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 > create_number(const ::LMCAS::BigInt &v)
Result< ExactLinearSolution > solve_linear_exact(ExactMatrixData augmented, std::size_t coefficient_columns, ComputationContext &context, const std::string &operation)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
static std::pair< SymbolicExpr, SymbolicExpr > isolate_linear_coeff(const SymbolicExpr &expr, const std::string &var, ComputationContext &context)

引用了 LMCAS::context, LMCAS::SymbolicFactory::create_multiply(), LMCAS::SymbolicFactory::create_number(), LMCAS::detail::ExactMatrixData::entries, LMCAS::isolate_linear_coeff(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::node(), LMCAS::detail::normalize_node() , 以及 LMCAS::detail::solve_linear_exact().

被这些函数引用 LMCAS::find_extrema_impl() , 以及 project_unconditional_linear_system().

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

◆ solver_number_value()

bool LMCAS::solver_detail::solver_number_value ( const NumberNode & number,
double & value )

在文件 solver_imaginary.cpp 第 6 行定义.

6 {
7 if (std::holds_alternative<BigInt>(number.value())) {
8 out_value = std::get<BigInt>(number.value()).to_double();
9 return true;
10 }
11 if (std::holds_alternative<Rational>(number.value())) {
12 out_value = std::get<Rational>(number.value()).to_double();
13 return true;
14 }
15 return false;
16}
const std::variant< BigInt, Rational > & value() const noexcept

引用了 solver_number_value() , 以及 LMCAS::NumberNode::value().

被这些函数引用 solver_number_value() , 以及 LMCAS::anonymous_namespace{solver_assumptions.cpp}::try_get_numeric_value().

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

◆ to_ptr()

std::shared_ptr< SymbolicExpr > LMCAS::solver_detail::to_ptr ( const SymbolicExpr & expression)

在文件 solver_linear.cpp 第 26 行定义.

26 {
28}

引用了 LMCAS::detail::make_expression_ptr().

被这些函数引用 LMCAS::anonymous_namespace{solver_groebner_system.cpp}::clear_denominators() , 以及 LMCAS::isolate_linear_coeff().

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