SymPy-1-13-中文文档-七-

SymPy 1.13 中文文档(七)

原文:docs.sympy.org/latest/index.html

积分

原文:docs.sympy.org/latest/modules/integrals/index.html

本模块文档包含有关梅耶尔 G 函数和 SymPy 积分的详细信息。

内容

  • 使用梅耶尔 G 函数计算积分

  • 积分

使用 Meijer G 函数计算积分

docs.sympy.org/latest/modules/integrals/g-functions.html

本文旨在详细描述使用 Meijer G 函数计算定积分和不定积分所涉及的步骤(及其微妙之处)。我们将完全忽略证明。

概述

计算 (\int f(x) \mathrm{d}x) 或 (\int_0^\infty f(x) \mathrm{d}x) 的算法通常包括三个步骤:

  1. 使用 Meijer G 函数(有时一个或两个)重新写出被积函数。

  2. 应用积分定理得到答案(通常表示为另一个 G 函数)。

  3. 在命名的特殊函数中展开结果。

步骤 (3) 在函数 hyperexpand 中实现。步骤 (1) 和 (2) 如下所述。此外,G 函数通常是分支的。因此,我们首先描述了分支函数的处理方式。

有些其他积分(例如 (\int_{-\infty}^\infty)) 可以通过首先将它们重新表述为上述形式之一来计算。这里有很多选择,算法至多是一种启发式算法。

极数和分支函数

Meijer G 函数和超几何函数通常是分支的(可能的分支点为 (0),(\pm 1),(\infty))。当例如将单个超几何函数展开为命名的特殊函数时,这并不是很重要,因为可以将分支问题留给人类用户。然而,这个算法操纵和转换 G 函数,要正确地做到这一点,至少需要一些关于所涉及分支的粗略理解。

首先,我们考虑集合 (\mathcal{S} = {(r, \theta) : r > 0, \theta \in \mathbb{R}})。我们有一个映射 (p: \mathcal{S} \rightarrow \mathbb{C}-{0}, (r, \theta) \mapsto r e^{i \theta})。将其定为局部双全纯映射给了 (\mathcal{S}) 一个拓扑和一个复结构。这个黎曼面通常被称为对数的黎曼面,原因如下:我们可以定义映射 (\operatorname{Exp}: \mathbb{C} \rightarrow \mathcal{S}, (x + i y) \mapsto (\exp(x), y)) 和 (\operatorname{Log}: \mathcal{S} \rightarrow \mathbb{C}, (e^x, y) \mapsto x + iy)。这两者都可以显示为全纯的,并且是互为逆映射。

有时我们还正式将点 “零” ((0)) 附加到 (\mathcal{S}) 上,并将结果对象称为 (\mathcal{S}_0)。显然,在 (0) 附近未定义复结构。一个基本的邻域系统由 ({\operatorname{Exp}(z) : \Re(z) < k}) 给出,至少定义了一个拓扑。 (\mathcal{S}_0) 的元素称为极数。我们进一步定义函数 (\operatorname{Arg}: \mathcal{S} \rightarrow \mathbb{R}, (r, \theta) \mapsto \theta) 和 (|.|: \mathcal{S}0 \rightarrow \mathbb{R}, (r, \theta) \mapsto r)。这些函数具有明显的意义,并且在所有地方都是连续的。

使用这些映射,许多操作可以从(\mathbb{C})扩展到(\mathcal{S})。我们定义(\operatorname{Exp}(a) \operatorname{Exp}(b) = \operatorname{Exp}(a + b))对于(a, b \in \mathbb{C}),同时对于(a \in \mathcal{S})和(b \in \mathbb{C}),我们定义(a^b = \operatorname{Exp}(b \operatorname{Log}(a)))。可以轻松地检验到,使用这些定义,许多代数性质(例如((ab)^c = a^c b^c))在正实数中适用(由于分支切割)在所有极坐标数中确实适用。

作为一种特殊性质,应当提到极坐标数的加法通常是未定义的。然而,极坐标数的形式和可以用来表达分支行为。例如,考虑函数(F(z) = \sqrt{1 + z})和(G(a, b) = \sqrt{a + b}),其中(a, b, z)为极坐标数。一般规则是,单个极坐标变量的函数定义为在圆上连续,并且与正实数的通常定义一致。因此,如果(S(z))表示在(\mathbb{C})上的平方根函数的标准分支,则我们被迫定义

[\begin{split}F(z) = \begin{cases} S(p(z)) &: |z| < 1 \ S(p(z)) &: -\pi < \operatorname{Arg}(z) + 4\pi n \le \pi \text{ for some } n \in \mathbb{Z} \ -S(p(z)) &: \text{else} \end{cases}.\end{split}]

(我们在这里省略了( |z| = 1 ),这对于积分不重要。) 最后我们定义(G(a, b) = \sqrt{a}F(b/a))。

在阿干平面上表示分支函数

假设(f: \mathcal{S} \to \mathbb{C})是一个全纯函数。我们希望在(部分)复数(\mathbb{C})上定义一个函数(F),尽可能地代表(f)。这个过程称为“引入分支切割”。在我们的情况下,实际上有一种标准做法(在 SymPy 的所有情况下都遵循),如下:引入“切割复平面”(C = \mathbb{C} \setminus \mathbb{R}_{\le 0})。通过(re^{i\theta} \mapsto r \operatorname{Exp}(i\theta))定义一个函数(l: C \to \mathcal{S})。这里(r > 0)和(-\pi < \theta \le \pi)。然后(l)是全纯的,并且我们定义(G = f \circ l)。这称为在 SymPy 文档中的“提升到主分支”。

表查找和反梅林变换

假设我们有一个被积函数 (f(x)),并尝试将其重写为一个单一的 G 函数。为此,我们首先将 (f(x)) 分解为 (x^s g(x)) 的形式(其中 (g(x)) 应该比 (f(x)) 简单)。这是通过函数 _split_mul(f, x) 完成的。然后我们将出现在 (f) 中的函数组装成一个元组(例如,如果 (f(x) = e^x \cos{x}),我们将组装成 ((\cos, \exp)))。这是由函数 _mytype(f, x) 完成的。接下来,我们使用 _create_lookup_table() 创建一个查找表,并用这个元组索引它。这(希望地)会产生涉及这些函数的 Meijer G 函数公式的列表,然后我们尝试模式匹配它们。如果有一个匹配成功,我们就成功了;否则,我们需要尝试其他方法。

现在假设我们想将 (f(x)) 重写为两个 G 函数的乘积形式。为此,我们(试图)找出将 (f(x)) 分解为 (f_1(x) f_2(x)) 的所有不等价方式。我们可以按任意顺序尝试这些分解,但通常建议最小化 (f_i(x)) 中出现的幂次数和不同函数的数量。例如,给定 (f(x) = \sin{x}, e^{x} \sin{2x}),我们首先尝试 (f_1(x) = \sin{x}, \sin{2x}),(f_2(x) = e^{x})。所有这些操作都由函数 _mul_as_two_parts(f) 完成。

最后,我们可以尝试递归的 Mellin 变换技术。由于 Meijer G 函数本质上被定义为某种反 Mellin 变换,如果我们想将函数 (f(x)) 写成一个 G 函数,我们可以计算它的 Mellin 变换 (F(s))。如果 (F(s)) 符合要求的形式,那么 G 函数表达式可以直接得到。这种技术推广了许多标准的重写,例如 (e^{ax} e^{bx} = e^{(a + b) x})。

一个小变化是,一些函数没有 Mellin 变换,尽管它们可以被写成 G 函数。例如,对于 (f(x) = e^x \sin{x})(函数增长太快,没有 Mellin 变换)。然而,如果函数被认为是解析的,那么我们可以尝试计算 (f(ax)) 的 Mellin 变换(其中 (a) 是参数),并通过解析延拓推导出 G 函数表达式。(检查解析性是容易的。由于我们只能处理一定的函数子集,我们只需过滤掉那些不是解析的函数。)

函数 _rewrite_single 执行表查找和递归 Mellin 变换。函数 _rewrite1_rewrite2 分别使用上述辅助函数和 _rewrite_single 来将它们的参数重写为一个或两个 G 函数。

应用积分定理

如果被积函数已经重新表达为 G 函数,那么评估积分就相对容易了。我们首先进行一些替换,以减少 G 函数参数的指数(分别参见 _rewrite_saxena_1_rewrite_saxena,用于一个或两个 G 函数)。接下来,我们列出应用积分定理的条件列表。它可能失败基本有两个原因:要么积分不存在,要么在推导定理时的操作不允许(有关更多详细信息,请参见此处的 [博客帖子])。

有时可以通过减少所涉及的 G 函数的参数来纠正这一点。例如,很明显,表示(e^z)的 G 函数满足对于所有(z \in \mathcal{S}),有(G(\operatorname{Exp}(2 \pi i)z) = G(z))。函数 meijerg.get_period() 可用于发现这一点,而函数 functions/elementary/complexes.py 中的 principal_branch(z, period) 可用于利用这些信息。这是由积分代码透明地完成的。

[博客帖子]

nessgrh.wordpress.com/2011/07/07/tricky-branch-cuts/

G-函数积分定理

本节旨在详细展示代码中使用的确定积分定理。以下两个公式可以追溯到迈杰尔(实际上他证明了更一般的公式;事实上,在文献中,公式通常以更一般的形式陈述。然而,从我们在这里给出的公式中,推导出一般的公式非常容易。最好保持定理尽可能简单,因为它们本身非常复杂。):

  1. [\begin{split}\int_0^\infty G_{p, q}^{m, n} \left.\left(\begin{matrix} a_1, \cdots, a_p \ b_1, \cdots, b_q \end{matrix} \right| \eta x \right) \mathrm{d}x = \frac{\prod_{j=1}^m \Gamma(b_j + 1) \prod_{j=1}^n \Gamma(-a_j)}{\eta \prod_{j=m+1}^q \Gamma(-b_j) \prod_{j=n+1}^p \Gamma(a_j + 1)}\end{split}]

  2. [\begin{split}\int_0^\infty G_{u, v}^{s, t} \left.\left(\begin{matrix} c_1, \cdots, c_u \ d_1, \cdots, d_v \end{matrix} \right| \sigma x \right) G_{p, q}^{m, n} \left.\left(\begin{matrix} a_1, \cdots, a_p \ b_1, \cdots, b_q \end{matrix} \right| \omega x \right) \mathrm{d}x = G_{v+p, u+q}^{m+t, n+s} \left.\left( \begin{matrix} a_1, \cdots, a_n, -d_1, \cdots, -d_v, a_{n+1}, \cdots, a_p \ b_1, \cdots, b_m, -c_1, \cdots, -c_u, b_{m+1}, \cdots, b_q \end{matrix} \right| \frac{\omega}{\sigma} \right)\end{split}]

更有趣的问题是在什么条件下这些公式是有效的。下面我们详细说明了 SymPy 中实施的条件。它们是在[Prudnikov1990][Luke1969]中找到的条件的混合;如果您发现任何错误,请告诉我们。

收敛条件积分 (1)

我们可以假设没有一般性损失地认为 (p \le q),因为指标 (m, n, p, q) 的 G 函数和指标 (n, m, q, p) 的 G 函数可以轻松相关联(见例如 [Luke1969],第 5.3 节)。我们引入以下符号:

[\begin{split}\xi = m + n - p \ \delta = m + n - \frac{p + q}{2}\end{split}][\begin{split}C_3: -\Re(b_j) < 1 \text{ for } j=1, \ldots, m \ 0 < -\Re(a_j) \text{ for } j=1, \ldots, n\end{split}][\begin{split}C_3^*: -\Re(b_j) < 1 \text{ for } j=1, \ldots, q \ 0 < -\Re(a_j) \text{ for } j=1, \ldots, p\end{split}][C_4: -\Re(\delta) + \frac{q + 1 - p}{2} > q - p]

收敛条件将在几个“情况”中详细说明,编号从一到五。为了以后的使用,将“无限远处”的条件与“零点”的条件分开将是有帮助的。我们所说的“无限远处”的条件是指仅依赖于积分被积函数在大正值 (x) 处的行为,而所说的“零点”的条件是指仅依赖于积分被积函数在 ((0, \epsilon)) 内的行为,对于任意 (\epsilon > 0)。由于我们所有的条件都是用 G 函数的参数来指定的,这种区别并不立即可见。然而,在数学上它们是非常不同的;特别是无限远处的条件更难控制。

为了使积分定理有效,必须同时满足 (n) 在“零点”和“无限远处”的条件,对于某些 (n)。

这些是“无限远处”的条件:

  1. [\delta > 0 \wedge |\arg(\eta)| < \delta \pi \wedge (A \vee B \vee C)]

    其中

    [A = 1 \le n \wedge p < q \wedge 1 \le m][B = 1 \le p \wedge 1 \le m \wedge q = p+1 \wedge \neg (n = 0 \wedge m = p + 1 )][C = 1 \le n \wedge q = p \wedge |\arg(\eta)| \ne (\delta - 2k)\pi \text{ for } k = 0, 1, \ldots \left\lceil \frac{\delta}{2} \right\rceil.]

  2. [n = 0 \wedge p + 1 \le m \wedge |\arg(\eta)| < \delta \pi]

  3. [(p < q \wedge 1 \le m \wedge \delta > 0 \wedge |\arg(\eta)| = \delta \pi) \vee (p \le q - 2 \wedge \delta = 0 \wedge \arg(\eta) = 0)]

  4. [p = q \wedge \delta = 0 \wedge \arg(\eta) = 0 \wedge \eta \ne 0 \wedge \Re\left(\sum_{j=1}^p b_j - a_j \right) < 0]

  5. [\delta > 0 \wedge |\arg(\eta)| < \delta \pi]

而这些是“零点”的条件:

  1. [\eta \ne 0 \wedge C_3]

  2. [C_3]

  3. [C_3 \wedge C_4]

  4. [C_3]

  5. [C_3]

积分(2)的收敛条件

我们引入以下符号:

[b^* = s + t - \frac{u + v}{2}][c^* = m + n - \frac{p + q}{2}][\rho = \sum_{j=1}^v d_j - \sum_{j=1}^u c_j + \frac{u - v}{2} + 1][\mu = \sum_{j=1}^q b_j - \sum_{j=1}^p a_j + \frac{p - q}{2} + 1][\phi = q - p - \frac{u - v}{2} + 1][\eta = 1 - (v - u) - \mu - \rho][\psi = \frac{\pi(q - m - n) + |\arg(\omega)|}{q - p}][\theta = \frac{\pi(v - s - t) + |\arg(\sigma)|)}{v - u}][\lambda_c = (q - p)|\omega|^{1/(q - p)} \cos{\psi} + (v - u)|\sigma|^{1/(v - u)} \cos{\theta}][\lambda_{s0}(c_1, c_2) = c_1 (q - p)|\omega|^{1/(q - p)} \sin{\psi} + c_2 (v - u)|\sigma|^{1/(v - u)} \sin{\theta}][\begin{split}\lambda_s = \begin{cases} \operatorname{\lambda_{s0}}\left(-1,-1\right) \operatorname{\lambda_{s0}}\left(1,1\right) & \text{for}: \arg(\omega) = 0 \wedge \arg(\sigma) = 0 \\operatorname{\lambda_{s0}}\left(\operatorname{sign}\left(\operatorname{\arg}\left(\omega\right)\right),-1\right) \operatorname{\lambda_{s0}}\left(\operatorname{sign}\left(\operatorname{\arg}\left(\omega\right)\right),1\right) & \text{for}: \arg(\omega) \ne 0 \wedge \arg(\sigma) = 0 \\operatorname{\lambda_{s0}}\left(-1,\operatorname{sign}\left(\operatorname{\arg}\left(\sigma\right)\right)\right) \operatorname{\lambda_{s0}}\left(1,\operatorname{sign}\left(\operatorname{\arg}\left(\sigma\right)\right)\right) & \text{for}: \arg(\omega) = 0 \wedge \arg(\sigma) \ne 0) \\operatorname{\lambda_{s0}}\left(\operatorname{sign}\left(\operatorname{\arg}\left(\omega\right)\right),\operatorname{sign}\left(\operatorname{\arg}\left(\sigma\right)\right)\right) & \text{otherwise} \end{cases}\end{split}][z_0 = \frac{\omega}{\sigma} e^{-i\pi (b^* + c^)}][z_1 = \frac{\sigma}{\omega} e^{-i\pi (b^ + c^*)}]

以下条件将会非常有帮助:

[\begin{split}C_1: (a_i - b_j \notin \mathbb{Z}{>0} \text{ for } i = 1, \ldots, n, j = 1, \ldots, m) \ \wedge (c_i - d_j \notin \mathbb{Z} \text{ for } i = 1, \ldots, t, j = 1, \ldots, s)\end{split}][C_2: \Re(1 + b_i + d_j) > 0 \text{ for } i = 1, \ldots, m, j = 1, \ldots, s][C_3: \Re(a_i + c_j) < 1 \text{ for } i = 1, \ldots, n, j = 1, \ldots, t][C_4: (p - q)\Re(c_i) - \Re(\mu) > -\frac{3}{2} \text{ for } i=1, \ldots, t][C_5: (p - q)\Re(1 + d_i) - \Re(\mu) > -\frac{3}{2} \text{ for } i=1, \ldots, s][C_6: (u - v)\Re(a_i) - \Re(\rho) > -\frac{3}{2} \text{ for } i=1, \ldots, n][C_7: (u - v)\Re(1 + b_i) - \Re(\rho) > -\frac{3}{2} \text{ for } i=1, \ldots, m][C_8: 0 < \lvert{\phi}\rvert + 2 \Re\left(\left(\mu -1\right) \left(- u + v\right) + \left(- p + q\right) \left(\rho -1\right) + \left(- p + q\right) \left(- u + v\right)\right)][C_9: 0 < \lvert{\phi}\rvert - 2 \Re\left(\left(\mu -1\right) \left(- u + v\right) + \left(- p + q\right) \left(\rho -1\right) + \left(- p + q\right) \left(- u + v\right)\right)][C_{10}: \lvert{\operatorname{arg}\left(\sigma\right)}\rvert < \pi b^{}][C_{11}: \lvert{\operatorname{arg}\left(\sigma\right)}\rvert = \pi b^{}][C_{12}: |\arg(\omega)| < c^\pi][C_{13}: |\arg(\omega)| = c^\pi][C_{14}¹: \left(z_0 \ne 1 \wedge |\arg(1 - z_0)| < \pi \right) \vee \left(z_0 = 1 \wedge \Re(\mu + \rho - u + v) < 1 \right)][C_{14}²: \left(z_1 \ne 1 \wedge |\arg(1 - z_1)| < \pi \right) \vee \left(z_1 = 1 \wedge \Re(\mu + \rho - p + q) < 1 \right)][C_{14}: \phi = 0 \wedge b^* + c^* \le 1 \wedge (C_{14}¹ \vee C_{14}²)][C_{15}: \lambda_c > 0 \vee (\lambda_c = 0 \wedge \lambda_s \ne 0 \wedge \Re(\eta) > -1) \vee (\lambda_c = 0 \wedge \lambda_s = 0 \wedge \Re(\eta) > 0)][C_{16}: \int_0^\infty G_{u, v}^{s, t}(\sigma x) \mathrm{d} x \text{ 在无穷远处收敛 }][C_{17}: \int_0^\infty G_{p, q}^{m, n}(\omega x) \mathrm{d} x \text{ 在无穷远处收敛 }]

注意 (C_{16}) 和 (C_{17}) 是我们为积分 (1) 拆分收敛条件的原因。

