序列展开#

限制#

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

sympy.series.limits.limit(e, z, z0, dir='+')[源代码]#

计算 e(z) 在这一点上 z0 .

参数:

e :表达式,取其极限

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

其他符号被视为常量。不支持多元限制。

z0 :指向哪个值 z 倾向于。可以是任何表情,

包括 oo-oo .

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

The limit is bi-directional if dir="+-", from the right (z->z0+) if dir="+", and from the left (z->z0-) if dir="-". For infinite z0 (oo or -oo), the dir argument is determined from the direction of the infinity (i.e., dir="-" for oo).

实例

>>> 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,可选(默认值:True)

调用 doit 求极限前所涉及表达式的方法。

提示 :可选关键字参数

传递给 doit 方法;仅在deep为True时使用。

如上所述,极限计算的主力是函数gruntz(),它实现了gruntz计算极限的算法。

格伦茨算法#

本节介绍用于计算极限的算法的基本知识。在大多数情况下,limit()函数应该可以正常工作。然而,记住如何在某些东西不能按预期工作的情况下实现它仍然是有用的。

First we define an ordering on functions. Suppose \(f(x)\) and \(g(x)\) are two real-valued functions such that \(\lim_{x \to \infty} f(x) = \infty\) and similarly \(\lim_{x \to \infty} g(x) = \infty\). We shall say that \(f(x)\) dominates \(g(x)\), written \(f(x) \succ g(x)\), if for all \(a, b \in \mathbb{R}_{>0}\) we have \(\lim_{x \to \infty} \frac{f(x)^a}{g(x)^b} = \infty\). We also say that \(f(x)\) and \(g(x)\) are of the same comparability class if neither \(f(x) \succ g(x)\) nor \(g(x) \succ f(x)\) and shall denote it as \(f(x) \asymp g(x)\).

请注意,无论何时 \(a, b \in \mathbb{{R}}_{{>0}}\) 然后 \(a f(x)^b \asymp f(x)\) ,我们将用这个来扩展 \(\succ\) 对所有倾向于 \(0\)\(\pm \infty\) 作为 \(x \to \infty\) . 因此,我们声明 \(f(x) \asymp 1/f(x)\)\(f(x) \asymp -f(x)\) .

下面的例子很容易演示:

  • \(e^x \succ x^m\)

  • \(e^{x^2} \succ e^{mx}\)

  • \(e^{e^x} \succ e^{x^m}\)

  • \(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\)\(\omega \succ g_i\) 为了所有 \(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\) 如上所述,我们还有以下简单的结果:

  • \(\lim_{x \to \infty} g \omega^c = 0\) for \(c > 0\)

  • \(\lim_{x \to \infty} g \omega^c = \pm \infty\) for \(c < 0\), where the sign is determined by the (eventual) sign of \(g\)

  • \(\lim_{{x \to \infty}} g \omega^0 = \lim_{{x \to \infty}} g\) .

使用这些结果可以得出以下计算策略 \(\lim_{{x \to \infty}} f(x)\)

  1. 找到 最快变化的子表达式 (MRV套件)共 \(f(x)\) . 也就是说,从 \(f(x)\) ,找出关系下最大的元素 \(\succ\) .

  2. 选择函数 \(\omega\) 它与MRV集合中的元素在同一个可比类中,因此 \(\lim_{{x \to \infty}} \omega = 0\) .

  3. 展开 \(f(x)\) 作为一系列 \(\omega\) 以满足上述定理的前提条件。

  4. 应用该定理,得出 \(\lim_{{x \to \infty}} f(x)\) ,可能是递归地 \(g_1(x)\) .

笔记#

这个论述掩盖了几个细节。文件中描述了很多格伦茨.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. 为什么算法终止?

If you are interested, be sure to take a look at Gruntz Thesis.

参考文献#

sympy.series.gruntz.gruntz(e, z, z0, dir='+')[源代码]#

使用Gruntz算法计算z0点的e(z)极限。

解释

z0 can be any expression, including oo and -oo.

For dir="+" (default) it calculates the limit from the right (z->z0+) and for dir="-" the limit from the left (z->z0-). For infinite z0 (oo or -oo), the dir argument does not matter.

该算法在格伦茨.py文件。它在很大程度上依赖于系列扩张。最常见的情况是,gruntz()仅在faster limit()函数(使用启发式)失败时使用。

sympy.series.gruntz.compare(a, b, x)[源代码]#

返回“<”如果a<b,“=”表示a==b,“>”表示a>b

sympy.series.gruntz.rewrite(e, Omega, x, wsym)[源代码]#

e(x)。。。欧米茄函数。。。mrv集合了。。。将用于w的符号

以w和log(w)返回重写的e。有关示例和正确的结果,请参见test_rewrite1()。

sympy.series.gruntz.build_expression_tree(Omega, rewrites)[源代码]#

