LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
integration_rational_terms.cpp
浏览该文件的文档.
2
3namespace LMCAS {
4
5namespace {
6std::shared_ptr<SymbolicExpr> rd_var_minus(const std::string& var, const Rational& r) {
7 auto v = SymbolicExpr::variable(var);
8 if (r == Rational(0)) { return v; }
9 return SymbolicExpr::add(v, SymbolicExpr::number(Rational(0) - r));
10}
11
12std::shared_ptr<SymbolicExpr> rd_integrate_linear_term(
13 const Polynomial<Rational>& numerator, const Polynomial<Rational>& factor,
14 int power, const std::string& var) {
15 Rational r = Rational(0) - factor.coeffs[0];
16 Rational A = (numerator.coeffs.size() > 0) ? numerator.coeffs[0] : Rational(0);
17 if (A == Rational(0)) { return SymbolicExpr::number(0); }
18
19 if (power == 1) {
20 auto inner = rd_var_minus(var, r);
21 return SymbolicExpr::multiply(SymbolicExpr::number(A), SymbolicExpr::ln(inner));
22 }
23 Rational coeff = Rational(0) - A / Rational(BigInt(power - 1));
24 auto base = rd_var_minus(var, r);
25 auto exp = SymbolicExpr::number(BigInt(power - 1));
26 auto pw = SymbolicExpr::power(base, exp);
27 auto inv_pw = SymbolicExpr::power(pw, SymbolicExpr::number(BigInt(-1)));
28 return SymbolicExpr::multiply(SymbolicExpr::number(coeff), inv_pw);
29}
30
31std::shared_ptr<SymbolicExpr> rd_fraction_term(
32 const Polynomial<Rational>& numerator,
33 const Polynomial<Rational>& factor,
34 int power) {
35 auto numerator_expr = poly_to_symbolic(numerator);
36 auto denominator = poly_to_symbolic(factor);
37 auto denominator_power = SymbolicExpr::power(
38 denominator, SymbolicExpr::number(BigInt(power)));
39 auto inverse = SymbolicExpr::power(
40 denominator_power, SymbolicExpr::number(BigInt(-1)));
41 return SymbolicExpr::multiply(numerator_expr, inverse);
42}
43
44std::shared_ptr<SymbolicExpr> rd_integrate_repeated_quadratic(
45 const Polynomial<Rational>& numerator,
46 const Polynomial<Rational>& factor,
47 const Rational& p, const Rational& B,
48 const Rational& residual, const std::string& var) {
50 std::vector<Rational>{p / Rational(2), Rational(1)},
51 factor.variable_name);
52 Polynomial<Rational> linear_numerator(
53 std::vector<Rational>{B}, numerator.variable_name);
54 Polynomial<Rational> repeated_numerator(
55 std::vector<Rational>{residual}, numerator.variable_name);
56 auto logarithmic = rd_integrate_linear_term(
57 linear_numerator, linear, 1, var);
58 auto repeated = rd_integrate_linear_term(
59 repeated_numerator, linear, 2, var);
60 return SymbolicExpr::add(logarithmic, repeated);
61}
62
63std::shared_ptr<SymbolicExpr> rd_quadratic_logarithm(
64 const Polynomial<Rational>& factor, const Rational& B) {
65 const Rational half = B / Rational(2);
66 auto result = SymbolicExpr::number(0);
67 if (half == Rational(0)) {
68 return result;
69 }
70 auto denominator = poly_to_symbolic(factor);
71 auto logarithm = SymbolicExpr::multiply(
72 SymbolicExpr::number(half), SymbolicExpr::ln(denominator));
73 return SymbolicExpr::add(result, logarithm);
74}
75
76std::shared_ptr<SymbolicExpr> rd_shifted_double_variable(
77 const Rational& p, const std::string& var) {
78 auto two_x = SymbolicExpr::multiply(
79 SymbolicExpr::number(BigInt(2)), SymbolicExpr::variable(var));
80 return p == Rational(0)
81 ? two_x
82 : SymbolicExpr::add(two_x, SymbolicExpr::number(p));
83}
84
85std::shared_ptr<SymbolicExpr> rd_integrate_negative_discriminant(
86 const std::shared_ptr<SymbolicExpr>& result,
87 const std::shared_ptr<SymbolicExpr>& shifted,
88 const Rational& residual, const Rational& discriminant) {
89 auto square_root = SymbolicExpr::sqrt(
90 SymbolicExpr::number(Rational(0) - discriminant));
91 auto inverse_root = SymbolicExpr::power(
92 square_root, SymbolicExpr::number(BigInt(-1)));
93 auto arctangent = make_arctan(
94 SymbolicExpr::multiply(shifted, inverse_root));
95 auto coefficient = SymbolicExpr::multiply(
96 SymbolicExpr::multiply(
97 SymbolicExpr::number(residual),
98 SymbolicExpr::number(BigInt(2))),
99 inverse_root);
100 return SymbolicExpr::add(
101 result, SymbolicExpr::multiply(coefficient, arctangent));
102}
103
104std::shared_ptr<SymbolicExpr> rd_integrate_positive_discriminant(
105 const std::shared_ptr<SymbolicExpr>& result,
106 const std::shared_ptr<SymbolicExpr>& shifted,
107 const Rational& residual, const Rational& discriminant) {
108 auto square_root =
109 SymbolicExpr::sqrt(SymbolicExpr::number(discriminant));
110 auto negative_root = SymbolicExpr::multiply(
111 SymbolicExpr::number(BigInt(-1)), square_root);
112 auto ratio = SymbolicExpr::divide(
113 SymbolicExpr::add(shifted, negative_root),
114 SymbolicExpr::add(shifted, square_root));
115 auto inverse_root = SymbolicExpr::power(
116 square_root, SymbolicExpr::number(BigInt(-1)));
117 auto coefficient = SymbolicExpr::multiply(
118 SymbolicExpr::number(residual), inverse_root);
119 return SymbolicExpr::add(
120 result,
121 SymbolicExpr::multiply(coefficient, SymbolicExpr::ln(ratio)));
122}
123
124std::shared_ptr<SymbolicExpr> rd_integrate_quadratic_term(
125 const Polynomial<Rational>& numerator, const Polynomial<Rational>& factor,
126 const std::string& var) {
127 const Rational q = factor.coeffs.empty()
128 ? Rational(0) : factor.coeffs[0];
129 const Rational p = factor.coeffs.size() > 1
130 ? factor.coeffs[1] : Rational(0);
131 const Rational discriminant = p * p - Rational(4) * q;
132 const Rational B = numerator.coeffs.size() > 1
133 ? numerator.coeffs[1] : Rational(0);
134 const Rational C = numerator.coeffs.empty()
135 ? Rational(0) : numerator.coeffs[0];
136 const Rational residual = C - (B * p) / Rational(2);
137
138 if (discriminant == Rational(0)) {
140 numerator, factor, p, B, residual, var);
141 }
142
143 auto result = rd_quadratic_logarithm(factor, B);
144 if (residual == Rational(0)) {
145 return result;
146 }
147 auto shifted = rd_shifted_double_variable(p, var);
148 if (discriminant.get_numerator().is_negative()) {
150 result, shifted, residual, discriminant);
151 }
153 result, shifted, residual, discriminant);
154}
155}
156
157
159 const Polynomial<Rational>& numerator,
160 const Polynomial<Rational>& factor,
161 int power, const std::string& var) {
162 const SymbolicExpr zero = *SymbolicExpr::number(0);
163 if (numerator.is_zero()) { return {zero, zero}; }
164 if (factor.degree() == 1) {
165 return {*rd_integrate_linear_term(numerator, factor, power, var), zero};
166 }
167 if (factor.degree() == 2 && power == 1) {
168 return {*rd_integrate_quadratic_term(numerator, factor, var), zero};
169 }
170 return {zero, *rd_fraction_term(numerator, factor, power)};
171}
172
173}
一元多项式模板类
std::string variable_name
变量名
bool is_zero() const
判断是否为零多项式
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
int degree() const
获取多项式的次数
std::shared_ptr< SymbolicExpr > rd_integrate_linear_term(const Polynomial< Rational > &numerator, const Polynomial< Rational > &factor, int power, const std::string &var)
std::shared_ptr< SymbolicExpr > rd_quadratic_logarithm(const Polynomial< Rational > &factor, const Rational &B)
std::shared_ptr< SymbolicExpr > rd_var_minus(const std::string &var, const Rational &r)
std::shared_ptr< SymbolicExpr > rd_integrate_negative_discriminant(const std::shared_ptr< SymbolicExpr > &result, const std::shared_ptr< SymbolicExpr > &shifted, const Rational &residual, const Rational &discriminant)
std::shared_ptr< SymbolicExpr > rd_integrate_positive_discriminant(const std::shared_ptr< SymbolicExpr > &result, const std::shared_ptr< SymbolicExpr > &shifted, const Rational &residual, const Rational &discriminant)
std::shared_ptr< SymbolicExpr > rd_shifted_double_variable(const Rational &p, const std::string &var)
std::shared_ptr< SymbolicExpr > rd_fraction_term(const Polynomial< Rational > &numerator, const Polynomial< Rational > &factor, int power)
std::shared_ptr< SymbolicExpr > rd_integrate_repeated_quadratic(const Polynomial< Rational > &numerator, const Polynomial< Rational > &factor, const Rational &p, const Rational &B, const Rational &residual, const std::string &var)
std::shared_ptr< SymbolicExpr > rd_integrate_quadratic_term(const Polynomial< Rational > &numerator, const Polynomial< Rational > &factor, const std::string &var)
IntegralParts integrate_rational_term(const Polynomial< Rational > &numerator, const Polynomial< Rational > &factor, int power, const std::string &var)
ExprResult exp(const ExprPtr &expression, ComputationContext &context)
__attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std std::shared_ptr< SymbolicExpr > r
__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
std::shared_ptr< SymbolicExpr > make_arctan(const std::shared_ptr< SymbolicExpr > &operand)
const ExprPtr & denominator