LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
LMCAS::anonymous_namespace{integration_trigonometric.cpp} 命名空间参考

函数

bool extract_sec_power (const SymbolicExpr &expr, const std::string &var, int &n_out, ComputationContext &context)
bool extract_sin_cos_powers (const SymbolicExpr &expr, const std::string &var, int &m_out, int &n_out, ComputationContext &context)
bool extract_tan_power (const SymbolicExpr &expr, const std::string &var, int &n_out, ComputationContext &context)
std::shared_ptr< SymbolicExpr > integrate_even_case (int m, int n, const BigInt &scale, const std::string &var)
std::shared_ptr< SymbolicExpr > integrate_odd_case (int m, int n, const BigInt &scale, const std::string &var)
std::shared_ptr< SymbolicExpr > integrate_sec_power (int n, const std::string &var)
std::shared_ptr< SymbolicExpr > integrate_sin_m_cos_n (int m, int n, const BigInt &scale, const std::string &var)
std::shared_ptr< SymbolicExpr > integrate_tan_power (int n, const std::string &var)
std::shared_ptr< SymbolicExpr > make_cos_scaled (const BigInt &scale, const std::string &var)
std::shared_ptr< SymbolicExpr > make_sin_scaled (const BigInt &scale, const std::string &var)
BigInt trig_binomial (int degree, int selected_degree)
bool trig_extract_factor (const std::shared_ptr< const SymbolicNode > &node, const std::string &var, int &kind_out, int &power_out, ComputationContext &context)
bool trig_extract_nonneg_int (const std::shared_ptr< const SymbolicNode > &exp_node, int &degree_out, ComputationContext &context)
int trig_match_of_var (const std::shared_ptr< const SymbolicNode > &node, const std::string &var)

函数说明

◆ extract_sec_power()

bool LMCAS::anonymous_namespace{integration_trigonometric.cpp}::extract_sec_power ( const SymbolicExpr & expr,
const std::string & var,
int & n_out,
ComputationContext & context )

在文件 integration_trigonometric.cpp 第 124 行定义.

125 {
126 int kind = -1, p = 0;
127 if (!trig_extract_factor(LMCAS::detail::node(expr), var, kind, p, context)) { return false; }
128 if (kind != 3) { return false; }
129 n_out = p;
130 return true;
131}
bool trig_extract_factor(const std::shared_ptr< const SymbolicNode > &node, const std::string &var, int &kind_out, int &power_out, ComputationContext &context)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context

引用了 LMCAS::context, extract_sec_power(), LMCAS::detail::node() , 以及 trig_extract_factor().

被这些函数引用 extract_sec_power().

函数调用图:
这是这个函数的调用关系图:

◆ extract_sin_cos_powers()

bool LMCAS::anonymous_namespace{integration_trigonometric.cpp}::extract_sin_cos_powers ( const SymbolicExpr & expr,
const std::string & var,
int & m_out,
int & n_out,
ComputationContext & context )

要求 sin/cos 乘积至少含一个非零次幂。

在文件 integration_trigonometric.cpp 第 84 行定义.

85 {
86
87 int m = 0, n = 0;
88 std::vector<std::shared_ptr<const SymbolicNode>> factors;
89 if (auto mul = std::dynamic_pointer_cast<const MultiplyNode>(LMCAS::detail::node(expr))) {
90 factors = mul->operands();
91 } else {
92 factors.push_back(LMCAS::detail::node(expr));
93 }
94
95 for (const auto& f : factors) {
96 int kind = -1, p = 0;
97 if (!trig_extract_factor(f, var, kind, p, context)) { return false; }
98 // Only sin/cos contribute to (m,n); tan/sec disqualify this form.
99 if (kind == 0) {
100 if (p > std::numeric_limits<int>::max() - m) { return false; }
101 m += p;
102 } else if (kind == 1) {
103 if (p > std::numeric_limits<int>::max() - n) { return false; }
104 n += p;
105 }
106 else return false;
107 }
108
109 if (m == 0 && n == 0) { return false; } /** @brief 要求 sin/cos 乘积至少含一个非零次幂。 */
110 m_out = m;
111 n_out = n;
112 return true;
113}
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)