重写的助手函数。

我们需要对Omega(mrv set)进行排序,以便在替换任何需要重写的表达式之前替换表达式:

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)[源代码]#

Calculates at least one term of the series of e in x.

这是一个最常失败的地方,所以它有它自己的功能。

sympy.series.gruntz.limitinf(e, x)[源代码]#

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的(两个元素),并返回位于两者并集的较高可比性类中的集合,前提是它们的变化顺序相同。还返回exps,并进行适当的替换。

sympy.series.gruntz.mrv_max3(f, expsf, g, expsg, union, expsboth, x)[源代码]#

计算同一可比性类中两组表达式f和g的最大值,即max()比较f和g的(两个元素)并返回(f,expsf) [如果f更大] ,(g,表达式) [如果g较大] 或(联合,expsboth) [如果f,g属于同一类] .

class sympy.series.gruntz.SubsSet[源代码]#

存储(expr,dummy)对,以及如何重写expr-s。

解释

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()[源代码]#

创建子集的浅拷贝

do_subs(e)[源代码]#

用表达式代替变量

meets(s2)[源代码]#

判断self和s2是否有非空交集

union(s2, exps=None)[源代码]#

计算self和s2的并,调整exps

更直观的系列扩展#

这是通过在基本系列(). 这允许使用系列(x cos(x),这可能比(x)更直观 cos(x))。系列(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='+')[源代码]#

expr绕点的级数展开 \(x = x0\) .

参数:

expr :表达式

要展开其级数的表达式。

x :符号

它是要计算的表达式的变量。

x0 :值

围绕它的价值 x 是经过计算的。可以是来自 -oooo .

n :值

级数要扩展到的项数。

dir :字符串,可选

The series-expansion can be bi-directional. If dir="+", then (x->x0+). If dir="-", then (x->x0-). For infinite x0 (oo or -oo), the dir argument is determined from the direction of the infinity (i.e., dir="-" for 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.系列()以获取此包装的完整详细信息。

订货条件#

此模块还实现了对扩展顺序的自动跟踪。

实例#

>>> 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)[源代码]#

Represents the limiting behavior of some function.

解释

The order of a function characterizes the function based on the limiting behavior of the function as it goes to some limit. Only taking the limit point to be a number is currently supported. This is expressed in big O notation [R835].

The formal definition for the order of a function \(g(x)\) about a point \(a\) is such that \(g(x) = O(f(x))\) as \(x \rightarrow a\) if and only if there exists a \(\delta > 0\) and an \(M > 0\) such that \(|g(x)| \leq M|f(x)|\) for \(|x-a| < \delta\). This is equivalent to \(\limsup_{x \rightarrow a} |g(x)/f(x)| < \infty\).

让我们在下面的例子中用 \(\sin(x)\) 关于0:

\[\sin(x)=x-x^3/3!+O(x^5)\]

where in this case \(O(x^5) = x^5/5! - x^7/7! + \cdots\). By the definition of \(O\), there is a \(\delta > 0\) and an \(M\) such that:

\[|x^5/5! - x^7/7! + ....| <= M|x^5| \text{ for } |x| < \delta\]

或者根据另一种定义:

\[\lim{x\右箭头0}(x^5/5!-x^7/7!+…)/x^5 |<\infty\]

这当然是真的,因为

\[\lim{x\右箭头0}(x^5/5!-x^7/7!+…)/x^5 |=1/5!\]

由于它通常被使用,一个函数的顺序可以被直观地认为是代表所有比指定的一个更大的幂项。例如, \(O(x^3)\) 对应于任何与 \(x^3, x^4,\ldots\) 任何更高的权力。对于多项式,这使得项与 \(x^2\)\(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) is O(f(x), x)

O(expr, x) is O(1)

O(0, x) 是0。

还支持多变量O:

O(f(x, y), x, y) is transformed to O(f(x, y).as_leading_term(x,y).as_leading_term(y), x, y)

在多变量的情况下,假设各种符号之间的相互转换的极限。

如果未传递符号,则使用表达式中的所有符号,并假定极限点为零。

工具书类

[R835] (1,2)

Big O notation

contains(expr)[源代码]#

如果expr属于Order,则返回True(自我表达, * 自变量). 如果self属于expr,则返回False。当表达式g不具有自包含关系时返回。

串联加速度#

TODO

参考文献#

sympy.series.acceleration.richardson(A, k, n, N)[源代码]#

使用Richardson外推法计算lim k->ooa(k)的近似值,其中A(n),A(n+1),…,A(n+n+1)。选择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个适当选择的术语给出了一个精确到指定精度的值:

>>> 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

理查森外推法表现得更好:

>>> 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->ooa(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)[源代码]#

找到 expr 在x=x0点。

The residue is defined as the coefficient of 1/(x-x0) in the power series expansion about 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] .

工具书类