Functions
=========

Mpmath provides a rich collection of mathematical functions.

Constants (``pi``, ``e``, etc)
------------------------------

The predefined objects ``j`` (imaginary unit), ``inf`` (positive infinity) and ``nan`` (not-a-number) are shortcuts to ``mpc`` and ``mpf`` instances with these fixed values.

Mpmath supports arbitrary-precision computation of various common (and less common) mathematical constants.

+------------+-------------+-------------------------------------+
| Symbol     | Value       |  Description                        |
+------------+-------------+-------------------------------------+
| ``pi``     | 3.141592654 | Area of the unit circle             |
+------------+-------------+-------------------------------------+
| ``degree`` | 0.017453292 | 1 degree of angle = pi/180          |
+------------+-------------+-------------------------------------+
| ``e``      | 2.718281828 | Base of the natural logarithm       |
+------------+-------------+-------------------------------------+
| ``phi``    | 1.618033989 | The golden ratio, (1+sqrt(5))/2     |
+------------+-------------+-------------------------------------+
| ``ln2``    | 0.693147180 | The natural logarithm of 2          |
+------------+-------------+-------------------------------------+
| ``ln10``   | 2.302585093 | The natural logarithm of 10         |
+------------+-------------+-------------------------------------+
| ``euler``  | 0.577215664 | Euler's constant (gamma)            |
+------------+-------------+-------------------------------------+
|``catalan`` | 0.915965594 | Catalan's constant                  |
+------------+-------------+-------------------------------------+
| ``apery``  | 1.202056903 | Apery's constant, zeta(3)           |
+------------+-------------+-------------------------------------+
|``khinchin``| 2.685452001 | Khinchin's constant                 |
+------------+-------------+-------------------------------------+
|``glaisher``| 1.282427129 | Glaisher's constant                 |
+------------+-------------+-------------------------------------+

These constants are implemented as lazy objects that can be computed with any precision. Whenever the objects are used as function arguments or as operands in arithmetic operations, they automagically evaluate to the current working precision. A lazy number can be converted to a regular ``mpf`` using the unary ``+`` operator::

    >>> from mpmath import *
    >>> mp.dps = 15
    >>> pi
    <pi: 3.14159~>
    >>> 2*pi
    mpf('6.2831853071795862')
    >>> +pi
    mpf('3.1415926535897931')
    >>> mp.dps = 40
    >>> pi
    <pi: 3.14159~>
    >>> 2*pi
    mpf('6.283185307179586476925286766559005768394338')
    >>> +pi
    mpf('3.141592653589793238462643383279502884197169')

To show many digits of a number, you can just set the desired precision and print it:

>>> mp.dps = 1000
>>> print pi    # doctest:+SKIP
3.141592653589793238462643383279502884197169399375105820974944592307816406286208

32171226806613001927876611195909216420198

The time needed to compute many digits of the various constants differs greatly. On the author's computer, the golden ratio can be evaluated to 100,000 digits in one second, while obtaining just 500 digits of Khinchin's constant takes several seconds. However, mpmath caches computed values of constants so that subsequent calculations at the same or lower precision are instant. This important for general efficiency reasons since for example the value of pi is required internally by mpmath to compute trigonometric functions.

Elementary functions (``sqrt``, ``exp``, ``sin``, ...)
------------------------------------------------------

Mpmath implements the standard functions available in Python's ``math`` and ``cmath`` modules, for both real and complex numbers and with arbitrary precision. Many other named elementary functions are also available, including the reciprocal trigonometric and hyperbolic functions sec, csc, cot, sech, etc. Here are some simple evaluations using elementary functions:

    >>> mp.dps = 25
    >>> print cosh('1.234')
    1.863033801698422589073644
    >>> print asin(1)
    1.570796326794896619231322
    >>> print log(1+2j)
    (0.8047189562170501873003797 + 1.107148717794090503017065j)
    >>> print exp(2+3j)
    (-7.315110094901102517486536 + 1.042743656235904414101504j)

Trigonometric functions can be evaluated at degree angles using the ``degree`` constant:

    >>> mp.dps = 15
    >>> print cos(45*degree)
    0.707106781186548

An example with very high precision:

    >>> mp.dps = 500
    >>> print tanh(pi)     # doctest:+SKIP
    0.996272076220749944264690580012536711896899190804587614362612415978541298982821
    71768528355120691683454615502559430681804165984973439112096298906391022044704505
    48122748988701224416244977555668537821981195835666118518137460301886473587466464
    21806234986385738703533092864596585365203757599676939623117433432914420827886553
    76127620464757884951425425306744563300307924663159394900310518383521418687640452
    46705057548209662896867568997817626620037806847842642167105610253517933039999796
    6863567179835779017033