引用了 LMCAS::context, extract_sin_cos_powers(), LMCAS::mul(), LMCAS::detail::node() , 以及 trig_extract_factor().

被这些函数引用 extract_sin_cos_powers().

函数调用图:
这是这个函数的调用关系图:

◆ extract_tan_power()

bool LMCAS::anonymous_namespace{integration_trigonometric.cpp}::extract_tan_power ( const SymbolicExpr & expr,
const std::string & var,
int & n_out,
ComputationContext & context )

在文件 integration_trigonometric.cpp 第 115 行定义.

116 {
117 int kind = -1, p = 0;
118 if (!trig_extract_factor(LMCAS::detail::node(expr), var, kind, p, context)) { return false; }
119 if (kind != 2) { return false; }
120 n_out = p;
121 return true;
122}

引用了 LMCAS::context, extract_tan_power(), LMCAS::detail::node() , 以及 trig_extract_factor().

被这些函数引用 extract_tan_power().

函数调用图:
这是这个函数的调用关系图:

◆ integrate_even_case()

std::shared_ptr< SymbolicExpr > LMCAS::anonymous_namespace{integration_trigonometric.cpp}::integrate_even_case ( int m,
int n,
const BigInt & scale,
const std::string & var )

在文件 integration_trigonometric.cpp 第 217 行定义.

218 {
219
220 if ((m % 2 != 0) || (n % 2 != 0)) { return nullptr; }
221 int p = m / 2;
222 int q = n / 2;
223 int K = p + q;
224
225 // sin^(2p)(c*x)*cos^(2q)(c*x)
226 // = (1/2^(p+q)) * sum_{i,j} C(p,i)(-1)^i C(q,j) cos^(i+j)(2c*x)
227 // Compute coefficients a[k] = sum_{i+j=k} C(p,i)*C(q,j)*(-1)^i for k=0..K.
228 std::vector<BigInt> a(K + 1, BigInt(0));
229 for (int i = 0; i <= p; ++i) {
230 const BigInt bp = trig_binomial(p, i);
231 const BigInt alternating_sign((i % 2) == 0 ? 1 : -1);
232 for (int j = 0; j <= q; ++j) {
233 const BigInt bq = trig_binomial(q, j);
234 a[i + j] += alternating_sign * bp * bq;
235 }
236 }
237
238 BigInt denominator(1);
239 for (int t = 0; t < K; ++t) denominator *= BigInt(2);
240
241 std::vector<std::shared_ptr<const SymbolicNode>> add_terms;
242 for (int k = 0; k <= K; ++k) {
243 if (a[k] == 0) { continue; }
244 // Recurse: integrate cos^k(2c*x) at the new scale 2c.
245 auto inner = integrate_sin_m_cos_n(0, k, scale * BigInt(2), var);
246 if (!inner) { return nullptr; }
247 auto coeff = SymbolicExpr::number(Rational(a[k], denominator));
248 auto term = SymbolicExpr::multiply(coeff, inner);
249 add_terms.push_back(LMCAS::detail::node(term));
250 }
251
252 if (add_terms.empty()) { return SymbolicExpr::number(0); }
253 if (add_terms.size() == 1) {
254 return LMCAS::detail::make_expression_ptr(add_terms[0]);
255 }
257}
std::shared_ptr< SymbolicExpr > integrate_sin_m_cos_n(int m, int n, const BigInt &scale, const std::string &var)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
std::shared_ptr< const Node > make_node(Args &&... args)
@ Rational
Rational numbers
__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
const ExprPtr & denominator
__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

