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

类

struct  ExactInequalityRoot

函数

Result< void > append_exact_factor_roots (std::vector< ExactInequalityRoot > &roots, const Polynomial< Rational > &factor, int multiplicity, const std::string &variable, detail::RewriteBudget &budget, std::size_t &root_nodes)
void check_interval_forest (const std::vector< Interval > &intervals, detail::RewriteBudget &budget)
bool constant_satisfies (const Rational &value, InequalityType type)
std::vector< Interval > exact_polynomial_sign_intervals (const Polynomial< Rational > &polynomial, const std::vector< ExactInequalityRoot > &roots, InequalityType type)
Endpoint finite_endpoint (const std::shared_ptr< SymbolicExpr > &value, bool strict)
bool rational_is_negative (const Rational &value)
std::shared_ptr< SymbolicExpr > rational_polynomial_expression (const Polynomial< Rational > &polynomial, detail::RewriteBudget &budget)
Result< IntervalUnion > solve_exact_affine_inequality_impl (const Polynomial< Rational > &polynomial, InequalityType type, ComputationContext &context)
Result< IntervalUnion > solve_exact_polynomial_inequality_impl (const Polynomial< Rational > &polynomial, InequalityType type, ComputationContext &context)
Result< void > sort_exact_inequality_roots (std::vector< ExactInequalityRoot > &roots, ComputationContext &context)
Result< void > verify_quadratic_boundary (const Polynomial< Rational > &polynomial, const std::shared_ptr< SymbolicExpr > &boundary, const Rational &rational_part, const Rational &radical_coefficient, const Rational &radicand, ComputationContext &context)

变量

constexpr const char * kCheckedInequalityOperation = "solve_inequality_checked"

类说明

◆ LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::ExactInequalityRoot

struct LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::ExactInequalityRoot

在文件 inequality_solver_polynomial.cpp 第 299 行定义.

LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::ExactInequalityRoot 的协作图:
类成员
ExactRealAlgebraic algebraic
shared_ptr< SymbolicExpr > expression
int multiplicity = 1

函数说明

◆ append_exact_factor_roots()

Result< void > LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::append_exact_factor_roots ( std::vector< ExactInequalityRoot > & roots,
const Polynomial< Rational > & factor,
int multiplicity,
const std::string & variable,
detail::RewriteBudget & budget,
std::size_t & root_nodes )

在文件 inequality_solver_polynomial.cpp 第 326 行定义.

329 {
330 auto& context = budget.context();
331 auto isolated = isolate_real_roots_checked(factor, context);
332 if (!isolated) {
333 return Result<void>::failure(isolated.error());
334 }
335 const auto& intervals = isolated.value();
336 auto factor_expression = rational_polynomial_expression(factor, budget);
337 for (std::size_t index = 0; index < intervals.size(); ++index) {
339 factor, index, static_cast<std::size_t>(multiplicity), context);
340 if (!algebraic) {
341 return Result<void>::failure(algebraic.error());
342 }
343 roots.push_back(ExactInequalityRoot{
344 SymbolicExpr::root_of(
345 factor_expression, variable,
346 static_cast<int>(index)),
347 std::move(algebraic.value()),
348 multiplicity});
349 root_nodes = budget.append_size(root_nodes, budget.measure(detail::node(roots.back().expression)));
350 }
351 return Result<void>::success();
352}
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
ComputationContext & context() const noexcept
std::size_t measure(const std::shared_ptr< const SymbolicNode > &node)
std::size_t append_size(std::size_t current, std::size_t child)
std::shared_ptr< SymbolicExpr > rational_polynomial_expression(const Polynomial< Rational > &polynomial, detail::RewriteBudget &budget)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
ExactRealAlgebraicResult make_exact_real_algebraic(Polynomial< Rational > polynomial, std::size_t root_index, std::size_t multiplicity, ComputationContext &context)
const std::string & variable
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
Result< std::vector< std::pair< Rational, Rational > > > isolate_real_roots_checked(const Polynomial< Rational > &polynomial, ComputationContext &context)
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)

