Elliptic functions

Elliptic integrals

ellipk()

mpmath.functions.ellipk(x, **kwargs)

Evaluates the complete elliptic integral of the first kind, K(m), defined by

K(m) = \int_0^{\pi/2} \frac{1}{\sqrt{1-m \sin^2 t}} dt.

Note that the argument is the parameter m = k^2, not the modulus k which is sometimes used.

Alternatively, in terms of a hypergeometric function, we have:

K(m) = \frac{\pi}{2} \,_2F_1(1/2, 1/2, 1, m)

Examples

Values and limits include:

>>> from mpmath import *
>>> mp.dps = 25; mp.pretty = True
>>> ellipk(0)
1.570796326794896619231322
>>> ellipk(inf)
(0.0 + 0.0j)
>>> ellipk(-inf)
0.0
>>> ellipk(1)
+inf
>>> ellipk(-1)
1.31102877714605990523242
>>> ellipk(2)
(1.31102877714605990523242 - 1.31102877714605990523242j)

Verifying the defining integral and hypergeometric representation:

>>> ellipk(0.5)
1.85407467730137191843385
>>> quad(lambda t: (1-0.5*sin(t)**2)**-0.5, [0, pi/2])
1.85407467730137191843385
>>> pi/2*hyp2f1(0.5,0.5,1,0.5)
1.85407467730137191843385

Evaluation is supported for arbitrary complex m:

>>> ellipk(3+4j)
(0.9111955638049650086562171 + 0.6313342832413452438845091j)

A definite integral:

>>> quad(ellipk, [0, 1])
2.0

ellipe()

mpmath.functions.ellipe(x, **kwargs)

Evaluates the complete elliptic integral of the second kind, E(m), defined by

E(m) = \int_0^{\pi/2} \sqrt{1-m \sin^2 t} dt.

Note that the argument is the parameter m = k^2, not the modulus k which is sometimes used.

Alternatively, in terms of a hypergeometric function, we have:

E(m) = \frac{\pi}{2} \,_2F_1(1/2, -1/2, 1, m)

Examples

Basic values and limits:

>>> from mpmath import *
>>> mp.dps = 25; mp.pretty = True
>>> ellipe(0)
1.570796326794896619231322
>>> ellipe(1)
1.0
>>> ellipe(-1)
1.910098894513856008952381
>>> ellipe(2)
(0.5990701173677961037199612 + 0.5990701173677961037199612j)
>>> ellipe(inf)
(0.0 + +infj)
>>> ellipe(-inf)
+inf

Verifying the defining integral and hypergeometric representation:

>>> ellipe(0.5)
1.350643881047675502520175
>>> quad(lambda t: sqrt(1-0.5*sin(t)**2), [0, pi/2])
1.350643881047675502520175
>>> pi/2*hyp2f1(0.5,-0.5,1,0.5)
1.350643881047675502520175

Evaluation is supported for arbitrary complex m:

>>> ellipe(0.5+0.25j)
(1.360868682163129682716687 - 0.1238733442561786843557315j)
>>> ellipe(3+4j)
(1.499553520933346954333612 - 1.577879007912758274533309j)

A definite integral:

>>> quad(ellipe, [0,1])
1.333333333333333333333333

Jacobi theta functions

jtheta()

mpmath.elliptic.jtheta(n, z, q)

Computes the Jacobi theta function \vartheta_n(z, q), where n = 1, 2, 3, 4. The theta functions are functions of two variables:

  • z is the argument, an arbitrary real or complex number
  • q is the nome, which must be a real or complex number in the unit disk (i.e. |q| < 1)

One also commonly encounters the notation \vartheta_n(z, \tau) in the literature. The variable \tau is called the parameter and can be converted to a nome using the formula q = \exp(i \pi \tau). Note the condition |q| < 1 requires \Im(\tau) > 0; i.e. Jacobi theta functions are defined for \tau in the upper half plane.

Other notations are also in use. For example, some authors use the single-argument form \vartheta_n(x). Depending on context, this can mean jtheta(n, 0, x), jtheta(n, x, q), or possibly something else. Needless to say, it is a good idea to cross-check the definitions when working with theta functions.

Definition

The four Jacobi theta functions as implemented by jtheta() are defined by the following infinite series:

\vartheta_1(z,q) = 2 q^{1/4} \sum_{n=0}^{\infty} (-1)^n q^{n^2+n\,} \sin((2n+1)z) \vartheta_2(z,q) = 2 q^{1/4} \sum_{n=0}^{\infty} q^{n^{2\,} + n} \cos((2n+1)z) \vartheta_3(z,q) = 1 + 2 \sum_{n=0}^{\infty} q^{n^2\,} \cos(2 n z) \vartheta_4(z,q) = 1 + 2 \sum_{n=0}^{\infty} (-q)^{n^2\,} \cos(2 n z)

For |q| \ll 1, these series converge very quickly, so the Jacobi theta functions can efficiently be evaluated to high precision.

Examples and basic properties