引用了 LMCAS::a, LMCAS::denominator, integrate_even_case(), integrate_sin_m_cos_n(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::make_node(), LMCAS::detail::node(), LMCAS::t , 以及 trig_binomial().

被这些函数引用 integrate_even_case() , 以及 integrate_sin_m_cos_n().

函数调用图:
这是这个函数的调用关系图:

◆ integrate_odd_case()

std::shared_ptr< SymbolicExpr > LMCAS::anonymous_namespace{integration_trigonometric.cpp}::integrate_odd_case ( int m,
int n,
const BigInt & scale,
const std::string & var )

包含换元微分 du 的符号。

上界为输入总次数加一。

在文件 integration_trigonometric.cpp 第 154 行定义.

155 {
156
157 if (scale == BigInt(0)) { return nullptr; }
158
159 // Pick which factor to peel:
160 // m odd -> peel one sin, set u = cos(scale*x), du = -scale*sin(scale*x)dx
161 // so sin(scale*x)dx = -du/scale.
162 // remaining: sin^(m-1) cos^n = (1-u^2)^k * u^n, k=(m-1)/2.
163 // n odd -> peel one cos, set u = sin(scale*x), du = +scale*cos(scale*x)dx
164 // so cos(scale*x)dx = du/scale.
165 // remaining: sin^m cos^(n-1) = u^m * (1-u^2)^k, k=(n-1)/2.
166 bool peel_sin = (m % 2 == 1);
167 int k = 0;
168 int other_pow = 0;
169 BigInt sign_factor(1); /** @brief 包含换元微分 du 的符号。 */
170 bool u_is_cos = false;
171
172 if (peel_sin) {
173 k = (m - 1) / 2;
174 other_pow = n;
175 sign_factor = -1;
176 u_is_cos = true;
177 } else {
178 k = (n - 1) / 2;
179 other_pow = m;
180 sign_factor = 1;
181 u_is_cos = false;
182 }
183
184 auto u_expr = u_is_cos ? make_cos_scaled(scale, var)
185 : make_sin_scaled(scale, var);
186
187 // Result = sum_{i=0..k} C(k,i)*(-1)^i * u^(2i+other_pow+1) / (scale*(2i+other_pow+1)) * sign_factor
188 std::vector<std::shared_ptr<const SymbolicNode>> add_terms;
189 for (int i = 0; i <= k; ++i) {
190 const BigInt binomial = trig_binomial(k, i);
191 const BigInt alternating_sign((i % 2) == 0 ? 1 : -1);
192 BigInt numerator = sign_factor * alternating_sign * binomial;
193 int u_pow = 2 * i + other_pow + 1; /** @brief 上界为输入总次数加一。 */
194 BigInt denominator = scale * BigInt(u_pow);
195 if (denominator == BigInt(0)) { return nullptr; }
196
197 std::shared_ptr<SymbolicExpr> u_to_pow;
198 if (u_pow == 1) {
199 u_to_pow = u_expr;
200 } else {
201 u_to_pow = SymbolicExpr::power(u_expr, SymbolicExpr::number(u_pow));
202 }
203 // Normalize sign so the rational denominator is positive.
204 if (denominator.is_negative()) { numerator = -numerator; denominator = -denominator; }
205 auto coeff = SymbolicExpr::number(Rational(numerator, denominator));
206 auto term = SymbolicExpr::multiply(coeff, u_to_pow);
207 add_terms.push_back(LMCAS::detail::node(term));
208 }
209
210 if (add_terms.empty()) { return SymbolicExpr::number(0); }
211 if (add_terms.size() == 1) {
212 return LMCAS::detail::make_expression_ptr(add_terms[0]);
213 }
215}
std::shared_ptr< SymbolicExpr > make_sin_scaled(const BigInt &scale, const std::string &var)
std::shared_ptr< SymbolicExpr > make_cos_scaled(const BigInt &scale, const std::string &var)

引用了 LMCAS::denominator, integrate_odd_case(), make_cos_scaled(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::make_node(), make_sin_scaled(), LMCAS::detail::node() , 以及 trig_binomial().

被这些函数引用 integrate_odd_case() , 以及 integrate_sin_m_cos_n().

函数调用图:
这是这个函数的调用关系图:

◆ integrate_sec_power()

std::shared_ptr< SymbolicExpr > LMCAS::anonymous_namespace{integration_trigonometric.cpp}::integrate_sec_power ( int n,
const std::string & var )

在文件 integration_trigonometric.cpp 第 292 行定义.

292 {
293
294 if (n < 2 || (n % 2) != 0) { return nullptr; }
295
296 using FT = FunctionNode::FuncType;
297 auto v = SymbolicExpr::variable(var);
298 auto tan_x = SymbolicExpr::tan(v);
299 auto make_sec_x = [&]() -> std::shared_ptr<SymbolicExpr> {
302 std::vector<std::shared_ptr<const SymbolicNode>>{LMCAS::detail::node(v)}));
303 };
304
305 if (n == 2) {
306 return tan_x;
307 }
308
309 auto sec_x = make_sec_x();
310 std::shared_ptr<SymbolicExpr> sec_pow;
311 if (n - 2 == 1) {
312 sec_pow = sec_x;
313 } else {
314 sec_pow = SymbolicExpr::power(sec_x, SymbolicExpr::number(n - 2));
315 }
316
317 // First term: sec^(n-2)(x) * tan(x) / (n-1)
318 auto inner = SymbolicExpr::multiply(sec_pow, tan_x);
319 auto first = SymbolicExpr::multiply(sym_rational(1, n - 1), inner);
320
321 // Second term: ((n-2)/(n-1)) * int sec^(n-2)
322 auto rest = integrate_sec_power(n - 2, var);
323 if (!rest) { return nullptr; }
324 auto coeff = SymbolicExpr::number(Rational(BigInt(n - 2), BigInt(n - 1)));
325 auto second = SymbolicExpr::multiply(coeff, rest);
326
327 return SymbolicExpr::add(first, second);
328}
std::shared_ptr< SymbolicExpr > integrate_sec_power(int n, const std::string &var)
__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 > sym_rational(const BigInt &numerator, const BigInt &denominator)