引用了 append_exact_factor_roots(), LMCAS::detail::RewriteBudget::append_size(), LMCAS::context, LMCAS::detail::RewriteBudget::context(), LMCAS::Result< T >::failure(), LMCAS::isolate_real_roots_checked(), LMCAS::detail::make_exact_real_algebraic(), LMCAS::detail::RewriteBudget::measure(), LMCAS::detail::node(), rational_polynomial_expression(), LMCAS::roots(), LMCAS::Result< T >::success() , 以及 LMCAS::variable.

被这些函数引用 append_exact_factor_roots() , 以及 solve_exact_polynomial_inequality_impl().

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

◆ check_interval_forest()

void LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::check_interval_forest ( const std::vector< Interval > & intervals,
detail::RewriteBudget & budget )

在文件 inequality_solver_polynomial.cpp 第 25 行定义.

26 {
27 std::size_t nodes = 0;
28 for (const auto& interval : intervals) {
29 nodes = budget.append_size(nodes, budget.measure(detail::node(interval.lower.value)));
30 nodes = budget.append_size(nodes, budget.measure(detail::node(interval.upper.value)));
31 }
32}
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)

引用了 LMCAS::detail::RewriteBudget::append_size(), check_interval_forest(), LMCAS::interval(), LMCAS::detail::RewriteBudget::measure(), LMCAS::detail::node() , 以及 LMCAS::Result< T >::value().

被这些函数引用 check_interval_forest(), solve_exact_affine_inequality_impl() , 以及 solve_exact_polynomial_inequality_impl().

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

◆ constant_satisfies()

bool LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::constant_satisfies ( const Rational & value,
InequalityType type )

在文件 inequality_solver_polynomial.cpp 第 38 行定义.

38 {
39 const bool zero = value == Rational(0);
40 const bool negative = rational_is_negative(value);
41 switch (type) {
42 case InequalityType::GreaterThan: return !negative && !zero;
43 case InequalityType::GreaterEqual: return !negative;
44 case InequalityType::LessThan: return negative;
45 case InequalityType::LessEqual: return negative || zero;
46 }
47 return false;
48}
const std::string const ExprPtr & value

引用了 constant_satisfies(), LMCAS::GreaterEqual, LMCAS::GreaterThan, LMCAS::LessEqual, LMCAS::LessThan, rational_is_negative() , 以及 LMCAS::value.

被这些函数引用 constant_satisfies() , 以及 solve_exact_affine_inequality_impl().

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

◆ exact_polynomial_sign_intervals()

std::vector< Interval > LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::exact_polynomial_sign_intervals ( const Polynomial< Rational > & polynomial,
const std::vector< ExactInequalityRoot > & roots,
InequalityType type )

在文件 inequality_solver_polynomial.cpp 第 376 行定义.

378 {
379 const bool wants_positive =
382 const bool strict =
385 auto sign_satisfies = [&](int sign_value) {
386 return wants_positive ? sign_value > 0 : sign_value < 0;
387 };
388
389 int sign_value = rational_is_negative(polynomial.lead_coeff()) ? -1 : 1;
390 if ((polynomial.degree() & 1) != 0) {
391 sign_value = -sign_value;
392 }
393
394 std::vector<Interval> intervals;
395 Endpoint lower = Endpoint::neg_inf();
396 for (const auto& root : roots) {
397 if (sign_satisfies(sign_value)) {
398 intervals.push_back(Interval{
399 lower, Endpoint::open(root.expression)});
400 }
401 if (!strict) {
402 intervals.push_back(Interval::point(root.expression));
403 }
404 lower = Endpoint::open(root.expression);
405 if ((root.multiplicity & 1) != 0) {
406 sign_value = -sign_value;
407 }
408 }
409 if (sign_satisfies(sign_value)) {
410 intervals.push_back(Interval{lower, Endpoint::pos_inf()});
411 }
412 return intervals;
413}
CoeffType lead_coeff() const
获取首项系数
int degree() const
获取多项式的次数
const ExprPtr & lower