确定了这些符号后,实施的收敛条件可以列举如下:

  1. [m n s t \neq 0 \wedge 0 < b^{} \wedge 0 < c^{} \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{10} \wedge C_{12}]

  2. [u = v \wedge b^{} = 0 \wedge 0 < c^{} \wedge 0 < \sigma \wedge \Re{\rho} < 1 \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{12}]

  3. [p = q \wedge u = v \wedge b^{} = 0 \wedge c^{} = 0 \wedge 0 < \sigma \wedge 0 < \omega \wedge \Re{\mu} < 1 \wedge \Re{\rho} < 1 \wedge \sigma \neq \omega \wedge C_{1} \wedge C_{2} \wedge C_{3}]

  4. [p = q \wedge u = v \wedge b^{} = 0 \wedge c^{} = 0 \wedge 0 < \sigma \wedge 0 < \omega \wedge \Re\left(\mu + \rho\right) < 1 \wedge \omega \neq \sigma \wedge C_{1} \wedge C_{2} \wedge C_{3}]

  5. [p = q \wedge u = v \wedge b^{} = 0 \wedge c^{} = 0 \wedge 0 < \sigma \wedge 0 < \omega \wedge \Re\left(\mu + \rho\right) < 1 \wedge \omega \neq \sigma \wedge C_{1} \wedge C_{2} \wedge C_{3}]

  6. [q < p \wedge 0 < s \wedge 0 < b^{} \wedge 0 \leq c^{} \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{5} \wedge C_{10} \wedge C_{13}]

  7. [p < q \wedge 0 < t \wedge 0 < b^{} \wedge 0 \leq c^{} \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{4} \wedge C_{10} \wedge C_{13}]

  8. [v < u \wedge 0 < m \wedge 0 < c^{} \wedge 0 \leq b^{} \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{7} \wedge C_{11} \wedge C_{12}]

  9. [u < v \wedge 0 < n \wedge 0 < c^{} \wedge 0 \leq b^{} \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{6} \wedge C_{11} \wedge C_{12}]

  10. [q < p \wedge u = v \wedge b^{} = 0 \wedge 0 \leq c^{} \wedge 0 < \sigma \wedge \Re{\rho} < 1 \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{5} \wedge C_{13}]

  11. [p < q \wedge u = v \wedge b^{} = 0 \wedge 0 \leq c^{} \wedge 0 < \sigma \wedge \Re{\rho} < 1 \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{4} \wedge C_{13}]

  12. [p = q \wedge v < u \wedge 0 \leq b^{} \wedge c^{} = 0 \wedge 0 < \omega \wedge \Re{\mu} < 1 \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{7} \wedge C_{11}]

  13. [p = q \wedge u < v \wedge 0 \leq b^{} \wedge c^{} = 0 \wedge 0 < \omega \wedge \Re{\mu} < 1 \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{6} \wedge C_{11}]

  14. [p < q \wedge v < u \wedge 0 \leq b^{} \wedge 0 \leq c^{} \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{4} \wedge C_{7} \wedge C_{11} \wedge C_{13}]

  15. [q < p \wedge u < v \wedge 0 \leq b^{} \wedge 0 \leq c^{} \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{5} \wedge C_{6} \wedge C_{11} \wedge C_{13}]

  16. [q < p \wedge v < u \wedge 0 \leq b^{} \wedge 0 \leq c^{} \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{5} \wedge C_{7} \wedge C_{8} \wedge C_{11} \wedge C_{13} \wedge C_{14}]

  17. [p < q \wedge u < v \wedge 0 \leq b^{} \wedge 0 \leq c^{} \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{4} \wedge C_{6} \wedge C_{9} \wedge C_{11} \wedge C_{13} \wedge C_{14}]

  18. [t = 0 \wedge 0 < s \wedge 0 < b^{*} \wedge 0 < \phi \wedge C_{1} \wedge C_{2} \wedge C_{10}]

  19. [s = 0 \wedge 0 < t \wedge 0 < b^{*} \wedge \phi < 0 \wedge C_{1} \wedge C_{3} \wedge C_{10}]

  20. [n = 0 \wedge 0 < m \wedge 0 < c^{*} \wedge \phi < 0 \wedge C_{1} \wedge C_{2} \wedge C_{12}]

  21. [m = 0 \wedge 0 < n \wedge 0 < c^{*} \wedge 0 < \phi \wedge C_{1} \wedge C_{3} \wedge C_{12}]

  22. [s t = 0 \wedge 0 < b^{} \wedge 0 < c^{} \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{10} \wedge C_{12}]

  23. [m n = 0 \wedge 0 < b^{} \wedge 0 < c^{} \wedge C_{1} \wedge C_{2} \wedge C_{3} \wedge C_{10} \wedge C_{12}]

  24. [p < m + n \wedge t = 0 \wedge \phi = 0 \wedge 0 < s \wedge 0 < b^{} \wedge c^{} < 0 \wedge \lvert{\operatorname{arg}\left(\omega\right)}\rvert < \pi \left(m + n - p + 1\right) \wedge C_{1} \wedge C_{2} \wedge C_{10} \wedge C_{14} \wedge C_{15}]

  25. [q < m + n \wedge s = 0 \wedge \phi = 0 \wedge 0 < t \wedge 0 < b^{} \wedge c^{} < 0 \wedge \lvert{\operatorname{arg}\left(\omega\right)}\rvert < \pi \left(m + n - q + 1\right) \wedge C_{1} \wedge C_{3} \wedge C_{10} \wedge C_{14} \wedge C_{15}]

  26. [p = q -1 \wedge t = 0 \wedge \phi = 0 \wedge 0 < s \wedge 0 < b^{} \wedge 0 \leq c^{} \wedge \pi c^{*} < \lvert{\operatorname{arg}\left(\omega\right)}\rvert \wedge C_{1} \wedge C_{2} \wedge C_{10} \wedge C_{14} \wedge C_{15}]

  27. [p = q + 1 \wedge s = 0 \wedge \phi = 0 \wedge 0 < t \wedge 0 < b^{} \wedge 0 \leq c^{} \wedge \pi c^{*} < \lvert{\operatorname{arg}\left(\omega\right)}\rvert \wedge C_{1} \wedge C_{3} \wedge C_{10} \wedge C_{14} \wedge C_{15}]

  28. [p < q -1 \wedge t = 0 \wedge \phi = 0 \wedge 0 < s \wedge 0 < b^{} \wedge 0 \leq c^{} \wedge \pi c^{*} < \lvert{\operatorname{arg}\left(\omega\right)}\rvert \wedge \lvert{\operatorname{arg}\left(\omega\right)}\rvert < \pi \left(m + n - p + 1\right) \wedge C_{1} \wedge C_{2} \wedge C_{10} \wedge C_{14} \wedge C_{15}]

  29. [q + 1 < p \wedge s = 0 \wedge \phi = 0 \wedge 0 < t \wedge 0 < b^{} \wedge 0 \leq c^{} \wedge \pi c^{*} < \lvert{\operatorname{arg}\left(\omega\right)}\rvert \wedge \lvert{\operatorname{arg}\left(\omega\right)}\rvert < \pi \left(m + n - q + 1 \right) \wedge C_{1} \wedge C_{3} \wedge C_{10} \wedge C_{14} \wedge C_{15}]

  30. [n = 0 \wedge \phi = 0 \wedge 0 < s + t \wedge 0 < m \wedge 0 < c^{} \wedge b^{} < 0 \wedge \lvert{\operatorname{arg}\left(\sigma\right)}\rvert < \pi \left(s + t - u + 1\right) \wedge C_{1} \wedge C_{2} \wedge C_{12} \wedge C_{14} \wedge C_{15}]

  31. [m = 0 \wedge \phi = 0 \wedge v < s + t \wedge 0 < n \wedge 0 < c^{} \wedge b^{} < 0 \wedge \lvert{\operatorname{arg}\left(\sigma\right)}\rvert < \pi \left(s + t - v + 1\right) \wedge C_{1} \wedge C_{3} \wedge C_{12} \wedge C_{14} \wedge C_{15}]

  32. [n = 0 \wedge \phi = 0 \wedge u = v -1 \wedge 0 < m \wedge 0 < c^{} \wedge 0 \leq b^{} \wedge \pi b^{} < \lvert{\operatorname{arg}\left(\sigma\right)}\rvert \wedge \lvert{\operatorname{arg}\left(\sigma\right)}\rvert < \pi \left(b^{} + 1\right) \wedge C_{1} \wedge C_{2} \wedge C_{12} \wedge C_{14} \wedge C_{15}]

  33. [m = 0 \wedge \phi = 0 \wedge u = v + 1 \wedge 0 < n \wedge 0 < c^{} \wedge 0 \leq b^{} \wedge \pi b^{} < \lvert{\operatorname{arg}\left(\sigma\right)}\rvert \wedge \lvert{\operatorname{arg}\left(\sigma\right)}\rvert < \pi \left(b^{} + 1\right) \wedge C_{1} \wedge C_{3} \wedge C_{12} \wedge C_{14} \wedge C_{15}]

  34. [n = 0 \wedge \phi = 0 \wedge u < v -1 \wedge 0 < m \wedge 0 < c^{} \wedge 0 \leq b^{} \wedge \pi b^{*} < \lvert{\operatorname{arg}\left(\sigma\right)}\rvert \wedge \lvert{\operatorname{arg}\left(\sigma\right)}\rvert < \pi \left(s + t - u + 1\right) \wedge C_{1} \wedge C_{2} \wedge C_{12} \wedge C_{14} \wedge C_{15}]

  35. [m = 0 \wedge \phi = 0 \wedge v + 1 < u \wedge 0 < n \wedge 0 < c^{} \wedge 0 \leq b^{} \wedge \pi b^{*} < \lvert{\operatorname{arg}\left(\sigma\right)}\rvert \wedge \lvert{\operatorname{arg}\left(\sigma\right)}\rvert < \pi \left(s + t - v + 1 \right) \wedge C_{1} \wedge C_{3} \wedge C_{12} \wedge C_{14} \wedge C_{15}]

  36. [C_{17} \wedge t = 0 \wedge u < s \wedge 0 < b^{*} \wedge C_{10} \wedge C_{1} \wedge C_{2} \wedge C_{3}]

  37. [C_{17} \wedge s = 0 \wedge v < t \wedge 0 < b^{*} \wedge C_{10} \wedge C_{1} \wedge C_{2} \wedge C_{3}]

  38. [C_{16} \wedge n = 0 \wedge p < m \wedge 0 < c^{*} \wedge C_{12} \wedge C_{1} \wedge C_{2} \wedge C_{3}]

  39. [C_{16} \wedge m = 0 \wedge q < n \wedge 0 < c^{*} \wedge C_{12} \wedge C_{1} \wedge C_{2} \wedge C_{3}]

一个 G-函数的拉普拉斯逆变换

Meijer G-函数的拉普拉斯逆变换可以表示为另一个 G-函数。这是计算该变换的一种非常通用的方法。然而,我在文献中找不到详细信息,所以在这里进行了推导。在 [Luke1969] 的第 5.6.3 节中,给出了关于 G-函数的拉普拉斯逆变换的公式,同时也给出了收敛条件。然而,我们需要一个关于参数 (bz^a) 的公式,其中 (a) 是有理数。

我们被要求计算

[f(t) = \frac{1}{2\pi i} \int_{c-i\infty}^{c+i\infty} e^{zt} G(bz^a) \mathrm{d}z,]

对于正实数 (t)。三个问题出现:

  1. 这个积分何时收敛?

  2. 怎样计算积分?

  3. 我们的计算何时有效?

如何计算积分

现在我们暂时形式化处理。用 (\Delta(s)) 表示在 (G) 的定义中出现的伽玛函数的乘积,因此

[G(z) = \frac{1}{2\pi i} \int_L \Delta(s) z^s \mathrm{d}s.]

因此

[f(t) = \frac{1}{(2\pi i)²} \int_{c - i\infty}^{c + i\infty} \int_L e^{zt} \Delta(s) b^s z^{as} \mathrm{d}s \mathrm{d}z.]

我们交换积分的顺序得到

[f(t) = \frac{1}{2\pi i} \int_L b^s \Delta(s) \int_{c-i\infty}^{c+i\infty} e^{zt} z^{as} \frac{\mathrm{d}z}{2\pi i} \mathrm{d}s.]

内积分很容易看出为 (\frac{1}{\Gamma(-as)} \frac{1}{t^{1+as}})。(使用柯西定理和约当引理使轮廓从 (-\infty) 变形到 (-\infty),围绕 (0) 一次。对于实数且大于一的 (as),这个轮廓可以推到负实轴上,并且积分被识别为正弦和伽玛函数的乘积。然后利用伽玛函数的函数方程证明该公式,并通过解析延拓到原积分的收敛域)因此我们得到

[f(t) = \frac{1}{t} \frac{1}{2\pi i} \int_L \Delta(s) \frac{1}{\Gamma(-as)} \left(\frac{b}{ta}\right)s \mathrm{d}s,]

这是所谓的 Fox H 函数(参数为 (\frac{b}{t^a}))。对于有理数 (a),这可以利用伽玛函数乘法定理表示为 Meijer G 函数。

当这个计算有效时

在这个计算中有很多障碍。只有当涉及的所有积分都绝对收敛时,积分的互换才有效。特别是内积分必须收敛。此外,为了正确地将最终积分识别为 Fox H / Meijer G 函数,新引入的伽玛函数的极点必须正确分离。

很容易检查内积分对于 (\Re(as) < -1) 绝对收敛。因此轮廓 (L) 必须位于线 (\Re(as) = -1) 的左侧。在这种条件下,新引入的伽玛函数的极点正确分离。

我们还需观察 Meijer G 函数是其参数的解析、无分支函数,以及系数 (b) 的解析。因此 (f(t)) 也是有效的最终计算,只要初始积分收敛,并且存在一组参数变化使计算有效。如果我们假设 w.l.o.g. (a > 0),则后一条件在 (G) 沿着 [Luke1969],第 5.2 节的轮廓 (2) 或 (3) 收敛时成立,即 (\delta \ge \frac{a}{2}) 或 (p \ge 1, p \ge q)。

当积分存在时

使用 [Luke1969],第 5.10 节,对于任何给定的 Meijer G 函数,我们可以找到形如 (z^a e{bzc}) 的主导项(尽管由于抵消的原因,这个表达可能不是最佳的)。

因此,我们必须调查

[\lim_{T \to \infty} \int_{c-iT}^{c+iT} e^{zt} z^a e{bzc} \mathrm{d}z.]

(这个主值积分正是拉普拉斯反演定理中使用的确切陈述。)我们写成 (z = c + i \tau)。那么 (arg(z) \to \pm \frac{\pi}{2}),因此 (e^{zt} \sim e^{it \tau})(其中 (\sim) 总是意味着“渐近等价,直到正实数乘法常数为止”)。还有 (z^{x + iy} \sim |\tau|^x e^{i y \log{|\tau|}} e^{\pm x i \frac{\pi}{2}})。

设定 (\omega_{\pm} = b e^{\pm i \Re(c) \frac{\pi}{2}})。我们有三种情况:

  1. (b=0) 或 (\Re(c) \le 0)。在这种情况下,如果 (\Re(a) \le -1),积分收敛。

  2. (b \ne 0), (\Im(c) = 0), (\Re(c) > 0)。在这种情况下,如果 (\Re(\omega_{\pm}) < 0),则积分收敛。

  3. (b \ne 0), (\Im(c) = 0), (\Re(c) > 0), (\Re(\omega_{\pm}) \le 0), 并且至少一个 (\Re(\omega_{\pm}) = 0)。在这种情况下,与 (1) 中相同的条件适用。

实施的 G-函数公式

算法的一个重要部分是将各种函数表达为 Meijer G 函数的表格。实质上,这是一个掩盖着的 Mellin 变换表格。以下是自动生成的表格,显示了目前在 SymPy 中实现的公式。条目“generated”表示相应的 G 函数具有可变数量的参数。这张表格预计会在算法改进导出新公式的能力时缩减。当然,每当需要处理新的特殊函数类时,它也必须增长。

基本函数:

函数涉及(\theta\left(z^{q} p - b\right)):

[\begin{split}a = a {G_{1, 1}^{1, 0}\left(\begin{matrix} & 1 \0 & \end{matrix} \middle| {z} \right)} + a {G_{1, 1}^{0, 1}\left(\begin{matrix} 1 & \ & 0 \end{matrix} \middle| {z} \right)}\end{split}][\begin{split}\left(z^{q} p + b\right)^{- a} = \frac{b^{- a} {G_{1, 1}^{1, 1}\left(\begin{matrix} 1 - a & \0 & \end{matrix} \middle| {\frac{z^{q} p}{b}} \right)}}{\Gamma\left(a\right)}\end{split}][\begin{split}\frac{- b^{a} + \left(z^{q} p\right){a}}{z p - b} = \frac{b^{a - 1} {G_{2, 2}^{2, 2}\left(\begin{matrix} 0, a & \0, a & \end{matrix} \middle| {\frac{z^{q} p}{b}} \right)} \sin{\left(\pi a \right)}}{\pi}\end{split}][\begin{split}\left(a + \sqrt{z^{q} p + a{2}}\right) = - \frac{a^{b} b {G_{2, 2}^{1, 2}\left(\begin{matrix} \frac{b}{2} + \frac{1}{2}, \frac{b}{2} + 1 & \0 & b \end{matrix} \middle| {\frac{z^{q} p}{a^{2}}} \right)}}{2 \sqrt{\pi}}\end{split}][\begin{split}\left(- a + \sqrt{z^{q} p + a{2}}\right) = \frac{a^{b} b {G_{2, 2}^{1, 2}\left(\begin{matrix} \frac{b}{2} + \frac{1}{2}, \frac{b}{2} + 1 & \b & 0 \end{matrix} \middle| {\frac{z^{q} p}{a^{2}}} \right)}}{2 \sqrt{\pi}}\end{split}][\begin{split}\frac{\left(a + \sqrt{z^{q} p + a{2}}\right){b}}{\sqrt{z^{q} p + a^{2}}} = \frac{a^{b - 1} {G_{2, 2}^{1, 2}\left(\begin{matrix} \frac{b}{2}, \frac{b}{2} + \frac{1}{2} & \0 & b \end{matrix} \middle| {\frac{z^{q} p}{a^{2}}} \right)}}{\sqrt{\pi}}\end{split}][\begin{split}\frac{\left(- a + \sqrt{z^{q} p + a{2}}\right){b}}{\sqrt{z^{q} p + a^{2}}} = \frac{a^{b - 1} {G_{2, 2}^{1, 2}\left(\begin{matrix} \frac{b}{2}, \frac{b}{2} + \frac{1}{2} & \b & 0 \end{matrix} \middle| {\frac{z^{q} p}{a^{2}}} \right)}}{\sqrt{\pi}}\end{split}][\begin{split}\left(z^{\frac{q}{2}} \sqrt{p} + \sqrt{z^{q} p + a}\right)^{b} = - \frac{a^{\frac{b}{2}} b {G_{2, 2}^{2, 1}\left(\begin{matrix} \frac{b}{2} + 1 & 1 - \frac{b}{2} \0, \frac{1}{2} & \end{matrix} \middle| {\frac{z^{q} p}{a}} \right)}}{2 \sqrt{\pi}}\end{split}][\begin{split}\left(- z^{\frac{q}{2}} \sqrt{p} + \sqrt{z^{q} p + a}\right)^{b} = \frac{a^{\frac{b}{2}} b {G_{2, 2}^{2, 1}\left(\begin{matrix} 1 - \frac{b}{2} & \frac{b}{2} + 1 \0, \frac{1}{2} & \end{matrix} \middle| {\frac{z^{q} p}{a}} \right)}}{2 \sqrt{\pi}}\end{split}][\begin{split}\frac{\left(z^{\frac{q}{2}} \sqrt{p} + \sqrt{z^{q} p + a}\right){b}}{\sqrt{z p + a}} = \frac{a^{\frac{b}{2} - \frac{1}{2}} {G_{2, 2}^{2, 1}\left(\begin{matrix} \frac{b}{2} + \frac{1}{2} & \frac{1}{2} - \frac{b}{2} \0, \frac{1}{2} & \end{matrix} \middle| {\frac{z^{q} p}{a}} \right)}}{\sqrt{\pi}}\end{split}][\begin{split}\frac{\left(- z^{\frac{q}{2}} \sqrt{p} + \sqrt{z^{q} p + a}\right){b}}{\sqrt{z p + a}} = \frac{a^{\frac{b}{2} - \frac{1}{2}} {G_{2, 2}^{2, 1}\left(\begin{matrix} \frac{1}{2} - \frac{b}{2} & \frac{b}{2} + \frac{1}{2} \0, \frac{1}{2} & \end{matrix} \middle| {\frac{z^{q} p}{a}} \right)}}{\sqrt{\pi}}\end{split}]

[\begin{split}\left(z^{q} p - b\right)^{a - 1} \theta\left(z^{q} p - b\right) = b^{a - 1} {G_{1, 1}^{0, 1}\left(\begin{matrix} a & \ & 0 \end{matrix} \middle| {\frac{z^{q} p}{b}} \right)} \Gamma\left(a\right),\text{ if } b > 0\end{split}][\begin{split}\left(- z^{q} p + b\right)^{a - 1} \theta\left(- z^{q} p + b\right) = b^{a - 1} {G_{1, 1}^{1, 0}\left(\begin{matrix} & a \0 & \end{matrix} \middle| {\frac{z^{q} p}{b}} \right)} \Gamma\left(a\right),\text{ if } b > 0\end{split}][\begin{split}\left(z^{q} p - b\right)^{a - 1} \theta\left(z - \left(\frac{b}{p}\right)^{\frac{1}{q}}\right) = b^{a - 1} {G_{1, 1}^{0, 1}\left(\begin{matrix} a & \ & 0 \end{matrix} \middle| {\frac{z^{q} p}{b}} \right)} \Gamma\left(a\right),\text{ if } b > 0\end{split}][\begin{split}\left(- z^{q} p + b\right)^{a - 1} \theta\left(- z + \left(\frac{b}{p}\right)^{\frac{1}{q}}\right) = b^{a - 1} {G_{1, 1}^{1, 0}\left(\begin{matrix} & a \0 & \end{matrix} \middle| {\frac{z^{q} p}{b}} \right)} \Gamma\left(a\right),\text{ if } b > 0\end{split}]

涉及(\left|{z^{q} p - b}\right|)的函数:

[\begin{split}\left|{z^{q} p - b}\right|^{- a} = 2 {G_{2, 2}^{1, 1}\left(\begin{matrix} 1 - a & \frac{1}{2} - \frac{a}{2} \0 & \frac{1}{2} - \frac{a}{2} \end{matrix} \middle| {\frac{z^{q} p}{b}} \right)} \sin{\left(\frac{\pi a}{2} \right)} \left|{b}\right|^{- a} \Gamma\left(1 - a\right),\text{ if } \operatorname{re}{\left(a\right)} < 1\end{split}]

涉及(e{z p e^{i \pi}})的函数:

[\begin{split}e{z p e^{i \pi}} = {G_{0, 1}^{1, 0}\left(\begin{matrix} & \0 & \end{matrix} \middle| {z^{q} p} \right)}\end{split}]

涉及(\sinh{\left(z^{q} p \right)})的函数:

[\begin{split}\sinh{\left(z^{q} p \right)} = \pi^{\frac{3}{2}} {G_{1, 3}^{1, 0}\left(\begin{matrix} & 1 \\frac{1}{2} & 0, 1 \end{matrix} \middle| {\frac{z^{2 q} p^{2}}{4}} \right)}\end{split}]

涉及(\cosh{\left(z^{q} p \right)})的函数:

[\begin{split}\cosh{\left(z^{q} p \right)} = \pi^{\frac{3}{2}} {G_{1, 3}^{1, 0}\left(\begin{matrix} & \frac{1}{2} \0 & \frac{1}{2}, \frac{1}{2} \end{matrix} \middle| {\frac{z^{2 q} p^{2}}{4}} \right)}\end{split}]

涉及(\sin{\left(z^{q} p \right)})的函数:

[\begin{split}\sin{\left(z^{q} p \right)} = \sqrt{\pi} {G_{0, 2}^{1, 0}\left(\begin{matrix} & \\frac{1}{2} & 0 \end{matrix} \middle| {\frac{z^{2 q} p^{2}}{4}} \right)}\end{split}]

涉及(\cos{\left(z^{q} p \right)})的函数:

[\begin{split}\cos{\left(z^{q} p \right)} = \sqrt{\pi} {G_{0, 2}^{1, 0}\left(\begin{matrix} & \0 & \frac{1}{2} \end{matrix} \middle| {\frac{z^{2 q} p^{2}}{4}} \right)}\end{split}]

涉及(\operatorname{sinc}{\left(z^{q} p \right)})的函数:

[\begin{split}\operatorname{sinc}{\left(z^{q} p \right)} = \frac{\sqrt{\pi} {G_{0, 2}^{1, 0}\left(\begin{matrix} & \0 & - \frac{1}{2} \end{matrix} \middle| {\frac{z^{2 q} p^{2}}{4}} \right)}}{2}\end{split}]

涉及(\log{\left(z^{q} p \right)}), (\theta\left(- z^{q} p + 1\right))的函数:

[\log{\left(z^{q} p \right)}^{n} \theta\left(- z^{q} p + 1\right) = \text{生成}][\log{\left(z^{q} p \right)}^{n} \theta\left(z^{q} p - 1\right) = \text{生成}]

函数涉及 (\log{\left(z^{q} p \right)}):

[\log{\left(z^{q} p \right)}^{n} = \text{生成}][\begin{split}\log{\left(z^{q} p + a \right)} = {G_{1, 1}^{1, 0}\left(\begin{matrix} & 1 \0 & \end{matrix} \middle| {z} \right)} \log{\left(a \right)} + {G_{1, 1}^{0, 1}\left(\begin{matrix} 1 & \ & 0 \end{matrix} \middle| {z} \right)} \log{\left(a \right)} + {G_{2, 2}^{1, 2}\left(\begin{matrix} 1, 1 & \1 & 0 \end{matrix} \middle| {\frac{z^{q} p}{a}} \right)}\end{split}][\begin{split}\log{\left(\left|{z^{q} p - a}\right| \right)} = {G_{1, 1}^{1, 0}\left(\begin{matrix} & 1 \0 & \end{matrix} \middle| {z} \right)} \log{\left(\left|{a}\right| \right)} + {G_{1, 1}^{0, 1}\left(\begin{matrix} 1 & \ & 0 \end{matrix} \middle| {z} \right)} \log{\left(\left|{a}\right| \right)} + \pi {G_{3, 3}^{1, 2}\left(\begin{matrix} 1, 1 & \frac{1}{2} \1 & 0, \frac{1}{2} \end{matrix} \middle| {\frac{z^{q} p}{a}} \right)}\end{split}]

函数涉及 (\operatorname{Ei}{\left(z^{q} p \right)}):

[\begin{split}\operatorname{Ei}{\left(z^{q} p \right)} = - i \pi {G_{1, 1}^{1, 0}\left(\begin{matrix} & 1 \0 & \end{matrix} \middle| {z} \right)} - {G_{1, 2}^{2, 0}\left(\begin{matrix} & 1 \0, 0 & \end{matrix} \middle| {z^{q} p e^{i \pi}} \right)} - i \pi {G_{1, 1}^{0, 1}\left(\begin{matrix} 1 & \ & 0 \end{matrix} \middle| {z} \right)}\end{split}]

函数涉及 (\operatorname{Si}{\left(z^{q} p \right)}):

[\begin{split}\operatorname{Si}{\left(z^{q} p \right)} = \frac{\sqrt{\pi} {G_{1, 3}^{1, 1}\left(\begin{matrix} 1 & \\frac{1}{2} & 0, 0 \end{matrix} \middle| {\frac{z^{2 q} p^{2}}{4}} \right)}}{2}\end{split}]

函数涉及 (\operatorname{Ci}{\left(z^{q} p \right)}):

[\begin{split}\operatorname{Ci}{\left(z^{q} p \right)} = - \frac{\sqrt{\pi} {G_{1, 3}^{2, 0}\left(\begin{matrix} & 1 \0, 0 & \frac{1}{2} \end{matrix} \middle| {\frac{z^{2 q} p^{2}}{4}} \right)}}{2}\end{split}]

