This module implements elementary functions, as well as functions like Abs, Max, etc.
Returns the absolute value of the argument.
>>> from sympy.functions import Abs
>>> Abs(-1)
1
Return the absolute value of the argument.
This is an extension of the built-in function abs() to accept symbolic values. If you pass a SymPy expression to the built-in abs(), it will pass it automatically to Abs().
Examples
>>> from sympy import Abs, Symbol, S
>>> Abs(-1)
1
>>> x = Symbol('x', real=True)
>>> Abs(-x)
Abs(x)
>>> Abs(x**2)
x**2
>>> abs(-x) # The Python built-in
Abs(x)
Note that the Python built-in will return either an Expr or int depending on the argument:
>>> type(abs(-1))
<type 'int'>
>>> type(abs(S.NegativeOne))
<class 'sympy.core.numbers.One'>
Abs will always return a sympy object.
Returns the argument (in radians) of a complex number. For a real number, the argument is always 0.
>>> from sympy.functions import arg
>>> from sympy import I, sqrt
>>> arg(2.0)
0
>>> arg(I)
pi/2
>>> arg(sqrt(2) + I*sqrt(2))
pi/4
Returns the ‘complex conjugate <http://en.wikipedia.org/wiki/Complex_conjugation>’_ of an argument. In mathematics, the complex conjugate of a complex number is given by changing the sign of the imaginary part. Thus, the conjugate of the complex number
a + ib
(where a and b are real numbers) is
a - ib
>>> from sympy.functions import conjugate
>>> from sympy import I
>>> conjugate(2)
2
>>> conjugate(I)
-I
Returns the minimum of two (comparable) expressions.
>>> from sympy.functions import Min
>>> Min(1,2)
1
>>> from sympy.abc import x
>>> Min(1, x)
Min(1, x)
It is named Min and not min to avoid conflicts with the built-in function min.
Return, if possible, the minimum value of the list.
>>> from sympy import Min, Symbol, oo
>>> from sympy.abc import x, y
>>> p = Symbol('p', positive=True)
>>> n = Symbol('n', negative=True)
>>> Min(x, -2)
Min(x, -2)
>>> Min(x, -2).subs(x, 3)
-2
>>> Min(p, -3)
-3
>>> Min(x, y)
Min(x, y)
>>> Min(n, 8, p, -7, p, oo)
Min(n, -7)
Max() : find maximum values
Returns the maximum of two (comparable) expressions
It is named Max and not max to avoid conflicts with the built-in function max.
Return, if possible, the maximum value of the list.
When number of arguments is equal one, then return this argument.
When number of arguments is equal two, then return, if possible, the value from (a, b) that is >= the other.
In common case, when the length of list greater than 2, the task is more complicated. Return only the arguments, which are greater than others, if it is possible to determine directional relation.
If is not possible to determine such a relation, return a partially evaluated result.
Assumptions are used to make the decision too.
Also, only comparable arguments are permitted.
>>> from sympy import Max, Symbol, oo
>>> from sympy.abc import x, y
>>> p = Symbol('p', positive=True)
>>> n = Symbol('n', negative=True)
>>> Max(x, -2)
Max(x, -2)
>>> Max(x, -2).subs(x, 3)
3
>>> Max(p, -2)
p
>>> Max(x, y)
Max(x, y)
>>> Max(x, y) == Max(y, x)
True
>>> Max(x, Max(y, z))
Max(x, y, z)
>>> Max(n, 8, p, 7, -oo)
Max(8, p)
>>> Max (1, x, oo)
oo
The task can be considered as searching of supremums in the directed complete partial orders [1]_.
The source values are sequentially allocated by the isolated subsets in which supremums are searched and result as Max arguments.
If the resulted supremum is single, then it is returned.
The isolated subsets are the sets of values which are only the comparable with each other in the current set. E.g. natural numbers are comparable with each other, but not comparable with the \(x\) symbol. Another example: the symbol \(x\) with negative assumption is comparable with a natural number.
Also there are “least” elements, which are comparable with all others, and have a zero property (maximum or minimum for all elements). E.g. \(oo\). In case of it the allocation operation is terminated and only this value is returned.
[1] http://en.wikipedia.org/wiki/Directed_complete_partial_order [2] http://en.wikipedia.org/wiki/Lattice_(order)
Min() : find minimum values
Return the real part of an expression
>>> from sympy.functions import re
>>> from sympy import I
>>> re(2+3*I)
2
Returns real part of expression. This function performs only elementary analysis and so it will fail to decompose properly more complicated expressions. If completely simplified result is needed then use Basic.as_real_imag() or perform complex expansion on instance of this function.
>>> from sympy import re, im, I, E
>>> from sympy.abc import x, y
>>> re(2*E)
2*E
>>> re(2*I + 17)
17
>>> re(2*I)
0
>>> re(im(x) + x*I + 2)
2
Returns the square root of an expression. It is equivalent to raise to Rational(1,2)
>>> from sympy.functions import sqrt
>>> from sympy import Rational
>>> sqrt(2) == 2**Rational(1,2)
True
0 if expr is zero 1 if expr is positive
>>> from sympy.functions import sign
>>> sign(-1)
-1
>>> sign(0)
0
This module implements various combinatorial functions.
Implementation of the binomial coefficient. It can be defined in two ways depending on its desired interpretation:
C(n,k) = n!/(k!(n-k)!) or C(n, k) = ff(n, k)/k!
First, in a strict combinatorial sense it defines the number of ways we can choose ‘k’ elements from a set of ‘n’ elements. In this case both arguments are nonnegative integers and binomial is computed using an efficient algorithm based on prime factorization.
The other definition is generalization for arbitrary ‘n’, however ‘k’ must also be nonnegative. This case is very useful when evaluating summations.
For the sake of convenience for negative ‘k’ this function will return zero no matter what valued is the other argument.
>>> from sympy import Symbol, Rational, binomial
>>> n = Symbol('n', integer=True)
>>> binomial(15, 8)
6435
>>> binomial(n, -1)
0
>>> [ binomial(0, i) for i in range(1)]
[1]
>>> [ binomial(1, i) for i in range(2)]
[1, 1]
>>> [ binomial(2, i) for i in range(3)]
[1, 2, 1]
>>> [ binomial(3, i) for i in range(4)]
[1, 3, 3, 1]
>>> [ binomial(4, i) for i in range(5)]
[1, 4, 6, 4, 1]
>>> binomial(Rational(5,4), 3)
-5/128
>>> binomial(n, 3)
n*(n - 2)*(n - 1)/6
Implementation of factorial function over nonnegative integers. For the sake of convenience and simplicity of procedures using this function it is defined for negative integers and returns zero in this case.
The factorial is very important in combinatorics where it gives the number of ways in which ‘n’ objects can be permuted. It also arises in calculus, probability, number theory etc.
There is strict relation of factorial with gamma function. In fact n! = gamma(n+1) for nonnegative integers. Rewrite of this kind is very useful in case of combinatorial simplification.
Computation of the factorial is done using two algorithms. For small arguments naive product is evaluated. However for bigger input algorithm Prime-Swing is used. It is the fastest algorithm known and computes n! via prime factorization of special class of numbers, called here the ‘Swing Numbers’.
>>> from sympy import Symbol, factorial
>>> n = Symbol('n', integer=True)
>>> factorial(-2)
0
>>> factorial(0)
1
>>> factorial(7)
5040
>>> factorial(n)
n!
>>> factorial(2*n)
(2*n)!
Falling factorial (related to rising factorial) is a double valued function arising in concrete mathematics, hypergeometric functions and series expansions. It is defined by
ff(x, k) = x * (x-1) * ... * (x - k+1)
where ‘x’ can be arbitrary expression and ‘k’ is an integer. For more information check “Concrete mathematics” by Graham, pp. 66 or visit http://mathworld.wolfram.com/FallingFactorial.html page.
>>> from sympy import ff
>>> from sympy.abc import x
>>> ff(x, 0)
1
>>> ff(5, 5)
120
>>> ff(x, 5) == x*(x-1)*(x-2)*(x-3)*(x-4)
True
Rising factorial (also called Pochhammer symbol) is a double valued function arising in concrete mathematics, hypergeometric functions and series expansions. It is defined by
rf(x, k) = x * (x+1) * ... * (x + k-1)
where ‘x’ can be arbitrary expression and ‘k’ is an integer. For more information check “Concrete mathematics” by Graham, pp. 66 or visit http://mathworld.wolfram.com/RisingFactorial.html page.
>>> from sympy import rf
>>> from sympy.abc import x
>>> rf(x, 0)
1
>>> rf(1, 5)
120
>>> rf(x, 5) == x*(1 + x)*(2 + x)*(3 + x)*(4 + x)
True
DiracDelta function, and the derivatives. DiracDelta function has the following properties: 1) diff(Heaviside(x),x) = DiracDelta(x) 2) integrate(DiracDelta(x-a)*f(x),(x,-oo,oo)) = f(a)
integrate(DiracDelta(x-a)*f(x),(x,a-e,a+e)) = f(a)
Derivatives of k order of DiracDelta have the following property: 5) DiracDelta(x,k) = 0, for all x!=0
For more information, see: http://mathworld.wolfram.com/DeltaFunction.html
Heaviside Piecewise function. Heaviside function has the following properties: 1) diff(Heaviside(x),x) = DiracDelta(x)
( 0, if x<0
( 1, if x>0
[*]Regarding to the value at 0, Mathematica adopt the value H(0)=1, and Maple H(0)=undefined
I think is better to have H(0)=1/2, due to the following: integrate(DiracDelta(x),x) = Heaviside(x) integrate(DiracDelta(x),(x,-oo,oo)) = 1
and since DiracDelta is a symmetric function, integrate(DiracDelta(x),(x,0,oo)) should be 1/2 in fact, that is what maple returns.
If we take Heaviside(0)=1/2, we would have integrate(DiracDelta(x),(x,0,oo)) = Heaviside(oo)-Heaviside(0)=1-1/2= 1/2 and integrate(DiracDelta(x),(x,-oo,0)) = Heaviside(0)-Heaviside(-oo)=1/2-0= 1/2
If we consider, instead Heaviside(0)=1, we would have integrate(DiracDelta(x),(x,0,oo)) = Heaviside(oo)-Heaviside(0) = 0 and integrate(DiracDelta(x),(x,-oo,0)) = Heaviside(0)-Heaviside(-oo) = 1
For more information, see: http://mathworld.wolfram.com/HeavisideStepFunction.html
The gamma function returns a function which passes through the integral values of the factorial function, i.e. though defined in the complex plane, when n is an integer, gamma(n) = (n - 1)!
Upper incomplete gamma function
It can be defined as the meromorphic continuation of
This can be shown to be the same as
where \({}_1F_1\) is the (confluent) hypergeometric function.
Examples
>>> from sympy import uppergamma, S
>>> from sympy.abc import s, x
>>> uppergamma(s, x)
uppergamma(s, x)
>>> uppergamma(3, x)
x**2*exp(-x) + 2*x*exp(-x) + 2*exp(-x)
>>> uppergamma(-S(1)/2, x)
-2*pi**(1/2)*(-erf(x**(1/2)) + 1) + 2*exp(-x)/x**(1/2)
See also: gamma, lowergamma, hyper.
References
Lower incomplete gamma function
It can be defined as the meromorphic continuation of
This can be shown to be the same as
where \({}_1F_1\) is the (confluent) hypergeometric function.
See also: gamma, uppergamma, hyper.
Examples
>>> from sympy import lowergamma, S
>>> from sympy.abc import s, x
>>> lowergamma(s, x)
lowergamma(s, x)
>>> lowergamma(3, x)
-x**2*exp(-x) - 2*x*exp(-x) + 2 - 2*exp(-x)
>>> lowergamma(-S(1)/2, x)
-2*pi**(1/2)*erf(x**(1/2)) - 2*exp(-x)/x**(1/2)
References
Bessel function of the first kind.
The Bessel J function of order \(\nu\) is defined to be the function satisfying Bessel’s differential equation
with Laurent expansion
if \(\nu\) is not a negative integer. If \(\nu=-n \in \mathbb{Z}_{<0}\) is a negative integer, then the definition is
Examples
Create a bessel function object:
>>> from sympy import besselj, jn
>>> from sympy.abc import z, n
>>> b = besselj(n, z)
Differentiate it:
>>> b.diff(z)
besselj(n - 1, z)/2 - besselj(n + 1, z)/2
Rewrite in terms of spherical bessel functions:
>>> b.rewrite(jn)
2**(1/2)*z**(1/2)*jn(n - 1/2, z)/pi**(1/2)
Access the parameter and argument:
>>> b.order
n
>>> b.argument
z
References
Bessel function of the second kind.
The Bessel Y function of order \(\nu\) is defined as
where \(J_\mu(z)\) is the Bessel function of the first kind.
It is a solution to Bessel’s equation, and linearly independent from \(J_\nu\).
Examples
>>> from sympy import bessely, yn
>>> from sympy.abc import z, n
>>> b = bessely(n, z)
>>> b.diff(z)
bessely(n - 1, z)/2 - bessely(n + 1, z)/2
>>> b.rewrite(yn)
2**(1/2)*z**(1/2)*yn(n - 1/2, z)/pi**(1/2)
See also: besselj
Modified Bessel function of the first kind.
The Bessel I function is a solution to the modified Bessel equation
It can be defined as
where \(J_\mu(z)\) is the Bessel function of the first kind.
Examples
>>> from sympy import besseli
>>> from sympy.abc import z, n
>>> besseli(n, z).diff(z)
besseli(n - 1, z)/2 + besseli(n + 1, z)/2
See also: besselj
Modified Bessel function of the second kind.
The Bessel K function of order \(\nu\) is defined as
where \(I_\mu(z)\) is the modified Bessel function of the first kind.
It is a solution of the modified Bessel equation, and linearly independent from \(Y_\nu\).
Examples
>>> from sympy import besselk
>>> from sympy.abc import z, n
>>> besselk(n, z).diff(z)
-besselk(n - 1, z)/2 - besselk(n + 1, z)/2
See also: besselj
Hankel function of the first kind.
This function is defined as
where \(J_\nu(z)\) is the Bessel function of the first kind, and \(Y_\nu(z)\) is the Bessel function of the second kind.
It is a solution to Bessel’s equation.
Examples
>>> from sympy import hankel1
>>> from sympy.abc import z, n
>>> hankel1(n, z).diff(z)
hankel1(n - 1, z)/2 - hankel1(n + 1, z)/2
See also: besselj
Hankel function of the second kind.
This function is defined as
where \(J_\nu(z)\) is the Bessel function of the first kind, and \(Y_\nu(z)\) is the Bessel function of the second kind.
It is a solution to Bessel’s equation, and linearly independent from \(H_\nu^{(1)}\).
Examples
>>> from sympy import hankel2
>>> from sympy.abc import z, n
>>> hankel2(n, z).diff(z)
hankel2(n - 1, z)/2 - hankel2(n + 1, z)/2
See also: besselj
Spherical Bessel function of the first kind.
This function is a solution to the spherical bessel equation
It can be defined as
where \(J_\nu(z)\) is the Bessel function of the first kind.
Examples
>>> from sympy import Symbol, jn, sin, cos, expand_func
>>> z = Symbol("z")
>>> print jn(0, z).expand(func=True)
sin(z)/z
>>> jn(1, z).expand(func=True) == sin(z)/z**2 - cos(z)/z
True
>>> expand_func(jn(3, z))
(-6/z**2 + 15/z**4)*sin(z) + (1/z - 15/z**3)*cos(z)
The spherical Bessel functions of integral order are calculated using the formula:
where the coefficients \(f_n(z)\) are available as polys.orthopolys.spherical_bessel_fn().
See also: besselj
Spherical Bessel function of the second kind.
This function is another solution to the spherical bessel equation, and linearly independent from \(j_n\). It can be defined as
where \(Y_\nu(z)\) is the Bessel function of the second kind.
Examples
>>> from sympy import Symbol, yn, sin, cos, expand_func
>>> z = Symbol("z")
>>> print expand_func(yn(0, z))
-cos(z)/z
>>> expand_func(yn(1, z)) == -cos(z)/z**2-sin(z)/z
True
For integral orders \(n\), \(y_n\) is calculated using the formula:
See also: besselj, bessely, jn
The (generalized) hypergeometric function is defined by a series where the ratios of successive terms are a rational function of the summation index. When convergent, it is continued analytically to the largest possible domain.
The hypergeometric function depends on two vectors of parameters, called the numerator parameters \(a_p\), and the denominator parameters \(b_q\). It also has an argument \(z\). The series definition is
where \((a)_n = (a)(a+1)\dots(a+n-1)\) denotes the rising factorial.
If one of the \(b_q\) is a non-positive integer then the series is undefined unless one of the \(a_p\) is a larger (i.e. smaller in magnitude) non-positive integer. If none of the \(b_q\) is a non-positive integer and one of the \(a_p\) is a non-positive integer, then the series reduces to a polynomial. To simplify the following discussion, we assume that none of the \(a_p\) or \(b_q\) is a non-positive integer. For more details, see the references.
The series converges for all \(z\) if \(p \le q\), and thus defines an entire single-valued function in this case. If \(p = q+1\) the series converges for \(|z| < 1\), and can be continued analytically into a half-plane. If \(p > q+1\) the series is divergent for all \(z\).
Note: The hypergeometric function constructor currently does not check if the parameters actually yield a well-defined function.
Examples
The parameters \(a_p\) and \(b_q\) can be passed as arbitrary iterables, for example:
>>> from sympy.functions import hyper
>>> from sympy.abc import x, n, a
>>> hyper((1, 2, 3), [3, 4], x)
hyper((1, 2, 3), (3, 4), x)
There is also pretty printing (it looks better using unicode):
>>> from sympy import pprint
>>> pprint(hyper((1, 2, 3), [3, 4], x), use_unicode=False)
_
|_ /1, 2, 3 | \
| | | x|
3 2 \ 3, 4 | /
The parameters must always be iterables, even if they are vectors of length one or zero:
>>> hyper((1, ), [], x)
hyper((1,), (), x)
But of course they may be variables (but if they depend on x then you should not expect much implemented functionality):
>>> hyper((n, a), (n**2,), x)
hyper((n, a), (n**2,), x)
The hypergeometric function generalises many named special functions. The function hyperexpand() tries to express a hypergeometric function using named special functions. For example:
>>> from sympy import hyperexpand
>>> hyperexpand(hyper([], [], x))
exp(x)
You can also use expand_func:
>>> from sympy import expand_func
>>> expand_func(x*hyper([1, 1], [2], -x))
log(x + 1)
More examples:
>>> from sympy import S
>>> hyperexpand(hyper([], [S(1)/2], -x**2/4))
cos(x)
>>> hyperexpand(x*hyper([S(1)/2, S(1)/2], [S(3)/2], x**2))
asin(x)
We can also sometimes hyperexpand parametric functions:
>>> from sympy.abc import a
>>> hyperexpand(hyper([-a], [], x))
(-x + 1)**a
See Also:
References
The Meijer G-function is defined by a Mellin-Barnes type integral that resembles an inverse Mellin transform. It generalises the hypergeometric functions.
The Meijer G-function depends on four sets of parameters. There are “numerator parameters” \(a_1, \dots, a_n\) and \(a_{n+1}, \dots, a_p\), and there are “denominator parameters” \(b_1, \dots, b_m\) and \(b_{m+1}, \dots, b_q\). Confusingly, it is traditionally denoted as follows (note the position of \(m\), \(n\), \(p\), \(q\), and how they relate to the lengths of the four parameter vectors):
However, in sympy the four parameter vectors are always available separately (see examples), so that there is no need to keep track of the decorating sub- and super-scripts on the G symbol.
The G function is defined as the following integral:
where \(\Gamma(z)\) is the gamma function. There are three possible contours which we will not describe in detail here (see the references). If the integral converges along more than one of them the definitions agree. The contours all separate the poles of \(\Gamma(1-a_j+s)\) from the poles of \(\Gamma(b_k-s)\), so in particular the G function is undefined if \(a_j - b_k \in \mathbb{Z}_{>0}\) for some \(j \le n\) and \(k \le m\).
The conditions under which one of the contours yields a convergent integral are complicated and we do not state them here, see the references.
Note: Currently the Meijer G-function constructor does not check any convergence conditions.
Examples
You can pass the parameters either as four separate vectors:
>>> from sympy.functions import meijerg
>>> from sympy.abc import x, a
>>> from sympy.core.containers import Tuple
>>> from sympy import pprint
>>> pprint(meijerg((1, 2), (a, 4), (5,), [], x), use_unicode=False)
__1, 2 /1, 2 a, 4 | \
/__ | | x|
\_|4, 1 \ 5 | /
or as two nested vectors:
>>> pprint(meijerg([(1, 2), (3, 4)], ([5], Tuple()), x), use_unicode=False)
__1, 2 /1, 2 3, 4 | \
/__ | | x|
\_|4, 1 \ 5 | /
As with the hypergeometric function, the parameters may be passed as arbitrary iterables. Vectors of length zero and one also have to be passed as iterables. The parameters need not be constants, but if they depend on the argument then not much implemented functionality should be expected.
All the subvectors of parameters are available:
>>> from sympy import pprint
>>> g = meijerg([1], [2], [3], [4], x)
>>> pprint(g, use_unicode=False)
__1, 1 /1 2 | \
/__ | | x|
\_|2, 2 \3 4 | /
>>> g.an
(1,)
>>> g.ap
(1, 2)
>>> g.aother
(2,)
>>> g.bm
(3,)
>>> g.bq
(3, 4)
>>> g.bother
(4,)
The Meijer G-function generalises the hypergeometric functions. In some cases it can be expressed in terms of hypergeometric functions, using Slater’s theorem. For example:
>>> from sympy import hyperexpand
>>> from sympy.abc import a, b, c
>>> hyperexpand(meijerg([a], [], [c], [b], x), allow_hyper=True)
x**c*gamma(-a + c + 1)*hyper((-a + c + 1,), (-b + c + 1,), -x)/gamma(-b + c + 1)
Thus the Meijer G-function also subsumes many named functions as special cases. You can use expand_func or hyperexpand to (try to) rewrite a Meijer G-function in terms of named special functions. For example:
>>> from sympy import expand_func, S
>>> expand_func(meijerg([[],[]], [[0],[]], -x))
exp(x)
>>> hyperexpand(meijerg([[],[]], [[S(1)/2],[0]], (x/2)**2))
sin(x)/pi**(1/2)
See Also:
References