引用了 LMCAS::Polynomial< CoeffType >::degree(), exact_polynomial_sign_intervals(), LMCAS::GreaterEqual, LMCAS::GreaterThan, LMCAS::Polynomial< CoeffType >::lead_coeff(), LMCAS::LessThan, LMCAS::lower, rational_is_negative() , 以及 LMCAS::roots().

被这些函数引用 exact_polynomial_sign_intervals() , 以及 solve_exact_polynomial_inequality_impl().

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

◆ finite_endpoint()

Endpoint LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::finite_endpoint ( const std::shared_ptr< SymbolicExpr > & value,
bool strict )

在文件 inequality_solver_polynomial.cpp 第 50 行定义.

50 {
51 return strict ? Endpoint::open(value) : Endpoint::closed(value);
52}

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

被这些函数引用 finite_endpoint().

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

◆ rational_is_negative()

bool LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::rational_is_negative ( const Rational & value)

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

34 {
35 return value.get_numerator().is_negative();
36}

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

被这些函数引用 constant_satisfies(), exact_polynomial_sign_intervals(), rational_is_negative() , 以及 solve_exact_affine_inequality_impl().

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

◆ rational_polynomial_expression()

std::shared_ptr< SymbolicExpr > LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::rational_polynomial_expression ( const Polynomial< Rational > & polynomial,
detail::RewriteBudget & budget )

在文件 inequality_solver_polynomial.cpp 第 305 行定义.

306 {
307 auto variable = SymbolicExpr::variable(polynomial.variable_name);
308 std::shared_ptr<SymbolicExpr> sum = SymbolicExpr::number(0);
309 for (int degree = 0; degree <= polynomial.degree(); ++degree) {
310 if (polynomial.coeffs[degree] == Rational(0)) {
311 continue;
312 }
313 auto term = SymbolicExpr::number(polynomial.coeffs[degree]);
314 if (degree > 0) {
315 auto power = degree == 1
316 ? variable
317 : SymbolicExpr::power(variable, SymbolicExpr::number(degree));
318 term = SymbolicExpr::multiply(term, power);
319 }
320 sum = SymbolicExpr::add(sum, term);
321 budget.measure(detail::node(sum));
322 }
324}
std::string variable_name
变量名
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)

引用了 LMCAS::Polynomial< CoeffType >::coeffs, LMCAS::Polynomial< CoeffType >::degree(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::RewriteBudget::measure(), LMCAS::detail::node(), LMCAS::detail::normalize_node(), rational_polynomial_expression(), LMCAS::variable , 以及 LMCAS::Polynomial< CoeffType >::variable_name.

被这些函数引用 append_exact_factor_roots() , 以及 rational_polynomial_expression().

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

◆ solve_exact_affine_inequality_impl()

Result< IntervalUnion > LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::solve_exact_affine_inequality_impl ( const Polynomial< Rational > & polynomial,
InequalityType type,
ComputationContext & context )

在文件 inequality_solver_polynomial.cpp 第 239 行定义.

242 {
243 auto step = context.consume_steps(1, kCheckedInequalityOperation);
244 if (!step) {
245 return Result<IntervalUnion>::failure(step.error());
246 }
247
248 if (polynomial.degree() <= 0) {
249 const Rational value = polynomial.is_zero()
250 ? Rational(0)
251 : polynomial.coeffs[0];
254 ? IntervalUnion::entire_line()
255 : IntervalUnion::empty());
256 }
257
258 if (polynomial.degree() != 1 || polynomial.coeffs.size() < 2) {
261 "checked inequality solving currently supports exact polynomials through degree two",
263 }
264
265 const Rational& intercept = polynomial.coeffs[0];
266 const Rational& slope = polynomial.coeffs[1];
267 if (slope == Rational(0)) {
270 "affine polynomial has a zero leading coefficient",
272 }
273
274 const Rational boundary = (Rational(0) - intercept) / slope;
275 auto boundary_expr = SymbolicExpr::number(boundary);
276 auto nodes = context.require_ast_nodes(1, kCheckedInequalityOperation);
277 if (!nodes) {
278 return Result<IntervalUnion>::failure(nodes.error());
279 }
280
281 const bool wants_greater = type == InequalityType::GreaterThan ||
283 const bool strict = type == InequalityType::GreaterThan ||
285 const bool solution_above = wants_greater != rational_is_negative(slope);
286 const Endpoint finite = strict
287 ? Endpoint::open(boundary_expr)
288 : Endpoint::closed(boundary_expr);
289 const Interval interval = solution_above
290 ? Interval{finite, Endpoint::pos_inf()}
291 : Interval{Endpoint::neg_inf(), finite};
292 detail::RewriteBudget budget(context, context.limits().max_recursion_depth,
293 context.limits().max_ast_nodes, kCheckedInequalityOperation);
295 return Result<IntervalUnion>::success(IntervalUnion::from_single(interval));
296}
bool is_zero() const
判断是否为零多项式
void check_interval_forest(const std::vector< Interval > &intervals, detail::RewriteBudget &budget)
@ Rational
Rational numbers

