LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
ode_advanced.cpp
浏览该文件的文档.
1#include <stdexcept>
3#include "limit_result.hpp"
4/**
5 * @file ode_advanced.cpp
6 * @brief 通过受检接口用常数变易法构造解。
7 */
10#include "symbolic.hpp"
11#include "poly_utils.hpp"
13#include "lmmc/config.h"
14#include "lmmc/numeric.h"
16#include "integrator.hpp"
18#include <cmath>
19#include <memory>
20#include <string>
21
22namespace LMCAS {
23
25 const std::shared_ptr<SymbolicExpr>& y1,
26 const std::shared_ptr<SymbolicExpr>& y2,
27 const std::shared_ptr<SymbolicExpr>& g,
28 const std::string& x,
30
32 const std::shared_ptr<SymbolicExpr>& y1,
33 const std::shared_ptr<SymbolicExpr>& y2,
34 const std::shared_ptr<SymbolicExpr>& g,
35 const std::string& x,
37{
38 const std::string operation = "solve_variation_of_parameters";
39 auto valid = validate_ode_three_expr_one_var(y1, y2, g, x, context, operation);
40 if (!valid) {
41 return ODESolutionResult::failure(valid.error());
42 }
43
44 auto budget = context.consume_steps(24, operation);
45 if (!budget) {
46 return ODESolutionResult::failure(budget.error());
47 }
48
49 try {
51 y1, y2, g, x, context);
52 if (!solved) {
53 return solved;
54 }
55 return wrap_ode_solution(
56 std::move(solved.value()),
58 operation);
59 } catch (const std::bad_alloc&) {
62 "allocation failed while applying variation of parameters",
63 operation);
64 } catch (const std::exception& ex) {
67 ex.what(),
68 operation);
69 }
70}
71
73 const std::shared_ptr<SymbolicExpr>& y1,
74 const std::shared_ptr<SymbolicExpr>& y2,
75 const std::shared_ptr<SymbolicExpr>& g,
76 const std::string& x)
77{
80}
81
83 const std::shared_ptr<SymbolicExpr>& y1,
84 const std::shared_ptr<SymbolicExpr>& y2,
85 const std::shared_ptr<SymbolicExpr>& g,
86 const std::string& x,
88try {
89 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
90 (context).limits().max_ast_nodes, "transform");
91 /// 计算 y₁' 和 y₂'
92 auto y1_prime = detail::make_expression_ptr(detail::differentiate_node(detail::node(y1), x, transform_budget));
93 auto y2_prime = detail::make_expression_ptr(detail::differentiate_node(detail::node(y2), x, transform_budget));
94
95 /// 计算 Wronskian: W = y₁·y₂' - y₂·y₁'
96 auto term1 = SymbolicExpr::multiply(y1, y2_prime);
97 auto term2 = SymbolicExpr::multiply(y2, y1_prime);
98 auto W = SymbolicExpr::add(term1,
99 SymbolicExpr::multiply(SymbolicExpr::number(-1), term2));
101 EqvOptions trig_options;
102 trig_options.profile = EqvProfile::TrigBasic;
103 auto unit_wronskian = check_equivalent(
104 W, SymbolicExpr::number(1), context, trig_options);
105 if (!unit_wronskian) {
106 return ODESolutionResult::failure(unit_wronskian.error());
107 }
108 if (std::holds_alternative<ProvedZeroResidual>(
109 unit_wronskian.value())) {
110 W = SymbolicExpr::number(1);
111 }
112
113 if (W->is_zero()) {
114 return ODESolution{};
115 }
116
117 /// 计算 u₁' = -y₂·g(x)/W
118 auto u1_prime = SymbolicExpr::divide(
119 SymbolicExpr::multiply(SymbolicExpr::number(-1),
120 SymbolicExpr::multiply(y2, g)),
121 W);
122 u1_prime = detail::make_expression_ptr(detail::normalize_node(detail::node(u1_prime), transform_budget));
123
124 /// 计算 u₂' = y₁·g(x)/W
125 auto u2_prime = SymbolicExpr::divide(
126 SymbolicExpr::multiply(y1, g),
127 W);
128 u2_prime = detail::make_expression_ptr(detail::normalize_node(detail::node(u2_prime), transform_budget));
129
130 Integrator integrator;
131 auto u1_value =
132 integrator.integrate_checked(*u1_prime, x, context);
133 if (!u1_value) {
134 return ODESolutionResult::failure(u1_value.error());
135 }
136 auto u2_value =
137 integrator.integrate_checked(*u2_prime, x, context);
138 if (!u2_value) {
139 return ODESolutionResult::failure(u2_value.error());
140 }
141 auto u1 = std::make_shared<SymbolicExpr>(
142 std::move(u1_value.value()));
143 auto u2 = std::make_shared<SymbolicExpr>(
144 std::move(u2_value.value()));
145
146 /// 特解: y_p = u₁·y₁ + u₂·y₂
147 auto y_p = SymbolicExpr::add(
148 SymbolicExpr::multiply(u1, y1),
149 SymbolicExpr::multiply(u2, y2));
151
152 ODESolution result{};
154 result.general_solution = std::move(y_p);
155 return result;
156} catch (const CasError& error) {
157 return ODESolutionResult::failure(error);
158} catch (const std::bad_alloc&) {
159 return ODESolutionResult::failure(CasErrc::ResourceLimit, "allocation failed", "solve_variation_of_parameters_core");
160} catch (const std::length_error& error) {
161 return ODESolutionResult::failure(CasErrc::ResourceLimit, error.what(), "solve_variation_of_parameters_core");
162} catch (const std::exception& error) {
163 return ODESolutionResult::failure(CasErrc::InternalInvariant, error.what(), "solve_variation_of_parameters_core");
164}
165
166}
static Result failure(CasErrc code, std::string message, std::string operation={})
SymbolicNodePtr differentiate_node(const SymbolicNodePtr &node, const std::string &variable, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
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)
ODESolutionResult wrap_ode_solution(ODESolution solution, ODEType expected_method, const std::string &operation)
ODEType method_used
使用的求解方法
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
@ HigherOrder_ConstCoeff
高阶常系数线性
ResidualCheckResult check_equivalent(const ExprPtr &left, const ExprPtr &right, ComputationContext &context, const LMCAS::EqvOptions &options)
Result< void > validate_ode_three_expr_one_var(const std::shared_ptr< SymbolicExpr > &first, const std::shared_ptr< SymbolicExpr > &second, const std::shared_ptr< SymbolicExpr > &third, const std::string &x, ComputationContext &context, const std::string &operation)
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)
static ODESolutionResult solve_variation_of_parameters_core(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 > general_solution
通解表达式
Result< ODESolution > ODESolutionResult
const std::vector< IntegrationStep > Integrator & integrator
多项式转换与精确符号多项式代数。
符号表达式主类 SymbolicExpr 及其工厂方法,运算接口.
内部 AST 定义。
统一 ODE 求解引擎:分类,分派,多种求解方法.