函数涉及 (\operatorname{Shi}{\left(z^{q} p \right)}):

[\begin{split}\operatorname{Shi}{\left(z^{q} p \right)} = \frac{z^{q} \sqrt{\pi} p {G_{1, 3}^{1, 1}\left(\begin{matrix} \frac{1}{2} & \0 & - \frac{1}{2}, - \frac{1}{2} \end{matrix} \middle| {\frac{z^{2 q} p^{2} e^{i \pi}}{4}} \right)}}{4}\end{split}]

函数涉及 (\operatorname{Chi}\left(z^{q} p\right)):

[\begin{split}\operatorname{Chi}\left(z^{q} p\right) = - \frac{\pi^{\frac{3}{2}} {G_{2, 4}^{2, 0}\left(\begin{matrix} & \frac{1}{2}, 1 \0, 0 & \frac{1}{2}, \frac{1}{2} \end{matrix} \middle| {\frac{z^{2 q} p^{2}}{4}} \right)}}{2}\end{split}]

函数涉及 (\operatorname{E}_{a}\left(z^{q} p\right)):

[\begin{split}\operatorname{E}{a}\left(z^{q} p\right) = {G^{2, 0}\left(\begin{matrix} & a \0, a - 1 & \end{matrix} \middle| {z^{q} p} \right)}\end{split}]

函数涉及(\operatorname{erf}{\left(z^{q} p \right)}):

[\begin{split}\operatorname{erf}{\left(z^{q} p \right)} = \frac{{G_{1, 2}^{1, 1}\left(\begin{matrix} 1 & \\frac{1}{2} & 0 \end{matrix} \middle| {z^{2 q} p^{2}} \right)}}{\sqrt{\pi}}\end{split}]

函数涉及(\operatorname{erfc}{\left(z^{q} p \right)}):

[\begin{split}\operatorname{erfc}{\left(z^{q} p \right)} = \frac{{G_{1, 2}^{2, 0}\left(\begin{matrix} & 1 \0, \frac{1}{2} & \end{matrix} \middle| {z^{2 q} p^{2}} \right)}}{\sqrt{\pi}}\end{split}]

函数涉及(\operatorname{erfi}{\left(z^{q} p \right)}):

[\begin{split}\operatorname{erfi}{\left(z^{q} p \right)} = \frac{z^{q} p {G_{1, 2}^{1, 1}\left(\begin{matrix} \frac{1}{2} & \0 & - \frac{1}{2} \end{matrix} \middle| {- z^{2 q} p^{2}} \right)}}{\sqrt{\pi}}\end{split}]

函数涉及(S\left(z^{q} p\right)):

[\begin{split}S\left(z^{q} p\right) = \frac{{G_{1, 3}^{1, 1}\left(\begin{matrix} 1 & \\frac{3}{4} & 0, \frac{1}{4} \end{matrix} \middle| {\frac{z^{4 q} \pi^{2} p^{4}}{16}} \right)}}{2}\end{split}]

函数涉及(C\left(z^{q} p\right)):

[\begin{split}C\left(z^{q} p\right) = \frac{{G_{1, 3}^{1, 1}\left(\begin{matrix} 1 & \\frac{1}{4} & 0, \frac{3}{4} \end{matrix} \middle| {\frac{z^{4 q} \pi^{2} p^{4}}{16}} \right)}}{2}\end{split}]

函数涉及(J_{a}\left(z^{q} p\right)):

[\begin{split}J_{a}\left(z^{q} p\right) = {G_{0, 2}^{1, 0}\left(\begin{matrix} & \\frac{a}{2} & - \frac{a}{2} \end{matrix} \middle| {\frac{z^{2 q} p^{2}}{4}} \right)}\end{split}]

函数涉及(Y_{a}\left(z^{q} p\right)):

[\begin{split}Y_{a}\left(z^{q} p\right) = {G_{1, 3}^{2, 0}\left(\begin{matrix} & - \frac{a}{2} - \frac{1}{2} \- \frac{a}{2}, \frac{a}{2} & - \frac{a}{2} - \frac{1}{2} \end{matrix} \middle| {\frac{z^{2 q} p^{2}}{4}} \right)}\end{split}]

函数涉及(I_{a}\left(z^{q} p\right)):

[\begin{split}I_{a}\left(z^{q} p\right) = \pi {G_{1, 3}^{1, 0}\left(\begin{matrix} & \frac{a}{2} + \frac{1}{2} \\frac{a}{2} & - \frac{a}{2}, \frac{a}{2} + \frac{1}{2} \end{matrix} \middle| {\frac{z^{2 q} p^{2}}{4}} \right)}\end{split}]

函数涉及(K_{a}\left(z^{q} p\right)):

[\begin{split}K_{a}\left(z^{q} p\right) = \frac{{G_{0, 2}^{2, 0}\left(\begin{matrix} & \- \frac{a}{2}, \frac{a}{2} & \end{matrix} \middle| {\frac{z^{2 q} p^{2}}{4}} \right)}}{2}\end{split}]

函数涉及(K\left(z^{q} p\right)):

[\begin{split}K\left(z^{q} p\right) = \frac{{G_{2, 2}^{1, 2}\left(\begin{matrix} \frac{1}{2}, \frac{1}{2} & \0 & 0 \end{matrix} \middle| {- z^{q} p} \right)}}{2}\end{split}]

函数涉及(E\left(z^{q} p\right)):

[\begin{split}E\left(z^{q} p\right) = - \frac{{G_{2, 2}^{1, 2}\left(\begin{matrix} \frac{1}{2}, \frac{3}{2} & \0 & 0 \end{matrix} \middle| {- z^{q} p} \right)}}{4}\end{split}] ### 内部 API 参考

通过将它们重写为 Meijer G 函数来积分函数。

有三个用户可见函数可以由 sympy 库的其他部分使用来解决各种积分问题:

  • meijerint_indefinite

  • meijerint_definite

  • meijerint_inversion

它们可以用于计算无穷大、实数线段上的定积分以及反拉普拉斯类型的积分(从 c-Ioo 到 c+Ioo)。详细信息请参见各自的文档字符串。

主要参考文献包括:

[L] 卢克,Y·L·(1969 年),特殊函数及其近似,

卷 1

[R] 凯利·B·罗奇。Meijer G 函数表示。

在:1997 年国际符号和代数计算研讨会论文集,205-211 页,纽约,1997 年。ACM。

[P] A·P·普鲁德尼科夫,Yu·A·布里奇科夫和 O·I·马里切夫(1990 年)。

积分与级数:更多特殊函数,第 3 卷,戈登和布雷奇科科学出版社

exception sympy.integrals.meijerint._CoeffExpValueError

_get_coeff_exp 引发的异常,仅供内部使用。

sympy.integrals.meijerint._check_antecedents(g1, g2, x)

返回适用于积分定理的条件。

sympy.integrals.meijerint._check_antecedents_1(g, x, helper=False)

返回使得 g 的 mellin 变换存在的条件。任何 x 的幂已经被吸收进 G 函数中,因此这只是 (\int_0^\infty g, dx)。

见[L,第 5.6.1 节]。(注意 s=1。)

如果 helper 为 True,则仅检查无穷远处的 MT 是否存在,即是否存在 (\int_1^\infty g, dx)。

sympy.integrals.meijerint._check_antecedents_inversion(g, x)

检查拉普拉斯反演积分的前提条件。

sympy.integrals.meijerint._condsimp(cond, first=True)

cond 进行天真的简化。

解释

请注意,此例程完全是特定应用的,简化规则是根据需要添加的,而不是遵循任何逻辑模式。

示例

>>> from sympy.integrals.meijerint import _condsimp as simp
>>> from sympy import Or, Eq
>>> from sympy.abc import x, y
>>> simp(Or(x < y, Eq(x, y)))
x <= y 
sympy.integrals.meijerint._create_lookup_table(table)

添加函数 -> meijerg 查询表格的公式。

sympy.integrals.meijerint._dummy(name, token, expr, **kwargs)

返回一个虚拟值。如果请求同一 token+name 多次且它尚未在表达式中,则返回相同的虚拟值,这样做是为了更友好地使用缓存。

sympy.integrals.meijerint._dummy_(name, token, **kwargs)

返回与名称和 token 关联的虚拟值。与全局声明效果相同。

sympy.integrals.meijerint._eval_cond(cond)

重新评估条件。

sympy.integrals.meijerint._exponents(expr, x)

expr 中找到 x 的指数(不包括零)。

示例

>>> from sympy.integrals.meijerint import _exponents
>>> from sympy.abc import x, y
>>> from sympy import sin
>>> _exponents(x, x)
{1}
>>> _exponents(x**2, x)
{2}
>>> _exponents(x**2 + x, x)
{1, 2}
>>> _exponents(x**3*sin(x + x**y) + 1/x, x)
{-1, 1, 3, y} 
sympy.integrals.meijerint._find_splitting_points(expr, x)

找到使得线性替换 x -> x + a(希望)简化表达式的数字 a。

示例

>>> from sympy.integrals.meijerint import _find_splitting_points as fsp
>>> from sympy import sin
>>> from sympy.abc import x
>>> fsp(x, x)
{0}
>>> fsp((x-1)**3, x)
{1}
>>> fsp(sin(x+3)*x, x)
{-3, 0} 
sympy.integrals.meijerint._flip_g(g)

将 G 函数转换为其逆参数之一(即 G(1/x) -> G’(x))。

sympy.integrals.meijerint._functions(expr, x)

找到 expr 中函数的类型,以估计其复杂性。

sympy.integrals.meijerint._get_coeff_exp(expr, x)

当 expr 已知为形式 c*x**b 时,其中 c 和/或 b 可能为 1 时,返回 c, b。

示例

>>> from sympy.abc import x, a, b
>>> from sympy.integrals.meijerint import _get_coeff_exp
>>> _get_coeff_exp(a*x**b, x)
(a, b)
>>> _get_coeff_exp(x, x)
(1, 1)
>>> _get_coeff_exp(2*x, x)
(2, 1)
>>> _get_coeff_exp(x**3, x)
(1, 3) 
sympy.integrals.meijerint._guess_expansion(f, x)

尝试猜测积分被 f(x) 重写的合理方式。

sympy.integrals.meijerint._inflate_fox_h(g, a)

设 d 表示 G 函数 g 的被积函数。考虑以相同方式定义的函数 H,但积分变为 d/Gamma(a*s)(遵循通常的轮廓惯例)。

如果 a 是有理数,则函数 H 可以写成 C*G,其中 C 是常数,G 函数是 G。

此函数返回 C, G。

sympy.integrals.meijerint._inflate_g(g, n)

返回 C, h,使得 h 是参数 z**n 的 G 函数,且 g = C*h。

sympy.integrals.meijerint._int0oo(g1, g2, x)

用 G 函数表示从零到无穷大的积分 g1*g2,假设满足必要条件。

示例

>>> from sympy.integrals.meijerint import _int0oo
>>> from sympy.abc import s, t, m
>>> from sympy import meijerg, S
>>> g1 = meijerg([], [], [-S(1)/2, 0], [], s**2*t/4)
>>> g2 = meijerg([], [], [m/2], [-m/2], t/4)
>>> _int0oo(g1, g2, t)
4*meijerg(((0, 1/2), ()), ((m/2,), (-m/2,)), s**(-2))/s**2 
sympy.integrals.meijerint._int0oo_1(g, x)

使用 G 函数计算 (\int_0^\infty g, dx),假设满足必要条件。

示例

>>> from sympy.abc import a, b, c, d, x, y
>>> from sympy import meijerg
>>> from sympy.integrals.meijerint import _int0oo_1
>>> _int0oo_1(meijerg([a], [b], [c], [d], x*y), x)
gamma(-a)*gamma(c + 1)/(y*gamma(-d)*gamma(b + 1)) 
sympy.integrals.meijerint._int_inversion(g, x, t)

计算拉普拉斯反演积分,假设公式适用。

sympy.integrals.meijerint._is_analytic(f, x)

检查在正实数上使用 G 函数表示的 f(x) 是否实际上几乎处处与 G 函数相符。

sympy.integrals.meijerint._meijerint_definite_2(f, x)

尝试从零到无穷大积分 f dx。

此函数的主体计算 f 的各种简化形式(例如通过调用 expand_mul()、trigexpand() - 见 _guess_expansion),并依次调用 _meijerint_definite_3。如果 _meijerint_definite_3 在任何简化函数上成功,则返回此结果。

sympy.integrals.meijerint._meijerint_definite_3(f, x)

尝试从零到无穷大积分 f dx。

此函数调用 _meijerint_definite_4 尝试计算积分。如果失败,则尝试使用线性性。

sympy.integrals.meijerint._meijerint_definite_4(f, x, only_double=False)

尝试从零到无穷大积分 f dx。

解释

此函数尝试应用文献中找到的积分定理,即尝试将 f 重写为一个或两个 G 函数的乘积。

参数 only_double 在递归算法中内部使用,以禁止将 f 试图重写为单个 G 函数。

sympy.integrals.meijerint._meijerint_indefinite_1(f, x)

不尝试任何替换的辅助函数。

sympy.integrals.meijerint._mul_args(f)

返回一个列表 L,使得 Mul(*L) == f

如果 f 不是 MulPowL=[f]。如果 f=g**n,其中 n 是整数,L=[g]*n。如果 fMulL 来自将 _mul_args 应用于 f 的所有因子。

sympy.integrals.meijerint._mul_as_two_parts(f)

找到将 f 拆分为两项乘积的所有方式。失败时返回 None。

解释

尽管从 multiset_partitions 中的规范顺序来看,这不一定是处理项的最佳顺序。例如,如果去掉 len(gs) == 2 的情况,并允许 multiset 对项进行排序,某些测试会失败。

示例

>>> from sympy.integrals.meijerint import _mul_as_two_parts
>>> from sympy import sin, exp, ordered
>>> from sympy.abc import x
>>> list(ordered(_mul_as_two_parts(x*sin(x)*exp(x))))
[(x, exp(x)*sin(x)), (x*exp(x), sin(x)), (x*sin(x), exp(x))] 
sympy.integrals.meijerint._my_principal_branch(expr, period, full_pb=False)

通过去除多余的因子将 expr 接近其主分支。此函数不保证产生主分支,以避免引入不透明的 principal_branch() 对象,除非 full_pb=True。

sympy.integrals.meijerint._mytype(f: Basic, x: Symbol) → tuple[type[Basic], ...]

创建描述 f 类型的可哈希实体。

sympy.integrals.meijerint._rewrite1(f, x, recursive=True)

尝试使用参数 ax**b 的单个 G 函数(或其和)重写 f。返回 fac, po, g,使得 f = facpo*g,其中 fac 独立于 x,po = x**s。这里的 g 是 _rewrite_single 的结果。失败时返回 None。

sympy.integrals.meijerint._rewrite2(f, x)

尝试将 f 重写为参数为 ax**b 的两个 G 函数的乘积。返回 fac, po, g1, g2,使得 f = facpog1g2,其中 fac 独立于 x,po = x**s。这里的 g1 和 g2 是 _rewrite_single 的结果。失败时返回 None。

sympy.integrals.meijerint._rewrite_inversion(fac, po, g, x)

吸收 po == x**s 到 g 中。

sympy.integrals.meijerint._rewrite_saxena(fac, po, g1, g2, x, full_pb=False)

在参数为 c*x 的 G 函数项中,将从 0 到 oo 的积分 fac*po*g1*g2 重写为积分 fac*G

解释

返回 C, f1, f2,使得从 0 到无穷大的积分 C f1 f2 等于从 0 到无穷大的积分 fac po, g1, g2

示例

>>> from sympy.integrals.meijerint import _rewrite_saxena
>>> from sympy.abc import s, t, m
>>> from sympy import meijerg
>>> g1 = meijerg([], [], [0], [], s*t)
>>> g2 = meijerg([], [], [m/2], [-m/2], t**2/4)
>>> r = _rewrite_saxena(1, t**0, g1, g2, t)
>>> r[0]
s/(4*sqrt(pi))
>>> r[1]
meijerg(((), ()), ((-1/2, 0), ()), s**2*t/4)
>>> r[2]
meijerg(((), ()), ((m/2,), (-m/2,)), t/4) 
sympy.integrals.meijerint._rewrite_saxena_1(fac, po, g, x)

将从零到无穷大的积分 facpog dx 重写为积分 facG,其中 G 的参数为 ax。注意 po=x**s。返回 fac, G。

sympy.integrals.meijerint._rewrite_single(f, x, recursive=True)

尝试将 f 重写为形式为 Cx**sG(a*xb) 的单个 G 函数的和,其中 b 是有理数且 C 与 x 无关。我们保证 result.argument.as_coeff_mul(x) 返回 (a, (xb,)) 或 (a, ())。在失败时返回空列表。

sympy.integrals.meijerint._split_mul(f, x)

将表达式 f 拆分为 fac、po、g,其中 fac 是常数因子,po = x**s(其中 s 与 s 独立)且 g 是“其余部分”。

示例

>>> from sympy.integrals.meijerint import _split_mul
>>> from sympy import sin
>>> from sympy.abc import s, x
>>> _split_mul((3*x)**s*sin(x**2)*x, x)
(3**s, x*x**s, sin(x**2)) 
sympy.integrals.meijerint.meijerint_definite(f, x, a, b)

f 在区间 [a, b] 上进行积分,通过将其重写为两个 G 函数的乘积或一个单一的 G 函数。

返回 res、cond,其中 cond 是收敛条件。

示例

>>> from sympy.integrals.meijerint import meijerint_definite
>>> from sympy import exp, oo
>>> from sympy.abc import x
>>> meijerint_definite(exp(-x**2), x, -oo, oo)
(sqrt(pi), True) 

此函数实现为 meijerint_definite、_meijerint_definite_2、_meijerint_definite_3、_meijerint_definite_4 的一系列函数。列表中的每个函数多次调用下一个函数(可能)。这意味着调用 meijerint_definite 可能非常昂贵。

sympy.integrals.meijerint.meijerint_indefinite(f, x)

通过将 f 重写为 G 函数的形式计算不定积分。

示例

>>> from sympy.integrals.meijerint import meijerint_indefinite
>>> from sympy import sin
>>> from sympy.abc import x
>>> meijerint_indefinite(sin(x), x)
-cos(x) 
sympy.integrals.meijerint.meijerint_inversion(f, x, t)

计算逆拉普拉斯变换 (\int_{c+i\infty}^{c-i\infty} f(x) e^{tx}, dx),其中 c 是大于 f 的所有奇点的实部的实数。

注意 t 始终假定为实数且为正数。

如果积分不存在或无法评估,则返回 None。

示例

>>> from sympy.abc import x, t
>>> from sympy.integrals.meijerint import meijerint_inversion
>>> meijerint_inversion(1/x, x, t)
Heaviside(t) 

积分

译文:docs.sympy.org/latest/modules/integrals/integrals.html

SymPy 中的 integrals 模块实现了计算表达式的定积分和不定积分的方法。

此模块中的主要方法是 integrate()

  • integrate(f, x) 返回不定积分 (\int f,dx)
  • integrate(f, (x, a, b)) 返回确定积分 (\int_{a}^{b} f,dx)

示例

SymPy 可以积分各种函数。它可以积分多项式函数:

>>> from sympy import *
>>> init_printing(use_unicode=False)
>>> x = Symbol('x')
>>> integrate(x**2 + x + 1, x)
 3    2
x    x
-- + -- + x
3    2 

有理函数:

>>> integrate(x/(x**2+2*x+1), x)
 1
log(x + 1) + -----
 x + 1 

指数多项式函数。这些多项式与函数 expcossin 的乘积组合可以通过重复分部积分手工积分,这是一个极其繁琐的过程。幸运的是,SymPy 将处理这些积分。

>>> integrate(x**2 * exp(x) * cos(x), x)
 2  x           2  x                         x           x
x *e *sin(x)   x *e *cos(x)      x          e *sin(x)   e *cos(x)
------------ + ------------ - x*e *sin(x) + --------- - ---------
 2              2                           2           2 

即使有一些非初等积分(特别是一些涉及误差函数的积分)也可以计算:

>>> integrate(exp(-x**2)*erf(x), x)
 ____    2
\/ pi *erf (x)
--------------
 4 

积分变换

SymPy 对确定积分和积分变换有特殊支持。

sympy.integrals.transforms.mellin_transform(f, x, s, **hints)

计算 (f(x)) 的 Mellin 变换 (F(s)),

[F(s) = \int_0^\infty x^{s-1} f(x) \mathrm{d}x.]

对于所有“合理”的函数,这在一个条带内绝对收敛。

(a < \operatorname{Re}(s) < b).

解释

Mellin 变换通过变量变换与 Fourier 变换相关联,并且与(双边)拉普拉斯变换也相关。

此函数返回 (F, (a, b), cond),其中 Ff 的 Mellin 变换,(a, b) 是基本条(如上所述),而 cond 是辅助收敛条件。

如果积分无法以闭合形式计算,则此函数返回一个未评估的 MellinTransform 对象。

有关可能提示的描述,请参阅 sympy.integrals.transforms.IntegralTransform.doit() 的文档字符串。如果 noconds=False,则仅返回 (F)(即不返回 cond,也不返回条带 (a, b))。

示例

>>> from sympy import mellin_transform, exp
>>> from sympy.abc import x, s
>>> mellin_transform(exp(-x), x, s)
(gamma(s), (0, oo), True) 

另请参阅

inverse_mellin_transform, laplace_transform, fourier_transform, hankel_transform, inverse_hankel_transform

class sympy.integrals.transforms.MellinTransform(*args)

表示未评估的 Mellin 变换的类。

如何使用这个类,请参阅IntegralTransform文档字符串。

如何计算 Mellin 变换,请参阅mellin_transform()文档字符串。

sympy.integrals.transforms.inverse_mellin_transform(F, s, x, strip, **hints)

计算给定由strip=(a, b)确定的基本带上(F(s))的逆 Mellin 变换。

解释

这可以定义为

[f(x) = \frac{1}{2\pi i} \int_{c - i\infty}^{c + i\infty} x^{-s} F(s) \mathrm{d}s,]

对于任意在基本带中的(c)。在(F)和/或(f)的某些正则条件下,这可以从其 Mellin 变换(F)(及反之)恢复(f),对于正实数(x)。

(a)或(b)中的一个可以传递为None;适当的(c)将被推断。

如果无法闭合计算积分,则此函数返回一个未评估的InverseMellinTransform对象。

请注意,此函数将假定 x 为正实数,不考虑 SymPy 的假设!

有关可能提示的描述,请参阅sympy.integrals.transforms.IntegralTransform.doit()文档字符串。

示例

>>> from sympy import inverse_mellin_transform, oo, gamma
>>> from sympy.abc import x, s
>>> inverse_mellin_transform(gamma(s), s, x, (0, oo))
exp(-x) 

基本带很重要:

>>> f = 1/(s**2 - 1)
>>> inverse_mellin_transform(f, s, x, (-oo, -1))
x*(1 - 1/x**2)*Heaviside(x - 1)/2
>>> inverse_mellin_transform(f, s, x, (-1, 1))
-x*Heaviside(1 - x)/2 - Heaviside(x - 1)/(2*x)
>>> inverse_mellin_transform(f, s, x, (1, oo))
(1/2 - x**2/2)*Heaviside(1 - x)/x 

参见

mellin_transform, hankel_transform, inverse_hankel_transform

class sympy.integrals.transforms.InverseMellinTransform(*args)

表示未评估逆 Mellin 变换的类。

如何使用这个类,请参阅IntegralTransform文档字符串。

如何计算逆 Mellin 变换,请参阅inverse_mellin_transform()文档字符串。

sympy.integrals.transforms.laplace_transform(f, t, s, legacy_matrix=True, **hints)

计算拉普拉斯变换 (F(s)) 的 (f(t)),

[F(s) = \int_{0{-}}\infty e^{-st} f(t) \mathrm{d}t.]

解释

对于所有合理的函数,这在半平面绝对收敛

[a < \operatorname{Re}(s)]