The Lambert W function is the inverse function of w*exp(w):

    >>> mp.dps = 35
    >>> w = lambertw(1)
    >>> print w
    0.56714329040978387299996866221035555
    >>> print w*exp(w)
    1.0

The Lambert W function has infinitely many complex branches. By default, the principal branch (k = 0) is evaluated. You can choose a custom branch:

    >>> w = lambertw(1, k=3)
    >>> print w
    (-2.8535817554090378072068187234910812 + 17.113535539412145912607826671159289j)
    >>> print w*exp(w)
    (1.0 - 9.9465893710591698326300157883907326e-38j)

The list of available elementary functions (and related simple functions) is given in the following table.

=====================   ==================================================================
Function                Description
=====================   ==================================================================
``sqrt(x)``             Square root
``hypot(x,y)``          Euclidean norm
``exp(x)``              Exponential function
``log(x,b)``            Natural logarithm (optionally base-b logarithm)
``power(x,y)``          Power, ``x**y``
``floor(x)``            Floor function (round to integer in the direction of -inf)
``ceil(x)``             Ceiling function (round to integer in the direction of +inf)
``arg(z)``              Complex argument of z
``cos(x)``              Cosine
``sin(x)``              Sine
``tan(x)``              Tangent
``sec(x)``              Secant
``csc(x)``              Cosecant
``cot(x)``              Cotangent
``cosh(x)``             Hyperbolic cosine
``sinh(x)``             Hyperbolic sine
``tanh(x)``             Hyperbolic tangent
``sech(x)``             Hyperbolic secant
``csch(x)``             Hyperbolic cosecant
``coth(x)``             Hyperbolic cotangent
``acos(x)``             Inverse cosine
``asin(x)``             Inverse sine
``atan(x)``             Inverse tangent
``atan2(y,x)``          Inverse tangent atan(y/x) with attention to signs of both x and y
``asec(x)``             Inverse secant
``acsc(x)``             Inverse cosecant
``acot(x)``             Inverse cotangent
``acosh(x)``            Inverse hyperbolic cosine
``asinh(x)``            Inverse hyperbolic sine
``atanh(x)``            Inverse hyperbolic tangent
``asech(x)``            Inverse hyperbolic secant
``acsch(x)``            Inverse hyperbolic cosecant
``acoth(x)``            Inverse hyperbolic cotangent
``lambertw(x,k)``       Lambert W function
=====================   ==================================================================

Nonelementary functions
-----------------------

Various useful nonelementary functions that do not exist in the standard Python ``math`` library are available, such as factorials (with support for noninteger arguments):

    >>> mp.dps = 20
    >>> print factorial(10)
    3628800.0
    >>> print factorial(0.25)
    0.90640247705547707798
    >>> print factorial(2+3j)
    (-0.44011340763700171113 - 0.06363724312631702183j)

The nonelementary functions can all be evaluated to high precision:

    >>> mp.dps = 200
    >>> print j0(ellipe(1/pi)) + erf(1)     # doctest:+SKIP
    1.389312963715905348881873975556967070995660558533781734716705228600460043954957
    61618134488095800072249215436991243117271403513444828929928306553194119494900584
    6834728102001723155155631593301614083021

The function ``hyper`` sums a general hypergeometric series (this works only for argument where the series converges):

    >>> print hyper([1,2,3],[4,5,6], 1/pi)     # doctest:+SKIP
    1.016210574248696702302096161058517020553783149632248720837030993406388717433423
    76737176412753643360654694328402996208151824851693763066257492700066724382806555
    22803873785096931980990953468408484030225

