Series Expansions

The series module implements series expansions as a function and many related functions.

class diofant.series.limits.Limit[source]

Represents a directional limit of expr at the point z0.

Parameters:

expr : Expr

algebraic expression

z : Symbol

variable of the expr

z0 : Expr

limit point, \(z_0\)

dir : {“+”, “-”, “real”}, optional

For dir="+" (default) it calculates the limit from the right (\(z\to z_0 + 0\)) and for dir="-" the limit from the left (\(z\to z_0 - 0\)). If dir="real", the limit is the bidirectional real limit. For infinite z0 (oo or -oo), the dir argument is determined from the direction of the infinity (i.e., dir="-" for oo).

Examples

>>> from diofant import Limit, sin
>>> from diofant.abc import x
>>> Limit(sin(x)/x, x, 0)
Limit(sin(x)/x, x, 0)
>>> Limit(1/x, x, 0, dir="-")
Limit(1/x, x, 0, dir='-')
doit(**hints)[source]

Evaluates limit.

Notes

First we handle some trivial cases (i.e. constant), then try Gruntz algorithm (see the gruntz module).

diofant.series.limits.limit(expr, z, z0, dir='+')[source]

Compute the directional limit of expr at the point z0.

See also

Limit

Examples

>>> from diofant import limit, sin, oo
>>> from diofant.abc import x
>>> limit(sin(x)/x, x, 0)
1
>>> limit(1/x, x, 0, dir="+")
oo
>>> limit(1/x, x, 0, dir="-")
-oo
>>> limit(1/x, x, oo)
0
diofant.series.series.series(expr, x=None, x0=0, n=6, dir='+')[source]

Series expansion of expr in x around point x0.

diofant.series.order.O

alias of Order

class diofant.series.order.Order[source]

Represents the limiting behavior of function.

The formal definition [R457] for order symbol \(O(f(x))\) (Big O) is that \(g(x) \in O(f(x))\) as \(x\to a\) iff

\[\lim\limits_{x \rightarrow a} \sup \left|\frac{g(x)}{f(x)}\right| < \infty\]
Parameters:

expr : Expr

an expression

args : sequence of Symbol’s or pairs (Symbol, Expr), optional

If only symbols are provided, i.e. no limit point are passed, then the limit point is assumed to be zero. If no symbols are passed then all symbols in the expression are used.

References

[R457](1, 2) http://en.wikipedia.org/wiki/Big_O_notation

Examples

>>> from diofant import O, oo, cos, pi
>>> from diofant.abc import x, y

The order of a function can be intuitively thought of representing all terms of powers greater than the one specified. For example, \(O(x^3)\) corresponds to any terms proportional to \(x^3, x^4,\ldots\) and any higher power. For a polynomial, this leaves terms proportional to \(x^2\), \(x\) and constants.

>>> 1 + x + x**2 + x**3 + x**4 + O(x**3)
1 + x + x**2 + O(x**3)

O(f(x)) is automatically transformed to O(f(x).as_leading_term(x)):

>>> O(x + x**2)
O(x)
>>> O(cos(x))
O(1)

Some arithmetic operations:

>>> O(x)*x
O(x**2)
>>> O(x) - O(x)
O(x)

The Big O symbol is a set, so we support membership test:

>>> x in O(x)
True
>>> 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

Limit points other then zero and multivariate Big O are also supported:

>>> O(x) == O(x, (x, 0))
True
>>> O(x + x**2, (x, oo))
O(x**2, (x, oo))
>>> O(cos(x), (x, pi/2))
O(x - pi/2, (x, pi/2))
>>> 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))
contains(expr)[source]

Membership test.

Returns:

Boolean or None

Return True if expr belongs to self. Return False if self belongs to expr. Return None if the inclusion relation cannot be determined.

diofant.series.residues.residue(expr, x, x0)[source]

Finds the residue of expr at the point x=x0.

The residue is defined [R458] as the coefficient of \(1/(x - x_0)\) in the power series expansion around \(x=x_0\).

This notion is essential for the Residue Theorem [R459]

References

[R458](1, 2) http://en.wikipedia.org/wiki/Residue_%28complex_analysis%29
[R459](1, 2) http://en.wikipedia.org/wiki/Residue_theorem

Examples

>>> from diofant import residue, sin
>>> from diofant.abc import x
>>> residue(1/x, x, 0)
1
>>> residue(1/x**2, x, 0)
0
>>> residue(2/sin(x), x, 0)
2

The Gruntz Algorithm

This section explains the basics of the algorithm [R460] used for computing limits. Most of the time the limit() function should just work. However it is still useful to keep in mind how it is implemented in case something does not work as expected.

First we define an ordering on functions of single variable \(x\) according to how rapidly varying they at infinity. Any two functions \(f(x)\) and \(g(x)\) can be compared using the properties of:

\[L = \lim\limits_{x\to\infty}\frac{\log|f(x)|}{\log|g(x)|}\]

We shall say that \(f(x)\) dominates \(g(x)\), written \(f(x) \succ g(x)\), iff \(L=\pm\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)\).

