LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
integration_table_algebraic.cpp
浏览该文件的文档.
3
5
6void load_algebraic_elementary_rules(std::vector<detail::IntegrationEntry>& table) {
7 {
8 auto u = wildcard("_u");
9 auto u_sq = SymbolicExpr::power(detail::make_expression_ptr(u), SymbolicExpr::number(2));
10 auto neg_u_sq = SymbolicExpr::multiply(SymbolicExpr::number(-1), u_sq);
11 auto one_minus_u_sq = SymbolicExpr::add(SymbolicExpr::number(1), neg_u_sq);
12 auto pat = *SymbolicExpr::power(SymbolicExpr::sqrt(one_minus_u_sq), SymbolicExpr::number(-1));
13 auto res = *make_unary_function(FT::ArcSin, detail::make_expression_ptr(u));
14 table.push_back(detail::IntegrationEntry("1/sqrt(1-x^2)", pat, res, {"_u"}, u_is_var("_u"), 40));
15 }
16 {
17 auto u = wildcard("_u");
19 auto res = *SymbolicExpr::multiply(
20 SymbolicExpr::number(Rational(1, 2)),
22 table.push_back(detail::IntegrationEntry("|x|", pat, res, {"_u"}, u_is_real_var("_u"), 40));
23 auto square = SymbolicExpr::power(detail::make_expression_ptr(u), SymbolicExpr::number(2));
24 auto root = *SymbolicExpr::sqrt(square);
25 table.push_back(detail::IntegrationEntry("sqrt(x^2)", root, res, {"_u"}, u_is_real_var("_u"), 40));
26 }
27 {
28 auto u = wildcard("_u");
29 auto u_sq = SymbolicExpr::power(detail::make_expression_ptr(u), SymbolicExpr::number(2));
30 auto one_plus_u_sq = SymbolicExpr::add(SymbolicExpr::number(1), u_sq);
31 auto pat = *SymbolicExpr::power(one_plus_u_sq, SymbolicExpr::number(-1));
32 auto res = *make_unary_function(FT::ArcTan, detail::make_expression_ptr(u));
33 table.push_back(detail::IntegrationEntry("1/(1+x^2)", pat, res, {"_u"}, u_is_var("_u"), 40));
34 }
35}
36
37void load_algebraic_radicals_rules(std::vector<detail::IntegrationEntry>& table) {
38 {
39 auto u = wildcard("_u");
40 auto a = wildcard("_a");
41 auto u_sq = SymbolicExpr::power(detail::make_expression_ptr(u), SymbolicExpr::number(2));
42 auto a_sq = SymbolicExpr::power(detail::make_expression_ptr(a), SymbolicExpr::number(2));
43 auto sum = SymbolicExpr::add(u_sq, a_sq);
44 auto pat = *SymbolicExpr::power(SymbolicExpr::sqrt(sum), SymbolicExpr::number(-1));
45
46 auto u_sq_r = SymbolicExpr::power(detail::make_expression_ptr(u), SymbolicExpr::number(2));
47 auto a_sq_r = SymbolicExpr::power(detail::make_expression_ptr(a), SymbolicExpr::number(2));
48 auto sum_r = SymbolicExpr::add(u_sq_r, a_sq_r);
49 auto inner = SymbolicExpr::add(detail::make_expression_ptr(u), SymbolicExpr::sqrt(sum_r));
50 auto res = *SymbolicExpr::ln(make_unary_function(FT::Abs, inner));
51 table.push_back(detail::IntegrationEntry("1/sqrt(x^2+a^2)", pat, res, {"_u", "_a"},
52 u_is_var_a_nonzero("_u", "_a", true), 50));
53 }
54 {
55 auto u = wildcard("_u");
56 auto a = wildcard("_a");
57 auto u_sq = SymbolicExpr::power(detail::make_expression_ptr(u), SymbolicExpr::number(2));
58 auto a_sq = SymbolicExpr::power(detail::make_expression_ptr(a), SymbolicExpr::number(2));
59 auto neg_a_sq = SymbolicExpr::multiply(SymbolicExpr::number(-1), a_sq);
60 auto diff = SymbolicExpr::add(u_sq, neg_a_sq);
61 auto pat = *SymbolicExpr::power(SymbolicExpr::sqrt(diff), SymbolicExpr::number(-1));
62
63 auto u_sq_r = SymbolicExpr::power(detail::make_expression_ptr(u), SymbolicExpr::number(2));
64 auto a_sq_r = SymbolicExpr::power(detail::make_expression_ptr(a), SymbolicExpr::number(2));
65 auto neg_a_sq_r = SymbolicExpr::multiply(SymbolicExpr::number(-1), a_sq_r);
66 auto diff_r = SymbolicExpr::add(u_sq_r, neg_a_sq_r);
67 auto inner = SymbolicExpr::add(detail::make_expression_ptr(u), SymbolicExpr::sqrt(diff_r));
68 auto res = *SymbolicExpr::ln(make_unary_function(FT::Abs, inner));
69 table.push_back(detail::IntegrationEntry("1/sqrt(x^2-a^2)", pat, res, {"_u", "_a"},
70 u_is_var_a_nonzero("_u", "_a", true), 50));
71 }
72}
73
74void load_algebraic_reciprocals_rules(std::vector<detail::IntegrationEntry>& table) {
75 {
76 auto u = wildcard("_u");
77 auto a = wildcard("_a");
78 auto u_sq = SymbolicExpr::power(detail::make_expression_ptr(u), SymbolicExpr::number(2));
79 auto a_sq = SymbolicExpr::power(detail::make_expression_ptr(a), SymbolicExpr::number(2));
80 auto sum = SymbolicExpr::add(u_sq, a_sq);
81 auto pat = *SymbolicExpr::power(sum, SymbolicExpr::number(-1));
82
83 auto inv_a = SymbolicExpr::power(detail::make_expression_ptr(a), SymbolicExpr::number(-1));
84 auto u_over_a = SymbolicExpr::multiply(detail::make_expression_ptr(u), SymbolicExpr::power(detail::make_expression_ptr(a), SymbolicExpr::number(-1)));
85 auto res = *SymbolicExpr::multiply(inv_a, make_unary_function(FT::ArcTan, u_over_a));
86 table.push_back(detail::IntegrationEntry("1/(x^2+a^2)", pat, res, {"_u", "_a"},
87 u_is_var_a_nonzero("_u", "_a"), 50));
88 }
89 {
90 auto u = wildcard("_u");
91 auto a = wildcard("_a");
92 auto u_sq = SymbolicExpr::power(detail::make_expression_ptr(u), SymbolicExpr::number(2));
93 auto a_sq = SymbolicExpr::power(detail::make_expression_ptr(a), SymbolicExpr::number(2));
94 auto neg_a_sq = SymbolicExpr::multiply(SymbolicExpr::number(-1), a_sq);
95 auto diff = SymbolicExpr::add(u_sq, neg_a_sq);
96 auto pat = *SymbolicExpr::power(diff, SymbolicExpr::number(-1));
97
98 auto two_a = SymbolicExpr::multiply(SymbolicExpr::number(2), detail::make_expression_ptr(a));
99 auto inv_2a = SymbolicExpr::power(two_a, SymbolicExpr::number(-1));
100 auto neg_a = SymbolicExpr::multiply(SymbolicExpr::number(-1), detail::make_expression_ptr(a));
101 auto u_minus_a = SymbolicExpr::add(detail::make_expression_ptr(u), neg_a);
102 auto u_plus_a = SymbolicExpr::add(detail::make_expression_ptr(u), detail::make_expression_ptr(a));
103 auto frac = SymbolicExpr::divide(u_minus_a, u_plus_a);
104 auto res = *SymbolicExpr::multiply(inv_2a, SymbolicExpr::ln(make_unary_function(FT::Abs, frac)));
105 table.push_back(detail::IntegrationEntry("1/(x^2-a^2)", pat, res, {"_u", "_a"},
106 u_is_var_a_nonzero("_u", "_a", true), 50));
107 }
108}
109
110void load_polynomial_rules(std::vector<detail::IntegrationEntry>& table) {
111 {
112 auto u = wildcard("_u");
113 auto pat = *SymbolicExpr::power(detail::make_expression_ptr(u), SymbolicExpr::number(-1));
114 auto res = *SymbolicExpr::ln(detail::make_expression_ptr(u));
115 table.push_back(detail::IntegrationEntry("1/x", pat, res, {"_u"}, u_is_var("_u"), 50));
116 }
117 {
118 auto u = wildcard("_u");
119 auto n = wildcard("_n");
120 auto pat = *SymbolicExpr::power(detail::make_expression_ptr(u), detail::make_expression_ptr(n));
121 auto n_plus_1 = SymbolicExpr::add(detail::make_expression_ptr(n), SymbolicExpr::number(1));
122 auto res = *SymbolicExpr::divide(
123 SymbolicExpr::power(detail::make_expression_ptr(u), n_plus_1),
124 n_plus_1);
125 table.push_back(detail::IntegrationEntry("x^n", pat, res, {"_u", "_n"},
126 [](const MatchMap& m, const std::string& var, ComputationContext& context) {
127 auto it_u = m.find("_u");
128 if (it_u == m.end()) { return false; }
129 auto v = std::dynamic_pointer_cast<const VariableNode>(LMCAS::detail::node(it_u->second));
130 if (!v || v->is_constant() || v->name() != var) { return false; }
131 auto it_n = m.find("_n");
132 if (it_n == m.end()) { return false; }
133 if (expression_depends_on_variable(LMCAS::detail::node(it_n->second), var)) { return false; }
134 const auto exponent = detail::exact_rational_value(detail::node(it_n->second));
135 if (exponent) { return *exponent + Rational(1) != Rational(0); }
136 detail::RewriteBudget budget(context, context.limits().max_recursion_depth,
137 context.limits().max_ast_nodes, "integrate.power");
138 auto next = detail::normalize_node(detail::node(SymbolicExpr::add(
139 detail::make_expression_ptr(it_n->second), SymbolicExpr::number(1))), budget);
140 std::optional<detail::AssumptionFacts> assumptions;
141 if (context.assumptions()) { assumptions.emplace(*context.assumptions()); }
143 assumptions ? static_cast<const FactsQuery&>(*assumptions) : detail::no_facts(),
145 }, 80));
146 }
147 {
148 auto u = wildcard("_u");
150 auto res = *SymbolicExpr::multiply(
151 SymbolicExpr::power(detail::make_expression_ptr(u), SymbolicExpr::number(2)),
152 sym_rational(1, 2));
153 table.push_back(detail::IntegrationEntry("x", pat, res, {"_u"}, u_is_var("_u"), 90));
154 }
155}
156
157}
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
Result< Tribool > query_nonzero_value(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
const FactsQuery & no_facts() noexcept
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
std::optional< Rational > exact_rational_value(const NumberNode &number)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
auto u_is_var_a_nonzero(const std::string &u_wc, const std::string &a_wc, bool real_scale=false)
void load_algebraic_elementary_rules(std::vector< detail::IntegrationEntry > &table)
void load_polynomial_rules(std::vector< detail::IntegrationEntry > &table)
void load_algebraic_reciprocals_rules(std::vector< detail::IntegrationEntry > &table)
void load_algebraic_radicals_rules(std::vector< detail::IntegrationEntry > &table)
__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
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
SymbolicExpr wildcard(const std::string &name)
@ Real
Real numbers
bool expression_depends_on_variable(const detail::SymbolicNodePtr &expression, const std::string &variable, detail::RewriteBudget *budget)
std::shared_ptr< SymbolicExpr > sym_rational(const BigInt &numerator, const BigInt &denominator)
const ExprPtr & exponent
__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 const std::shared_ptr< SymbolicExpr > & a
std::unordered_map< std::string, SymbolicExpr > MatchMap
匹配结果映射,通配符名称 → 绑定的表达式
bool normalization_proved(const Result< Tribool > &result)
std::shared_ptr< SymbolicExpr > make_unary_function(FunctionNode::FuncType type, const std::shared_ptr< SymbolicExpr > &operand)
__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 & u