=====================   ==================================================================
Function                Description
=====================   ==================================================================
``factorial(x)``        Factorial
``gamma(x)``            Gamma function
``binomial(x,y)``       Binomial coefficient
``gammaprod(x,y)``      Gamma function product G(x[0])*G(x[1])... / (G(y[0])*G(y[1])...)
``rf(x,n)``             Rising factorial (Pochhammer symbol), x^(n)
``ff(x,n)``             Falling factorial, x_(n)
``lower_gamma(a,x)``    Lower gamma function
``upper_gamma(a,x)``    Upper gamma function
``erf(x)``              Error function
``zeta(x)``             Riemann zeta function
``bernoulli(n)``        Bernoulli number, B_n
``j0(x)``               Bessel function J_0(x)
``j1(x)``               Bessel function J_1(x)
``jn(n,x)``             Bessel function J_n(x)
``ellipe(x)``           Complete elliptic integral E
``ellipk(x)``           Complete elliptic integral K
``agm(x,y)``            Arithmetic geometric mean
``hyper(as,bs,z)``      Hypergeometric function PFQ
``hyp0f1(a,z)``         Hypergeometric function 0F1
``hyp1f1(a,b,z)``       Hypergeometric function 1F1
``hyp2f1(a,b,c,z)``     Hypergeometric function 2F1
``jacobi(n,a,b,x)``     Jacobi polynomial / Jacobi function
``legendre(n,x)``       Legendre polynomial / Legendre function
``chebyt(n,x)``         Chebyshev polynomial of the first kind, T_n(x)
``chebyu(n,x)``         Chebyshev polynomial of the second kind, U_n(x)
=====================   ==================================================================

Number sequences
----------------

For some functions, one is often interested in computing the sequence of values f(1), f(2), f(3), ... perhaps up to some unknown bound. Mpmath implements a few such sequences as generators. Use of these generators is generally much more efficient than computing each value from scratch. 

The precision of each generated number will be the same as that of the first, regardless of whether the global working precision is changed subsequently.

``bernoulli_range``
    Generates the Bernoulli numbers with positive even index: 1/6, -1/30, 1/42, ...

    >>> mp.dps = 15
    >>> b = bernoulli_range()
    >>> print b.next()
    0.166666666666667
    >>> print b.next()
    -0.0333333333333333

``log_range``
    Generates the nonzero integer logarithms: log(2), log(3), log(4), ...

    >>> l = log_range()
    >>> print l.next()
    0.693147180559945
    >>> print l.next()
    1.09861228866811

Utility functions
-----------------

Ranges
......

``arange``, with the same argument order as Python's built-in ``range`` function, generates a range of floating-point numbers, not including the endpoint:

    >>> arange(0, 1, 0.25)
    [mpf('0.0'), mpf('0.25'), mpf('0.5'), mpf('0.75')]

All three arguments must currently be given.

Current epsilon
...............

The special number ``eps`` is defined as the difference between 1 and the smallest floating-point number after 1 that can be represented with the current working precision::

    >>> mp.dps = 15
    >>> eps
    <epsilon of working precision: 2.22045e-16~>
    >>> 1 + eps
    mpf('1.0000000000000002')
    >>> 1 + eps/2    # Too small to make a difference
    mpf('1.0')
    >>>
    >>> mp.dps = 100
    >>> eps
    <epsilon of working precision: 1.42873e-101~>

An useful application of ``eps`` is to perform approximate comparisons that work at any precision level, for example to check for convergence of iterative algorithms::

    >>> def a_series():
    ...     s = 0
    ...     n = 1
    ...     while 1:
    ...         term = mpf(5) ** (-n)
    ...         s += term
    ...         if term < eps:
    ...             print "added", n, "terms"
    ...             return s
    ...         n += 1
    ...
    >>> mp.dps = 15
    >>> a_series()
    added 23 terms
    mpf('0.25000000000000011')
    >>>
    >>> mp.dps = 40
    >>> a_series()
    added 59 terms
    mpf('0.2500000000000000000000000000000000000000057')

Random numbers
..............

``rand()`` returns a random number chosen from the uniform distribution on the interval [0, 1). All bits up to the working precision are random (this is not true if generating a ``float`` directly with Python's ``random`` module and then converting it into an ``mpf``).

The output might look like this:

    >>> mp.dps = 30
    >>> for i in range(10): print rand()  # doctest:+SKIP
    ...
    0.391978954448554897401435871089
    0.0807882783964168543644048960474
    0.703930940186206635051721420436
    0.626158757167772268326252881759
    0.662757493867073525281224309434
    0.756414034497179767347019515565
    0.927214900855958669681240990671
    0.244655678804068448731650701685
    0.34560622640274419514821879678
    0.353366977589549657670073479468

Polynomial evaluation
.....................

Polynomial functions can be evaluated using ``polyval``, which takes as input a list of coefficients and the desired evaluation point. The following example evaluates 2 + 5x + x^3 at x = 3.5:

    >>> mp.dps = 20
    >>> polyval([2, 5, 0, 1], mpf('3.5'))
    mpf('62.375')

With ``derivative=True``, both the polynomial and its derivative are evaluated at the same point:

    >>> polyval([2, 5, 0, 1], mpf('3.5'), derivative=True)
    (mpf('62.375'), mpf('41.75'))

The point and coefficients may be complex numbers.