引用了 integrate_sec_power(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::make_node(), LMCAS::detail::node(), LMCAS::sym_rational() , 以及 LMCAS::v.

被这些函数引用 integrate_sec_power().

函数调用图:
这是这个函数的调用关系图:

◆ integrate_sin_m_cos_n()

std::shared_ptr< SymbolicExpr > LMCAS::anonymous_namespace{integration_trigonometric.cpp}::integrate_sin_m_cos_n ( int m,
int n,
const BigInt & scale,
const std::string & var )

在文件 integration_trigonometric.cpp 第 139 行定义.

140 {
141
142 if (m < 0 || n < 0) { return nullptr; }
143
144 if (m == 0 && n == 0) {
145 // Constant 1 with respect to var: integrand is essentially 1.
146 return SymbolicExpr::variable(var);
147 }
148 if ((m % 2 == 1) || (n % 2 == 1)) {
149 return integrate_odd_case(m, n, scale, var);
150 }
151 return integrate_even_case(m, n, scale, var);
152}
std::shared_ptr< SymbolicExpr > integrate_odd_case(int m, int n, const BigInt &scale, const std::string &var)
std::shared_ptr< SymbolicExpr > integrate_even_case(int m, int n, const BigInt &scale, const std::string &var)

引用了 integrate_even_case(), integrate_odd_case() , 以及 integrate_sin_m_cos_n().

被这些函数引用 integrate_even_case() , 以及 integrate_sin_m_cos_n().

函数调用图:
这是这个函数的调用关系图:

◆ integrate_tan_power()

std::shared_ptr< SymbolicExpr > LMCAS::anonymous_namespace{integration_trigonometric.cpp}::integrate_tan_power ( int n,
const std::string & var )

在文件 integration_trigonometric.cpp 第 259 行定义.

259 {
260
261 if (n < 0) { return nullptr; }
262 auto v = SymbolicExpr::variable(var);
263
264 if (n == 0) {
265 // int 1 dx = x
266 return v;
267 }
268 if (n == 1) {
269 // int tan(x) dx = -ln(cos(x))
270 auto cos_x = SymbolicExpr::cos(v);
271 auto ln_cos = SymbolicExpr::ln(cos_x);
272 return SymbolicExpr::multiply(SymbolicExpr::number(-1), ln_cos);
273 }
274
275 // n >= 2: tan^n = tan^(n-2)*(sec^2 - 1)
276 // int tan^n = tan^(n-1)/(n-1) - int tan^(n-2)
277 auto tan_x = SymbolicExpr::tan(v);
278 std::shared_ptr<SymbolicExpr> tan_pow_term;
279 if (n - 1 == 1) {
280 tan_pow_term = tan_x;
281 } else {
282 tan_pow_term = SymbolicExpr::power(tan_x, SymbolicExpr::number(n - 1));
283 }
284 auto first = SymbolicExpr::multiply(sym_rational(1, n - 1), tan_pow_term);
285
286 auto rest = integrate_tan_power(n - 2, var);
287 if (!rest) { return nullptr; }
288 auto neg_rest = SymbolicExpr::multiply(SymbolicExpr::number(-1), rest);
289 return SymbolicExpr::add(first, neg_rest);
290}
std::shared_ptr< SymbolicExpr > integrate_tan_power(int n, const std::string &var)

引用了 integrate_tan_power(), LMCAS::sym_rational() , 以及 LMCAS::v.

被这些函数引用 integrate_tan_power().

函数调用图:
这是这个函数的调用关系图:

◆ make_cos_scaled()

std::shared_ptr< SymbolicExpr > LMCAS::anonymous_namespace{integration_trigonometric.cpp}::make_cos_scaled ( const BigInt & scale,
const std::string & var )

在文件 integration_trigonometric.cpp 第 18 行定义.

18 {
19 auto v = SymbolicExpr::variable(var);
20 if (scale == BigInt(1)) { return SymbolicExpr::cos(v); }
21 auto cx = SymbolicExpr::multiply(SymbolicExpr::number(scale), v);
22 return SymbolicExpr::cos(cx);
23}

引用了 make_cos_scaled() , 以及 LMCAS::v.

被这些函数引用 integrate_odd_case() , 以及 make_cos_scaled().

函数调用图:
这是这个函数的调用关系图:

◆ make_sin_scaled()

std::shared_ptr< SymbolicExpr > LMCAS::anonymous_namespace{integration_trigonometric.cpp}::make_sin_scaled ( const BigInt & scale,
const std::string & var )

在文件 integration_trigonometric.cpp 第 11 行定义.

11 {
12 auto v = SymbolicExpr::variable(var);
13 if (scale == BigInt(1)) { return SymbolicExpr::sin(v); }
14 auto cx = SymbolicExpr::multiply(SymbolicExpr::number(scale), v);
15 return SymbolicExpr::sin(cx);
16}

引用了 make_sin_scaled() , 以及 LMCAS::v.

被这些函数引用 integrate_odd_case() , 以及 make_sin_scaled().

函数调用图:
这是这个函数的调用关系图:

◆ trig_binomial()

BigInt LMCAS::anonymous_namespace{integration_trigonometric.cpp}::trig_binomial ( int degree,
int selected_degree )

在文件 integration_trigonometric.cpp 第 24 行定义.

24 {
25 return BigInt::ncr(BigInt(degree), BigInt(selected_degree));
26}

引用了 trig_binomial().

被这些函数引用 integrate_even_case(), integrate_odd_case() , 以及 trig_binomial().

函数调用图:
这是这个函数的调用关系图:

◆ trig_extract_factor()

bool LMCAS::anonymous_namespace{integration_trigonometric.cpp}::trig_extract_factor ( const std::shared_ptr< const SymbolicNode > & node,
const std::string & var,
int & kind_out,
int & power_out,
ComputationContext & context )

在文件 integration_trigonometric.cpp 第 64 行定义.

66 {
67 int kind = trig_match_of_var(node, var);
68 if (kind >= 0) {
69 kind_out = kind;
70 power_out = 1;
71 return true;
72 }
73 auto pn = std::dynamic_pointer_cast<const PowerNode>(node);
74 if (!pn) { return false; }
75 int base_kind = trig_match_of_var(pn->base(), var);
76 if (base_kind < 0) { return false; }
77 int p = 0;
78 if (!trig_extract_nonneg_int(pn->exponent(), p, context)) { return false; }
79 kind_out = base_kind;
80 power_out = p;
81 return true;
82}
int trig_match_of_var(const std::shared_ptr< const SymbolicNode > &node, const std::string &var)
bool trig_extract_nonneg_int(const std::shared_ptr< const SymbolicNode > &exp_node, int &degree_out, ComputationContext &context)

引用了 LMCAS::context, trig_extract_factor(), trig_extract_nonneg_int() , 以及 trig_match_of_var().

被这些函数引用 extract_sec_power(), extract_sin_cos_powers(), extract_tan_power() , 以及 trig_extract_factor().

函数调用图:
这是这个函数的调用关系图:

◆ trig_extract_nonneg_int()

bool LMCAS::anonymous_namespace{integration_trigonometric.cpp}::trig_extract_nonneg_int ( const std::shared_ptr< const SymbolicNode > & exp_node,
int & degree_out,
ComputationContext & context )

在文件 integration_trigonometric.cpp 第 46 行定义.

47 {
48 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
49 (context).limits().max_ast_nodes, "transform");
52 if (!simp) { return false; }
53 const auto number = std::dynamic_pointer_cast<const NumberNode>(LMCAS::detail::node(simp));
54 if (!number) { return false; }
55 const auto degree = integration_bounded_exponent(*number, 0, std::numeric_limits<int>::max());
56 if (!degree) { return false; }
57 degree_out = *degree;
58 return true;
59}
inline ::LMCAS::SymbolicExpr expression_from_node(SymbolicNodePtr root)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
ExprResult e()
std::optional< int > integration_bounded_exponent(const NumberNode &number, int minimum_exponent, int maximum_exponent)

