39 const std::shared_ptr<SymbolicExpr>& expr,
46 kCheckedInequalityOperation);
51 kCheckedInequalityOperation);
59 if (!recognized.value()) {
62 "expression is not an exact rational polynomial in the requested variable",
63 kCheckedInequalityOperation);
65 if (recognized.value()->degree() == 2 &&
66 recognized.value()->coeffs.size() >= 3) {
67 return solve_exact_quadratic_inequality(
68 *recognized.value(), type,
context);
70 if (recognized.value()->degree() <= 1) {
72 *recognized.value(), type,
context);
75 *recognized.value(), type,
context);
78 }
catch (
const std::bad_alloc&) {
81 kCheckedInequalityOperation);
82 }
catch (
const std::length_error& error) {
85 }
catch (
const std::exception& error) {
92 const std::shared_ptr<SymbolicExpr>& expr,
100 const std::vector<std::pair<std::shared_ptr<SymbolicExpr>,
107 "solve_inequalities_checked");
110 auto initial_step =
context.consume_steps(1,
"solve_inequalities_checked");
114 if (inequalities.empty()) {
118 std::optional<IntervalUnion> aggregate;
119 for (
const auto& inequality : inequalities) {
120 auto solved = solve_inequality_checked(
126 aggregate = std::move(solved.value());
129 auto intersection = aggregate->intersect_checked(solved.value(),
context);
133 aggregate = std::move(intersection.value());
134 if (aggregate->is_empty()) {
142}
catch (
const std::bad_alloc&) {
144 "inequality intersection allocation failed",
"solve_inequalities_checked");
145}
catch (
const std::length_error& error) {
148}
catch (
const std::exception& error) {
154 const std::vector<std::pair<std::shared_ptr<SymbolicExpr>,
167 (
context).limits().max_ast_nodes,
"transform");
170 return IntervalUnion::empty();
173 if (sign == 0 && !lc->is_zero()) {
175 if (!simplified || !simplified->is_zero()) {
176 return IntervalUnion::empty();
180 bool satisfies =
false;
187 return IntervalUnion::empty();
189 return satisfies ? IntervalUnion::entire_line() : IntervalUnion::empty();
192IntervalUnion InequalitySolver::solve_inequality_impl(
193 const std::shared_ptr<SymbolicExpr>& expr,
198 return IntervalUnion::empty();
201 auto converted = symbolic_to_poly<SymbolicPolyCoeff>(expr,
variable);
202 if (!converted)
throw std::invalid_argument(converted.error().message);
203 const auto& poly = converted.value();
204 if (poly.is_zero()) {
206 return IntervalUnion::entire_line();
208 return IntervalUnion::empty();
211 if (poly.degree() <= 0) {
216 auto poly_rat = symbolic_to_poly<Rational>(expr,
variable);
217 if (!poly_rat)
throw std::invalid_argument(poly_rat.error().message);
223 std::sort(roots_with_mult.begin(), roots_with_mult.end(),
224 [&
context](
const auto&
a,
const auto&
b) {
225 return root_less_than(a.first, b.first, context);
228 std::vector<std::pair<std::shared_ptr<SymbolicExpr>,
int>> unique_roots;
229 for (
const auto& [root, mult] : roots_with_mult) {
232 unique_roots.back().second = std::max(unique_roots.back().second, mult);
234 unique_roots.push_back({root, mult});
238 std::vector<std::shared_ptr<SymbolicExpr>>
roots;
239 std::vector<int> multiplicities;
240 for (
const auto& [root, mult] : unique_roots) {
241 roots.push_back(root);
242 multiplicities.push_back(mult);
247 return select_intervals(chart, type,
roots, multiplicities,
context);
251IntervalUnion InequalitySolver::solve_inequality(
258IntervalUnion InequalitySolver::solve_inequalities(
259 const std::vector<std::pair<std::shared_ptr<SymbolicExpr>,
264 if (inequalities.empty()) {
265 return IntervalUnion::entire_line();
268 IntervalUnion result = solve_inequality_impl(
271 for (
size_t i = 1; i < inequalities.size(); ++i) {
272 auto solution = solve_inequality_impl(
274 result = result.intersect(solution);
275 if (result.is_empty()) {
CoeffType lead_coeff() const
获取首项系数
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
不等式求解器 InequalitySolver,支持多项式,有理式,参数化不等式.
constexpr const char * kCheckedInequalityOperation
Result< IntervalUnion > solve_exact_polynomial_inequality(const Polynomial< Rational > &polynomial, InequalityType type, ComputationContext &context)
std::vector< std::pair< std::shared_ptr< SymbolicExpr >, int > > find_roots_with_multiplicity(const std::shared_ptr< SymbolicExpr > &expr, const std::string &variable, ComputationContext &context)
bool root_less_than(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context)
bool roots_equal(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context)
int exact_numeric_sign(const std::shared_ptr< SymbolicExpr > &expr, ComputationContext &context)
Result< IntervalUnion > solve_exact_affine_inequality(const Polynomial< Rational > &polynomial, InequalityType type, ComputationContext &context)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
const std::string & variable
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
__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
Result< OptionalRationalPolynomial > recognize_rational_polynomial(const SymbolicExpr &expression, const std::string &variable, ComputationContext &context)
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)
static IntervalUnion solve_constant_inequality(const Polynomial< SymbolicPolyCoeff > &poly, InequalityType type, ComputationContext &context)
数值求根:Newton-Raphson 迭代,二分法,Sturm 实根隔离.
方程求解策略调度器 solve_dispatch 及相关选项结构体.