此函数返回(F, a, cond),其中Ff的 Laplace 变换,(a)是收敛的半平面,(cond)是辅助收敛条件。

实现是基于规则的,如果您对应用了哪些规则感兴趣,以及是否尝试了集成,可以通过设置sympy.SYMPY_DEBUG=True来打开调试信息。调试信息中的规则编号(及代码)参考 Bateman 的积分变换表[1]。

下限为 ( 0^- ),意味着应该从下侧接近此下限。仅当涉及分布时才需要这样做。目前仅在 ( f(t) ) 包含 DiracDelta 时才执行此操作,此时 Laplace 变换将隐式计算为

[F(s) = \lim_{\tau\to 0^{-}} \int_{\tau}^\infty e^{-st} f(t) \mathrm{d}t]

通过应用规则。

如果 Laplace 变换无法以封闭形式完全计算,则此函数将返回包含未评估的 LaplaceTransform 对象的表达式。

要获取可能的提示描述,请参阅 sympy.integrals.transforms.IntegralTransform.doit() 的文档字符串。如果 noconds=True,只返回 ( F )(即不包括 cond,也不包括平面 a)。

自版本 1.9 起弃用:对于 laplace_transform 使用 noconds=False(默认),返回一个元素为元组的矩阵的旧行为。SymPy 未来版本中,laplace_transform 在矩阵的行为将发生变化,以返回转换后的矩阵及其整体收敛条件的元组。使用 legacy_matrix=False 可启用新行为。

示例

>>> from sympy import DiracDelta, exp, laplace_transform
>>> from sympy.abc import t, s, a
>>> laplace_transform(t**4, t, s)
(24/s**5, 0, True)
>>> laplace_transform(t**a, t, s)
(gamma(a + 1)/(s*s**a), 0, re(a) > -1)
>>> laplace_transform(DiracDelta(t)-a*exp(-a*t), t, s, simplify=True)
(s/(a + s), -re(a), True) 

还有一些辅助函数可通过 Laplace 变换轻松解决微分方程。例如,要解决

