LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
symbolic.hpp
浏览该文件的文档.
1/**
2 * @file symbolic.hpp
3 * @brief 符号表达式主类 SymbolicExpr 及其工厂方法,运算接口.
4 */
5#pragma once
6#define _USE_MATH_DEFINES
7#include "lmcas_export.hpp"
8#include "bigint.hpp"
10#include "limit_value.hpp"
11#include "rational.hpp"
12#include <memory>
13#include <string>
14#include <variant>
15#include <cmath>
16#include <limits>
17#include <algorithm>
18#include <map>
19#include <functional>
20#include <stdexcept>
21#include <type_traits>
22
23namespace LMCAS {
24
25class SymbolicExpr;
26
27
28class AssumptionContext;
29
30/** Result of an operation that produces a symbolic expression. */
32
33struct Binding {
34 std::shared_ptr<SymbolicExpr> symbol;
35 std::shared_ptr<SymbolicExpr> value;
36};
37
38/** @brief Stable relational operator used by public APIs. */
47
48namespace detail {
49struct SymbolicExprAccess;
50} // namespace detail
51
52/**
53 * @brief 符号表达式主类,封装 AST 根节点并提供运算,化简,求解等接口.
54 *
55 * 通过静态工厂方法创建表达式,支持算术运算,三角函数,微积分,
56 * 矩阵运算,方程求解等符号计算功能.
57 */
58class LMCAS_API SymbolicExpr : public std::enable_shared_from_this<SymbolicExpr> {
59private:
60 struct Impl;
61 std::shared_ptr<const Impl> impl_;
62
63 explicit SymbolicExpr(std::shared_ptr<const Impl> impl) : impl_(std::move(impl)) {
64 if (!impl_) {
65 throw std::invalid_argument("SymbolicExpr requires a non-null implementation");
66 }
67 }
68
69 LMCAS::ExpressionResult factor_impl(
70 LMCAS::ComputationContext& context) const;
71
72 friend struct LMCAS::detail::SymbolicExprAccess;
73
74public:
75
76
77 SymbolicExpr() = delete;
78
79 /**
80 * @brief 与另一个表达式进行全序比较.
81 * @param other 待比较的表达式
82 * @return 小于返回负数,等于返回 0,大于返回正数
83 */
84 int compare(const std::shared_ptr<SymbolicExpr>& other) const;
85
86
87 /** @brief 判断表达式是否为零. */
88 bool is_zero() const;
89 /** @brief 判断表达式是否为一. */
90 bool is_one() const;
91
92 /**
93 * @brief 计算两个多项式关于指定变量的结式.
94 * @param a 第一个多项式
95 * @param b 第二个多项式
96 * @param var 消去的变量名
97 * @return 结式表达式
98 */
99 static std::shared_ptr<SymbolicExpr> poly_resultant(const std::shared_ptr<SymbolicExpr>& a, const std::shared_ptr<SymbolicExpr>& b, const std::string& var);
100
101 /**
102 * @brief 计算矩阵转置.
103 * @param mat 矩阵表达式
104 * @return 转置矩阵
105 */
106 static std::shared_ptr<SymbolicExpr> transpose(const std::shared_ptr<SymbolicExpr>& mat);
107
108
109
110 /**
111 * @brief 求解方程组(无参数变量版本).
112 * @param equations 方程列表(每个表达式等于零)
113 * @param vars 未知数变量名列表
114 * @return 解的列表,每个解为变量名到表达式的映射
115 */
116 static std::vector<std::map<std::string, std::shared_ptr<SymbolicExpr>>> solve_system(
117 const std::vector<std::shared_ptr<SymbolicExpr>>& equations,
118 const std::vector<std::string>& vars);
119
120 /**
121 * @brief 求解含参数的方程组.
122 * @param equations 方程列表(每个表达式等于零)
123 * @param unknowns 未知数变量名列表
124 * @param parameters 参数变量名列表
125 * @return 解的列表,每个解为变量名到表达式的映射
126 */
127 static std::vector<std::map<std::string, std::shared_ptr<SymbolicExpr>>> solve_system(
128 const std::vector<std::shared_ptr<SymbolicExpr>>& equations,
129 const std::vector<std::string>& unknowns,
130 const std::vector<std::string>& parameters);
131
132 /**
133 * @brief 在指定点展开为泰勒级数.
134 * @param var 展开变量名
135 * @param point 展开中心点
136 * @param order 展开阶数
137 * @param ctx 可选的假设上下文,用于验证收敛域和选择展开形式
138 * @return 级数表达式
139 */
140 std::shared_ptr<SymbolicExpr> series(const std::string& var, const std::shared_ptr<SymbolicExpr>& point, int order, const LMCAS::AssumptionContext* ctx = nullptr) const;
141
142 /**
143 * @brief 执行符号除法.
144 * @param num 被除数
145 * @param den 除数
146 * @return 商表达式
147 */
148 static std::shared_ptr<SymbolicExpr> divide(const std::shared_ptr<SymbolicExpr>& num, const std::shared_ptr<SymbolicExpr>& den);
149
150 /**
151 * @brief 创建积分表达式节点(不求值).
152 * @param expr 被积表达式
153 * @param var 积分变量名
154 * @return 积分表达式
155 */
156 static std::shared_ptr<SymbolicExpr> make_integral(const std::shared_ptr<SymbolicExpr>& expr, const std::string& var);
157
158 /**
159 * @brief 创建极限表达式节点(不求值).
160 * @param expr 表达式
161 * @param var 趋近变量名
162 * @param point 趋近目标值
163 * @return 极限表达式
164 */
165 static std::shared_ptr<SymbolicExpr> make_limit(const std::shared_ptr<SymbolicExpr>& expr, const std::string& var, const std::shared_ptr<SymbolicExpr>& point);
166
167 /**
168 * @brief Factor this expression with explicit failure and budget reporting.
169 */
170 LMCAS::ExpressionResult factor_checked(
171 LMCAS::ComputationContext& context) const;
172 LMCAS::ExpressionResult factor_checked() const;
173
174 /**
175 * @brief 有理函数约分(消去分子分母公因式).
176 *
177 * 将表达式视为有理函数 P(x)/Q(x),计算 gcd(P, Q) 并约分.
178 * 支持多元多项式(逐变量迭代 GCD).
179 * 例如 (x^2-1)/(x-1) 约分为 x+1.
180 *
181 * @return 约分后的表达式
182 */
183 std::shared_ptr<SymbolicExpr> cancel() const;
184
185
186 /**
187 * @brief 创建整数数值表达式.
188 * @param n 整数值
189 * @return 数值表达式
190 */
191 static std::shared_ptr<SymbolicExpr> number(int n);
192
193 /** @brief 较宽的整数值须显式转为 BigInt。 */
194 template <typename Integer,
195 std::enable_if_t<std::is_integral_v<Integer> &&
196 !std::is_same_v<Integer, int>, int> = 0>
197 static std::shared_ptr<SymbolicExpr> number(Integer) = delete;
198
199 static std::shared_ptr<SymbolicExpr> number(double n);
200
201 /**
202 * @brief 创建大整数数值表达式.
203 * @param bi 大整数
204 * @return 数值表达式
205 */
206 static std::shared_ptr<SymbolicExpr> number(const ::LMCAS::BigInt& bi);
207
208 /**
209 * @brief 创建有理数数值表达式.
210 * @param r 有理数
211 * @return 数值表达式
212 */
213 static std::shared_ptr<SymbolicExpr> number(const ::LMCAS::Rational& r);
214
215 /**
216 * @brief 创建无穷大表达式.
217 * @param k 正数表示正无穷,负数表示负无穷
218 * @return 无穷大表达式
219 */
220 static std::shared_ptr<SymbolicExpr> infinity(int k = 1);
221
222 /**
223 * @brief 创建平方根表达式,等价于 operand^(1/2).
224 * @param operand 被开方数
225 * @return 平方根表达式
226 */
227 static std::shared_ptr<SymbolicExpr> sqrt(std::shared_ptr<SymbolicExpr> operand);
228
229 /**
230 * @brief 创建乘法表达式.
231 * @param left 左操作数
232 * @param right 右操作数
233 * @return 乘积表达式
234 */
235 static std::shared_ptr<SymbolicExpr> multiply(std::shared_ptr<SymbolicExpr> left, std::shared_ptr<SymbolicExpr> right);
236
237 /**
238 * @brief 创建加法表达式.
239 * @param left 左操作数
240 * @param right 右操作数
241 * @return 和表达式
242 */
243 static std::shared_ptr<SymbolicExpr> add(std::shared_ptr<SymbolicExpr> left, std::shared_ptr<SymbolicExpr> right);
244
245 /**
246 * @brief 创建幂运算表达式.
247 * @param base 底数
248 * @param exponent 指数
249 * @return 幂表达式
250 */
251 static std::shared_ptr<SymbolicExpr> power(std::shared_ptr<SymbolicExpr> base, std::shared_ptr<SymbolicExpr> exponent);
252
253 /**
254 * @brief 创建正弦函数表达式.
255 * @param op 参数表达式
256 * @return sin(op)
257 */
258 static std::shared_ptr<SymbolicExpr> sin(std::shared_ptr<SymbolicExpr> op);
259
260 /**
261 * @brief 创建余弦函数表达式.
262 * @param op 参数表达式
263 * @return cos(op)
264 */
265 static std::shared_ptr<SymbolicExpr> cos(std::shared_ptr<SymbolicExpr> op);
266
267 /**
268 * @brief 创建正切函数表达式.
269 * @param op 参数表达式
270 * @return tan(op)
271 */
272 static std::shared_ptr<SymbolicExpr> tan(std::shared_ptr<SymbolicExpr> op);
273
274 /**
275 * @brief 创建自然对数表达式.
276 * @param op 参数表达式
277 * @return ln(op)
278 */
279 static std::shared_ptr<SymbolicExpr> ln(std::shared_ptr<SymbolicExpr> op);
280
281 /**
282 * @brief 创建指数函数表达式 e^op.
283 * @param op 指数参数
284 * @return exp(op)
285 */
286 static std::shared_ptr<SymbolicExpr> exp(std::shared_ptr<SymbolicExpr> op);
287
288 /**
289 * @brief 创建 Lambert W 函数表达式.
290 * @param op 参数表达式
291 * @return W(op)
292 */
293 static std::shared_ptr<SymbolicExpr> lambertw(std::shared_ptr<SymbolicExpr> op);
294
295 /**
296 * @brief 创建以指定底数的对数表达式.
297 * @param val 真数
298 * @param base 底数
299 * @return log_base(val)
300 */
301 static std::shared_ptr<SymbolicExpr> log(std::shared_ptr<SymbolicExpr> val, std::shared_ptr<SymbolicExpr> base);
302
303 /**
304 * @brief 创建双参数反正切表达式 atan2(y, x).
305 * @param y y 坐标
306 * @param x x 坐标
307 * @return atan2 表达式
308 */
309 static std::shared_ptr<SymbolicExpr> atan2(std::shared_ptr<SymbolicExpr> y, std::shared_ptr<SymbolicExpr> x);
310
311 /**
312 * @brief 创建 RootOf 表达式,表示多项式的第 index 个根.
313 * @param poly 多项式表达式
314 * @param var 多项式变量名
315 * @param index 根的索引
316 * @return RootOf 表达式
317 */
318 static std::shared_ptr<SymbolicExpr> root_of(std::shared_ptr<SymbolicExpr> poly, const std::string& var, int index);
319
320 /**
321 * @brief 创建等式关系表达式 lhs = rhs.
322 * @param lhs 左侧表达式
323 * @param rhs 右侧表达式
324 * @return 等式表达式
325 */
326 static std::shared_ptr<SymbolicExpr> eq(std::shared_ptr<SymbolicExpr> lhs, std::shared_ptr<SymbolicExpr> rhs);
327
328 /**
329 * @brief 从二维元素列表创建矩阵表达式.
330 * @param elements 二维表达式数组,elements[i][j] 为第 i 行第 j 列元素
331 * @return 矩阵表达式
332 */
333 static std::shared_ptr<SymbolicExpr> matrix(const std::vector<std::vector<std::shared_ptr<SymbolicExpr>>>& elements);
334
335 /**
336 * @brief 创建变量表达式.
337 * @param name 变量名
338 * @return 变量表达式
339 */
340 static std::shared_ptr<SymbolicExpr> variable(const std::string& name);
341
342 /**
343 * @brief 对表达式进行三角恒等式化简.
344 * @return 化简后的表达式
345 */
346 std::shared_ptr<SymbolicExpr> simplify_trig() const;
347
348 /**
349 * @brief 将表达式转换为可读字符串.
350 * @return 字符串表示
351 */
352 std::string to_string() const;
353
354 /** @brief 判断表达式是否为数值节点. */
355 bool is_number() const;
356
357 /** @brief 判断表达式数值是否为零. */
358 bool get_number_value_is_zero() const;
359
360 /** @brief 判断表达式是否为大整数类型. */
361 bool is_big_int() const;
362
363 /** @brief 判断表达式是否为有理数类型. */
364 bool is_rational() const;
365
366 /** @brief 判断表达式是否为整数(包括 BigInt,整数 Rational,近似整数浮点). */
367 bool is_int() const;
368
369 /**
370 * @brief 获取数值表达式的值.
371 * @return 数值(int,BigInt 或 Rational)
372 * @throws std::runtime_error 节点类型与数值访问器不匹配时抛出
373 */
374 std::variant<int, ::LMCAS::BigInt, ::LMCAS::Rational> get_number() const;
375
376 int get_int() const;
377 /**
378 * @brief 获取大整数值.
379 * @return BigInt 值
380 * @throws std::runtime_error 节点类型与 BigInt 访问器不匹配时抛出
381 */
382 ::LMCAS::BigInt get_big_int() const;
383 /**
384 * @brief 获取有理数值.
385 * @return Rational 值
386 * @throws std::runtime_error 节点类型与 Rational 访问器不匹配时抛出
387 */
388 ::LMCAS::Rational get_rational() const;
389 /**
390 * @brief 将数值表达式转换为 Rational(BigInt 也会转换).
391 * @return 有理数值,非数值类型返回 Rational(0)
392 */
393 ::LMCAS::Rational convert_rational() const;
394
395 /**
396 * @brief 将表达式求值为浮点数.
397 * @return 数值结果
398 */
399 lmmc_real_t to_numeric() const;
400};
401
402} // namespace LMCAS
任意精度整数 BigInt,底层调用 LMMP 实现高性能大数运算。
#define LMCAS_API
bool is_zero(const SymbolicExpr &expression)
Node divide(const Node &numerator, const Node &denominator)
const std::string & variable
ExprResult eq(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
ExprResult exp(const ExprPtr &expression, ComputationContext &context)
@ Rational
Rational numbers
std::shared_ptr< SymbolicExpr > symbol
Result< std::shared_ptr< SymbolicExpr > > ExpressionResult
Result of an operation that produces a symbolic expression.
ExprResult sin(const ExprPtr &expression, ComputationContext &context)
RelationOp
Stable relational operator used by public APIs.
ExprResult tan(const ExprPtr &expression, ComputationContext &context)
ExprResult cos(const ExprPtr &expression, ComputationContext &context)
ExprResult sqrt(const ExprPtr &expression, ComputationContext &context)
std::shared_ptr< SymbolicExpr > value
ExprResult log(const ExprPtr &expression, ComputationContext &context)
精确有理数 Rational,基于 BigInt 分子/分母表示,自动约分。