LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
inequality_solver.hpp
浏览该文件的文档.
1/**
2 * @file inequality_solver.hpp
3 * @brief 不等式求解器 InequalitySolver,支持多项式,有理式,参数化不等式.
4 */
5#pragma once
7#include "interval.hpp"
8#include "polynomial.hpp"
9#include "result.hpp"
10#include "symbolic.hpp"
11#include <vector>
12#include <memory>
13#include <string>
14#include <utility>
15
16namespace LMCAS {
17
18/** @brief 符号图条目,记录区间及其上的符号 */
20 Interval interval; ///< 区间
21 int sign; ///< 该区间上表达式的符号(+1, 0, -1)
22};
23
24/** @brief 参数化不等式的分段解集 */
25struct LMCAS_API PiecewiseIntervalResult {
26 /** @brief 单个分段:条件 + 对应解集 */
27 struct Case {
28 std::shared_ptr<SymbolicExpr> condition; ///< 参数满足的条件
29 IntervalUnion solution; ///< 该条件下的解集
30 };
31 std::vector<Case> cases; ///< 所有分段
32
33 /**
34 * @brief 判断结果是否为空
35 * @return 无分段时返回 true
36 */
37 bool is_empty() const { return cases.empty(); }
38
39 /**
40 * @brief 判断是否只有一个分段
41 * @return 恰好一个分段时返回 true
42 */
43 bool is_single() const { return cases.size() == 1; }
44
45 /**
46 * @brief 获取唯一分段的解集
47 *
48 * is_single() 为真时返回该分段;多分段解依赖参数取值,
49 * 因而映射为空集以完整保留分段语义.
50 * @return 单一分段的解集;多分段结果映射为空集
51 */
52 IntervalUnion single_solution() const {
53 if (!is_single()) return IntervalUnion::empty();
54 return cases[0].solution;
55 }
56};
57
58/** @brief 不等式求解器,提供多项式,有理式及参数化不等式的求解 */
59class LMCAS_API InequalitySolver {
60public:
61
62 /**
63 * @brief 在计算上下文预算内求解精确有理系数的单变量多项式不等式。
64 * @note 近似系数或符号参数返回 CasErrc::Inconclusive。
65 */
66 static Result<IntervalUnion> solve_inequality_checked(
67 const std::shared_ptr<SymbolicExpr>& expr,
68 InequalityType type,
69 const std::string& variable,
70 ComputationContext& context);
71
72 static Result<IntervalUnion> solve_inequality_checked(
73 const std::shared_ptr<SymbolicExpr>& expr,
74 InequalityType type,
75 const std::string& variable);
76
77 /**
78 * @brief Solve a conjunction of inequalities through the checked solver.
79 *
80 * Every component must lie in the checked scalar support domain and every
81 * required endpoint comparison must be exact. An empty conjunction denotes
82 * the entire real line.
83 */
84 static Result<IntervalUnion> solve_inequalities_checked(
85 const std::vector<std::pair<std::shared_ptr<SymbolicExpr>,
86 InequalityType>>& inequalities,
87 const std::string& variable,
88 ComputationContext& context);
89
90 static Result<IntervalUnion> solve_inequalities_checked(
91 const std::vector<std::pair<std::shared_ptr<SymbolicExpr>,
92 InequalityType>>& inequalities,
93 const std::string& variable);
94
95 /**
96 * @brief 求解单个不等式
97 * @param expr 不等式左端表达式(右端为 0)
98 * @param type 不等式类型
99 * @param variable 求解变量名
100 * @return 解集
101 *
102 * Exact quadratic coefficients are converted to numerical roots with a
103 * cancellation-resistant quadratic formula. Integer snapping requires an
104 * exactly integral approximation, and exact roots are deduplicated
105 * symbolically rather than by a fixed floating-point distance before the
106 * sign chart is constructed. Prefer solve_inequality_checked() when a
107 * proved exact result is required.
108 */
109 static IntervalUnion solve_inequality(
110 const std::shared_ptr<SymbolicExpr>& expr,
111 InequalityType type,
112 const std::string& variable);
113
114 /**
115 * @brief 求解不等式组(取交集)
116 * @param inequalities 不等式列表,每项为 (表达式, 不等式类型)
117 * @param variable 求解变量名
118 * @return 解集
119 */
120 static IntervalUnion solve_inequalities(
121 const std::vector<std::pair<std::shared_ptr<SymbolicExpr>,
122 InequalityType>>& inequalities,
123 const std::string& variable);
124
125 /**
126 * @brief 求解有理不等式 numerator/denominator >/< 0
127 * @param numerator 分子表达式
128 * @param denominator 分母表达式
129 * @param type 不等式类型
130 * @param variable 求解变量名
131 * @return 解集
132 */
133 static IntervalUnion solve_rational_inequality(
134 const std::shared_ptr<SymbolicExpr>& numerator,
135 const std::shared_ptr<SymbolicExpr>& denominator,
136 InequalityType type,
137 const std::string& variable);
138
139 /**
140 * @brief 在计算上下文预算内求解可证明的参数多项式不等式。
141 * @note 无法证明完整参数分支时返回 CasErrc::Inconclusive。
142 */
143 static Result<PiecewiseIntervalResult> solve_parametric_inequality_checked(
144 const std::shared_ptr<SymbolicExpr>& expr,
145 InequalityType type,
146 const std::string& variable,
147 const std::vector<std::string>& parameters,
148 ComputationContext& context);
149
150 static Result<PiecewiseIntervalResult> solve_parametric_inequality_checked(
151 const std::shared_ptr<SymbolicExpr>& expr,
152 InequalityType type,
153 const std::string& variable,
154 const std::vector<std::string>& parameters);
155
156private:
157 static IntervalUnion solve_inequality_impl(
158 const std::shared_ptr<SymbolicExpr>& expr,
159 InequalityType type,
160 const std::string& variable,
161 ComputationContext& context);
162
163
164 static Result<IntervalUnion> solve_exact_quadratic_inequality(
165 const Polynomial<Rational>& polynomial,
166 InequalityType type,
167 ComputationContext& context);
168
169 static std::vector<SignChartEntry> build_sign_chart(
170 const std::shared_ptr<SymbolicExpr>& poly,
171 const std::string& variable,
172 const std::vector<std::shared_ptr<SymbolicExpr>>& roots,
173 const std::vector<int>& multiplicities,
174 ComputationContext& context);
175
176 static IntervalUnion select_intervals(
177 const std::vector<SignChartEntry>& chart,
178 InequalityType type,
179 const std::vector<std::shared_ptr<SymbolicExpr>>& roots,
180 const std::vector<int>& multiplicities,
181 ComputationContext& context);
182
183 static IntervalUnion build_parametric_solution(
184 const std::vector<std::shared_ptr<SymbolicExpr>>& symbolic_roots,
185 const std::vector<int>& multiplicities,
186 int leading_sign,
187 InequalityType type);
188};
189
190}
区间与区间并集 IntervalUnion,用于不等式解集表示。
#define LMCAS_API
int sign
该区间上表达式的符号(+1, 0, -1)
符号图条目,记录区间及其上的符号
一元多项式模板类 Polynomial<T>,支持四则运算,GCD,求导,求值.
符号表达式主类 SymbolicExpr 及其工厂方法,运算接口.