引用了 check_interval_forest(), LMCAS::Polynomial< CoeffType >::coeffs, constant_satisfies(), LMCAS::context, LMCAS::Polynomial< CoeffType >::degree(), LMCAS::Result< T >::failure(), LMCAS::GreaterEqual, LMCAS::GreaterThan, LMCAS::Inconclusive, LMCAS::InternalInvariant, LMCAS::interval(), LMCAS::Polynomial< CoeffType >::is_zero(), kCheckedInequalityOperation, LMCAS::LessThan, rational_is_negative(), solve_exact_affine_inequality_impl(), LMCAS::Result< T >::success() , 以及 LMCAS::value.

被这些函数引用 solve_exact_affine_inequality_impl().

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

◆ solve_exact_polynomial_inequality_impl()

Result< IntervalUnion > LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::solve_exact_polynomial_inequality_impl ( const Polynomial< Rational > & polynomial,
InequalityType type,
ComputationContext & context )

在文件 inequality_solver_polynomial.cpp 第 415 行定义.

418 {
419 auto factors = square_free_factorization(polynomial);
420 std::vector<ExactInequalityRoot> roots;
421 try {
422 detail::RewriteBudget budget(context, context.limits().max_recursion_depth,
423 context.limits().max_ast_nodes, kCheckedInequalityOperation);
424 std::size_t root_nodes = 0;
425 for (const auto& [factor, multiplicity] : factors) {
426 if (factor.degree() < 1) {
427 continue;
428 }
429 auto appended = append_exact_factor_roots(
430 roots, factor, multiplicity, polynomial.variable_name, budget, root_nodes);
431 if (!appended) {
432 return Result<IntervalUnion>::failure(appended.error());
433 }
434 }
436 if (!sorted) {
437 return Result<IntervalUnion>::failure(sorted.error());
438 }
439 auto intervals = exact_polynomial_sign_intervals(polynomial, roots, type);
440 check_interval_forest(intervals, budget);
441 return IntervalUnion::from_intervals_checked(std::move(intervals), context);
442 } catch (const CasError& error) {
443 return Result<IntervalUnion>::failure(error);
444 } catch (const std::length_error& error) {
447 } catch (const std::bad_alloc&) {
450 "polynomial inequality root allocation failed",
452 } catch (const std::exception& error) {
454 CasErrc::InternalInvariant, error.what(),
456 }
457
458}
std::vector< Interval > exact_polynomial_sign_intervals(const Polynomial< Rational > &polynomial, const std::vector< ExactInequalityRoot > &roots, InequalityType type)
Result< void > append_exact_factor_roots(std::vector< ExactInequalityRoot > &roots, const Polynomial< Rational > &factor, int multiplicity, const std::string &variable, detail::RewriteBudget &budget, std::size_t &root_nodes)
Result< void > sort_exact_inequality_roots(std::vector< ExactInequalityRoot > &roots, ComputationContext &context)
std::vector< std::pair< Polynomial< Rational >, int > > square_free_factorization(const Polynomial< Rational > &poly)