It is easy to show the following examples:

  • \(e^{e^x} \succ e^{x^2} \succ e^x \succ x \succ 42\)
  • \(2 \asymp 3 \asymp -5\)
  • \(x \asymp x^2 \asymp x^3 \asymp -x\)
  • \(e^x \asymp e^{-x} \asymp e^{2x} \asymp e^{x + e^{-x}}\)
  • \(f(x) \asymp 1/f(x)\)

Using these definitions yields the following strategy for computing \(\lim_{x \to \infty} f(x)\):

  1. Given the function \(f(x)\), we find the set of most rapidly varying subexpressions (MRV set) of it. All items of this set belongs to the same comparability class. Let’s say it is \(\{e^x, e^{2x}\}\).

  2. Choose an expression \(\omega\) which is positive and tends to zero and which is in the same comparability class as any element of the MRV set. Such element always exists. Then we rewrite the MRV set using \(\omega\), in our case \(\{\omega^{-1}, \omega^{-2}\}\), and substitute it into \(f(x)\).

  3. Let \(f(\omega)\) be the function which is obtained from \(f(x)\) after the rewrite step above. Consider all expressions independent of \(\omega\) as constants and compute the leading term of the power series of \(f(\omega)\) around \(\omega = 0^+\):

    \[f(\omega) = c_0 \omega^{e_0} + c_1 \omega^{e_1} + \ldots\]

    where \(e_0 < e_1 < e_2 \ldots\)

  4. If the leading exponent \(e_0 > 0\) then the limit is \(0\). If \(e_0 < 0\), then the answer is \(\pm\infty\) (depends on sign of \(c_0\)). Finally, if \(e_0 = 0\), the limit is the limit of the leading coefficient \(c_0\).

Notes

This exposition glossed over several details. For example, limits could be computed recursively (steps 1 and 4). Please address to the Gruntz thesis [R460] for proof of the termination (pp. 52-60).

References

[R460](1, 2) Gruntz Thesis
diofant.series.gruntz.compare(a, b, x)[source]

Determine order relation between two functons.

Returns:

{1, 0, -1}

Respectively, if \(a(x) \succ b(x)\), \(a(x) \asymp b(x)\) or \(b(x) \succ a(x)\).

Examples

>>> from diofant import Symbol, exp
>>> x = Symbol('x', real=True, positive=True)
>>> m = Symbol('m', real=True, positive=True)
>>> compare(x, x**2, x)
0
>>> compare(1/x, x**m, x)
0
>>> compare(exp(x), exp(x**2), x)
-1
>>> compare(exp(x), x**5, x)
1
diofant.series.gruntz.limitinf(e, x)[source]

Compute limit of the expression at the infinity.

Examples

>>> from diofant import Symbol, exp, log
>>> x = Symbol('x', real=True, positive=True)
>>> limitinf(exp(x)*(exp(1/x - exp(-x)) - exp(1/x)), x)
-1
>>> limitinf(x/log(x**(log(x**(log(2)/log(x))))), x)
oo
diofant.series.gruntz.mrv(e, x)[source]

Calculate the MRV set of expression.

Examples

>>> from diofant import Symbol, exp, log
>>> x = Symbol('x', real=True, positive=True)
>>> mrv(log(x - log(x))/log(x), x)
{x}
>>> mrv(exp(x + exp(-x)), x)
{E**(-x), E**(x + E**(-x))}
diofant.series.gruntz.mrv_leadterm(e, x)[source]

Compute the leading term of the series.

Returns:

tuple

The leading term \(c_0 w^{e_0}\) of the series of \(e\) in terms of the most rapidly varying subexpression \(w\) in form of the pair (c0, e0) of Expr.

Examples

>>> from diofant import Symbol, exp
>>> x = Symbol('x', real=True, positive=True)
>>> mrv_leadterm(1/exp(-x + exp(-x)) - exp(x), x)
(-1, 0)
diofant.series.gruntz.mrv_max(f, g, x)[source]

Computes the maximum of two MRV sets.

diofant.series.gruntz.rewrite(e, x, w)[source]

Rewrites expression in terms of the most rapidly varying subexpression.

Parameters:

e : Expr

an expression

x : Symbol

variable of the \(e\)

w : Symbol

The symbol which is going to be used for substitution in place of the most rapidly varying in \(x\) subexpression.

Returns:

tuple

A pair: rewritten (in \(w\)) expression and \(\log(w)\).

Examples

>>> from diofant import Symbol, exp
>>> x = Symbol('x', real=True, positive=True)
>>> m = Symbol('m', real=True, positive=True)
>>> rewrite(exp(x), x, m)
(1/m, -x)
>>> rewrite(exp(x)*log(log(exp(x))), x, m)
(log(x)/m, -x)
diofant.series.gruntz.sign(e, x)[source]

Determine a sign of an expression at infinity.

Returns:

{1, 0, -1}

One or minus one, if \(e > 0\) or \(e < 0\) for \(x\) sufficiently large and zero if \(e\) is constantly zero for \(x\to\infty\).

The result of this function is currently undefined if \(e\) changes sign arbitarily often at infinity (e.g. \(\sin(x)\)).