Considered as functions of z, the Jacobi theta functions may be viewed as generalizations of the ordinary trigonometric functions cos and sin. They are periodic functions:

>>> from mpmath import *
>>> mp.dps = 15; mp.pretty = True
>>> jtheta(1, 0.1, 1/5.)
0.117756191842059
>>> jtheta(1, 0.1 + 2*pi, 1/5.)
0.117756191842059

Indeed, the series defining the theta functions are essentially trigonometric Fourier series. The coefficients can be retrieved using fourier():

>>> nprint(fourier(lambda x: jtheta(2, x, 0.5), [-pi, pi], 4))
([0.0, 1.68179, 0.0, 0.420448, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0])

The Jacobi theta functions are also so-called quasiperiodic functions of z and \tau, meaning that for fixed \tau, \vartheta_n(z, q) and \vartheta_n(z+\pi \tau, q) are the same except for an exponential factor:

>>> tau = 0.3*j
>>> q = exp(pi*j*tau)
>>> z = 10
>>> jtheta(4, z+tau*pi, q)
(-0.682420280786035 + 1.5266839997214j)
>>> -exp(-2*j*z)/q * jtheta(4, z, q)
(-0.682420280786035 + 1.5266839997214j)

The Jacobi theta functions satisfy a huge number of other functional equations, such as the following identity (valid for any q):

>>> q = 0.3
>>> jtheta(3,0,q)**4
6.82374408935276
>>> jtheta(2,0,q)**4 + jtheta(4,0,q)**4
6.82374408935276

Extensive listings of identities satisfied by the Jacobi theta functions can be found in standard reference works.

The Jacobi theta functions are related to the gamma function for special arguments:

>>> jtheta(3, 0, exp(-pi))
1.08643481121331
>>> pi**(1/4.) / gamma(3/4.)
1.08643481121331

jtheta() supports arbitrary precision evaluation and complex arguments:

>>> mp.dps = 50
>>> jtheta(4, sqrt(2), 0.5)
2.0549510717571539127004115835148878097035750653737
>>> mp.dps = 25
>>> jtheta(4, 1+2j, (1+j)/5)
(7.180331760146805926356634 - 1.634292858119162417301683j)

Possible issues

For |q| \ge 1 or \Im(\tau) \le 0, jtheta() raises ValueError. This exception is also raised for |q| extremely close to 1 (or equivalently \tau very close to 0), since the series would converge too slowly:

>>> jtheta(1, 10, 0.99999999 * exp(0.5*j))
Traceback (most recent call last):
  ...
ValueError: abs(q) > Q_LIM = 1.000000

djtheta()

mpmath.elliptic.djtheta(n, z, q, nd=1)

For an integer nd \ge 1, computes the nd:th derivative with respect to z of the Jacobi theta function \vartheta_n(z,q):

>>> from mpmath import *
>>> mp.dps = 15; mp.pretty = True
>>> djtheta(3, 7, 0.2)
-0.795947847483158
>>> diff(lambda x: jtheta(3, x, 0.2), 7)
-0.795947847483158

For additional details, see jtheta().

Jacobi elliptic functions

jsn()

mpmath.elliptic.jsn(u, m)

Computes of the Jacobi elliptic sn function in terms of Jacobi theta functions. u is any complex number, m must be in the unit disk

The sn-function is doubly periodic in the complex plane with periods 4 K(m) and 2 i K(1-m) (see ellipk()):

>>> from mpmath import *
>>> mp.dps = 25; mp.pretty = True
>>> jsn(2, 0.25)
0.9628981775982774425751399
>>> jsn(2+4*ellipk(0.25), 0.25)
0.9628981775982774425751399
>>> chop(jsn(2+2*j*ellipk(1-0.25), 0.25))
0.9628981775982774425751399

jcn()

mpmath.elliptic.jcn(u, m)

Computes of the Jacobi elliptic cn function in terms of Jacobi theta functions. u is any complex number, m must be in the unit disk

The cn-function is doubly periodic in the complex plane with periods 4 K(m) and 4 i K(1-m) (see ellipk()):

>>> from mpmath import *
>>> mp.dps = 25; mp.pretty = True
>>> jcn(2, 0.25)
-0.2698649654510865792581416
>>> jcn(2+4*ellipk(0.25), 0.25)
-0.2698649654510865792581416
>>> chop(jcn(2+4*j*ellipk(1-0.25), 0.25))
-0.2698649654510865792581416

jdn()

mpmath.elliptic.jdn(u, m)

Computes of the Jacobi elliptic dn function in terms of Jacobi theta functions. u is any complex number, m must be in the unit disk

The dn-function is doubly periodic in the complex plane with periods 2 K(m) and 4 i K(1-m) (see ellipk()):

>>> from mpmath import *
>>> mp.dps = 25; mp.pretty = True
>>> jdn(2, 0.25)
0.8764740583123262286931578
>>> jdn(2+2*ellipk(0.25), 0.25)
0.8764740583123262286931578
>>> chop(jdn(2+4*j*ellipk(1-0.25), 0.25))
0.8764740583123262286931578