LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
mixed_transcendental_classification.cpp
浏览该文件的文档.
5
6namespace LMCAS {
7namespace {
8/**
9 * @internal
10 * @brief 判断函数类型是否为 sin、cos、tan、exp 或 ln。
11 */
13 switch (t) {
19 return true;
20 default:
21 return false;
22 }
23}
24
26 const std::string& target_var;
27 bool found = false;
28
29 explicit TranscendentalDetector(const std::string& v) : target_var(v) {}
30
31 void visit(const NumberNode&) override {}
32 void visit(const VariableNode&) override {}
33 void visit(const MatrixNode&) override {}
34 void visit(const RelationalNode& n) override {
35 if (found) {
36 return;
37 }
38 if (n.left()) {
39 n.left()->accept(*this);
40 }
41 if (!found && n.right()) {
42 n.right()->accept(*this);
43 }
44 }
45 void visit(const LogicalNode& n) override {
46 if (found) {
47 return;
48 }
49 if (n.left()) {
50 n.left()->accept(*this);
51 }
52 if (!found && n.right()) {
53 n.right()->accept(*this);
54 }
55 }
56 void visit(const PiecewiseNode& n) override {
57 for (const auto& branch : n.branches()) {
58 if (found) {
59 return;
60 }
61 branch.expression->accept(*this);
62 if (!found) {
63 branch.condition->accept(*this);
64 }
65 }
66 if (!found && n.default_expr()) {
67 n.default_expr()->accept(*this);
68 }
69 }
70 void visit(const SummationNode& n) override {
71 n.body()->accept(*this);
72 if (!found) {
73 n.lower_bound()->accept(*this);
74 }
75 if (!found) {
76 n.upper_bound()->accept(*this);
77 }
78 }
79 void visit(const ProductNode& n) override {
80 n.body()->accept(*this);
81 if (!found) {
82 n.lower_bound()->accept(*this);
83 }
84 if (!found) {
85 n.upper_bound()->accept(*this);
86 }
87 }
88 void visit(const TransformNode& n) override {
89 n.body()->accept(*this);
90 }
91 void visit(const QuantifierNode& n) override {
92 n.domain()->accept(*this);
93 if (!found) {
94 n.predicate()->accept(*this);
95 }
96 }
97 void visit(const SetBuilderNode& n) override {
98 n.domain()->accept(*this);
99 if (!found) {
100 n.predicate()->accept(*this);
101 }
102 }
103 void visit(const ComplexNode& n) override {
104 n.real()->accept(*this);
105 if (!found) {
106 n.imag()->accept(*this);
107 }
108 }
109 void visit(const FiniteSetNode& n) override { for (const auto& e : n.elements()) { if (found) {
110 return;
111 } e->accept(*this); } }
112 void visit(const IntervalNode& n) override { n.lower()->accept(*this); if (!found) {
113 n.upper()->accept(*this);
114 } }
115 void visit(const MembershipNode& n) override { n.element()->accept(*this); if (!found) {
116 n.set()->accept(*this);
117 } }
118 void visit(const QuantityNode& n) override { n.value()->accept(*this); }
119
120 void visit(const AddNode& n) override {
121 for (auto& op : n.operands()) {
122 if (found) {
123 return;
124 }
125 op->accept(*this);
126 }
127 }
128
129 void visit(const MultiplyNode& n) override {
130 for (auto& op : n.operands()) {
131 if (found) {
132 return;
133 }
134 op->accept(*this);
135 }
136 }
137
138 void visit(const PowerNode& n) override {
139 if (found) {
140 return;
141 }
142 n.base()->accept(*this);
143 if (!found) {
144 n.exponent()->accept(*this);
145 }
146 }
147
148 void visit(const FunctionNode& n) override {
149 if (found) {
150 return;
151 }
152
153 if (is_transcendental_func(n.type())) {
154 for (auto& arg : n.arguments()) {
156 found = true;
157 return;
158 }
159 }
160 }
161 for (auto& arg : n.arguments()) {
162 if (found) {
163 return;
164 }
165 arg->accept(*this);
166 }
167 }
168};
169
170static BigInt degree_in_var(
171 const std::shared_ptr<const SymbolicNode>& node, const std::string& var);
172
173static BigInt sum_degree(const AddNode& sum, const std::string& var) {
174 BigInt maximum;
175 for (const auto& operand : sum.operands()) {
176 auto degree = degree_in_var(operand, var);
177 if (degree < 0) {
178 return -1;
179 }
180 if (degree > maximum) {
181 maximum = std::move(degree);
182 }
183 }
184 return maximum;
185}
186
187static BigInt product_degree(const MultiplyNode& product, const std::string& var) {
188 BigInt total;
189 for (const auto& operand : product.operands()) {
190 auto degree = degree_in_var(operand, var);
191 if (degree < 0) {
192 return -1;
193 }
194 total += degree;
195 }
196 return total;
197}
198
199/**
200 * @internal
201 * @brief 计算节点关于指定变量的多项式次数。
202 * 与 var 无关的子表达式次数为 0。
203 * @param[in] node 符号节点。
204 * @param[in] var 变量名。
205 * @return 关于 var 的次数;超出多项式次数支持域时返回 -1。
206 */
207static BigInt degree_in_var(const std::shared_ptr<const SymbolicNode>& node, const std::string& var) {
208 if (!node) {
209 return 0;
210 }
211
212 if (!expression_depends_on_variable(node, var)) {
213 return 0;
214 }
215
216 if (auto v = std::dynamic_pointer_cast<const VariableNode>(node)) {
217 return (!v->is_constant() && v->name() == var) ? 1 : 0;
218 }
219
220 if (auto add = std::dynamic_pointer_cast<const AddNode>(node)) {
221 return sum_degree(*add, var);
222 }
223
224 if (auto mul = std::dynamic_pointer_cast<const MultiplyNode>(node)) {
225 return product_degree(*mul, var);
226 }
227
228 if (auto pow = std::dynamic_pointer_cast<const PowerNode>(node)) {
229 auto exp_num = std::dynamic_pointer_cast<const NumberNode>(pow->exponent());
230 BigInt e_val;
231 if (!try_get_integer_value(exp_num, e_val) || e_val.is_negative()) {
232 return -1;
233 }
234
235 BigInt base_deg = degree_in_var(pow->base(), var);
236 if (base_deg < 0) {
237 return -1;
238 }
239 return base_deg * e_val;
240 }
241 if (std::dynamic_pointer_cast<const FunctionNode>(node)) {
242 return -1;
243 }
244
245 return 0;
246}
247
248}
249
251 const std::shared_ptr<SymbolicExpr>& expr,
252 const std::string& var)
253{
254 if (!expr || !LMCAS::detail::node(expr)) {
255 return false;
256 }
257 TranscendentalDetector detector(var);
258 LMCAS::detail::node(expr)->accept(detector);
259 return detector.found;
260}
261
263 const TransSubstitutionResult& sub_result)
264{
265 if (sub_result.mappings.empty()) {
266 return false;
267 }
268 if (!sub_result.poly_expr || !LMCAS::detail::node(sub_result.poly_expr)) {
269 return false;
270 }
271
272 const auto& root = LMCAS::detail::node(sub_result.poly_expr);
273
274 for (const auto& m : sub_result.mappings) {
275 if (expression_depends_on_variable(root, m.indeterminate) &&
276 degree_in_var(root, m.indeterminate).is_negative()) {
277 return false;
278 }
279 }
280
281 return true;
282}
283
284}
加法节点,表示多个操作数的求和。
const std::vector< std::shared_ptr< const SymbolicNode > > & operands() const noexcept
复数节点,表示 real + imag * i。
const std::shared_ptr< const SymbolicNode > & real() const noexcept
const std::shared_ptr< const SymbolicNode > & imag() const noexcept
const std::vector< std::shared_ptr< const SymbolicNode > > & elements() const noexcept
函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
FuncType type() const noexcept
const std::vector< std::shared_ptr< const SymbolicNode > > & arguments() const noexcept
const auto & lower() const noexcept
const auto & upper() const noexcept
const std::shared_ptr< const SymbolicNode > & right() const noexcept
const std::shared_ptr< const SymbolicNode > & left() const noexcept
矩阵节点,支持稠密和稀疏两种存储方式。
const auto & set() const noexcept
const auto & element() const noexcept
乘法节点,表示多个操作数的乘积。
const std::vector< std::shared_ptr< const SymbolicNode > > & operands() const noexcept
分段函数节点,表示条件分支表达式.
const std::shared_ptr< const SymbolicNode > & default_expr() const noexcept
const std::vector< Branch > & branches() const noexcept
幂运算节点,表示 base^exponent。
const std::shared_ptr< const SymbolicNode > & exponent() const noexcept
const std::shared_ptr< const SymbolicNode > & base() const noexcept
连乘节点,表示符号有限/无限连乘 prod_{k=a}^{b} f(k).
const std::shared_ptr< const SymbolicNode > & lower_bound() const noexcept
const std::shared_ptr< const SymbolicNode > & upper_bound() const noexcept
const std::shared_ptr< const SymbolicNode > & body() const noexcept
const std::shared_ptr< const SymbolicNode > & predicate() const noexcept
const std::shared_ptr< const SymbolicNode > & domain() const noexcept
const auto & value() const noexcept
const std::shared_ptr< const SymbolicNode > & right() const noexcept
const std::shared_ptr< const SymbolicNode > & left() const noexcept
const std::shared_ptr< const SymbolicNode > & domain() const noexcept
const std::shared_ptr< const SymbolicNode > & predicate() const noexcept
求和节点,表示符号有限/无限求和 sum_{k=a}^{b} f(k).
const std::shared_ptr< const SymbolicNode > & lower_bound() const noexcept
const std::shared_ptr< const SymbolicNode > & body() const noexcept
const std::shared_ptr< const SymbolicNode > & upper_bound() const noexcept
virtual void accept(LMCAS::detail::SymbolicVisitor &visitor) const =0
积分变换节点,表示 Laplace,Fourier,Z 变换及其逆变换.
const std::shared_ptr< const SymbolicNode > & body() const noexcept
变量节点,表示一个符号变量。
static BigInt degree_in_var(const std::shared_ptr< const SymbolicNode > &node, const std::string &var)
计算节点关于指定变量的多项式次数。 与 var 无关的子表达式次数为 0。
static BigInt product_degree(const MultiplyNode &product, const std::string &var)
static bool is_transcendental_func(FunctionNode::FuncType t)
判断函数类型是否为 sin、cos、tan、exp 或 ln。
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
ExprResult pow(const ExprPtr &base, const ExprPtr &exponent, ComputationContext &context)
ExprResult e()
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::string & v
bool try_get_integer_value(const std::shared_ptr< const NumberNode > &node, BigInt &value)
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
bool expression_depends_on_variable(const detail::SymbolicNodePtr &expression, const std::string &variable, detail::RewriteBudget *budget)
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
std::shared_ptr< SymbolicExpr > poly_expr
换元后的多项式表达式
const ExprPtr RelationOp op
std::vector< TransSubstitution > mappings
所有换元映射
__attribute__((visibility("default"))) MixedTranscendentalResult solve_mixed_transcendental_checked(const std __attribute__((visibility("default"))) MixedTranscendentalResult solve_mixed_transcendental_checked(const std __attribute__((visibility("default"))) bool contains_transcendental_of_var(const std bool is_polynomial_after_substitution(const TransSubstitutionResult &sub_result)
在调用方计算上下文中执行混合超越方程求解.
__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 & t
bool contains_transcendental_of_var(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var)
混合超越方程求解:符号预处理 + 自适应根隔离 + Newton-Raphson 精化.
内部 AST 定义。