[m x''(t) + d x'(t) + k x(t) = 0]

初始值为 ( 0 ),初始导数为 ( v ):

>>> from sympy import Function, laplace_correspondence, diff, solve
>>> from sympy import laplace_initial_conds, inverse_laplace_transform
>>> from sympy.abc import d, k, m, v
>>> x = Function('x')
>>> X = Function('X')
>>> f = m*diff(x(t), t, 2) + d*diff(x(t), t) + k*x(t)
>>> F = laplace_transform(f, t, s, noconds=True)
>>> F = laplace_correspondence(F, {x: X})
>>> F = laplace_initial_conds(F, t, {x: [0, v]})
>>> F
d*s*X(s) + k*X(s) + m*(s**2*X(s) - v)
>>> Xs = solve(F, X(s))[0]
>>> Xs
m*v/(d*s + k + m*s**2)
>>> inverse_laplace_transform(Xs, s, t)
2*v*exp(-d*t/(2*m))*sin(t*sqrt((-d**2 + 4*k*m)/m**2)/2)*Heaviside(t)/sqrt((-d**2 + 4*k*m)/m**2) 

也见

inverse_laplace_transformmellin_transformfourier_transformhankel_transforminverse_hankel_transform

参考资料

[R567]

埃尔德艾伊,A.(编),积分变换表,第 1 卷,贝特曼手稿项目,麦克格劳-希尔(1954),可用:resolver.caltech.edu/CaltechAUTHORS:20140123-101456353

sympy.integrals.transforms.laplace_correspondence(f, fdict, /)

此辅助函数接受一个函数 ( f ),该函数是 laplace_transforminverse_laplace_transform 的结果。它将所有未评估的 LaplaceTransform(y(t), t, s) 替换为任何 ( s ) 的 ( Y(s) ),并将所有 InverseLaplaceTransform(Y(s), s, t) 替换为任何 ( t ) 的 ( y(t) ),如果 fdict 包含对应关系 {y: Y}

参数:

f:SymPy 表达式

包含未评估的 LaplaceTransformLaplaceTransform 对象的表达式。

fdict:字典

包含一个或多个函数对应关系的字典,例如{x: X, y: Y},意味着XY分别是xy的拉普拉斯变换。

示例

>>> from sympy import laplace_transform, diff, Function
>>> from sympy import laplace_correspondence, inverse_laplace_transform
>>> from sympy.abc import t, s
>>> y = Function("y")
>>> Y = Function("Y")
>>> z = Function("z")
>>> Z = Function("Z")
>>> f = laplace_transform(diff(y(t), t, 1) + z(t), t, s, noconds=True)
>>> laplace_correspondence(f, {y: Y, z: Z})
s*Y(s) + Z(s) - y(0)
>>> f = inverse_laplace_transform(Y(s), s, t)
>>> laplace_correspondence(f, {y: Y})
y(t) 
sympy.integrals.transforms.laplace_initial_conds(f, t, fdict, /)

此辅助函数接受一个laplace_transform结果的函数(f)。它接受一个形如{y: [1, 4, 2]}的 fdict,其中列表中的值是函数(y(t))的初始值、初始斜率、初始二阶导数等,用以替换所有未评估的初始条件。

参数:

f:sympy 表达式

包含未评估函数的初始条件的表达式。

t:sympy 表达式

初始条件要应用的变量。

fdict:字典

包含每个函数初始条件列表的字典,例如{y: [0, 1, 2], x: [3, 4, 5]}。导数顺序升序,因此(0)、(1)、(2)分别是(y(0))、(y'(0))和(y''(0))。

示例

>>> from sympy import laplace_transform, diff, Function
>>> from sympy import laplace_correspondence, laplace_initial_conds
>>> from sympy.abc import t, s
>>> y = Function("y")
>>> Y = Function("Y")
>>> f = laplace_transform(diff(y(t), t, 3), t, s, noconds=True)
>>> g = laplace_correspondence(f, {y: Y})
>>> laplace_initial_conds(g, t, {y: [2, 4, 8, 16, 32]})
s**3*Y(s) - 2*s**2 - 4*s - 8 
class sympy.integrals.transforms.LaplaceTransform(*args)

表示未评估拉普拉斯变换的类。

有关此类用法,请参阅IntegralTransform的文档字符串。

如何计算拉普拉斯变换,请参阅laplace_transform()的文档字符串。

如果使用.doit()调用它,它将作为表达式返回拉普拉斯变换。如果使用.doit(noconds=False)调用它,则返回包含相同表达式、收敛平面和条件的元组。

doit(**hints)

尝试以闭合形式评估变换。

解释

标准提示如下:- noconds:如果为 True,则不返回收敛条件。默认设置为(True)。- simplify:如果为 True,则简化最终结果。默认设置为(False)。

sympy.integrals.transforms.inverse_laplace_transform(F, s, t, plane=None, **hints)

计算(F(s))的逆拉普拉斯变换,定义为

[f(t) = \frac{1}{2\pi i} \int_{c-i\infty}^{c+i\infty} e^{st} F(s) \mathrm{d}s,]

对于(c)足够大,以至于(F(s))在半平面(\operatorname{Re}(s) > c-\epsilon)内无奇点。

解释

可以通过参数plane指定平面,但如果作为 None 传递,则会推断。

在某些正则条件下,这从其拉普拉斯变换(F(s))中恢复(f(t)),对于非负的(t),反之亦然。

如果无法计算闭合形式的积分,则此函数返回一个未评估的InverseLaplaceTransform对象。

请注意,此函数始终假定(t)为实数,而不考虑(t)的 SymPy 假设。

有关可能提示的描述,请参阅sympy.integrals.transforms.IntegralTransform.doit()的文档字符串。

示例

>>> from sympy import inverse_laplace_transform, exp, Symbol
>>> from sympy.abc import s, t
>>> a = Symbol('a', positive=True)
>>> inverse_laplace_transform(exp(-a*s)/s, s, t)
Heaviside(-a + t) 

另请参阅

laplace_transform, hankel_transform, inverse_hankel_transform

class sympy.integrals.transforms.InverseLaplaceTransform(*args)

表示未评估的逆拉普拉斯变换的类。

要使用此类,请参阅IntegralTransform的文档字符串。

如何计算逆拉普拉斯变换,请参阅inverse_laplace_transform()的文档字符串。

doit(**hints)

尝试以闭合形式评估变换。

解释

标准提示如下:- noconds:如果为 True,则不返回收敛条件。默认设置为(True)。- simplify:如果为 True,则简化最终结果。默认设置为(False)。

sympy.integrals.transforms.fourier_transform(f, x, k, **hints)

计算f的单位、普通频率傅里叶变换,定义为

[F(k) = \int_{-\infty}^\infty f(x) e^{-2\pi i x k} \mathrm{d} x.]

解释

如果无法以闭合形式计算变换,则此函数返回一个未评估的FourierTransform对象。

对于其他傅里叶变换约定,请参阅函数sympy.integrals.transforms._fourier_transform()

要了解可能的提示说明,请参阅sympy.integrals.transforms.IntegralTransform.doit()的文档字符串。请注意,默认情况下,对于此变换,noconds=True

示例

>>> from sympy import fourier_transform, exp
>>> from sympy.abc import x, k
>>> fourier_transform(exp(-x**2), x, k)
sqrt(pi)*exp(-pi**2*k**2)
>>> fourier_transform(exp(-x**2), x, k, noconds=False)
(sqrt(pi)*exp(-pi**2*k**2), True) 

另请参阅

inverse_fourier_transform, sine_transform, inverse_sine_transform, cosine_transform, inverse_cosine_transform, hankel_transform, inverse_hankel_transform, mellin_transform, laplace_transform

sympy.integrals.transforms._fourier_transform(f, x, k, a, b, name, simplify=True)

计算一般的傅里叶类型变换

[F(k) = a \int_{-\infty}^{\infty} e^{bixk} f(x), dx.]

对于适当选择的ab,这将简化为标准的傅里叶和逆傅里叶变换。

class sympy.integrals.transforms.FourierTransform(*args)

表示未评估的傅里叶变换的类。

对于此类的使用,请参见IntegralTransform的文档字符串。

如何计算傅里叶变换,请参见fourier_transform()文档字符串。

sympy.integrals.transforms.inverse_fourier_transform(F, k, x, **hints)

计算单位、普通频率的逆傅里叶变换,定义为

[f(x) = \int_{-\infty}^\infty F(k) e^{2\pi i x k} \mathrm{d} k.]

解释

如果不能以封闭形式计算变换,则此函数返回一个未评估的InverseFourierTransform对象。

对于其他傅里叶变换约定,请参见函数sympy.integrals.transforms._fourier_transform()

获取可能提示的说明,请参阅sympy.integrals.transforms.IntegralTransform.doit()的文档字符串。请注意,默认情况下,对于此变换,noconds=True

示例

>>> from sympy import inverse_fourier_transform, exp, sqrt, pi
>>> from sympy.abc import x, k
>>> inverse_fourier_transform(sqrt(pi)*exp(-(pi*k)**2), k, x)
exp(-x**2)
>>> inverse_fourier_transform(sqrt(pi)*exp(-(pi*k)**2), k, x, noconds=False)
(exp(-x**2), True) 

另请参阅

fourier_transformsine_transforminverse_sine_transformcosine_transforminverse_cosine_transformhankel_transforminverse_hankel_transformmellin_transformlaplace_transform

class sympy.integrals.transforms.InverseFourierTransform(*args)

表示未求值逆傅里叶变换的类。

关于此类使用,请参阅IntegralTransform文档字符串。

对于如何计算逆傅里叶变换,请参阅inverse_fourier_transform()文档字符串。

sympy.integrals.transforms.sine_transform(f, x, k, **hints)

计算定义为(f)的单位、普通频率正弦变换,如下所示:

[F(k) = \sqrt{\frac{2}{\pi}} \int_{0}^\infty f(x) \sin(2\pi x k) \mathrm{d} x.]

解释

如果不能以封闭形式计算变换,则此函数返回一个未求值的SineTransform对象。

关于可能的提示描述,请参阅sympy.integrals.transforms.IntegralTransform.doit()文档字符串。注意,默认情况下对于此变换,noconds=True

示例

>>> from sympy import sine_transform, exp
>>> from sympy.abc import x, k, a
>>> sine_transform(x*exp(-a*x**2), x, k)
sqrt(2)*k*exp(-k**2/(4*a))/(4*a**(3/2))
>>> sine_transform(x**(-a), x, k)
2**(1/2 - a)*k**(a - 1)*gamma(1 - a/2)/gamma(a/2 + 1/2) 

另请参见

fourier_transform, inverse_fourier_transform, inverse_sine_transform, cosine_transform, inverse_cosine_transform, hankel_transform, inverse_hankel_transform, mellin_transform, laplace_transform

class sympy.integrals.transforms.SineTransform(*args)

表示未计算正弦变换的类。

对于此类的使用方法,请参阅IntegralTransform的文档字符串。

如何计算正弦变换,请参阅sine_transform()文档字符串。

sympy.integrals.transforms.inverse_sine_transform(F, k, x, **hints)

计算(F)的单位、普通频率逆正弦变换,定义为

[f(x) = \sqrt{\frac{2}{\pi}} \int_{0}^\infty F(k) \sin(2\pi x k) \mathrm{d} k.]

解释

如果无法以封闭形式计算变换,则此函数返回一个未计算的InverseSineTransform对象。

有关可能的提示说明,请参阅sympy.integrals.transforms.IntegralTransform.doit()的文档字符串。请注意,对于此变换,默认情况下noconds=True

示例

>>> from sympy import inverse_sine_transform, exp, sqrt, gamma
>>> from sympy.abc import x, k, a
>>> inverse_sine_transform(2**((1-2*a)/2)*k**(a - 1)*
...     gamma(-a/2 + 1)/gamma((a+1)/2), k, x)
x**(-a)
>>> inverse_sine_transform(sqrt(2)*k*exp(-k**2/(4*a))/(4*sqrt(a)**3), k, x)
x*exp(-a*x**2) 

另请参阅

fourier_transform, inverse_fourier_transform, sine_transform, cosine_transform, inverse_cosine_transform, hankel_transform, inverse_hankel_transform, mellin_transform, laplace_transform

class sympy.integrals.transforms.InverseSineTransform(*args)

表示未评估的反正弦变换的类。

要使用此类,请参阅IntegralTransform的文档字符串。

要了解如何计算反正弦变换,请参阅inverse_sine_transform()的文档字符串。

sympy.integrals.transforms.cosine_transform(f, x, k, **hints)

计算(f)的单位,普通频率余弦变换定义为

[F(k) = \sqrt{\frac{2}{\pi}} \int_{0}^\infty f(x) \cos(2\pi x k) \mathrm{d} x.]

解释

如果无法以封闭形式计算变换,则此函数返回未评估的CosineTransform对象。

获取可能的提示描述,请参阅sympy.integrals.transforms.IntegralTransform.doit()的文档字符串。注意,默认情况下,此变换使用noconds=True

示例

>>> from sympy import cosine_transform, exp, sqrt, cos
>>> from sympy.abc import x, k, a
>>> cosine_transform(exp(-a*x), x, k)
sqrt(2)*a/(sqrt(pi)*(a**2 + k**2))
>>> cosine_transform(exp(-a*sqrt(x))*cos(a*sqrt(x)), x, k)
a*exp(-a**2/(2*k))/(2*k**(3/2)) 

另请参阅

fourier_transform, inverse_fourier_transform, sine_transform, inverse_sine_transform, inverse_cosine_transform, hankel_transform, inverse_hankel_transform, mellin_transform, laplace_transform

class sympy.integrals.transforms.CosineTransform(*args)

表示未求值余弦变换的类。

若要使用此类,请参阅IntegralTransform的文档字符串。

如需计算余弦变换,请参阅cosine_transform()文档字符串。

sympy.integrals.transforms.inverse_cosine_transform(F, k, x, **hints)

计算(F)的单位、普通频率的反余弦变换,定义为

[f(x) = \sqrt{\frac{2}{\pi}} \int_{0}^\infty F(k) \cos(2\pi x k) \mathrm{d} k.]

解释

如果无法计算该变换的闭合形式,则此函数返回一个未求值的InverseCosineTransform对象。

如需可能的提示说明,请参阅sympy.integrals.transforms.IntegralTransform.doit()的文档字符串。请注意,默认情况下,对于此变换,noconds=True

示例

>>> from sympy import inverse_cosine_transform, sqrt, pi
>>> from sympy.abc import x, k, a
>>> inverse_cosine_transform(sqrt(2)*a/(sqrt(pi)*(a**2 + k**2)), k, x)
exp(-a*x)
>>> inverse_cosine_transform(1/sqrt(k), k, x)
1/sqrt(x) 

另请参阅

fourier_transform, inverse_fourier_transform, sine_transform, inverse_sine_transform, cosine_transform, hankel_transform, inverse_hankel_transform, mellin_transform, laplace_transform

class sympy.integrals.transforms.InverseCosineTransform(*args)

表示未评估的反余弦变换的类。

有关此类的用法,请参阅IntegralTransform文档字符串。

有关如何计算反余弦变换,请参阅inverse_cosine_transform()的文档字符串。

sympy.integrals.transforms.hankel_transform(f, r, k, nu, **hints)

计算定义为[f]的 Hankel 变换

[F_\nu(k) = \int_{0}^\infty f(r) J_\nu(k r) r \mathrm{d} r.]

解释

如果无法以闭合形式计算变换,则此函数返回一个未评估的HankelTransform对象。

有关可能提示的描述,请参阅sympy.integrals.transforms.IntegralTransform.doit()的文档字符串。请注意,默认情况下对于此变换,noconds=True

示例

>>> from sympy import hankel_transform, inverse_hankel_transform
>>> from sympy import exp
>>> from sympy.abc import r, k, m, nu, a 
>>> ht = hankel_transform(1/r**m, r, k, nu)
>>> ht
2*k**(m - 2)*gamma(-m/2 + nu/2 + 1)/(2**m*gamma(m/2 + nu/2)) 
>>> inverse_hankel_transform(ht, k, r, nu)
r**(-m) 
>>> ht = hankel_transform(exp(-a*r), r, k, 0)
>>> ht
a/(k**3*(a**2/k**2 + 1)**(3/2)) 
>>> inverse_hankel_transform(ht, k, r, 0)
exp(-a*r) 

另见

fourier_transforminverse_fourier_transformsine_transforminverse_sine_transformcosine_transforminverse_cosine_transforminverse_hankel_transformmellin_transformlaplace_transform

class sympy.integrals.transforms.HankelTransform(*args)

表示未计算的汉克尔变换的类。

关于该类的使用,请参阅IntegralTransform文档字符串。

如何计算汉克尔变换,请参阅hankel_transform()文档字符串。

sympy.integrals.transforms.inverse_hankel_transform(F, k, r, nu, **hints)

计算定义为(F)的逆汉克尔变换,如下所示:

[f(r) = \int_{0}^\infty F_\nu(k) J_\nu(k r) k \mathrm{d} k.]

说明

如果无法以封闭形式计算变换,则此函数返回一个未计算的InverseHankelTransform对象。

有关可能提示的描述,请参阅sympy.integrals.transforms.IntegralTransform.doit()文档字符串。请注意,默认情况下,对于此变换,noconds=True

示例

>>> from sympy import hankel_transform, inverse_hankel_transform
>>> from sympy import exp
>>> from sympy.abc import r, k, m, nu, a 
>>> ht = hankel_transform(1/r**m, r, k, nu)
>>> ht
2*k**(m - 2)*gamma(-m/2 + nu/2 + 1)/(2**m*gamma(m/2 + nu/2)) 
>>> inverse_hankel_transform(ht, k, r, nu)
r**(-m) 
>>> ht = hankel_transform(exp(-a*r), r, k, 0)
>>> ht
a/(k**3*(a**2/k**2 + 1)**(3/2)) 
>>> inverse_hankel_transform(ht, k, r, 0)
exp(-a*r) 

另请参阅

傅里叶变换逆傅里叶变换正弦变换逆正弦变换余弦变换逆余弦变换汉克尔变换梅林变换拉普拉斯变换

class sympy.integrals.transforms.InverseHankelTransform(*args)

表示未计算逆汉克尔变换的类。

如何使用此类,请参见 IntegralTransform 的文档字符串。

如何计算逆汉克尔变换,请参见 inverse_hankel_transform() 的文档字符串。

class sympy.integrals.transforms.IntegralTransform(*args)

积分变换的基类。

解释

此类表示未计算的变换。

要实现具体的变换,从这个类派生并实现 _compute_transform(f, x, s, **hints)_as_integral(f, x, s) 函数。如果无法计算变换,则抛出 IntegralTransformError

还要设置 cls._name。例如,

>>> from sympy import LaplaceTransform
>>> LaplaceTransform._name
'Laplace' 

如果您的函数返回的不仅仅是一个数,可能还有一个收敛条件,则实现 self._collapse_extra

doit(**hints)

尝试以封闭形式评估变换。

解释

此通用函数处理线性性,但除此之外几乎所有事情都留给 _compute_transform

标准提示如下:

  • simplify: 是否简化结果

  • noconds: 如果为 True,则不返回收敛条件

  • needeval: 如果为 True,则抛出 IntegralTransformError 而不是

    返回 IntegralTransform 对象

这些提示的默认值取决于具体的变换,默认情况下是 (simplify, noconds, needeval) = (True, False, False)

property function

要进行变换的函数。

property function_variable

要进行变换的函数的依赖变量。

property transform_variable

变换的独立变量。

exception sympy.integrals.transforms.IntegralTransformError(transform, function, msg)

与计算变换相关的异常。

解释

此类主要用于内部使用;如果无法计算积分,则通常返回表示未计算的变换对象。

提示 needeval=True 可用于禁用返回变换对象,并在无法计算积分时引发异常。

内部

SymPy 使用多种算法来计算积分。按顺序尝试这些算法,直到一个产生答案。大多数算法可以通过各种标志手动启用或禁用,使用 integrate()doit()

SymPy 首先应用几个启发式算法,因为它们是最快的:

  1. 如果函数是一个有理函数,有一个完整的算法用于集成有理函数,称为 Lazard-Rioboo-Trager 和 Horowitz-Ostrogradsky 算法。它们在 ratint() 中实现。

    sympy.integrals.rationaltools.ratint(f, x, **flags)
    

    执行有理函数的不定积分。

    解释

    给定域 (K) 和有理函数 (f = p/q),其中 (p) 和 (q) 是 (K[x]) 中的多项式,返回一个函数 (g),使得 (f = g')。

    例子

    >>> from sympy.integrals.rationaltools import ratint
    >>> from sympy.abc import x 
    
    >>> ratint(36/(x**5 - 2*x**4 - 2*x**3 + 4*x**2 + x - 2), x)
    (12*x + 6)/(x**2 - 1) + 4*log(x - 2) - 4*log(x + 1) 
    

    另见

    sympy.integrals.integrals.Integral.doitsympy.integrals.rationaltools.ratint_logpartsympy.integrals.rationaltools.ratint_ratpart

    参考文献

    [R568]

    M. Bronstein, Symbolic Integration I: Transcendental Functions, Second Edition, Springer-Verlag, 2005, pp. 35-70

    sympy.integrals.rationaltools.ratint_ratpart(f, g, x)
    

    Horowitz-Ostrogradsky 算法。

    解释

    给定域 K 和 K[x] 中的多项式 f 和 g,使得 f 和 g 互素且 deg(f) < deg(g),返回 K(x) 中的分数 A 和 B,使得 f/g = A’ + B,且 B 具有无平方分母。

    例子

    >>> from sympy.integrals.rationaltools import ratint_ratpart
    >>> from sympy.abc import x, y
    >>> from sympy import Poly
    >>> ratint_ratpart(Poly(1, x, domain='ZZ'),
    ... Poly(x + 1, x, domain='ZZ'), x)
    (0, 1/(x + 1))
    >>> ratint_ratpart(Poly(1, x, domain='EX'),
    ... Poly(x**2 + y**2, x, domain='EX'), x)
    (0, 1/(x**2 + y**2))
    >>> ratint_ratpart(Poly(36, x, domain='ZZ'),
    ... Poly(x**5 - 2*x**4 - 2*x**3 + 4*x**2 + x - 2, x, domain='ZZ'), x)
    ((12*x + 6)/(x**2 - 1), 12/(x**2 - x - 2)) 
    

    另见

    ratintratint_logpart

    sympy.integrals.rationaltools.ratint_logpart(f, g, x, t=None)
    

    Lazard-Rioboo-Trager 算法。

    解释

    给定域 K 和 K[x] 中的多项式 f 和 g,使得 f 和 g 互素,deg(f) < deg(g) 且 g 是无平方的,返回多项式的元组 (s_i, q_i),其中 i = 1..n,使得 s_i 在 K[t, x] 中,q_i 在 K[t] 中,并且:

     ___    ___
    d  f   d  \  `   \  `
    -- - = --  )      )   a log(s_i(a, x))
    dx g   dx /__,   /__,
             i=1..n a | q_i(a) = 0 
    

    例子

    >>> from sympy.integrals.rationaltools import ratint_logpart
    >>> from sympy.abc import x
    >>> from sympy import Poly
    >>> ratint_logpart(Poly(1, x, domain='ZZ'),
    ... Poly(x**2 + x + 1, x, domain='ZZ'), x)
    [(Poly(x + 3*_t/2 + 1/2, x, domain='QQ[_t]'),
    ...Poly(3*_t**2 + 1, _t, domain='ZZ'))]
    >>> ratint_logpart(Poly(12, x, domain='ZZ'),
    ... Poly(x**2 - x - 2, x, domain='ZZ'), x)
    [(Poly(x - 3*_t/8 - 1/2, x, domain='QQ[_t]'),
    ...Poly(-_t**2 + 16, _t, domain='ZZ'))] 
    

    另见

    ratintratint_ratpart

  2. trigintegrate() 使用模式匹配解决三角函数的积分

    sympy.integrals.trigonometry.trigintegrate(f, x, conds='piecewise')
    

    对于 x,集成 f = Mul(trig)。

    例子

    >>> from sympy import sin, cos, tan, sec
    >>> from sympy.integrals.trigonometry import trigintegrate
    >>> from sympy.abc import x 
    
    >>> trigintegrate(sin(x)*cos(x), x)
    sin(x)**2/2 
    
    >>> trigintegrate(sin(x)**2, x)
    x/2 - sin(x)*cos(x)/2 
    
    >>> trigintegrate(tan(x)*sec(x), x)
    1/cos(x) 
    
    >>> trigintegrate(sin(x)*tan(x), x)
    -log(sin(x) - 1)/2 + log(sin(x) + 1)/2 - sin(x) 
    

    另见

    sympy.integrals.integrals.Integral.doitsympy.integrals.integrals.Integral

    参考文献

    [R569]

    en.wikibooks.org/wiki/Calculus/Integration_techniques

  3. deltaintegrate() 解决带有DiracDelta对象的积分问题。

    sympy.integrals.deltafunctions.deltaintegrate(f, x)
    

    解释

    积分的思路如下:

    • 如果我们正在处理 DiracDelta 表达式,即 DiracDelta(g(x)),我们尝试简化它。

      如果我们能简化它,那么我们就积分得到的表达式。我们已经知道我们可以积分一个简化的表达式,因为只涉及简单的 DiracDelta 表达式。

      如果我们无法简化它,有两种情况:

      1. 表达式是一个简单的表达式:我们返回积分结果,注意我们是否在处理导数或适当的 DiracDelta。

      2. 表达式不简单(例如 DiracDelta(cos(x))):我们根本无法处理。

    • 如果节点是一个包含 DiracDelta 项的乘法节点:

      首先我们将其展开。

      如果展开成功,我们就尝试积分这个展开式。

      如果不行,我们尝试提取一个简单的 DiracDelta 项,然后有两种情况:

      1. 我们有一个简单的 DiracDelta 项,所以我们返回积分结果。

      2. 我们没有一个简单的项,但是我们有一个包含简化的 DiracDelta 项的表达式,所以我们积分这个表达式。

    示例

    >>> from sympy.abc import x, y, z
    >>> from sympy.integrals.deltafunctions import deltaintegrate
    >>> from sympy import sin, cos, DiracDelta
    >>> deltaintegrate(x*sin(x)*cos(x)*DiracDelta(x - 1), x)
    sin(1)*cos(1)*Heaviside(x - 1)
    >>> deltaintegrate(y**2*DiracDelta(x - z)*DiracDelta(y - z), y)
    z**2*DiracDelta(x - z)*Heaviside(y - z) 
    

    参见

    sympy.functions.special.delta_functions.DiracDeltasympy.integrals.integrals.Integral

  4. singularityintegrate() 适用于函数包含SingularityFunction实例时。

    sympy.integrals.singularityfunctions.singularityintegrate(f, x)
    

    此函数处理 Singularity 函数的不定积分。每当 SingularityFunction 的实例作为参数传递时,integrate函数内部都会调用此函数。

    解释

    积分的思路如下:

    • 如果我们正在处理 SingularityFunction 表达式,即SingularityFunction(x, a, n),如果n >= 0,我们只需返回SingularityFunction(x, a, n + 1)/(n + 1),如果n < 0,则返回SingularityFunction(x, a, n + 1)

    • 如果节点是具有 SingularityFunction 项的乘法或幂节点,我们将整个表达式重写为 Heaviside 和 DiracDelta 的术语,然后积分输出。最后,我们将积分输出重新写成 SingularityFunction 的术语。

    • 如果上述情况都不符合,我们返回 None。

    示例

    >>> from sympy.integrals.singularityfunctions import singularityintegrate
    >>> from sympy import SingularityFunction, symbols, Function
    >>> x, a, n, y = symbols('x a n y')
    >>> f = Function('f')
    >>> singularityintegrate(SingularityFunction(x, a, 3), x)
    SingularityFunction(x, a, 4)/4
    >>> singularityintegrate(5*SingularityFunction(x, 5, -2), x)
    5*SingularityFunction(x, 5, -1)
    >>> singularityintegrate(6*SingularityFunction(x, 5, -1), x)
    6*SingularityFunction(x, 5, 0)
    >>> singularityintegrate(x*SingularityFunction(x, 0, -1), x)
    0
    >>> singularityintegrate(SingularityFunction(x, 1, -1) * f(x), x)
    f(1)*SingularityFunction(x, 1, 0) 
    
  5. 如果启发式算法无法应用,接下来会尝试 risch_integrate()Risch 算法 是一种计算初等函数的反导数的通用方法。Risch 算法是一个决策过程,可以确定是否存在初等解,并在这种情况下计算它。它可以扩展到处理许多非初等函数,除了初等函数。但是,在 SymPy 中实现的版本仅支持完整算法的一小部分,特别是仅实现了对指数和对数的超越算法的部分。risch_integrate() 相比其他方法的一个优势是,如果返回 NonElementaryIntegral 的一个实例,算法证明该积分为非初等的,这意味着积分不能用指数、对数、三角函数、幂函数、有理函数、代数函数和函数组合的组合表示。

    sympy.integrals.risch.risch_integrate(f, x, extension=None, handle_first='log', separate_integral=False, rewrite_complex=None, conds='piecewise')
    

    Risch 积分算法。

    解释

    仅支持超越函数。目前仅支持指数和对数,但支持三角函数即将推出。

    如果此函数在结果中返回一个未评估的积分,意味着它已证明该积分为非初等的。任何错误将导致抛出 NotImplementedError。未评估的积分将是 NonElementaryIntegral 的一个实例,是 Integral 的一个子类。

    handle_first 可以是 'exp' 或者 'log'。这会改变扩展的顺序,并可能导致不同(但等效)的解决方案(例如,参见问题 5109)。也有可能只能用其中一种计算积分,因为并未完全实现所有情况。默认为 'log',这样外部扩展在可能时是指数的,因为更多的指数情况已经实现。

    如果 separate_integralTrue,则结果作为元组 (ans, i) 返回,其中积分为 ans + i,ans 是初等的,i 是 NonElementaryIntegral 或 0。如果希望使用其他算法进一步积分 NonElementaryIntegral 部分以可能获得特殊函数的解,则此选项很有用。默认为 False。

    示例

    >>> from sympy.integrals.risch import risch_integrate
    >>> from sympy import exp, log, pprint
    >>> from sympy.abc import x 
    

    首先,我们尝试积分 exp(-x**2)。除了 sqrt(pi) 的常数因子为 2,这是著名的误差函数。

    >>> pprint(risch_integrate(exp(-x**2), x))
     /
     |
     |    2
     |  -x
     | e    dx
     |
    / 
    

    结果中的未求值积分意味着 risch_integrate() 已经证明了 exp(-x**2) 没有基本的反导数。

    在许多情况下,risch_integrate() 可以将非基本反导数部分分离出来。例如,

    >>> pprint(risch_integrate((2*log(x)**2 - log(x) - x**2)/(log(x)**3 -
    ... x**2*log(x)), x))
     /
     |
     log(-x + log(x))   log(x + log(x))    |   1
    - ---------------- + --------------- +  | ------ dx
     2                  2           | log(x)
     |
     / 
    

    这意味着它已经证明了 1/log(x) 的积分是非基本的。这个函数也被称为对数积分,通常表示为 Li(x)。

    risch_integrate() 目前只接受纯超越函数,包括指数和对数,尽管请注意,这可能包括嵌套的指数和对数,以及底数不为 E 的指数。

    >>> pprint(risch_integrate(exp(x)*exp(exp(x)), x))
     / x\
     \e /
    e
    >>> pprint(risch_integrate(exp(exp(x)), x))
     /
     |
     |  / x\
     |  \e /
     | e     dx
     |
    / 
    
    >>> pprint(risch_integrate(x*x**x*log(x) + x**x + x*x**x, x))
     x
    x*x
    >>> pprint(risch_integrate(x**x, x))
     /
     |
     |  x
     | x  dx
     |
    / 
    
    >>> pprint(risch_integrate(-1/(x*log(x)*log(log(x))**2), x))
     1
    -----------
    log(log(x)) 
    
    class sympy.integrals.risch.NonElementaryIntegral(function, *symbols, **assumptions)
    

    表示一个非基本积分。

    解释

    如果 integrate() 的结果是这个类的实例,则保证是非基本的。请注意,默认情况下,integrate() 将尝试找到任何闭合形式的解,即使是在可能本身不是基本的特殊函数中。为了使 integrate() 只提供基本解,或者在可以证明积分是非基本的情况下,返回这个类的实例,请使用 integrate(risch=True)。在这种情况下,如果无法做出这样的判断,integrate() 可能会引发 NotImplementedError。

    integrate() 使用确定性 Risch 算法来对基本函数进行积分或证明它们没有基本积分。在某些情况下,该算法可以将积分分解为基本和非基本部分,因此 integrate 的结果将是基本表达式和非基本积分的和。

    示例

    >>> from sympy import integrate, exp, log, Integral
    >>> from sympy.abc import x 
    
    >>> a = integrate(exp(-x**2), x, risch=True)
    >>> print(a)
    Integral(exp(-x**2), x)
    >>> type(a)
    <class 'sympy.integrals.risch.NonElementaryIntegral'> 
    
    >>> expr = (2*log(x)**2 - log(x) - x**2)/(log(x)**3 - x**2*log(x))
    >>> b = integrate(expr, x, risch=True)
    >>> print(b)
    -log(-x + log(x))/2 + log(x + log(x))/2 + Integral(1/log(x), x)
    >>> type(b.atoms(Integral).pop())
    <class 'sympy.integrals.risch.NonElementaryIntegral'> 
    
  6. 对于非基本定积分,SymPy 使用所谓的 Meijer G 函数。详细信息请参见 使用 Meijer G 函数计算积分。

  7. 到目前为止提到的所有算法都是基于模式匹配的启发式算法,或者使用与大多数人在微积分课程中所学的方式大不相同的算法来求解积分。SymPy 还实现了一种可以像在微积分中一样求解积分的方法。这种方法的优势在于可以提取出积分步骤,以便可以看到如何手工计算积分。这由 SymPy Gamma 使用。这在 manualintegrate() 函数中实现。可以通过 integral_steps() 函数查看积分步骤。

    sympy.integrals.manualintegrate.manualintegrate(f, var)
    

    解释

    使用类似学生手工操作的算法计算单变量的不定积分。

    integrate() 不同,var 只能是单个符号。

    示例

    >>> from sympy import sin, cos, tan, exp, log, integrate
    >>> from sympy.integrals.manualintegrate import manualintegrate
    >>> from sympy.abc import x
    >>> manualintegrate(1 / x, x)
    log(x)
    >>> integrate(1/x)
    log(x)
    >>> manualintegrate(log(x), x)
    x*log(x) - x
    >>> integrate(log(x))
    x*log(x) - x
    >>> manualintegrate(exp(x) / (1 + exp(2 * x)), x)
    atan(exp(x))
    >>> integrate(exp(x) / (1 + exp(2 * x)))
    RootSum(4*_z**2 + 1, Lambda(_i, _i*log(2*_i + exp(x))))
    >>> manualintegrate(cos(x)**4 * sin(x), x)
    -cos(x)**5/5
    >>> integrate(cos(x)**4 * sin(x), x)
    -cos(x)**5/5
    >>> manualintegrate(cos(x)**4 * sin(x)**3, x)
    cos(x)**7/7 - cos(x)**5/5
    >>> integrate(cos(x)**4 * sin(x)**3, x)
    cos(x)**7/7 - cos(x)**5/5
    >>> manualintegrate(tan(x), x)
    -log(cos(x))
    >>> integrate(tan(x), x)
    -log(cos(x)) 
    

    另请参阅

    sympy.integrals.integrals.integrate, sympy.integrals.integrals.Integral.doit, sympy.integrals.integrals.Integral

    sympy.integrals.manualintegrate.integral_steps(integrand, symbol, **options)
    

    返回计算积分所需的步骤。

    返回:

    规则:规则

    第一步;大多数规则还有必须考虑的子步骤。这些子步骤可以使用manualintegrate来评估以获得结果。

    解释

    此函数尝试尽可能地模仿学生手工操作。

    SymPy Gamma 使用此方法提供积分的逐步解释。它用于格式化该函数结果的代码可以在github.com/sympy/sympy_gamma/blob/master/app/logic/intsteps.py找到。

    例子

    >>> from sympy import exp, sin
    >>> from sympy.integrals.manualintegrate import integral_steps
    >>> from sympy.abc import x
    >>> print(repr(integral_steps(exp(x) / (1 + exp(2 * x)), x)))     
    URule(integrand=exp(x)/(exp(2*x) + 1), variable=x, u_var=_u, u_func=exp(x),
    substep=ArctanRule(integrand=1/(_u**2 + 1), variable=_u, a=1, b=1, c=1))
    >>> print(repr(integral_steps(sin(x), x)))     
    SinRule(integrand=sin(x), variable=x)
    >>> print(repr(integral_steps((x**2 + 3)**2, x)))     
    RewriteRule(integrand=(x**2 + 3)**2, variable=x, rewritten=x**4 + 6*x**2 + 9,
    substep=AddRule(integrand=x**4 + 6*x**2 + 9, variable=x,
    substeps=[PowerRule(integrand=x**4, variable=x, base=x, exp=4),
    ConstantTimesRule(integrand=6*x**2, variable=x, constant=6, other=x**2,
    substep=PowerRule(integrand=x**2, variable=x, base=x, exp=2)),
    ConstantRule(integrand=9, variable=x)])) 
    
  8. 最后,如果上述所有方法都失败了,SymPy 还使用了 Risch-Norman 算法的简化版本。这个算法通常是计算速度最慢的,因此被最后尝试。它在heurisch()中实现:

    sympy.integrals.heurisch.heurisch(f, x, rewrite=False, hints=None, mappings=None, retries=3, degree_offset=0, unnecessary_permutations=None, _try_heurisch=None)
    

    使用启发式 Risch 算法计算不定积分。

    解释

    这是一种启发式方法,使用扩展的启发式(并行)Risch 算法在有限项中进行不定积分,基于 Manuel Bronstein 的“穷人积分器”。

    该算法支持各类函数,包括超越元素或特殊函数,如 Airy,Bessel,Whittaker 和 Lambert。

    注意,该算法不是一个决策过程。如果它无法计算给定函数的反导数,那么这并不证明这样的函数不存在。在这种情况下应使用递归的 Risch 算法。这个算法是否可以成为一个完全的决策过程尚未解决。

    这是一个内部积分器过程。在大多数情况下,您应该使用顶层的‘integrate’函数,因为此过程需要一些预处理步骤,否则可能失败。

    规格

    heurisch(f, x, rewrite=False, hints=None)

    其中

    f:表达式 x:符号

    重写 -> 强制使用‘tan’和‘tanh’重写‘f’提示 -> 可能出现在反导数中的函数列表

    • hints = None –> 没有建议
    • hints = [ ] –> 尝试解析
    • hints = [f1, …, fn] –> 我们更了解

    例子

    >>> from sympy import tan
    >>> from sympy.integrals.heurisch import heurisch
    >>> from sympy.abc import x, y 
    
    >>> heurisch(y*tan(x), x)
    y*log(tan(x)**2 + 1)/2 
    

    参见 Manuel Bronstein 的“穷人积分器”:

    参见

    sympy.integrals.integrals.Integral.doit, sympy.integrals.integrals.Integral, sympy.integrals.heurisch.components

    参考

    [R570]

    www-sop.inria.fr/cafe/Manuel.Bronstein/pmint/index.html

    有关已实现算法的更多信息,请参阅:

    [R571]

    K. Geddes, L. Stefanus, On the Risch-Norman Integration Method and its Implementation in Maple, Proceedings of ISSAC’89, ACM Press, 212-217.

    [R572]

    J. H. Davenport, On the Parallel Risch Algorithm (I), Proceedings of EUROCAM’82, LNCS 144, Springer, 144-157.

    [R573]

    J. H. Davenport, On the Parallel Risch Algorithm (III): Use of Tangents, SIGSAM Bulletin 16 (1982), 3-6.

    [R574]

    J. H. Davenport, B. M. Trager, On the Parallel Risch Algorithm (II), ACM Transactions on Mathematical Software 11 (1985), 356-362.

    sympy.integrals.heurisch.components(f, x)
    

    返回给定表达式的所有功能组件,包括符号、函数应用和组合,以及非整数幂。分数幂以最小的正指数收集。

    示例

    >>> from sympy import cos, sin
    >>> from sympy.abc import x
    >>> from sympy.integrals.heurisch import components 
    
    >>> components(sin(x)*cos(x)**2, x)
    {x, sin(x), cos(x)} 
    

    另请参阅

    heurisch

API 参考

sympy.integrals.integrals.integrate(f, var, ...)

自 1.6 版起已弃用:使用 Polyintegrate() 已弃用。请改用 Poly.integrate()。参见 使用 Poly 进行积分。

解释

使用 Risch-Norman 算法和表查找计算一个或多个变量的定积分或不定积分。此过程能处理基本代数和超越函数,以及包括 Airy、Bessel、Whittaker 和 Lambert 在内的大量特殊函数。

变量 var 可以是:

  • 一个符号 – 不定积分

  • 一个元组 (symbol, a) – 不定积分并返回结果

    a 替换 symbol 给出的

  • 一个元组 (symbol, a, b) – 定积分

可指定多个变量,此时结果为多重积分。(如果省略 var 并且被积函数是一元的,则将在该变量上进行不定积分。)

不定积分返回时,与积分变量无关的项将被省略。(见示例)

定积分不恰当时常需精确的收敛条件。分别传递 conds=’piecewise’、‘separate’ 或 ‘none’ 以得到以下返回:作为 Piecewise 函数、作为单独结果(即结果将是一个元组),或者不返回(默认为 ‘piecewise’)。

策略

SymPy 使用多种方法进行定积分。一种方法是找到被积函数的反导函数,然后应用基本定理。实现了多项式、有理函数、三角函数以及包含 DiracDelta 项的积分函数。

SymPy 还实现了 Risch 算法的部分,这是一个用于积分基本函数的决策过程,即,算法可以找到一个基本反导数,或者证明不存在这样的反导数。还有一个(非常成功但有些慢)启发式 Risch 算法的通用实现。随着更多完整的 Risch 算法的实现,这种算法最终将被淘汰。有关使用代数方法计算反导数的更多详细信息,请参阅 Integral._eval_integral() 的文档字符串。

可以通过选项 risch=True 来仅使用(完整的)Risch 算法。如果要知道一个基本函数是否有基本反导数,这是很有用的。如果这个函数返回的不定积分是 NonElementaryIntegral 的实例,那么 Risch 算法已经证明该积分是非基本的。请注意,默认情况下,对这些积分尝试了其他方法(如下面概述的 Meijer G 方法),因为它们可能可以用特殊函数表达,因此如果只关心基本答案,请使用 risch=True。还请注意,即使使用 risch=True,由这个函数返回的未计算积分也不一定是 NonElementaryIntegral,因为这可能只是表示该函数的积分所需的 Risch 算法的特定部分尚未实现。

另一族策略来自将被积函数重写为所谓的 Meijer G-函数。单个 G-函数的不定积分总是可以计算的,并且两个 G-函数乘积的定积分可以从零到无穷计算。实施了各种策略来将被积函数重写为 G-函数,并使用此信息来计算积分(请参阅 meijerint 模块)。

可以通过选项 manual=True 来仅使用尝试模仿手工积分的算法。这种算法处理的积分因子较少,但可能以更熟悉的形式返回结果。manualintegrate 模块具有返回使用的步骤的函数(更多信息请参阅模块文档字符串)。

一般来说,代数方法最适合计算(可能复杂的)基本函数组合的反导数。G-函数方法最适合计算从零到无穷的中度复杂的特殊函数组合的定积分,或者非常简单的特殊函数组合的不定积分。

积分代码使用的策略如下:

  • 如果计算一个定积分,并且两个限制值都是实数,并且至少一个限制值是 +- oo,请首先尝试 G-函数方法进行定积分。

  • 尝试找到一个反导数,使用所有可用的方法,按性能排序(即首先尝试最快的方法,最后尝试最慢的方法;特别是首先尝试多项式积分,其次尝试 Meijer G-函数,最后尝试启发式 Risch 算法)。

  • 如果仍然不成功,请尝试 G 函数,无论限制如何。

选项 meijerg=True, False, None 可分别用于:始终使用 G 函数方法且不使用其他方法,永不使用 G 函数方法,或使用所有可用方法(如上述顺序)。默认为 None。

示例

>>> from sympy import integrate, log, exp, oo
>>> from sympy.abc import a, x, y 
>>> integrate(x*y, x)
x**2*y/2 
>>> integrate(log(x), x)
x*log(x) - x 
>>> integrate(log(x), (x, 1, a))
a*log(a) - a + 1 
>>> integrate(x)
x**2/2 

与 x 无关的项被不定积分舍弃:

>>> from sympy import sqrt
>>> integrate(sqrt(1 + x), (x, 0, x))
2*(x + 1)**(3/2)/3 - 2/3
>>> integrate(sqrt(1 + x), x)
2*(x + 1)**(3/2)/3 
>>> integrate(x*y)
Traceback (most recent call last):
...
ValueError: specify integration variables to integrate x*y 

注意,integrate(x)语法仅用于交互式会话的方便,应在库代码中避免使用。

>>> integrate(x**a*exp(-x), (x, 0, oo)) # same as conds='piecewise'
Piecewise((gamma(a + 1), re(a) > -1),
 (Integral(x**a*exp(-x), (x, 0, oo)), True)) 
>>> integrate(x**a*exp(-x), (x, 0, oo), conds='none')
gamma(a + 1) 
>>> integrate(x**a*exp(-x), (x, 0, oo), conds='separate')
(gamma(a + 1), re(a) > -1) 

参见

Integral, Integral.doit

sympy.integrals.integrals.line_integrate(field, Curve, variables)

计算线积分。

示例

>>> from sympy import Curve, line_integrate, E, ln
>>> from sympy.abc import x, y, t
>>> C = Curve([E**t + 1, E**t - 1], (t, 0, ln(2)))
>>> line_integrate(x + y, C, [x, y])
3*sqrt(2) 

参见

sympy.integrals.integrals.integrate, Integral

Integral表示未评估的积分,并具有一些有助于表达式积分的方法。

class sympy.integrals.integrals.Integral(function, *symbols, **assumptions)

表示未评估的积分。

is_commutative

返回积分中所有自由符号是否可交换。

as_sum(n=None, method='midpoint', evaluate=True)

通过求和近似确定积分。

参数:

n :

使用的子区间数,可选。

method :

其中之一:'left', 'right', 'midpoint', 'trapezoid'。

evaluate : bool

如果为 False,则返回一个未评估的求和表达式。默认为 True,评估求和。

注意事项

这些近似积分方法在[1]中描述。

示例

>>> from sympy import Integral, sin, sqrt
>>> from sympy.abc import x, n
>>> e = Integral(sin(x), (x, 3, 7))
>>> e
Integral(sin(x), (x, 3, 7)) 

出于演示目的,此间隔仅将分为两个区域,由[3, 5]和[5, 7]界定。

左手法则使用每个区间左侧的函数评估:

>>> e.as_sum(2, 'left')
2*sin(5) + 2*sin(3) 

中点法则使用每个区间的中心进行评估:

>>> e.as_sum(2, 'midpoint')
2*sin(4) + 2*sin(6) 

右手法则使用每个区间右侧的函数评估:

>>> e.as_sum(2, 'right')
2*sin(5) + 2*sin(7) 

梯形法则使用区间两侧的函数评估。这相当于取左手法和右手法结果的平均值:

>>> s = e.as_sum(2, 'trapezoid')
>>> s
2*sin(5) + sin(3) + sin(7)
>>> (e.as_sum(2, 'left') + e.as_sum(2, 'right'))/2 == s
True 

在这里,通过使用中点或右手法可以避免在 x = 0 处的不连续:

>>> e = Integral(1/sqrt(x), (x, 0, 1))
>>> e.as_sum(5).n(4)
1.730
>>> e.as_sum(10).n(4)
1.809
>>> e.doit().n(4)  # the actual value is 2
2.000 

左手法或梯形法将遇到不连续并返回无穷大:

>>> e.as_sum(5, 'left')
zoo 

区间数可以是符号的。如果省略,将使用一个虚拟符号。

>>> e = Integral(x**2, (x, 0, 2))
>>> e.as_sum(n, 'right').expand()
8/3 + 4/n + 4/(3*n**2) 

这表明中点法则更精确,因为其误差项按 n 的平方衰减:

>>> e.as_sum(method='midpoint').expand()
8/3 - 2/(3*_n**2) 

当 evaluate=False 时返回一个符号求和:

>>> e.as_sum(n, 'midpoint', evaluate=False)
2*Sum((2*_k/n - 1/n)**2, (_k, 1, n))/n 

参见

Integral.doit

使用任何给定的提示执行积分

参考文献

[R575]

en.wikipedia.org/wiki/Riemann_sum#Riemann_summation_methods

doit(**hints)

使用任何给定的提示执行积分。

示例

>>> from sympy import Piecewise, S
>>> from sympy.abc import x, t
>>> p = x**2 + Piecewise((0, x/t < 0), (1, True))
>>> p.integrate((t, S(4)/5, 1), (x, -1, 1))
1/3 

参见

sympy.integrals.trigonometry.trigintegrate, sympy.integrals.heurisch.heurisch, sympy.integrals.rationaltools.ratint

as_sum

通过求和来近似积分

property free_symbols

如果要确定积分是否依赖于某个符号,则此方法返回积分计算时存在的符号。这在试图确定积分是否依赖于某个符号时非常有用。

示例

>>> from sympy import Integral
>>> from sympy.abc import x, y
>>> Integral(x, (x, y, 1)).free_symbols
{y} 

另见

sympy.concrete.expr_with_limits.ExprWithLimits.function, sympy.concrete.expr_with_limits.ExprWithLimits.limits, sympy.concrete.expr_with_limits.ExprWithLimits.variables

principal_value(**kwargs)

计算给定实轴上给定区间内实函数的柯西主值。

解释

在数学中,柯西主值是一种方法,用于为某些原本未定义的不定积分赋值。

示例

>>> from sympy import Integral, oo
>>> from sympy.abc import x
>>> Integral(x+1, (x, -oo, oo)).principal_value()
oo
>>> f = 1 / (x**3)
>>> Integral(f, (x, -oo, oo)).principal_value()
0
>>> Integral(f, (x, -10, 10)).principal_value()
0
>>> Integral(f, (x, -10, oo)).principal_value() + Integral(f, (x, -oo, 10)).principal_value()
0 

参考文献

[R576]

en.wikipedia.org/wiki/Cauchy_principal_value

[R577]

mathworld.wolfram.com/CauchyPrincipalValue.html

transform(x, u)

执行从 (x) 到 (u) 的变量变换,使用由 (x) 和 (u) 之间的关系给出的关系,定义变换 (f) 和 (F)(它们是互为逆函数)如下:

  1. 如果 (x) 是一个符号(即积分的变量),那么 (u) 将被解释为某个函数 (f(u)),其逆为 (F(u))。这实际上只是将 (x) 替换为 (f(x))。

  2. 如果 (u) 是一个符号,那么 (x) 将被解释为某个函数 (F(x)),其逆为 (f(u))。这通常被称为 u-替换。

一旦识别出 (f) 和 (F),变换如下进行:

[\int_a^b x \mathrm{d}x \rightarrow \int_{F(a)}^{F(b)} f(x) \frac{\mathrm{d}}{\mathrm{d}x}]

其中 (F(x)) 是 (f(x)) 的逆函数,积分的限制和被积函数已经校正,以保证积分后的值保持不变。

注记

映射函数 (F(x)) 或 (f(u)) 必须导致唯一的积分结果。线性或有理线性表达式,如 2*x1/xsqrt(x),始终有效;二次表达式如 x**2 - 1 也是可接受的,只要积分被积函数不依赖解的符号(见示例)。

如果x不是积分变量,则积分将保持不变。

x必须是(或包含)积分变量之一。如果u有多个自由符号,则应作为元组(u, uvar)发送,其中uvar标识替换积分变量的变量。XXX 它可以包含另一个积分变量吗?

示例

>>> from sympy.abc import a, x, u
>>> from sympy import Integral, cos, sqrt 
>>> i = Integral(x*cos(x**2 - 1), (x, 0, 1)) 

变换可以改变积分变量

>>> i.transform(x, u)
Integral(u*cos(u**2 - 1), (u, 0, 1)) 

变换可以执行 u-替换,只要获得唯一的被积函数:

>>> ui = i.transform(x**2 - 1, u)
>>> ui
Integral(cos(u)/2, (u, -1, 0)) 

此尝试失败,因为 x = +/-sqrt(u + 1),符号未从被积函数中取消:

>>> Integral(cos(x**2 - 1), (x, 0, 1)).transform(x**2 - 1, u)
Traceback (most recent call last):
...
ValueError:
The mapping between F(x) and f(u) did not give a unique integrand. 

变换可以进行替换。在这里,使用“u-替换”将先前的结果转换回原始表达式:

>>> ui.transform(sqrt(u + 1), x) == i
True 

我们可以通过常规替换来完成相同的操作:

>>> ui.transform(u, x**2 - 1) == i
True 

如果(x)不包含积分符号,则积分将保持不变。积分(i)没有积分变量(a),因此没有变化:

>>> i.transform(a, x) == i
True 

当(u)有多个自由符号时,替换(x)的符号必须通过传递(u)作为元组来标识:

>>> Integral(x, (x, 0, 1)).transform(x, (u + a, u))
Integral(a + u, (u, -a, 1 - a))
>>> Integral(x, (x, 0, 1)).transform(x, (u + a, a))
Integral(a + u, (a, -u, 1 - u)) 

参见

sympy.concrete.expr_with_limits.ExprWithLimits.variables

列出积分变量

as_dummy

用虚拟变量替换积分变量

Integral 继承自 ExprWithLimits,这是 IntegralSum 的常见超类。

class sympy.concrete.expr_with_limits.ExprWithLimits(function, *symbols, **assumptions)
property bound_symbols

只返回虚拟变量。

示例

>>> from sympy import Integral
>>> from sympy.abc import x, i, j, k
>>> Integral(x**i, (i, 1, 3), (j, 2), k).bound_symbols
[i, j] 

参见

functionlimitsfree_symbols

as_dummy

重命名虚拟变量

sympy.integrals.integrals.Integral.transform

对虚拟变量执行映射

property free_symbols

此方法返回对象中的符号,不包括那些取特定值的符号(即虚拟符号)。

示例

>>> from sympy import Sum
>>> from sympy.abc import x, y
>>> Sum(x, (x, y, 1)).free_symbols
{y} 
property function

返回应用于限制的函数。

示例

>>> from sympy import Integral
>>> from sympy.abc import x
>>> Integral(x**2, (x,)).function
x**2 

参见

limits, variables, free_symbols

property has_finite_limits

如果极限已知为有限,则返回 True,可以通过显式边界、边界假设或变量假设来确定。如果根据边界已知为无限,则返回 False。如果没有足够的信息来确定,则返回 None。

示例

>>> from sympy import Sum, Integral, Product, oo, Symbol
>>> x = Symbol('x')
>>> Sum(x, (x, 1, 8)).has_finite_limits
True 
>>> Integral(x, (x, 1, oo)).has_finite_limits
False 
>>> M = Symbol('M')
>>> Sum(x, (x, 1, M)).has_finite_limits 
>>> N = Symbol('N', integer=True)
>>> Product(x, (x, 1, N)).has_finite_limits
True 

另请参阅

has_reversed_limits

property has_reversed_limits

如果极限已知为反向顺序,则返回 True,可以通过显式边界、边界假设或变量假设来确定。如果根据边界已知为正常顺序,则返回 False。如果没有足够的信息来确定,则返回 None。

示例

>>> from sympy import Sum, Integral, Product, oo, Symbol
>>> x = Symbol('x')
>>> Sum(x, (x, 8, 1)).has_reversed_limits
True 
>>> Sum(x, (x, 1, oo)).has_reversed_limits
False 
>>> M = Symbol('M')
>>> Integral(x, (x, 1, M)).has_reversed_limits 
>>> N = Symbol('N', integer=True, positive=True)
>>> Sum(x, (x, 1, N)).has_reversed_limits
False 
>>> Product(x, (x, 2, N)).has_reversed_limits 
>>> Product(x, (x, 2, N)).subs(N, N + 2).has_reversed_limits
False 

另请参阅

sympy.concrete.expr_with_intlimits.ExprWithIntLimits.has_empty_sequence

property is_number

如果 Sum 没有自由符号,则返回 True,否则返回 False。

property limits

返回表达式的极限。

示例

>>> from sympy import Integral
>>> from sympy.abc import x, i
>>> Integral(x**i, (i, 1, 3)).limits
((i, 1, 3),) 

另请参阅

function, variables, free_symbols

property variables

返回极限变量的列表。

>>> from sympy import Sum
>>> from sympy.abc import x, i
>>> Sum(x**i, (i, 1, 3)).variables
[i] 

另请参阅

function, limits, free_symbols

as_dummy

重命名虚拟变量

sympy.integrals.integrals.Integral.transform

对虚拟变量执行映射

待办事项和错误

SymPy 仍然有许多函数不知道如何进行积分。有关此模块的错误,请参见github.com/sympy/sympy/issues?q=is%3Aissue+is%3Aopen+label%3Aintegrals

数值积分

SymPy 有函数来计算任何阶数和任何精度的高斯积分的点和权重:

sympy.integrals.quadrature.gauss_legendre(n, n_digits)

计算高斯-勒让德积分[R578]的点和权重。

参数:

n:

积分的秩序。

n_digits:

返回要返回的点和权重的有效数字。

返回:

(x, w)xw是点和权重的浮点数列表。

点(x_i)和权重(w_i)作为(x, w)列表的元组返回。

解释

高斯-勒让德积分逼近积分:

[\int_{-1}¹ f(x),dx \approx \sum_{i=1}^n w_i f(x_i)]

一个秩为(n)的积分规则的节点(x_i)是(P_n)的根,权重(w_i)由以下给出:

[w_i = \frac{2}{\left(1-x_i²\right) \left(P'_n(x_i)\right)²}]

例子

>>> from sympy.integrals.quadrature import gauss_legendre
>>> x, w = gauss_legendre(3, 5)
>>> x
[-0.7746, 0, 0.7746]
>>> w
[0.55556, 0.88889, 0.55556]
>>> x, w = gauss_legendre(4, 5)
>>> x
[-0.86114, -0.33998, 0.33998, 0.86114]
>>> w
[0.34785, 0.65215, 0.65215, 0.34785] 

另见

gauss_laguerre, gauss_gen_laguerre, gauss_hermite, gauss_chebyshev_t, gauss_chebyshev_u, gauss_jacobi, gauss_lobatto

参考文献

[R578] (1,2)

en.wikipedia.org/wiki/Gaussian_quadrature

[R579]

people.sc.fsu.edu/~jburkardt/cpp_src/legendre_rule/legendre_rule.html

sympy.integrals.quadrature.gauss_laguerre(n, n_digits)

计算高斯-拉盖尔积分[R580]的点和权重。

参数:

n:

积分的秩序。

n_digits:

返回要返回的点和权重的有效数字。

返回:

(x, w)xw是点和权重的浮点数列表。

点(x_i)和权重(w_i)作为(x, w)列表的元组返回。

解释

高斯-拉盖尔积分逼近积分:

[\int_0^{\infty} e^{-x} f(x),dx \approx \sum_{i=1}^n w_i f(x_i)]

一个秩为(n)的积分规则的节点(x_i)是(L_n)的根,权重(w_i)由以下给出:

[w_i = \frac{x_i}{(n+1)² \left(L_{n+1}(x_i)\right)²}]

例子

>>> from sympy.integrals.quadrature import gauss_laguerre
>>> x, w = gauss_laguerre(3, 5)
>>> x
[0.41577, 2.2943, 6.2899]
>>> w
[0.71109, 0.27852, 0.010389]
>>> x, w = gauss_laguerre(6, 5)
>>> x
[0.22285, 1.1889, 2.9927, 5.7751, 9.8375, 15.983]
>>> w
[0.45896, 0.417, 0.11337, 0.010399, 0.00026102, 8.9855e-7] 

另见

gauss_legendre, gauss_gen_laguerre, gauss_hermite, gauss_chebyshev_t, gauss_chebyshev_u, gauss_jacobi, gauss_lobatto

参考文献

[R580] (1,2)

en.wikipedia.org/wiki/Gauss%E2%80%93Laguerre_quadrature

[R581]

people.sc.fsu.edu/~jburkardt/cpp_src/laguerre_rule/laguerre_rule.html

sympy.integrals.quadrature.gauss_hermite(n, n_digits)

计算 Gauss-Hermite 积分 [R582] 的节点和权重。

参数:

n:

积分的顺序。

n_digits:

返回的节点和权重的有效数字位数。

返回:

(x, w)xw 是浮点数列表。

节点 (x_i) 和权重 (w_i) 返回为 (x, w) 列表的元组。

解释

Gauss-Hermite 积分近似于积分:

[\int_{-\infty}^{\infty} e^{-x²} f(x),dx \approx \sum_{i=1}^n w_i f(x_i)]

秩为 (n) 的积分规则的节点 (x_i) 是 (H_n) 的根,权重 (w_i) 如下所示:

[w_i = \frac{2^{n-1} n! \sqrt{\pi}}{n² \left(H_{n-1}(x_i)\right)²}]

示例

>>> from sympy.integrals.quadrature import gauss_hermite
>>> x, w = gauss_hermite(3, 5)
>>> x
[-1.2247, 0, 1.2247]
>>> w
[0.29541, 1.1816, 0.29541] 
>>> x, w = gauss_hermite(6, 5)
>>> x
[-2.3506, -1.3358, -0.43608, 0.43608, 1.3358, 2.3506]
>>> w
[0.00453, 0.15707, 0.72463, 0.72463, 0.15707, 0.00453] 

参见

gauss_legendre, gauss_laguerre, gauss_gen_laguerre, gauss_chebyshev_t, gauss_chebyshev_u, gauss_jacobi, gauss_lobatto

参考文献

[R582] (1,2)

en.wikipedia.org/wiki/Gauss-Hermite_Quadrature

[R583]

people.sc.fsu.edu/~jburkardt/cpp_src/hermite_rule/hermite_rule.html

[R584]

people.sc.fsu.edu/~jburkardt/cpp_src/gen_hermite_rule/gen_hermite_rule.html

sympy.integrals.quadrature.gauss_gen_laguerre(n, alpha, n_digits)

计算广义 Gauss-Laguerre 积分 [R585] 的点和权重。

参数:

n :

积分的顺序。

alpha :

奇异性的指数,(\alpha > -1)。

n_digits :

要返回点和权重的显著数字的数量。

返回:

(x, w) : xw 是点和权重的列表,类型为 Float。

点 (x_i) 和权重 (w_i) 以 (x, w) 的列表形式返回。

解释

广义 Gauss-Laguerre 积分近似于:

[\int_{0}^\infty x^{\alpha} e^{-x} f(x),dx \approx \sum_{i=1}^n w_i f(x_i)]

秩为 (n) 的积分规则的节点 (x_i) 是 (L^{\alpha}_n) 的根,权重 (w_i) 由以下给出:

[w_i = \frac{\Gamma(\alpha+n)} {n \Gamma(n) L^{\alpha}{n-1}(x_i) L^{\alpha+1}(x_i)}]

示例

>>> from sympy import S
>>> from sympy.integrals.quadrature import gauss_gen_laguerre
>>> x, w = gauss_gen_laguerre(3, -S.Half, 5)
>>> x
[0.19016, 1.7845, 5.5253]
>>> w
[1.4493, 0.31413, 0.00906] 
>>> x, w = gauss_gen_laguerre(4, 3*S.Half, 5)
>>> x
[0.97851, 2.9904, 6.3193, 11.712]
>>> w
[0.53087, 0.67721, 0.11895, 0.0023152] 

见也

gauss_legendre, gauss_laguerre, gauss_hermite, gauss_chebyshev_t, gauss_chebyshev_u, gauss_jacobi, gauss_lobatto

参考文献

[R585] (1,2)

en.wikipedia.org/wiki/Gauss%E2%80%93Laguerre_quadrature

[R586]

people.sc.fsu.edu/~jburkardt/cpp_src/gen_laguerre_rule/gen_laguerre_rule.html

sympy.integrals.quadrature.gauss_chebyshev_t(n, n_digits)

计算第一类 Gauss-Chebyshev 积分 [R587] 的点和权重。

参数:

n :

积分的顺序。

n_digits :

要返回点和权重的显著数字的数量。

返回:

(x, w) : xw 是点和权重的列表,类型为 Float。

点 (x_i) 和权重 (w_i) 以 (x, w) 的列表形式返回。

解释

第一类 Gauss-Chebyshev 积分近似于:

[\int_{-1}^{1} \frac{1}{\sqrt{1-x²}} f(x),dx \approx \sum_{i=1}^n w_i f(x_i)]

秩为 (n) 的积分规则的节点 (x_i) 是 (T_n) 的根,权重 (w_i) 由以下给出:

[w_i = \frac{\pi}{n}]

示例

>>> from sympy.integrals.quadrature import gauss_chebyshev_t
>>> x, w = gauss_chebyshev_t(3, 5)
>>> x
[0.86602, 0, -0.86602]
>>> w
[1.0472, 1.0472, 1.0472] 
>>> x, w = gauss_chebyshev_t(6, 5)
>>> x
[0.96593, 0.70711, 0.25882, -0.25882, -0.70711, -0.96593]
>>> w
[0.5236, 0.5236, 0.5236, 0.5236, 0.5236, 0.5236] 

见也

gauss_legendre, gauss_laguerre, gauss_hermite, gauss_gen_laguerre, gauss_chebyshev_u, gauss_jacobi, gauss_lobatto

参考文献

[R587] (1,2]

zh.wikipedia.org/wiki/切比雪夫-高斯求积

[R588]

people.sc.fsu.edu/~jburkardt/cpp_src/chebyshev1_rule/chebyshev1_rule.html

sympy.integrals.quadrature.gauss_chebyshev_u(n, n_digits)

计算第二类 Gauss-Chebyshev 求积 [R589] 的点和权重。

参数:

n : 求积的阶数

n_digits : 点和权重的有效数字位数

返回:

(x, w) : xw 分别是浮点数列表。

返回 (x, w) 的元组,包含点 x_i 和权重 w_i 的列表。

解释

第二类 Gauss-Chebyshev 求积近似于积分:

[\int_{-1}^{1} \sqrt{1-x²} f(x),dx \approx \sum_{i=1}^n w_i f(x_i)]

一个阶数为 (n) 的求积规则的节点 (x_i) 是 (U_n) 的根,权重 (w_i) 由以下给出:

[w_i = \frac{\pi}{n+1} \sin² \left(\frac{i}{n+1}\pi\right)]

示例

>>> from sympy.integrals.quadrature import gauss_chebyshev_u
>>> x, w = gauss_chebyshev_u(3, 5)
>>> x
[0.70711, 0, -0.70711]
>>> w
[0.3927, 0.7854, 0.3927] 
>>> x, w = gauss_chebyshev_u(6, 5)
>>> x
[0.90097, 0.62349, 0.22252, -0.22252, -0.62349, -0.90097]
>>> w
[0.084489, 0.27433, 0.42658, 0.42658, 0.27433, 0.084489] 

另请参阅

gauss_legendre, gauss_laguerre, gauss_hermite, gauss_gen_laguerre, gauss_chebyshev_t, gauss_jacobi, gauss_lobatto

参考文献

[R589] (1,2)

zh.wikipedia.org/wiki/切比雪夫-高斯求积

[R590]

people.sc.fsu.edu/~jburkardt/cpp_src/chebyshev2_rule/chebyshev2_rule.html

sympy.integrals.quadrature.gauss_jacobi(n, alpha, beta, n_digits)

计算高斯-雅各比数值积分 [R591] 的点和权重。

参数:

n : 数值积分的阶数

alpha : Jacobian 多项式的第一个参数,(\alpha > -1)

beta : Jacobian 多项式的第二个参数,(\beta > -1)

n_digits : 返回的点和权重的有效数字数

返回:

(x, w) : xw 分别为点和权重的浮点数列表。

返回为 (x, w) 列表元组的点 (x_i) 和权重 (w_i)。

解释

第一类高斯-雅各比数值积分近似计算积分:

[\int_{-1}¹ (1-x)^\alpha (1+x)^\beta f(x),dx \approx \sum_{i=1}^n w_i f(x_i)]

节点 (x_i) 是一个阶 (n) 的数值积分规则的多项式 (P^{(\alpha,\beta)}_n) 的根,权重 (w_i) 给定为:

[w_i = -\frac{2n+\alpha+\beta+2}{n+\alpha+\beta+1} \frac{\Gamma(n+\alpha+1)\Gamma(n+\beta+1)} {\Gamma(n+\alpha+\beta+1)(n+1)!} \frac{2^{\alpha+\beta}}{P'n(x_i) P^{(\alpha,\beta)}(x_i)}]

示例

>>> from sympy import S
>>> from sympy.integrals.quadrature import gauss_jacobi
>>> x, w = gauss_jacobi(3, S.Half, -S.Half, 5)
>>> x
[-0.90097, -0.22252, 0.62349]
>>> w
[1.7063, 1.0973, 0.33795] 
>>> x, w = gauss_jacobi(6, 1, 1, 5)
>>> x
[-0.87174, -0.5917, -0.2093, 0.2093, 0.5917, 0.87174]
>>> w
[0.050584, 0.22169, 0.39439, 0.39439, 0.22169, 0.050584] 

另见

gauss_legendre, gauss_laguerre, gauss_hermite, gauss_gen_laguerre, gauss_chebyshev_t, gauss_chebyshev_u, gauss_lobatto

参考文献

[R591] (1,2)

en.wikipedia.org/wiki/Gauss%E2%80%93Jacobi_quadrature

[R592]

people.sc.fsu.edu/~jburkardt/cpp_src/jacobi_rule/jacobi_rule.html

[R593]

people.sc.fsu.edu/~jburkardt/cpp_src/gegenbauer_rule/gegenbauer_rule.html

sympy.integrals.quadrature.gauss_lobatto(n, n_digits)

计算高斯-洛巴托数值积分 [R594] 的点和权重。

参数:

n : 数值积分的阶数

n_digits : 返回的点和权重的有效数字数

返回:

(x, w) : xw 分别为点和权重的浮点数列表。

返回为 (x, w) 列表元组的点 (x_i) 和权重 (w_i)。

解释

高斯-洛巴托数值积分近似计算积分:

[\int_{-1}¹ f(x),dx \approx \sum_{i=1}^n w_i f(x_i)]

节点 (x_i) 是一个阶 (n) 的数值积分规则的多项式 (P'_(n-1)) 的根,权重 (w_i) 给定为:

[\begin{split}&w_i = \frac{2}{n(n-1) \left[P_{n-1}(x_i)\right]²},\quad x\neq\pm 1\ &w_i = \frac{2}{n(n-1)},\quad x=\pm 1\end{split}]

示例

>>> from sympy.integrals.quadrature import gauss_lobatto
>>> x, w = gauss_lobatto(3, 5)
>>> x
[-1, 0, 1]
>>> w
[0.33333, 1.3333, 0.33333]
>>> x, w = gauss_lobatto(4, 5)
>>> x
[-1, -0.44721, 0.44721, 1]
>>> w
[0.16667, 0.83333, 0.83333, 0.16667] 

参见

gauss_legendre, gauss_laguerre, gauss_gen_laguerre, gauss_hermite, gauss_chebyshev_t, gauss_chebyshev_u, gauss_jacobi

参考文献

[R594] (1,2)

zh.wikipedia.org/wiki/高斯求积#高斯-洛巴托规则

[R595]

web.archive.org/web/20200118141346/http://people.math.sfu.ca/~cbm/aands/page_888.htm

多面体积分

SymPy 中的intpoly模块实现了计算多面体上多项式积分的方法。使用了 Chin 等人(2015 年)[1] 中描述的评估技术。

二维多边形或多边形的输入使用了 SymPy 中已有的 Polygon 数据结构。参见 sympy.geometry.polygon 如何创建多边形。

对于三维多面体或多胞形,最经济的表示方法是指定顶点列表,并将每个组成面(多边形)表示为顶点索引列表。

例如,考虑单位立方体。其表示方法如下。

unit_cube = [[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0),(1, 0, 1), (1, 1, 0), (1, 1, 1)],

[3, 7, 6, 2], [1, 5, 7, 3], [5, 4, 6, 7], [0, 4, 5, 1], [2, 0, 1, 3], [2, 6, 4, 0]]

这里,第一个子列表是顶点列表。其他小列表如[3, 7, 6, 2]表示多面体的二维面,其顶点在第一个子列表中的索引为3, 7, 6, 2(按顺序)。

本模块中的主要方法是 polytope_integrate()

  • polytope_integrate(Polygon((0, 0), (0, 1), (1, 0)), x) 返回三角形(顶点为 (0, 0), (0, 1), (1, 0))上 (x) 的积分。
  • polytope_integrate(unit_cube, x + y + z) 返回单位立方体上 (x + y + z) 的积分。

参考文献

[1]:Chin, Eric B., Jean B. Lasserre 和 N. Sukumar。《计算力学》56.6(2015):967-981。

PDF 链接:dilbert.engr.ucdavis.edu/~suku/quadrature/cls-integration.pdf

示例

对于 2D 多边形

单一多项式:

>>> from sympy.integrals.intpoly import *
>>> init_printing(use_unicode=False)
>>> polytope_integrate(Polygon((0, 0), (0, 1), (1, 0)), x)
1/6
>>> polytope_integrate(Polygon((0, 0), (0, 1), (1, 0)), x + x*y + y**2)
7/24 

指定多项式列表:

>>> polytope_integrate(Polygon((0, 0), (0, 1), (1, 0)), [3, x*y + y**2, x**4], max_degree=4)
 4               2
{3: 3/2, x : 1/30, x*y + y : 1/8}
>>> polytope_integrate(Polygon((0, 0), (0, 1), (1, 0)), [1.125, x, x**2, 6.89*x**3, x*y + y**2, x**4], max_degree=4)
 2              3  689    4               2
{1.125: 9/16, x: 1/6, x : 1/12, 6.89*x : ----, x : 1/30, x*y + y : 1/8}
 2000 

计算所有单项式,直至最大次数:

>>> polytope_integrate(Polygon((0, 0), (0, 1), (1, 0)),max_degree=3)
 2         3                 2         3                      2         2
{0: 0, 1: 1/2, x: 1/6, x : 1/12, x : 1/20, y: 1/6, y : 1/12, y : 1/20, x*y: 1/24, x*y : 1/60, x *y: 1/60} 

对于 3-多胞体/多面体

单一多项式:

>>> from sympy.integrals.intpoly import *
>>> cube = [[(0, 0, 0), (0, 0, 5), (0, 5, 0), (0, 5, 5), (5, 0, 0), (5, 0, 5), (5, 5, 0), (5, 5, 5)], [2, 6, 7, 3], [3, 7, 5, 1], [7, 6, 4, 5], [1, 5, 4, 0], [3, 1, 0, 2], [0, 4, 6, 2]]
>>> polytope_integrate(cube, x**2 + y**2 + z**2 + x*y + y*z + x*z)
-21875/4
>>> octahedron = [[(S(-1) / sqrt(2), 0, 0), (0, S(1) / sqrt(2), 0), (0, 0, S(-1) / sqrt(2)), (0, 0, S(1) / sqrt(2)), (0, S(-1) / sqrt(2), 0), (S(1) / sqrt(2), 0, 0)], [3, 4, 5], [3, 5, 1], [3, 1, 0], [3, 0, 4], [4, 0, 2], [4, 2, 5], [2, 0, 1], [5, 2, 1]]
>>> polytope_integrate(octahedron, x**2 + y**2 + z**2 + x*y + y*z + x*z)
 ___
\/ 2
-----
 20 

指定多项式列表:

>>> polytope_integrate(Polygon((0, 0), (0, 1), (1, 0)), [3, x*y + y**2, x**4], max_degree=4)
 4               2
{3: 3/2, x : 1/30, x*y + y : 1/8}
>>> polytope_integrate(Polygon((0, 0), (0, 1), (1, 0)), [1.125, x, x**2, 6.89*x**3, x*y + y**2, x**4], max_degree=4)
 2              3  689    4               2
{1.125: 9/16, x: 1/6, x : 1/12, 6.89*x : ----, x : 1/30, x*y + y : 1/8}
 2000 

计算所有单项式,直至最大次数:

>>> polytope_integrate(Polygon((0, 0), (0, 1), (1, 0)),max_degree=3)
 2         3                 2         3                      2         2
{0: 0, 1: 1/2, x: 1/6, x : 1/12, x : 1/20, y: 1/6, y : 1/12, y : 1/20, x*y: 1/24, x*y : 1/60, x *y: 1/60} 

API 参考

sympy.integrals.intpoly.polytope_integrate(poly, expr=None, *, clockwise=False, max_degree=None)

在 2/3-多胞体上进行多项式积分。

参数:

poly:输入的多边形。

expr:输入的多项式。

clockwise:对 2-多面体输入点按顺时针排序的二进制值(可选)。

max_degree:输入多项式的任何单项式的最大次数(可选)。

解释

此函数接受poly中的多胞体和expr中的函数(实现了单/双/三变量多项式),并返回exprpoly上的精确积分。

示例

>>> from sympy.abc import x, y
>>> from sympy import Point, Polygon
>>> from sympy.integrals.intpoly import polytope_integrate
>>> polygon = Polygon(Point(0, 0), Point(0, 1), Point(1, 1), Point(1, 0))
>>> polys = [1, x, y, x*y, x**2*y, x*y**2]
>>> expr = x*y
>>> polytope_integrate(polygon, expr)
1/4
>>> polytope_integrate(polygon, polys, max_degree=3)
{1: 1, x: 1/2, y: 1/2, x*y: 1/4, x*y**2: 1/6, x**2*y: 1/6} 

级数

原文:docs.sympy.org/latest/modules/series/index.html

该系列模块将级数展开实现为一个函数,并实现了许多相关函数。

目录

  • 级数展开

  • 序列

  • 傅立叶级数

  • 形式幂级数

  • 序列的极限

级数展开

原文:docs.sympy.org/latest/modules/series/series.html

极限

本模块的主要目的是计算极限。

sympy.series.limits.limit(e, z, z0, dir='+')

计算在点z0处的e(z)的极限。

参数:

e : 表达式,要计算其极限

z : 表示极限中的变量的符号。

其他符号被视为常数。不支持多变量极限。

z0 : z趋向的值。可以是任何表达式,

包括oo-oo

dir : 字符串,可选(默认为“+”)

如果dir="+-",则极限是双向的,如果dir="+",则从右侧(z->z0+);如果dir="-",则从左侧(z->z0-)。对于无限的z0oo-oo),dir参数由无限方向确定(即对于oodir="-")。

示例

>>> from sympy import limit, sin, oo
>>> from sympy.abc import x
>>> limit(sin(x)/x, x, 0)
1
>>> limit(1/x, x, 0) # default dir='+'
oo
>>> limit(1/x, x, 0, dir="-")
-oo
>>> limit(1/x, x, 0, dir='+-')
zoo
>>> limit(1/x, x, oo)
0 

注意

首先我们尝试一些启发式方法处理像“x”,“1/x”,“x**2”和类似的简单和频繁的情况,以便处理速度更快。对于所有其他情况,我们使用 Gruntz 算法(请参阅 gruntz()函数)。

另请参见

limit_seq

返回序列的极限。

class sympy.series.limits.Limit(e, z, z0, dir='+')

表示一个未评估的极限。

示例

>>> from sympy import Limit, sin
>>> from sympy.abc import x
>>> Limit(sin(x)/x, x, 0)
Limit(sin(x)/x, x, 0, dir='+')
>>> Limit(1/x, x, 0, dir="-")
Limit(1/x, x, 0, dir='-') 
doit(**hints)

评估极限。

参数:

deep : bool, optional (default: True)

在进行极限之前调用涉及的表达式的doit方法。

hints : optional keyword arguments

被传递给doit方法;仅在 deep 为 True 时使用。

如上所述,极限计算的主要工具是 gruntz()函数,它实现了 Gruntz 算法来计算极限。

Gruntz 算法

本节介绍了用于计算极限的算法基础。大多数情况下,limit()函数应该正常工作。但是,记住它的实现方式仍然很有用,以防某些情况出乎意料。

首先我们定义函数的一个排序。假设(f(x))和(g(x))是两个实值函数,使得(\lim_{x \to \infty} f(x) = \infty)和同样(\lim_{x \to \infty} g(x) = \infty)。我们将说(f(x)) 支配 (g(x)),写作(f(x) \succ g(x)),如果对于所有(a, b \in \mathbb{R}{>0}),我们有(\lim \frac{f(x)a}{g(x)b} = \infty)。我们还说(f(x))和(g(x)) 具有相同的可比性类,如果既不是(f(x) \succ g(x))也不是(g(x) \succ f(x)),并将其表示为(f(x) \asymp g(x))。

注意,无论何时(a, b \in \mathbb{R}_{>0}),则(a f(x)^b \asymp f(x)),我们将使用此来扩展对所有函数的定义,它们随着(x \to \infty)趋向于(0)或(\pm \infty)。因此,我们声明(f(x) \asymp 1/f(x))和(f(x) \asymp -f(x))。

可以轻松展示以下示例:

  • (e^x \succ x^m)

  • (e^{x²} \succ e^{mx})

  • (e{ex} \succ e{xm})

  • (x^m \asymp x^n)

  • (e^{x + \frac{1}{x}} \asymp e^{x + \log{x}} \asymp e^x)。

根据上述定义,可以证明以下属性:

假设(\omega),(g_1, g_2, \ldots)是(x)的函数,(\lim_{x \to \infty} \omega = 0),并且对于所有(i),(\omega \succ g_i)。让(c_1, c_2, \ldots \in \mathbb{R}),其中(c_1 < c_2 < \cdots)。

然后(\lim_{x \to \infty} \sum_i g_i \omega^{c_i} = \lim_{x \to \infty} g_1 \omega^{c_1})。

对于(g_1 = g)和如上所述的(\omega),我们还有以下简单的结果:

  • 对于(c > 0),(\lim_{x \to \infty} g \omega^c = 0)
  • 对于(c < 0),当(g)的符号(最终)确定时,(\lim_{x \to \infty} g \omega^c = \pm \infty),其中符号由(g)的符号确定。
  • (\lim_{x \to \infty} g \omega⁰ = \lim_{x \to \infty} g).

使用这些结果产生了计算(\lim_{x \to \infty} f(x))的以下策略:

  1. 找到最快变化子表达式(MRV 集合)的集合(f(x))。也就是说,从(f(x))的所有子表达式集合中,找到在关系(\succ)下是最大的元素。

  2. 选择一个与 MRV 集合中的元素相同可比性类的函数(\omega),使得(\lim_{x \to \infty} \omega = 0)。

  3. 将(f(x))在(\omega)中作为级数展开,以满足上述定理的前提条件。

  4. 应用定理并得出对(\lim_{x \to \infty} f(x))的计算结果,可能通过递归地处理(g_1(x))。

注释

这段阐述省略了几个细节。许多细节在 gruntz.py 文件中有描述,并且都可以在格伦茨非常易读的论文中找到。尚未解释的最重要的几点是:

  1. 给定(f(x))和(g(x)),我们如何确定(f(x) \succ g(x)),(g(x) \succ f(x))或(g(x) \asymp f(x))?

  2. 我们如何找到一个表达式的 MRV 集合?

  3. 我们如何计算级数展开?

  4. 为什么算法会终止?

如果你感兴趣,请务必查看格伦茨论文

参考

sympy.series.gruntz.gruntz(e, z, z0, dir='+')

使用 Gruntz 算法计算在点 z0 处的 e(z)的极限。

解释

z0可以是任何表达式,包括 oo 和-oo。

对于dir="+"(默认),它从右侧计算极限(z->z0+),对于dir="-",从左侧计算极限(z->z0-)。对于无穷大 z0(oo 或-oo),dir 参数无关紧要。

该算法完全在 gruntz.py 文件的模块文档字符串中进行了详细描述。它严重依赖于级数展开。在大多数情况下,仅当速度更快的 limit()函数(使用启发式算法)失败时才会使用 gruntz()。

sympy.series.gruntz.compare(a, b, x)

如果 a<b,则返回“<”,如果 a == b,则返回“=”,如果 a>b,则返回“>”

sympy.series.gruntz.rewrite(e, Omega, x, wsym)

e(x) … 函数 Omega … mrv 集合 wsym … 将用于 w 的符号

返回以 w 和 log(w)的术语重写的 e。有关示例和正确结果,请参阅 test_rewrite1()。

sympy.series.gruntz.build_expression_tree(Omega, rewrites)

重写的辅助函数。

我们需要对 Omega(mrv 集合)进行排序,以便在替换任何需要重写的表达式之前替换表达式:

e1 ---> e2 ---> e3
         \
          -> e4 

在这里我们可以执行 e1, e2, e3, e4 或 e1, e2, e4, e3。为此,我们将节点组装成树,并按高度排序。

此函数构建树,然后重写并对节点进行排序。

sympy.series.gruntz.mrv_leadterm(e, x)

对于 e 返回 (c0, e0)。

sympy.series.gruntz.calculate_series(e, x, logx=None)

计算 ex 中至少一个系列项。

这是最常失败的地方,因此它处于自己的函数中。

sympy.series.gruntz.limitinf(e, x)

当 x-> oo 时限制 e(x)。

sympy.series.gruntz.sign(e, x)

对于 x-> oo 返回表达式 e(x) 的符号。

e >  0 for x sufficiently large ...  1
e == 0 for x sufficiently large ...  0
e <  0 for x sufficiently large ... -1 

如果 e 对于任意大的 x 改变符号,这个函数的结果目前未定义(例如 sin(x))。

请注意,仅当 e 对于足够大的 x 是 常数 时,此函数才返回零。[如果 e 是常数,当然,这与 e 的符号是相同的。]

sympy.series.gruntz.mrv(e, x)

返回 ‘e’ 中最迅速变化(mrv)子表达式的子集,并且用这些子表达式重写 ‘e’。

sympy.series.gruntz.mrv_max1(f, g, exps, x)

计算两组表达式 f 和 g 的最大值,它们处于相同的可比较类中,即 mrv_max1() 比较 f 和 g(两个元素)并返回集合,如果它们具有相同的变化顺序,则返回相应的替换。

sympy.series.gruntz.mrv_max3(f, expsf, g, expsg, union, expsboth, x)

计算两组表达式 f 和 g 的最大值,它们处于相同的可比较类中,即 max() 比较 f 和 g(两个元素)并返回 (f, expsf)(如果 f 更大),(g, expsg)(如果 g 更大),或者 (union, expsboth)(如果 f、g 属于相同类)。

class sympy.series.gruntz.SubsSet

存储 (expr, dummy) 对及如何重写表达式的方法。

解释

gruntz 算法需要将某些表达式重写为一个新变量 w 的术语。我们不能使用 subs,因为它对我们来说太智能了。例如:

> Omega=[exp(exp(_p - exp(-_p))/(1 - 1/_p)), exp(exp(_p))]
> O2=[exp(-exp(_p) + exp(-exp(-_p))*exp(_p)/(1 - 1/_p))/_w, 1/_w]
> e = exp(exp(_p - exp(-_p))/(1 - 1/_p)) - exp(exp(_p))
> e.subs(Omega[0],O2[0]).subs(Omega[1],O2[1])
-1/w + exp(exp(p)*exp(-exp(-p))/(1 - 1/p)) 

真的不是我们想要的!

因此,我们采取了更难的方式,并记录了所有我们可能想要用虚拟变量替换的东西。考虑表达式:

exp(x - exp(-x)) + exp(x) + x. 

mrv 集合为 {exp(x), exp(-x), exp(x - exp(-x))}。我们引入对应的虚拟变量 d1, d2, d3 并重新表述:

d3 + d1 + x. 

该类首先跟踪映射 expr->variable,即此阶段将是一个字典:

{exp(x): d1, exp(-x): d2, exp(x - exp(-x)): d3}. 

[原来这样做更方便。] 但有时 mrv 集合中的表达式具有其他 mrv 集合中的表达式作为子表达式,我们也需要跟踪这一点。在这种情况下,d3 实际上是 exp(x - d2),因此在这个阶段重写为:

{d3: exp(x-d2)}. 

函数 rewrite 利用所有这些信息来正确地用 w 的术语重写我们的表达式。在这种情况下,w 可以选择为 exp(-x),即 d2。正确的重写如下:

exp(-w)/w + 1/w + x. 
copy()

创建 SubsSet 的浅拷贝

do_subs(e)

用表达式替换变量

meets(s2)

告诉我们 self 和 s2 是否有非空交集

union(s2, exps=None)

计算 self 和 s2 的并集,并调整 exps

更直观的级数展开

这通过创建 Basic.series() 的包装来实现。这允许使用 series(xcos(x),x),可能比 (xcos(x)).series(x) 更直观。

例子

>>> from sympy import Symbol, cos, series
>>> x = Symbol('x')
>>> series(cos(x),x)
1 - x**2/2 + x**4/24 + O(x**6) 

参考文献

sympy.series.series.series(expr, x=None, x0=0, n=6, dir='+')

关于点 (x = x0) 周围的表达式的级数展开。

参数:

expr:表达式

将要展开级数的表达式。

x:符号

这是要计算的表达式的变量。

x0:数值

计算中 x 计算的值。可以是从 -oooo 的任意值。

n : 值

要展开的级数项数。

dir : 字符串,可选

级数展开可以是双向的。如果 dir="+",则 (x->x0+)。如果 dir="-",则 (x->x0-)。对于无限的 x0 (oo-oo),dir 参数由无穷的方向确定(即 dir="-" 适用于 oo)。

返回:

表达式

关于 x0 的表达式的级数展开

示例

>>> from sympy import series, tan, oo
>>> from sympy.abc import x
>>> f = tan(x)
>>> series(f, x, 2, 6, "+")
tan(2) + (1 + tan(2)**2)*(x - 2) + (x - 2)**2*(tan(2)**3 + tan(2)) +
(x - 2)**3*(1/3 + 4*tan(2)**2/3 + tan(2)**4) + (x - 2)**4*(tan(2)**5 +
5*tan(2)**3/3 + 2*tan(2)/3) + (x - 2)**5*(2/15 + 17*tan(2)**2/15 +
2*tan(2)**4 + tan(2)**6) + O((x - 2)**6, (x, 2)) 
>>> series(f, x, 2, 3, "-")
tan(2) + (2 - x)*(-tan(2)**2 - 1) + (2 - x)**2*(tan(2)**3 + tan(2))
+ O((x - 2)**3, (x, 2)) 
>>> series(f, x, 2, oo, "+")
Traceback (most recent call last):
...
TypeError: 'Infinity' object cannot be interpreted as an integer 

参见

sympy.core.expr.Expr.series

参见 Expr.series() 的文档字符串以获取此包装器的完整详细信息。

阶数项

此模块还实现了自动跟踪展开的阶数。

示例

>>> from sympy import Symbol, Order
>>> x = Symbol('x')
>>> Order(x) + x**2
O(x)
>>> Order(x) + 1
1 + O(x) 

参考

class sympy.series.order.Order(expr, *args, **kwargs)

表示某些函数的极限行为。

解释

函数的阶基于函数在某个极限处的极限行为进行特征化。当前仅支持将极限点设为数字。这以大 O 表示法表示 [R835]

函数 (g(x)) 关于点 (a) 的阶的正式定义是,当 (x \rightarrow a) 时,(g(x) = O(f(x))) 当且仅当存在 (\delta > 0) 和 (M > 0),使得 (|g(x)| \leq M|f(x)|) 对于 (|x-a| < \delta) 成立。这等价于 (\limsup_{x \rightarrow a} |g(x)/f(x)| < \infty)。

让我们通过以下示例来说明,通过对 (\sin(x)) 在 0 处的展开来理解:

[\sin(x) = x - x³/3! + O(x⁵)]

在这种情况下,(O(x⁵) = x⁵/5! - x⁷/7! + \cdots)。根据 (O) 的定义,存在 (\delta > 0) 和 (M),使得:

[|x⁵/5! - x⁷/7! + ....| <= M|x⁵| \text{ for } |x| < \delta]

或由备用定义:

[\lim_{x \rightarrow 0} | (x⁵/5! - x⁷/7! + ....) / x⁵| < \infty]

这当然是正确的,因为

[\lim_{x \rightarrow 0} | (x⁵/5! - x⁷/7! + ....) / x⁵| = 1/5!]

如通常所用,函数的阶可以直观地被认为代表大于指定幂的所有项。例如,(O(x³)) 对应于任何与 (x³, x⁴,\ldots) 和任何更高幂次成比例的项。对于多项式,这将留下与 (x²)、(x) 和常数成比例的项。

示例

>>> from sympy import O, oo, cos, pi
>>> from sympy.abc import x, y 
>>> O(x + x**2)
O(x)
>>> O(x + x**2, (x, 0))
O(x)
>>> O(x + x**2, (x, oo))
O(x**2, (x, oo)) 
>>> O(1 + x*y)
O(1, x, y)
>>> O(1 + x*y, (x, 0), (y, 0))
O(1, x, y)
>>> O(1 + x*y, (x, oo), (y, oo))
O(x*y, (x, oo), (y, oo)) 
>>> O(1) in O(1, x)
True
>>> O(1, x) in O(1)
False
>>> O(x) in O(1, x)
True
>>> O(x**2) in O(x)
True 
>>> O(x)*x
O(x**2)
>>> O(x) - O(x)
O(x)
>>> O(cos(x))
O(1)
>>> O(cos(x), (x, pi/2))
O(x - pi/2, (x, pi/2)) 

注意

O(f(x), x) 中,假定表达式 f(x) 具有主导项。O(f(x), x) 自动转换为 O(f(x).as_leading_term(x),x)

O(expr*f(x), x)O(f(x), x)

O(expr, x)O(1)

O(0, x) 等于 0。

多变量 O 也是支持的:

O(f(x, y), x, y) 被转换为 O(f(x, y).as_leading_term(x,y).as_leading_term(y), x, y)

在多变量情况下,假设关于各个符号的极限交换。

如果没有传递符号,则表达式中的所有符号都被使用,并且假定极限点为零。

参考

[R835] (1,2)

大 O 表示法

contains(expr)

如果expr属于Order(self.expr, *self.variables),则返回 True。如果self属于expr,则返回 False。如果无法确定包含关系(例如当selfexpr具有不同的符号时),则返回 None。

级数加速

TODO

参考

sympy.series.acceleration.richardson(A, k, n, N)

使用具有项 A(n), A(n+1), …, A(n+N+1)的 Richardson 外推计算 lim k->oo A(k)的近似。通常选择 N ~= 2*n 可以得到良好的结果。

示例

一个简单的例子是使用极限定义计算 exp(1)。这个极限收敛缓慢;n = 100 只能产生两个准确的数字:

>>> from sympy.abc import n
>>> e = (1 + 1/n)**n
>>> print(round(e.subs(n, 100).evalf(), 10))
2.7048138294 

使用 11 个适当选择的项进行 Richardson 外推得到的值精确到指定的精度:

>>> from sympy import E
>>> from sympy.series.acceleration import richardson
>>> print(round(richardson(e, n, 10, 20).evalf(), 10))
2.7182818285
>>> print(round(E.evalf(), 10))
2.7182818285 

另一个有用的应用是加快级数的收敛速度。计算 zeta(2)级数 1/k**2 的前 100 项仅产生两个准确的数字:

>>> from sympy.abc import k, n
>>> from sympy import Sum
>>> A = Sum(k**-2, (k, 1, n))
>>> print(round(A.subs(n, 100).evalf(), 10))
1.6349839002 

Richardson 外推表现得更好:

>>> from sympy import pi
>>> print(round(richardson(A, n, 10, 20).evalf(), 10))
1.6449340668
>>> print(round(((pi**2)/6).evalf(), 10))     # Exact value
1.6449340668 
sympy.series.acceleration.shanks(A, k, n, m=1)

使用 n 项 Shanks 变换 S(A)(n)计算 lim k->oo A(k)的近似。当 m > 1 时,计算 m 倍递归 Shanks 变换 S(S(…S(A)…))(n)。

Shanks 变换适用于在极点或奇点附近收敛缓慢的泰勒级数求和,例如对于 log(2):

>>> from sympy.abc import k, n
>>> from sympy import Sum, Integer
>>> from sympy.series.acceleration import shanks
>>> A = Sum(Integer(-1)**(k+1) / k, (k, 1, n))
>>> print(round(A.subs(n, 100).doit().evalf(), 10))
0.6881721793
>>> print(round(shanks(A, n, 25).evalf(), 10))
0.6931396564
>>> print(round(shanks(A, n, 25, 5).evalf(), 10))
0.6931471806 

正确的值为 0.6931471805599453094172321215。

余项

TODO

参考

sympy.series.residues.residue(expr, x, x0)

在点 x=x0 处找到expr的余项。

余项定义为关于x=x0的幂级数展开中1/(x-x0)的系数。

示例

>>> from sympy import Symbol, residue, sin
>>> x = Symbol("x")
>>> residue(1/x, x, 0)
1
>>> residue(1/x**2, x, 0)
0
>>> residue(2/sin(x), x, 0)
2 

这个函数对于余项定理[1]至关重要。

参考文献

[R836]

en.wikipedia.org/wiki/Residue_theorem

序列

原文:docs.sympy.org/latest/modules/series/sequences.html

序列是一个有限或无限的惰性评估列表。

sympy.series.sequences.sequence(seq, limits=None)

返回适当的序列对象。

解释

如果seq是 SymPy 序列,则返回SeqPer对象,否则返回SeqFormula对象。

示例

>>> from sympy import sequence
>>> from sympy.abc import n
>>> sequence(n**2, (n, 0, 5))
SeqFormula(n**2, (n, 0, 5))
>>> sequence((1, 2, 3), (n, 0, 5))
SeqPer((1, 2, 3), (n, 0, 5)) 

参见

sympy.series.sequences.SeqPersympy.series.sequences.SeqFormula

序列基类

class sympy.series.sequences.SeqBase(*args)

序列的基类

coeff(pt)

返回点pt处的系数

coeff_mul(other)

other不是序列时应使用。应定义以定义自定义行为。

示例

>>> from sympy import SeqFormula
>>> from sympy.abc import n
>>> SeqFormula(n**2).coeff_mul(2)
SeqFormula(2*n**2, (n, 0, oo)) 

注意事项

‘*’仅定义序列与序列的乘法。

find_linear_recurrence(n, d=None, gfvar=None)

如果可能的话,找到满足序列前n项的序列的最短线性递归,其阶数(\leq) n/2。如果指定了d,则找到阶数(\leq) min(d, n/2)的最短线性递归。返回系数列表[b(1), b(2), ...],对应于递归关系x(n) = b(1)*x(n-1) + b(2)*x(n-2) + ...。如果找不到递归,则返回[]。如果指定了gfvar,还返回以gfvar为变量的普通生成函数。

示例

>>> from sympy import sequence, sqrt, oo, lucas
>>> from sympy.abc import n, x, y
>>> sequence(n**2).find_linear_recurrence(10, 2)
[]
>>> sequence(n**2).find_linear_recurrence(10)
[3, -3, 1]
>>> sequence(2**n).find_linear_recurrence(10)
[2]
>>> sequence(23*n**4+91*n**2).find_linear_recurrence(10)
[5, -10, 10, -5, 1]
>>> sequence(sqrt(5)*(((1 + sqrt(5))/2)**n - (-(1 + sqrt(5))/2)**(-n))/5).find_linear_recurrence(10)
[1, 1]
>>> sequence(x+y*(-2)**(-n), (n, 0, oo)).find_linear_recurrence(30)
[1/2, 1/2]
>>> sequence(3*5**n + 12).find_linear_recurrence(20,gfvar=x)
([6, -5], 3*(5 - 21*x)/((x - 1)*(5*x - 1)))
>>> sequence(lucas(n)).find_linear_recurrence(15,gfvar=x)
([1, 1], (x - 2)/(x**2 + x - 1)) 
property free_symbols

此方法返回对象中的符号,不包括那些具有特定值的符号(即虚符号)。

示例

>>> from sympy import SeqFormula
>>> from sympy.abc import n, m
>>> SeqFormula(m*n**2, (n, 0, 5)).free_symbols
{m} 
property gen

返回序列的生成器

property interval

序列定义的区间

property length

序列的长度

property start

序列的起始点。该点包括在内。

property stop

序列的结束点。该点包括在内。

property variables

返回一个包含绑定变量的元组。

初等序列

class sympy.series.sequences.SeqFormula(formula, limits=None)

基于公式表示的序列。

基于公式生成元素的序列。

示例

>>> from sympy import SeqFormula, oo, Symbol
>>> n = Symbol('n')
>>> s = SeqFormula(n**2, (n, 0, 5))
>>> s.formula
n**2 

对特定点的值

>>> s.coeff(3)
9 

支持切片

>>> s[:]
[0, 1, 4, 9, 16, 25] 

可迭代的

>>> list(s)
[0, 1, 4, 9, 16, 25] 

序列从负无穷开始

>>> SeqFormula(n**2, (-oo, 0))[0:6]
[0, 1, 4, 9, 16, 25] 

参见

sympy.series.sequences.SeqPer

coeff_mul(coeff)

参见SeqBase.coeff_mul的文档字符串

class sympy.series.sequences.SeqPer(periodical, limits=None)

表示周期序列。

元素在给定周期后重复。

示例

>>> from sympy import SeqPer, oo
>>> from sympy.abc import k 
>>> s = SeqPer((1, 2, 3), (0, 5))
>>> s.periodical
(1, 2, 3)
>>> s.period
3 

对特定点的值

>>> s.coeff(3)
1 

支持切片

>>> s[:]
[1, 2, 3, 1, 2, 3] 

可迭代的

>>> list(s)
[1, 2, 3, 1, 2, 3] 

序列从负无穷开始

>>> SeqPer((1, 2, 3), (-oo, 0))[0:6]
[1, 2, 3, 1, 2, 3] 

周期公式

>>> SeqPer((k, k**2, k**3), (k, 0, oo))[0:6]
[0, 1, 8, 3, 16, 125] 

参见

sympy.series.sequences.SeqFormula

coeff_mul(coeff)

参见SeqBase.coeff_mul的文档字符串

单例序列

class sympy.series.sequences.EmptySequence

表示空序列。

空序列也作为单例S.EmptySequence可用。

示例

>>> from sympy import EmptySequence, SeqPer
>>> from sympy.abc import x
>>> EmptySequence
EmptySequence
>>> SeqPer((1, 2), (x, 0, 10)) + EmptySequence
SeqPer((1, 2), (x, 0, 10))
>>> SeqPer((1, 2)) * EmptySequence
EmptySequence
>>> EmptySequence.coeff_mul(-1)
EmptySequence 
coeff_mul(coeff)

参见SeqBase.coeff_mul的文档字符串

复合序列

class sympy.series.sequences.SeqAdd(*args, **kwargs)

逐项加法序列。

规则:

  • 序列定义的区间是各序列相应区间的交集。

  • 任何内容 + EmptySequence保持不变。

  • 其他规则在序列类的 _add 方法中定义。

示例

>>> from sympy import EmptySequence, oo, SeqAdd, SeqPer, SeqFormula
>>> from sympy.abc import n
>>> SeqAdd(SeqPer((1, 2), (n, 0, oo)), EmptySequence)
SeqPer((1, 2), (n, 0, oo))
>>> SeqAdd(SeqPer((1, 2), (n, 0, 5)), SeqPer((1, 2), (n, 6, 10)))
EmptySequence
>>> SeqAdd(SeqPer((1, 2), (n, 0, oo)), SeqFormula(n**2, (n, 0, oo)))
SeqAdd(SeqFormula(n**2, (n, 0, oo)), SeqPer((1, 2), (n, 0, oo)))
>>> SeqAdd(SeqFormula(n**3), SeqFormula(n**2))
SeqFormula(n**3 + n**2, (n, 0, oo)) 

另请参见

sympy.series.sequences.SeqMul

static reduce(args)

使用已知规则简化 SeqAdd

遍历所有对,并询问组成序列是否能通过与其他组成序列简化自己。

注意事项

改编自 Union.reduce

class sympy.series.sequences.SeqMul(*args, **kwargs)

表示序列的逐项乘法。

解释

仅处理序列的乘法。如需与其他对象相乘,请参见 SeqBase.coeff_mul()

规则:

  • 序列定义的区间是各序列相应区间的交集。

  • 任何 * EmptySequence 返回 EmptySequence

  • 其他规则在序列类的 _mul 方法中定义。

示例

>>> from sympy import EmptySequence, oo, SeqMul, SeqPer, SeqFormula
>>> from sympy.abc import n
>>> SeqMul(SeqPer((1, 2), (n, 0, oo)), EmptySequence)
EmptySequence
>>> SeqMul(SeqPer((1, 2), (n, 0, 5)), SeqPer((1, 2), (n, 6, 10)))
EmptySequence
>>> SeqMul(SeqPer((1, 2), (n, 0, oo)), SeqFormula(n**2))
SeqMul(SeqFormula(n**2, (n, 0, oo)), SeqPer((1, 2), (n, 0, oo)))
>>> SeqMul(SeqFormula(n**3), SeqFormula(n**2))
SeqFormula(n**5, (n, 0, oo)) 

另请参见

sympy.series.sequences.SeqAdd

static reduce(args)

使用已知规则简化 SeqMul

解释

遍历所有对,并询问组成序列是否能通过与其他组成序列简化自己。

注意事项

改编自 Union.reduce

递归序列

class sympy.series.sequences.RecursiveSeq(recurrence, yn, n, initial=None, start=0)

有限阶递归序列。

参数:

recurrence:定义递归的 SymPy 表达式

是一个等式,只是第 n 项等于的表达式。例如,如果 a(n) = f(a(n - 1), ..., a(n - d)),那么表达式应为 f(a(n - 1), ..., a(n - d))

yn:应用的未定义函数

将序列的第 n 项表示为例如 y(n),其中 y 是一个未定义的函数,( n ) 是序列的索引。

n:符号参数

递归所在的变量名称,例如,如果递归函数是 y(n),则该变量为 n

initial:长度与递归的次数相等的可迭代对象

递归的初始值。

start:序列的起始值(包含)

解释

即依赖于其前一个固定数量的值的序列 a(n)。其一般形式为

a(n) = f(a(n - 1), a(n - 2), …, a(n - d))

对于某个固定的正整数 d,其中 f 是由 SymPy 表达式定义的某个函数。

示例

>>> from sympy import Function, symbols
>>> from sympy.series.sequences import RecursiveSeq
>>> y = Function("y")
>>> n = symbols("n")
>>> fib = RecursiveSeq(y(n - 1) + y(n - 2), y(n), n, [0, 1]) 
>>> fib.coeff(3) # Value at a particular point
2 
>>> fib[:6] # supports slicing
[0, 1, 1, 2, 3, 5] 
>>> fib.recurrence # inspect recurrence
Eq(y(n), y(n - 2) + y(n - 1)) 
>>> fib.degree # automatically determine degree
2 
>>> for x in zip(range(10), fib): # supports iteration
...     print(x)
(0, 0)
(1, 1)
(2, 1)
(3, 2)
(4, 3)
(5, 5)
(6, 8)
(7, 13)
(8, 21)
(9, 34) 

另请参见

sympy.series.sequences.SeqFormula

property initial

序列的初始值

property interval

序列定义的区间。

property n

序列的索引符号

property recurrence

定义递归的方程。

property start

序列的起始点。包含此点

property stop

序列的结束点。(oo)

property y

序列第 n 项的未定义函数

property yn

应用的函数,表示第 n 项

Fourier 级数

原文:docs.sympy.org/latest/modules/series/fourier.html

提供计算 Fourier 级数的方法。

class sympy.series.fourier.FourierSeries(*args)

表示 Fourier 正弦/余弦级数。

Explanation

此类仅表示 Fourier 级数。不执行任何计算。

如何计算 Fourier 级数,请参见fourier_series()的文档字符串。

参见

sympy.series.fourier.fourier_series

scale(s)

通过与 x 无关的项来缩放函数。

Explanation

f(x) -> s * f(x)

如果已计算出 f(x)的 Fourier 级数,则此方法很快。

Examples

>>> from sympy import fourier_series, pi
>>> from sympy.abc import x
>>> s = fourier_series(x**2, (x, -pi, pi))
>>> s.scale(2).truncate()
-8*cos(x) + 2*cos(2*x) + 2*pi**2/3 
scalex(s)

通过与 x 无关的项来缩放 x。

Explanation

f(x) -> f(s*x)

如果已计算出 f(x)的 Fourier 级数,则此方法很快。

Examples

>>> from sympy import fourier_series, pi
>>> from sympy.abc import x
>>> s = fourier_series(x**2, (x, -pi, pi))
>>> s.scalex(2).truncate()
-4*cos(2*x) + cos(4*x) + pi**2/3 
shift(s)

将函数按独立于 x 的项移位。

Explanation

f(x) -> f(x) + s

如果已计算出 f(x)的 Fourier 级数,则此方法很快。

Examples

>>> from sympy import fourier_series, pi
>>> from sympy.abc import x
>>> s = fourier_series(x**2, (x, -pi, pi))
>>> s.shift(1).truncate()
-4*cos(x) + cos(2*x) + 1 + pi**2/3 
shiftx(s)

通过与 x 无关的项来移位 x。

Explanation

f(x) -> f(x + s)

如果已计算出 f(x)的 Fourier 级数,则此方法很快。

Examples

>>> from sympy import fourier_series, pi
>>> from sympy.abc import x
>>> s = fourier_series(x**2, (x, -pi, pi))
>>> s.shiftx(1).truncate()
-4*cos(x + 1) + cos(2*x + 2) + pi**2/3 
sigma_approximation(n=3)

返回关于阶数 n 的 Fourier 级数的(\sigma)-近似。

参数:

n : int

在近似中考虑的最高阶数。

返回:

表达式:

将函数展开为 Fourier 级数的 Sigma 近似。

Explanation

Sigma 近似调整 Fourier 求和以消除在不连续点处可能发生的吉布斯现象。对于周期为 T 的函数的 sigma-近似级数可以写成

[s(\theta) = \frac{1}{2} a_0 + \sum _{k=1}^{m-1} \operatorname{sinc} \Bigl( \frac{k}{m} \Bigr) \cdot \left[ a_k \cos \Bigl( \frac{2\pi k}{T} \theta \Bigr) + b_k \sin \Bigl( \frac{2\pi k}{T} \theta \Bigr) \right],]

其中(a_0, a_k, b_k, k=1,\ldots,{m-1})是标准 Fourier 级数系数,(\operatorname{sinc} \Bigl( \frac{k}{m} \Bigr))是以标准化的(\operatorname{sinc})函数表示的 Lanczos (\sigma)因子。

Examples

>>> from sympy import fourier_series, pi
>>> from sympy.abc import x
>>> s = fourier_series(x, (x, -pi, pi))
>>> s.sigma_approximation(4)
2*sin(x)*sinc(pi/4) - 2*sin(2*x)/pi + 2*sin(3*x)*sinc(3*pi/4)/3 

Notes

sigma_approximation()的行为与truncate()不同 - 它获取小于 n 的所有非零项,而不是前 n 个非零项。

参见

sympy.series.fourier.FourierSeries.truncate

References

[R830]

en.wikipedia.org/wiki/Gibbs_phenomenon

[R831]

en.wikipedia.org/wiki/Sigma_approximation

truncate(n=3)

返回级数的前 n 个非零项。

如果n为 None,则返回一个迭代器。

参数:

n : int 或 None

近似值的非零项数或无。

返回:

表达式或迭代器:

将函数近似展开为傅里叶级数。

示例

>>> from sympy import fourier_series, pi
>>> from sympy.abc import x
>>> s = fourier_series(x, (x, -pi, pi))
>>> s.truncate(4)
2*sin(x) - sin(2*x) + 2*sin(3*x)/3 - sin(4*x)/2 

参见

sympy.series.fourier.FourierSeries.sigma_approximation

sympy.series.fourier.fourier_series(f, limits=None, finite=True)

计算傅里叶三角级数展开。

参数:

限制:(sym,start,end),可选

sym 表示计算级数时所使用的符号。

startend 表示傅里叶级数收敛到给定函数的区间的起始和结束。

默认范围指定为 (-\pi) 至 (\pi)。

返回:

傅里叶级数

表示傅里叶三角级数的符号对象。

解释

定义在区间 ((a, b)) 上的傅里叶三角级数为:

[\frac{a_0}{2} + \sum_{n=1}^{\infty} (a_n \cos(\frac{2n \pi x}{L}) + b_n \sin(\frac{2n \pi x}{L}))]

其系数为:

[L = b - a][a_0 = \frac{2}{L} \int_{a}^{b}{f(x) dx}][a_n = \frac{2}{L} \int_{a}^{b}{f(x) \cos(\frac{2n \pi x}{L}) dx}][b_n = \frac{2}{L} \int_{a}^{b}{f(x) \sin(\frac{2n \pi x}{L}) dx}]

函数 (f(x)) 是否应周期性地给出的条件超出必要,因为只需考虑系列在给定区间内收敛到 (f(x)),而不是整个实数线上。

这也为计算带来了很多便利,因为您无需通过分段、模运算来人为地使 (f(x)) 成为周期函数,而是可以在区间 ((a, b)) 中塑造函数,使其看起来像期望的周期函数,计算出的级数将自动成为 (f(x)) 周期版本的级数。

该属性在下面的示例部分有所说明。

示例

计算 (f(x) = x²) 的傅里叶级数:

>>> from sympy import fourier_series, pi
>>> from sympy.abc import x
>>> f = x**2
>>> s = fourier_series(f, (x, -pi, pi))
>>> s1 = s.truncate(n=3)
>>> s1
-4*cos(x) + cos(2*x) + pi**2/3 

傅里叶级数的移动:

>>> s.shift(1).truncate()
-4*cos(x) + cos(2*x) + 1 + pi**2/3
>>> s.shiftx(1).truncate()
-4*cos(x + 1) + cos(2*x + 2) + pi**2/3 

傅里叶级数的缩放:

>>> s.scale(2).truncate()
-8*cos(x) + 2*cos(2*x) + 2*pi**2/3
>>> s.scalex(2).truncate()
-4*cos(2*x) + cos(4*x) + pi**2/3 

计算 (f(x) = x) 的傅里叶级数:

这说明了截断到更高阶会有更好的收敛性。

>>> from sympy import fourier_series, pi, plot
>>> from sympy.abc import x
>>> f = x
>>> s = fourier_series(f, (x, -pi, pi))
>>> s1 = s.truncate(n = 3)
>>> s2 = s.truncate(n = 5)
>>> s3 = s.truncate(n = 7)
>>> p = plot(f, s1, s2, s3, (x, -pi, pi), show=False, legend=True) 
>>> p[0].line_color = (0, 0, 0)
>>> p[0].label = 'x'
>>> p[1].line_color = (0.7, 0.7, 0.7)
>>> p[1].label = 'n=3'
>>> p[2].line_color = (0.5, 0.5, 0.5)
>>> p[2].label = 'n=5'
>>> p[3].line_color = (0.3, 0.3, 0.3)
>>> p[3].label = 'n=7' 
>>> p.show() 

pnghires.pngpdf

../../_images/fourier-1.png

这说明了当指定不同范围时,级数如何收敛到不同的锯齿波。

>>> s1 = fourier_series(x, (x, -1, 1)).truncate(10)
>>> s2 = fourier_series(x, (x, -pi, pi)).truncate(10)
>>> s3 = fourier_series(x, (x, 0, 1)).truncate(10)
>>> p = plot(x, s1, s2, s3, (x, -5, 5), show=False, legend=True) 
>>> p[0].line_color = (0, 0, 0)
>>> p[0].label = 'x'
>>> p[1].line_color = (0.7, 0.7, 0.7)
>>> p[1].label = '[-1, 1]'
>>> p[2].line_color = (0.5, 0.5, 0.5)
>>> p[2].label = '[-pi, pi]'
>>> p[3].line_color = (0.3, 0.3, 0.3)
>>> p[3].label = '[0, 1]' 
>>> p.show() 

pnghires.pngpdf

../../_images/fourier-2.png

注释

由于计算 an、bn 所需的积分而导致傅里叶级数计算较慢。

通过在已计算的傅里叶级数上使用移位和缩放,而不是重新计算,可以更快地计算函数的傅里叶级数。

例如,如果已知x**2的傅里叶级数,则通过移位 -1 可以找到x**2 - 1的傅里叶级数。

另见

sympy.series.fourier.FourierSeries

参考资料

[R832]

mathworld.wolfram.com/FourierSeries.html

posted @ 2024-06-27 17:18  绝不原创的飞龙  阅读(10)  评论(0编辑  收藏  举报