LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
symbolic_ode_engine.hpp
浏览该文件的文档.
1/**
2 * @file symbolic_ode_engine.hpp
3 * @brief 统一 ODE 求解引擎:分类,分派,多种求解方法.
4 *
5 * 扩展已有的 symbolic_ode.hpp,提供统一的 ODE 类型检测与分派机制,
6 * 支持可分离变量,一阶线性,齐次,Bernoulli,恰当,高阶常系数,Euler 等类型.
7 */
8#pragma once
10#include "lmcas_export.hpp"
11#include "result.hpp"
12#include "symbolic.hpp"
13#include "proof_outcome.hpp"
14#include <memory>
15#include <string>
16#include <vector>
17#include <optional>
18
19namespace LMCAS {
20
21/**
22 * @brief ODE 类型枚举,标识方程所属的求解类别.
23 */
24enum class ODEType {
25 Separable, ///< 可分离变量型 dy/dx = f(x)g(y)
26 Linear1, ///< 一阶线性 dy/dx + P(x)y = Q(x)
27 Linear2_ConstCoeff, ///< 二阶常系数线性
28 Homogeneous, ///< 齐次方程 y' = f(y/x)
29 Bernoulli, ///< Bernoulli 方程 y' + P(x)y = Q(x)y^n
30 Exact, ///< 恰当方程 M(x,y)dx + N(x,y)dy = 0
31 HigherOrder_ConstCoeff, ///< 高阶常系数线性
32 Euler, ///< Euler (Cauchy-Euler) 方程
33 System, ///< ODE 系统
34 LaplaceMethod, ///< Laplace 变换法
35 Frobenius, ///< Frobenius 级数解法
36 Unknown ///< 无法识别的类型
37};
38
39/**
40 * @brief ODE 分类结果,包含类型及提取的结构信息.
41 */
43 ODEType type = ODEType::Unknown; ///< 识别出的 ODE 类型
44 int order = 0; ///< 方程阶数
45
46 /// 一阶线性: P(x), Q(x) 使得 y' + P(x)y = Q(x)
47 std::shared_ptr<SymbolicExpr> P_coeff;
48 std::shared_ptr<SymbolicExpr> Q_coeff;
49
50 /// Bernoulli: P(x), Q(x), n 使得 y' + P(x)y = Q(x)y^n
51 std::shared_ptr<SymbolicExpr> bernoulli_P;
52 std::shared_ptr<SymbolicExpr> bernoulli_Q;
53 int bernoulli_n = 0;
54
55 /// 恰当方程: M(x,y), N(x,y)
56 std::shared_ptr<SymbolicExpr> exact_M;
57 std::shared_ptr<SymbolicExpr> exact_N;
58
59 /// 常系数: 系数列表 [a_n, a_{n-1}, ..., a_1, a_0] 和非齐次项 f(x)
60 std::vector<double> const_coeffs;
61 std::shared_ptr<SymbolicExpr> forcing_func;
62
63 /// Euler 方程: 系数列表 [a_n, ..., a_0] 对应 x^n*y^(n) + ... + a_0*y = f(x)
64 std::vector<double> euler_coeffs;
65 std::shared_ptr<SymbolicExpr> euler_forcing;
66};
67
68/**
69 * @brief ODE 求解结果.
70 */
72 std::shared_ptr<SymbolicExpr> general_solution; ///< 通解表达式
73 std::vector<std::string> constants; ///< 任意常数名称列表 (C1, C2, ...)
74 ODEType method_used = ODEType::Unknown; ///< 使用的求解方法
75 std::shared_ptr<SymbolicExpr> normalized_residual;
76 std::optional<ProofCertificate> certificate;
77};
78
80
81/**
82 * @brief 对一阶 ODE 进行类型分类.
83 *
84 * 给定 dy/dx = rhs(x, y) 形式的方程右端,检测其属于哪种可求解类型.
85 * 检测顺序:可分离 -> 一阶线性 -> 齐次 -> Bernoulli -> 恰当.
86 * 空 rhs 返回 Unknown。
87 *
88 * @param[in] rhs 方程右端表达式 (dy/dx = rhs)
89 * @param[in] x 自变量名
90 * @param[in] y 因变量名
91 * @return 分类结果
92 */
94 const std::shared_ptr<SymbolicExpr>& rhs,
95 const std::string& x,
96 const std::string& y);
97
98/**
99 * @brief 对高阶线性 ODE 进行类型分类.
100 *
101 * 给定系数列表和非齐次项,检测是否为常系数或 Euler 类型.
102 * 系数列表按降阶排列:coeffs[0] 对应最高阶导数.
103 * 常系数分类仅在所有系数都能表示为有限 double 时返回;否则返回 Unknown,
104 * 避免在 const_coeffs 中伪造数值。
105 *
106 * @param[in] coeffs 各阶导数的系数表达式列表(降阶排列)
107 * @param[in] forcing 非齐次项 f(x)
108 * @param[in] x 自变量名
109 * @param[in] y 因变量名
110 * @return 分类结果
111 */
113 const std::vector<std::shared_ptr<SymbolicExpr>>& coeffs,
114 const std::shared_ptr<SymbolicExpr>& forcing,
115 const std::string& x,
116 const std::string& y);
117
118/**
119 * @brief 检测表达式是否为可分离变量形式 f(x)*g(y).
120 *
121 * 空 rhs、空变量名或相同的 x/y 变量名返回 false。
122 *
123 * @param[in] rhs 方程右端表达式
124 * @param[in] x 自变量名
125 * @param[in] y 因变量名
126 * @return 若可分离返回 true
127 */
129 const std::shared_ptr<SymbolicExpr>& rhs,
130 const std::string& x,
131 const std::string& y);
132
133/**
134 * @brief 检测一阶 ODE 是否为线性形式 y' + P(x)y = Q(x).
135 *
136 * 空 rhs、空变量名或相同的 x/y 变量名返回 false;返回 false 时 P、Q
137 * 均置空。
138 *
139 * @param[in] rhs 方程右端表达式 (dy/dx = rhs)
140 * @param[in] x 自变量名
141 * @param[in] y 因变量名
142 * @param[out] P 若为线性,输出 P(x)
143 * @param[out] Q 若为线性,输出 Q(x)
144 * @return 若为一阶线性返回 true
145 */
147 const std::shared_ptr<SymbolicExpr>& rhs,
148 const std::string& x,
149 const std::string& y,
150 std::shared_ptr<SymbolicExpr>& P,
151 std::shared_ptr<SymbolicExpr>& Q);
152
153/**
154 * @brief 检测一阶 ODE 是否为齐次形式 y' = f(y/x).
155 *
156 * 通过检查 f(tx, ty) = f(x, y) 来判断齐次性.
157 * 判定只接受符号等价性证明;有限采样点相等不会被当作恒等证明。
158 * 空变量名或相同的 x/y 变量名返回 false。
159 *
160 * @param[in] rhs 方程右端表达式
161 * @param[in] x 自变量名
162 * @param[in] y 因变量名
163 * @return 若为齐次返回 true
164 */
166 const std::shared_ptr<SymbolicExpr>& rhs,
167 const std::string& x,
168 const std::string& y);
169
170/**
171 * @brief 检测一阶 ODE 是否为 Bernoulli 形式 y' + P(x)y = Q(x)y^n.
172 *
173 * 支持可由 AST 精确分解的任意 int 幂次,包括负幂;不通过有限点采样猜测
174 * 幂次。
175 * 空 rhs、空变量名或相同的 x/y 变量名返回 false;返回 false 时 P、Q
176 * 均置空且 n 置零。
177 *
178 * @param[in] rhs 方程右端表达式 (dy/dx = rhs)
179 * @param[in] x 自变量名
180 * @param[in] y 因变量名
181 * @param[out] P 若为 Bernoulli,输出 P(x)
182 * @param[out] Q 若为 Bernoulli,输出 Q(x)
183 * @param[out] n 若为 Bernoulli,输出幂次 n (n != 0, 1)
184 * @return 若为 Bernoulli 返回 true
185 */
187 const std::shared_ptr<SymbolicExpr>& rhs,
188 const std::string& x,
189 const std::string& y,
190 std::shared_ptr<SymbolicExpr>& P,
191 std::shared_ptr<SymbolicExpr>& Q,
192 int& n);
193
194/**
195 * @brief 检测方程是否为恰当形式 M(x,y) + N(x,y)y' = 0,即 partialM/partialy = partialN/partialx.
196 * 判定只接受符号等价性证明;有限采样点相等不会被当作恒等证明。
197 * 空表达式、空变量名或相同的 x/y 变量名返回 false。
198 *
199 * @param[in] M M(x,y) 表达式
200 * @param[in] N N(x,y) 表达式
201 * @param[in] x 自变量名
202 * @param[in] y 因变量名
203 * @return 若恰当返回 true
204 */
206 const std::shared_ptr<SymbolicExpr>& M,
207 const std::shared_ptr<SymbolicExpr>& N,
208 const std::string& x,
209 const std::string& y);
210
211/**
212 * @brief 检测高阶 ODE 系数是否全为常数.
213 *
214 * 系数列表和自变量名必须非空,否则返回 false。
215 * @param[in] coeffs 各阶导数的系数表达式列表
216 * @param[in] x 自变量名
217 * @return 若所有系数不依赖 x 返回 true
218 */
220 const std::vector<std::shared_ptr<SymbolicExpr>>& coeffs,
221 const std::string& x);
222
223/**
224 * @brief 检测高阶 ODE 是否为 Euler (Cauchy-Euler) 形式.
225 *
226 * Euler 方程形如 x^n*y^(n) + a_{n-1}*x^{n-1}*y^{n-1} + ... + a_0*y = f(x),
227 * 即第 k 阶导数的系数为常数乘以 x^k.
228 * 系数列表和自变量名必须非空,最高阶系数必须非零。判定要求每个比值
229 * coefficient_k/x^k 可被符号化简为有限常数,不用有限采样代替恒等证明。
230 * 返回 false 时 euler_consts 置空。
231 *
232 * @param[in] coeffs 各阶导数的系数表达式列表(降阶排列)
233 * @param[in] x 自变量名
234 * @param[out] euler_consts 提取的常数系数列表
235 * @return 若为 Euler 方程返回 true
236 */
238 const std::vector<std::shared_ptr<SymbolicExpr>>& coeffs,
239 const std::string& x,
240 std::vector<double>& euler_consts);
241
242
243/**
244 * @brief 求解齐次 ODE y' = f(y/x).
245 *
246 * 算法:令 v = y/x,则 y = vx,y' = v + xv'.
247 * 代入得 v + xv' = f(v),即 xv' = f(v) - v,
248 * 分离变量后积分,最后回代 v = y/x.
249 *
250 * @param[in] rhs 方程右端表达式 f(x, y)(满足 f(tx,ty)=f(x,y))
251 * @param[in] x 自变量名
252 * @param[in] y 因变量名
253 * @return 求解结果
254 */
256 const std::shared_ptr<SymbolicExpr>& rhs,
257 const std::string& x,
258 const std::string& y,
260
261/**
262 * @brief 使用默认计算上下文求解齐次 ODE,并显式报告无效输入和未覆盖域.
263 */
265 const std::shared_ptr<SymbolicExpr>& rhs,
266 const std::string& x,
267 const std::string& y);
268
269/**
270 * @brief 求解 Bernoulli 方程 y' + P(x)y = Q(x)y^n.
271 *
272 * 算法:令 v = y^(1-n),则 v' = (1-n)y^(-n)y'.
273 * 代入得线性方程 v' + (1-n)P(x)v = (1-n)Q(x),
274 * 用积分因子法求解后回代 y = v^(1/(1-n)).
275 *
276 * @param[in] P P(x) 系数
277 * @param[in] Q Q(x) 系数
278 * @param[in] n 幂次 (n != 0, 1)
279 * @param[in] x 自变量名
280 * @param[in] y 因变量名
281 * @return 求解结果
282 */
284 const std::shared_ptr<SymbolicExpr>& P,
285 const std::shared_ptr<SymbolicExpr>& Q,
286 int n,
287 const std::string& x,
288 const std::string& y,
290
291/**
292 * @brief 使用默认计算上下文求解 Bernoulli 方程,并显式报告无效输入和未覆盖域.
293 */
295 const std::shared_ptr<SymbolicExpr>& P,
296 const std::shared_ptr<SymbolicExpr>& Q,
297 int n,
298 const std::string& x,
299 const std::string& y);
300
301/**
302 * @brief 求解恰当方程 M(x,y)dx + N(x,y)dy = 0.
303 *
304 * 算法:当 partialM/partialy = partialN/partialx 时,存在势函数 F(x,y) 使得
305 * partialF/partialx = M, partialF/partialy = N.通过对 M 关于 x 积分并从 N 确定
306 * y 相关部分来构造 F,解为 F(x,y) = C.
307 *
308 * 当方程不恰当时,尝试寻找积分因子 mu(x) 或 mu(y).
309 *
310 * @param[in] M M(x,y) 表达式
311 * @param[in] N N(x,y) 表达式
312 * @param[in] x 自变量名
313 * @param[in] y 因变量名
314 * @return 求解结果(隐式解 F(x,y) = C)
315 */
317 const std::shared_ptr<SymbolicExpr>& M,
318 const std::shared_ptr<SymbolicExpr>& N,
319 const std::string& x,
320 const std::string& y,
322
323/**
324 * @brief 使用默认计算上下文求解恰当方程,并显式报告无效输入和未覆盖域.
325 */
327 const std::shared_ptr<SymbolicExpr>& M,
328 const std::shared_ptr<SymbolicExpr>& N,
329 const std::string& x,
330 const std::string& y);
331
332/**
333 * @brief 寻找积分因子使非恰当方程变为恰当方程.
334 *
335 * 尝试以下形式的积分因子:
336 * 1. mu = mu(x):当 (partialM/partialy - partialN/partialx)/N 仅依赖 x 时
337 * 2. mu = mu(y):当 (partialN/partialx - partialM/partialy)/M 仅依赖 y 时
338 *
339 * @param[in] M M(x,y) 表达式
340 * @param[in] N N(x,y) 表达式
341 * @param[in] x 自变量名
342 * @param[in] y 因变量名
343 * @return 积分因子表达式,若找不到返回 nullptr
344 */
345LMCAS_API std::shared_ptr<SymbolicExpr> find_integrating_factor(
346 const std::shared_ptr<SymbolicExpr>& M,
347 const std::shared_ptr<SymbolicExpr>& N,
348 const std::string& x,
349 const std::string& y);
350
351
352/**
353 * @brief 求解高阶常系数线性 ODE.
354 *
355 * 算法:构造特征多项式;二次实根使用避免相消的稳定公式;三至六次
356 * 多项式先用变量尺度平衡系数,再用多项式与其导数的近似 GCD 提取
357 * 高阶重根;最后根据根的类型构造通解:
358 * - 实根 r(重数 m):e^(rx), x*e^(rx), ..., x^(m-1)*e^(rx)
359 * - 复根 alpha+/-betai(重数 m):e^(alphax)(cos(betax), sin(betax)), x*e^(alphax)(cos(betax), sin(betax)), ...
360 *
361 * 非齐次支持域当前限于常数 forcing 且 y 的系数非零。
362 * 支持阶数最高为 6。统一乘以任意有限非零常数不改变输入方程。
363 * 特征根迭代必须收敛且通过后向误差检查;实根分类验证实轴投影相对于
364 * 候选根的误差,复根必须形成经尺度平衡后多项式验证的共轭对,不使用
365 * 会吞掉小非零虚部的固定绝对容差。归一化、尺度恢复、迭代或验证超出
366 * 有限 double 域时返回 CasErrc::NumericFailure。
367 *
368 * @param[in] coeffs 各阶导数的数值系数(降阶排列:coeffs[0] 对应最高阶)
369 * @param[in] forcing 非齐次项 f(x),齐次时为 nullptr 或零
370 * @param[in] x 自变量名
371 * @param[in] y 因变量名
372 * @return 求解结果
373 */
375 const std::vector<double>& coeffs,
376 const std::shared_ptr<SymbolicExpr>& forcing,
377 const std::string& x,
378 const std::string& y,
380
381/**
382 * @brief 使用默认计算上下文求解高阶常系数 ODE,并显式报告无效输入和未覆盖域.
383 */
385 const std::vector<double>& coeffs,
386 const std::shared_ptr<SymbolicExpr>& forcing,
387 const std::string& x,
388 const std::string& y);
389
390/**
391 * @brief 求解 Euler (Cauchy-Euler) 方程.
392 *
393 * 算法:对 Euler 方程 a_n*x^n*y^(n) + ... + a_0*y = f(x),
394 * 令 x = e^t(即 t = ln(x)),将方程转化为关于 t 的常系数 ODE,
395 * 求解后回代 t = ln(x).
396 *
397 * 支持二阶和三阶 Euler 方程.
398 *
399 * @param[in] euler_coeffs Euler 方程的常数系数列表(降阶排列)
400 * @param[in] forcing 非齐次项 f(x),齐次时为 nullptr 或零
401 * @param[in] x 自变量名
402 * @param[in] y 因变量名
403 * @return 求解结果
404 */
406 const std::vector<double>& euler_coeffs,
407 const std::shared_ptr<SymbolicExpr>& forcing,
408 const std::string& x,
409 const std::string& y,
411
412/**
413 * @brief 使用默认计算上下文求解 Euler 方程,并显式报告无效输入和未覆盖域.
414 */
416 const std::vector<double>& euler_coeffs,
417 const std::shared_ptr<SymbolicExpr>& forcing,
418 const std::string& x,
419 const std::string& y);
420
421
422/**
423 * @brief 奇点类型枚举.
424 */
426 Ordinary, ///< 常点
427 RegularSingular, ///< 正则奇点
428 IrregularSingular ///< 非正则奇点
429};
431
432/**
433 * @brief Frobenius 级数解结果.
434 */
436 std::shared_ptr<SymbolicExpr> series_solution; ///< 截断级数解
437 ODESingularityType point_type; ///< 展开点的奇点类型
438 std::vector<double> indicial_roots; ///< 指标方程的根(正则奇点时)
439 int truncation_order; ///< 截断阶数
440 std::shared_ptr<SymbolicExpr> normalized_residual;
441 std::optional<ProofCertificate> certificate;
442};
443
445
446/**
447 * @brief 用参数变分法求特解.
448 *
449 * @see Boyce and DiPrima, Elementary Differential Equations, Section3.6.
450 *
451 * 给定二阶线性 ODE y'' + p(x)y' + q(x)y = g(x) 的两个齐次解 y_1, y_2,
452 * 计算 Wronskian W = y_1y_2' - y_2y_1',然后:
453 * u_1' = -y_2*g(x)/W, u_2' = y_1*g(x)/W
454 * 积分得 u_1, u_2,特解为 y_p = u_1*y_1 + u_2*y_2.
455 *
456 * @param[in] y1 第一个齐次解
457 * @param[in] y2 第二个齐次解
458 * @param[in] g 非齐次项 g(x)(方程已归一化为首项系数 1)
459 * @param[in] x 自变量名
460 * @return 求解结果,general_solution 为特解 y_p
461 */
463 const std::shared_ptr<SymbolicExpr>& y1,
464 const std::shared_ptr<SymbolicExpr>& y2,
465 const std::shared_ptr<SymbolicExpr>& g,
466 const std::string& x,
468
469/**
470 * @brief 使用默认计算上下文执行参数变分法,并显式报告无效输入和未覆盖域.
471 */
473 const std::shared_ptr<SymbolicExpr>& y1,
474 const std::shared_ptr<SymbolicExpr>& y2,
475 const std::shared_ptr<SymbolicExpr>& g,
476 const std::string& x);
477
478/**
479 * @brief 对 ODE 的指定点进行奇点分类.
480 * 若代入点后仍含无法数值化的符号参数,则返回 CasErrc::Inconclusive,
481 * 而不是把未知值当作系数极点。
482 */
484 const std::shared_ptr<SymbolicExpr>& p,
485 const std::shared_ptr<SymbolicExpr>& q,
486 const std::shared_ptr<SymbolicExpr>& x0,
487 const std::string& x,
489
491 const std::shared_ptr<SymbolicExpr>& p,
492 const std::shared_ptr<SymbolicExpr>& q,
493 const std::shared_ptr<SymbolicExpr>& x0,
494 const std::string& x);
495
496/**
497 * @brief 用 Frobenius 方法求 ODE 的级数解.
498 *
499 * @see Bender and Orszag, Advanced Mathematical Methods for Scientists and Engineers, Chapter 3.
500 *
501 * 给定 y'' + p(x)y' + q(x)y = 0:
502 * - 常点:假设 y = suma_n(x-x_0)ⁿ,代入匹配系数
503 * - 正则奇点:假设 y = (x-x_0)^r*suma_n(x-x_0)ⁿ,
504 * 先求指标方程确定 r,再递推确定 a_n
505 *
506 * 当前 checked 实现要求在截断阶数内使用的系数及其导数均可转换为有限
507 * double;否则返回 CasErrc::Inconclusive,而不会把未知系数替换为零。
508 *
509 * @param[in] p 系数 p(x)(y' 的系数,方程已归一化)
510 * @param[in] q 系数 q(x)(y 的系数,方程已归一化)
511 * @param[in] x0 展开点
512 * @param[in] x 自变量名
513 * @param[in] order 截断阶数(默认 6)
514 * @return Frobenius 解结果
515 */
517 const std::shared_ptr<SymbolicExpr>& p,
518 const std::shared_ptr<SymbolicExpr>& q,
519 const std::shared_ptr<SymbolicExpr>& x0,
520 const std::string& x,
521 int order,
523
524/**
525 * @brief 使用默认计算上下文求 Frobenius 级数解,并显式报告无效输入和未覆盖域.
526 */
528 const std::shared_ptr<SymbolicExpr>& p,
529 const std::shared_ptr<SymbolicExpr>& q,
530 const std::shared_ptr<SymbolicExpr>& x0,
531 const std::string& x,
532 int order = 6);
533
534} // namespace LMCAS
#define LMCAS_API
std::vector< double > const_coeffs
常系数: 系数列表 [a_n, a_{n-1}, ..., a_1, a_0] 和非齐次项 f(x)
ODESolutionResult solve_bernoulli_ode_checked(const std::shared_ptr< SymbolicExpr > &P, const std::shared_ptr< SymbolicExpr > &Q, int n, const std::string &x, const std::string &y, ComputationContext &context)
bool is_homogeneous_ode(const std::shared_ptr< SymbolicExpr > &rhs, const std::string &x, const std::string &y)
ODESolutionResult solve_higher_order_ode_checked(const std::vector< double > &coeffs, const std::shared_ptr< SymbolicExpr > &forcing, const std::string &x, const std::string &y, ComputationContext &context)
std::shared_ptr< SymbolicExpr > bernoulli_P
Bernoulli: P(x), Q(x), n 使得 y' + P(x)y = Q(x)y^n
ODEClassification classify_higher_order_ode(const std::vector< std::shared_ptr< SymbolicExpr > > &coeffs, const std::shared_ptr< SymbolicExpr > &forcing, const std::string &x, const std::string &)
std::shared_ptr< SymbolicExpr > forcing_func
ODEType method_used
使用的求解方法
Result< ODESingularityType > ODESingularityResult
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ODEType
ODE 类型枚举,标识方程所属的求解类别.
@ Euler
Euler (Cauchy-Euler) 方程
@ Bernoulli
Bernoulli 方程 y' + P(x)y = Q(x)y^n
@ Exact
恰当方程 M(x,y)dx + N(x,y)dy = 0
@ Separable
可分离变量型 dy/dx = f(x)g(y)
@ Linear1
一阶线性 dy/dx + P(x)y = Q(x)
@ LaplaceMethod
Laplace 变换法
@ Homogeneous
齐次方程 y' = f(y/x)
@ HigherOrder_ConstCoeff
高阶常系数线性
@ Unknown
无法识别的类型
@ Frobenius
Frobenius 级数解法
@ Linear2_ConstCoeff
二阶常系数线性
ODEClassification classify_first_order_ode(const std::shared_ptr< SymbolicExpr > &rhs, const std::string &x, const std::string &y)
const std::vector< FGLMPoly > const MonomialOrder & order
FrobeniusSolutionResult solve_frobenius_checked(const std::shared_ptr< SymbolicExpr > &p, const std::shared_ptr< SymbolicExpr > &q, const std::shared_ptr< SymbolicExpr > &x0, const std::string &x, int order, ComputationContext &context)
std::shared_ptr< SymbolicExpr > Q_coeff
bool is_linear_first_order(const std::shared_ptr< SymbolicExpr > &rhs, const std::string &x, const std::string &y, std::shared_ptr< SymbolicExpr > &P, std::shared_ptr< SymbolicExpr > &Q)
std::shared_ptr< SymbolicExpr > find_integrating_factor(const std::shared_ptr< SymbolicExpr > &M, const std::shared_ptr< SymbolicExpr > &N, const std::string &x, const std::string &y)
std::shared_ptr< SymbolicExpr > euler_forcing
ODESolutionResult solve_euler_ode_checked(const std::vector< double > &euler_coeffs, const std::shared_ptr< SymbolicExpr > &forcing, const std::string &x, const std::string &y, ComputationContext &context)
std::shared_ptr< SymbolicExpr > P_coeff
一阶线性: P(x), Q(x) 使得 y' + P(x)y = Q(x)
bool is_bernoulli_ode(const std::shared_ptr< SymbolicExpr > &rhs, const std::string &x, const std::string &y, std::shared_ptr< SymbolicExpr > &P, std::shared_ptr< SymbolicExpr > &Q, int &n)
std::optional< ProofCertificate > certificate
Result< FrobeniusSolution > FrobeniusSolutionResult
ODESolutionResult solve_variation_of_parameters_checked(const std::shared_ptr< SymbolicExpr > &y1, const std::shared_ptr< SymbolicExpr > &y2, const std::shared_ptr< SymbolicExpr > &g, const std::string &x, ComputationContext &context)
std::shared_ptr< SymbolicExpr > exact_M
恰当方程: M(x,y), N(x,y)
ODESingularityResult classify_singular_point_checked(const std::shared_ptr< SymbolicExpr > &p, const std::shared_ptr< SymbolicExpr > &q, const std::shared_ptr< SymbolicExpr > &x0, const std::string &x, ComputationContext &context)
ODESingularityType
对一阶 ODE 进行类型分类.
std::vector< double > indicial_roots
指标方程的根(正则奇点时)
std::shared_ptr< SymbolicExpr > series_solution
截断级数解
ODESingularityType point_type
展开点的奇点类型
bool is_constant_coefficient(const std::vector< std::shared_ptr< SymbolicExpr > > &coeffs, const std::string &x)
std::shared_ptr< SymbolicExpr > general_solution
通解表达式
ODESolutionResult solve_homogeneous_ode_checked(const std::shared_ptr< SymbolicExpr > &rhs, const std::string &x, const std::string &y, ComputationContext &context)
const ExprPtr & rhs
std::vector< std::string > constants
任意常数名称列表 (C1, C2, ...)
ODEType type
识别出的 ODE 类型
std::shared_ptr< SymbolicExpr > normalized_residual
std::optional< ProofCertificate > certificate
@ Unknown
Parity not determined
ODESolutionResult solve_exact_ode_checked(const std::shared_ptr< SymbolicExpr > &M, const std::shared_ptr< SymbolicExpr > &N, const std::string &x, const std::string &y, ComputationContext &context)
std::shared_ptr< SymbolicExpr > bernoulli_Q
std::shared_ptr< SymbolicExpr > normalized_residual
Result< ODESolution > ODESolutionResult
std::shared_ptr< SymbolicExpr > exact_N
bool is_exact_ode(const std::shared_ptr< SymbolicExpr > &M, const std::shared_ptr< SymbolicExpr > &N, const std::string &x, const std::string &y)
bool is_euler_equation(const std::vector< std::shared_ptr< SymbolicExpr > > &coeffs, const std::string &x, std::vector< double > &euler_consts)
std::vector< double > euler_coeffs
Euler 方程: 系数列表 [a_n, ..., a_0] 对应 x^n*y^(n) + ... + a_0*y = f(x)
bool is_separable(const std::shared_ptr< SymbolicExpr > &rhs, const std::string &x, const std::string &y)
ODE 分类结果,包含类型及提取的结构信息.
符号表达式主类 SymbolicExpr 及其工厂方法,运算接口.