引用了 append_exact_factor_roots(), check_interval_forest(), LMCAS::context, exact_polynomial_sign_intervals(), LMCAS::Result< T >::failure(), LMCAS::InternalInvariant, kCheckedInequalityOperation, LMCAS::ResourceLimit, LMCAS::roots(), solve_exact_polynomial_inequality_impl(), sort_exact_inequality_roots(), LMCAS::square_free_factorization() , 以及 LMCAS::Polynomial< CoeffType >::variable_name.

被这些函数引用 solve_exact_polynomial_inequality_impl().

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

◆ sort_exact_inequality_roots()

Result< void > LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::sort_exact_inequality_roots ( std::vector< ExactInequalityRoot > & roots,
ComputationContext & context )

在文件 inequality_solver_polynomial.cpp 第 354 行定义.

355 {
356 for (std::size_t i = 1; i < roots.size(); ++i) {
357 auto root = std::move(roots[i]);
358 std::size_t position = i;
359 while (position > 0) {
361 roots[position - 1].algebraic, root.algebraic, context);
362 if (!order) {
363 return Result<void>::failure(order.error());
364 }
365 if (order.value() <= 0) {
366 break;
367 }
368 roots[position] = std::move(roots[position - 1]);
369 --position;
370 }
371 roots[position] = std::move(root);
372 }
373 return Result<void>::success();
374}
Result< int > compare_exact_real_algebraic(ExactRealAlgebraic lhs, ExactRealAlgebraic rhs, ComputationContext &context)
const std::vector< FGLMPoly > const MonomialOrder & order

引用了 LMCAS::detail::compare_exact_real_algebraic(), LMCAS::context, LMCAS::Result< T >::failure(), LMCAS::order, LMCAS::roots(), sort_exact_inequality_roots() , 以及 LMCAS::Result< T >::success().

被这些函数引用 solve_exact_polynomial_inequality_impl() , 以及 sort_exact_inequality_roots().

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

◆ verify_quadratic_boundary()

Result< void > LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::verify_quadratic_boundary ( const Polynomial< Rational > & polynomial,
const std::shared_ptr< SymbolicExpr > & boundary,
const Rational & rational_part,
const Rational & radical_coefficient,
const Rational & radicand,
ComputationContext & context )

在文件 inequality_solver_polynomial.cpp 第 54 行定义.

60 {
61 auto steps = context.consume_steps(2, kCheckedInequalityOperation);
62 if (!steps) {
63 return steps;
64 }
65
66 if (!boundary || !LMCAS::detail::node(boundary) || polynomial.coeffs.size() < 3) {
69 "quadratic boundary verification could not construct an expression",
71 }
72
73 const Rational& constant = polynomial.coeffs[0];
74 const Rational& linear = polynomial.coeffs[1];
75 const Rational& quadratic = polynomial.coeffs[2];
76 const Rational residual_rational =
77 quadratic * (rational_part * rational_part +
78 radical_coefficient * radical_coefficient * radicand) +
79 linear * rational_part + constant;
80 const Rational residual_radical =
81 Rational(2) * quadratic * rational_part * radical_coefficient +
82 linear * radical_coefficient;
83 if (residual_rational != Rational(0) ||
84 residual_radical != Rational(0)) {
87 "quadratic boundary could not be verified by exact substitution",
89 }
90 return Result<void>::success();
91}

引用了 LMCAS::Polynomial< CoeffType >::coeffs, LMCAS::context, LMCAS::Result< T >::failure(), LMCAS::Inconclusive, LMCAS::InternalInvariant, kCheckedInequalityOperation, LMCAS::detail::node(), LMCAS::steps, LMCAS::Result< T >::success() , 以及 verify_quadratic_boundary().

被这些函数引用 verify_quadratic_boundary().

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

变量说明

◆ kCheckedInequalityOperation

const char* LMCAS::anonymous_namespace{inequality_solver_polynomial.cpp}::kCheckedInequalityOperation = "solve_inequality_checked"
constexpr