引用了 LMCAS::context, LMCAS::e(), LMCAS::detail::expression_from_node(), LMCAS::integration_bounded_exponent(), LMCAS::detail::make_expression_ptr(), LMCAS::detail::node(), LMCAS::detail::normalize_node() , 以及 trig_extract_nonneg_int().

被这些函数引用 trig_extract_factor() , 以及 trig_extract_nonneg_int().

函数调用图:
这是这个函数的调用关系图:

◆ trig_match_of_var()

int LMCAS::anonymous_namespace{integration_trigonometric.cpp}::trig_match_of_var ( const std::shared_ptr< const SymbolicNode > & node,
const std::string & var )

在文件 integration_trigonometric.cpp 第 31 行定义.

31 {
32 auto fn = std::dynamic_pointer_cast<const FunctionNode>(node);
33 if (!fn) { return -1; }
34 if (fn->arguments().size() != 1) { return -1; }
35 auto v = std::dynamic_pointer_cast<const VariableNode>(fn->arguments()[0]);
36 if (!v || v->is_constant() || v->name() != var) { return -1; }
38 switch (fn->type()) {
39 case FT::Sin: return 0;
40 case FT::Cos: return 1;
41 case FT::Tan: return 2;
42 case FT::Sec: return 3;
43 default: return -1;
44 }
45}

引用了 trig_match_of_var() , 以及 LMCAS::v.

被这些函数引用 trig_extract_factor() , 以及 trig_match_of_var().

函数调用图:
这是这个函数的调用关系图: