Jacobi Elliptic Functions¶
This module implements the 12 Jacobi elliptic functions, along with their inverses and the Jacobi amplitude function.
Jacobi elliptic functions can be thought of as generalizations of both ordinary and hyperbolic trig functions. There are twelve Jacobian elliptic functions. Each of the twelve corresponds to an arrow drawn from one corner of a rectangle to another.
n ------------------- d
| |
| |
| |
s ------------------- c
Each of the corners of the rectangle are labeled, by convention, s,
c, d, and n. The rectangle is understood to be lying on the complex
plane, so that s is at the origin, c is on the real axis, and n is
on the imaginary axis. The twelve Jacobian elliptic functions are
then
, where p and q are one of the letters
s, c, d, n.
The Jacobian elliptic functions are then the unique doubly-periodic, meromorphic functions satisfying the following three properties:
- There is a simple zero at the corner
p, and a simple pole at the cornerq. - The step from
ptoqis equal to half the period of the function
; that is, the function
is
periodic in the direction pq, with the period being twice the distance fromptoq.
is periodic in the other two
directions as well, with a period such that the distance from pto one of the other corners is a quarter period. - If the function
is expanded in terms of
at one of
the corners, the leading term in the expansion has a coefficient of 1.
In other words, the leading term of the expansion of
at the corner pis
; the leading term of the expansion at the corner
qis
, and the leading term of an expansion at the other two
corners is 1.
We can write

where p, q, and r are any of the
letters s, c, d, n, with
the understanding that
.
Let

then the Jacobi elliptic function
is given by

and
is given by

and

To emphasize the dependence on
, one can write
for example (and similarly for
and
). This is the notation used below.
For a given
with
they therefore are
solutions to the following nonlinear ordinary differential
equations:
solves the differential equations
solves the differential equations
solves the differential equations
If
denotes the complete elliptic integral of the
first kind (named elliptic_kcin Sage), the elliptic functions
and
have real periods
, whereas
has a period
. The limit
gives
and trigonometric functions:
,
,
. The limit
gives
and hyperbolic functions:
,
,
.
REFERENCES:
| [KhaSuk04] | A. Khare and U. Sukhatme. “Cyclic Identities Involving Jacobi Elliptic Functions”. Arxiv math-ph/0201004 |
AUTHORS:
- David Joyner (2006): initial version
- Eviatar Bach (2013): complete rewrite, new numerical evaluation, and addition of the Jacobi amplitude function
-
class
sage.functions.jacobi.InverseJacobi(kind)¶ Bases:
sage.symbolic.function.BuiltinFunctionBase class for the inverse Jacobi elliptic functions.
-
class
sage.functions.jacobi.Jacobi(kind)¶ Bases:
sage.symbolic.function.BuiltinFunctionBase class for the Jacobi elliptic functions.
-
class
sage.functions.jacobi.JacobiAmplitude¶ Bases:
sage.symbolic.function.BuiltinFunctionThe Jacobi amplitude function
for
,
.
-
sage.functions.jacobi.inverse_jacobi(kind, x, m, **kwargs)¶ The inverses of the 12 Jacobi elliptic functions. They have the property that

INPUT:
kind– a string of the form'pq', wherep,qare inc,d,n,sx– a real numberm– a real number; note that
, where
is the elliptic
modulus
EXAMPLES:
sage: jacobi('dn', inverse_jacobi('dn', 3, 0.4), 0.4) 3.00000000000000 sage: inverse_jacobi('dn', 10, 1/10).n(digits=50) 2.4777736267904273296523691232988240759001423661683*I sage: inverse_jacobi_dn(x, 1) arcsech(x) sage: inverse_jacobi_dn(1, 3) 0 sage: m = var('m') sage: z = inverse_jacobi_dn(x, m).series(x, 4).subs(x=0.1, m=0.7) sage: jacobi_dn(z, 0.7) 0.0999892750039819... sage: inverse_jacobi_nd(x, 1) arccosh(x) sage: inverse_jacobi_nd(1, 2) 0 sage: inverse_jacobi_ns(10^-5, 3).n() 5.77350269202456e-6 + 1.17142008414677*I sage: jacobi('sn', 1/2, 1/2) jacobi_sn(1/2, 1/2) sage: jacobi('sn', 1/2, 1/2).n() 0.470750473655657 sage: inverse_jacobi('sn', 0.47, 1/2) 0.499098231322220 sage: inverse_jacobi('sn', 0.4707504, 0.5) 0.499999911466555 sage: P = plot(inverse_jacobi('sn', x, 0.5), 0, 1)
-
sage.functions.jacobi.inverse_jacobi_f(kind, x, m)¶ Internal function for numerical evaluation of a continous complex branch of each inverse Jacobi function, as described in [Tee97]. Only accepts real arguments.
REFERENCES:
[Tee97] Tee, Garry J. “Continuous branches of inverses of the 12 Jacobi elliptic functions for real argument”. 1997. https://researchspace.auckland.ac.nz/bitstream/handle/2292/5042/390.pdf. TESTS:
sage: from mpmath import ellipfun, chop sage: from sage.functions.jacobi import inverse_jacobi_f sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0.6, 0), 0)) mpf('0.59999999999999998') sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0.6, 1), 1)) mpf('0.59999999999999998') sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0, -3), -3)) mpf('0.0') sage: chop(ellipfun('sn', inverse_jacobi_f('sn', -1, 4), 4)) mpf('-1.0') sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0.3, 4), 4)) mpf('0.29999999999999999') sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0.8, 4), 4)) mpf('0.80000000000000004') sage: chop(ellipfun('ns', inverse_jacobi_f('ns', 0.8, 0), 0)) mpf('0.80000000000000004') sage: chop(ellipfun('ns', inverse_jacobi_f('ns', -0.7, 1), 1)) mpf('-0.69999999999999996') sage: chop(ellipfun('ns', inverse_jacobi_f('ns', 0.01, 2), 2)) mpf('0.01') sage: chop(ellipfun('ns', inverse_jacobi_f('ns', 0, 2), 2)) mpf('0.0') sage: chop(ellipfun('ns', inverse_jacobi_f('ns', -10, 6), 6)) mpf('-10.0') sage: chop(ellipfun('cn', inverse_jacobi_f('cn', -10, 0), 0)) mpf('-9.9999999999999982') sage: chop(ellipfun('cn', inverse_jacobi_f('cn', 50, 1), 1)) mpf('50.000000000000071') sage: chop(ellipfun('cn', inverse_jacobi_f('cn', 1, 5), 5)) mpf('1.0') sage: chop(ellipfun('cn', inverse_jacobi_f('cn', 0.5, -5), -5)) mpf('0.5') sage: chop(ellipfun('cn', inverse_jacobi_f('cn', -0.75, -15), -15)) mpf('-0.75000000000000022') sage: chop(ellipfun('cn', inverse_jacobi_f('cn', 10, 0.8), 0.8)) mpf('9.9999999999999982') sage: chop(ellipfun('cn', inverse_jacobi_f('cn', -2, 0.9), 0.9)) mpf('-2.0') sage: chop(ellipfun('nc', inverse_jacobi_f('nc', -4, 0), 0)) mpf('-3.9999999999999987') sage: chop(ellipfun('nc', inverse_jacobi_f('nc', 7, 1), 1)) mpf('7.0000000000000009') sage: chop(ellipfun('nc', inverse_jacobi_f('nc', 7, 3), 3)) mpf('7.0') sage: chop(ellipfun('nc', inverse_jacobi_f('nc', 0, 2), 2)) mpf('0.0') sage: chop(ellipfun('nc', inverse_jacobi_f('nc', -18, -4), -4)) mpf('-17.999999999999925') sage: chop(ellipfun('dn', inverse_jacobi_f('dn', -0.3, 1), 1)) mpf('-0.29999999999999999') sage: chop(ellipfun('dn', inverse_jacobi_f('dn', 1, -1), -1)) mpf('1.0') sage: chop(ellipfun('dn', inverse_jacobi_f('dn', 0.8, 0.5), 0.5)) mpf('0.80000000000000004') sage: chop(ellipfun('dn', inverse_jacobi_f('dn', 5, -4), -4)) mpf('5.0') sage: chop(ellipfun('dn', inverse_jacobi_f('dn', 0.4, 0.5), 0.5)) mpf('0.40000000000000002') sage: chop(ellipfun('dn', inverse_jacobi_f('dn', -0.4, 0.5), 0.5)) mpf('-0.40000000000000002') sage: chop(ellipfun('dn', inverse_jacobi_f('dn', -0.9, 0.5), 0.5)) mpf('-0.90000000000000002') sage: chop(ellipfun('dn', inverse_jacobi_f('dn', -1.9, 0.2), 0.2)) mpf('-1.8999999999999999') sage: chop(ellipfun('nd', inverse_jacobi_f('nd', -1.9, 1), 1)) mpf('-1.8999999999999999') sage: chop(ellipfun('nd', inverse_jacobi_f('nd', 1, -1), -1)) mpf('1.0') sage: chop(ellipfun('nd', inverse_jacobi_f('nd', 11, -6), -6)) mpf('11.0') sage: chop(ellipfun('nd', inverse_jacobi_f('nd', 0, 8), 8)) mpf('0.0') sage: chop(ellipfun('nd', inverse_jacobi_f('nd', -3, 0.8), 0.8)) mpf('-2.9999999999999996') sage: chop(ellipfun('sc', inverse_jacobi_f('sc', -3, 0), 0)) mpf('-3.0') sage: chop(ellipfun('sc', inverse_jacobi_f('sc', 2, 1), 1)) mpf('2.0') sage: chop(ellipfun('sc', inverse_jacobi_f('sc', 0, 9), 9)) mpf('0.0') sage: chop(ellipfun('sc', inverse_jacobi_f('sc', -7, 3), 3)) mpf('-7.0') sage: chop(ellipfun('cs', inverse_jacobi_f('cs', -7, 0), 0)) mpf('-6.9999999999999991') sage: chop(ellipfun('cs', inverse_jacobi_f('cs', 8, 1), 1)) mpf('8.0') sage: chop(ellipfun('cs', inverse_jacobi_f('cs', 2, 6), 6)) mpf('2.0') sage: chop(ellipfun('cs', inverse_jacobi_f('cs', 0, 4), 4)) mpf('0.0') sage: chop(ellipfun('cs', inverse_jacobi_f('cs', -6, 8), 8)) mpf('-6.0000000000000018') sage: chop(ellipfun('cd', inverse_jacobi_f('cd', -6, 0), 0)) mpf('-6.0000000000000009') sage: chop(ellipfun('cd', inverse_jacobi_f('cd', 1, 3), 3)) mpf('1.0') sage: chop(ellipfun('cd', inverse_jacobi_f('cd', 6, 8), 8)) mpf('6.0000000000000027') sage: chop(ellipfun('dc', inverse_jacobi_f('dc', 5, 0), 0)) mpf('5.0000000000000018') sage: chop(ellipfun('dc', inverse_jacobi_f('dc', -4, 2), 2)) mpf('-4.0000000000000018') sage: chop(ellipfun('sd', inverse_jacobi_f('sd', -4, 0), 0)) mpf('-3.9999999999999991') sage: chop(ellipfun('sd', inverse_jacobi_f('sd', 7, 1), 1)) mpf('7.0') sage: chop(ellipfun('sd', inverse_jacobi_f('sd', 0, 9), 9)) mpf('0.0') sage: chop(ellipfun('sd', inverse_jacobi_f('sd', 8, 0.8), 0.8)) mpf('7.9999999999999991') sage: chop(ellipfun('ds', inverse_jacobi_f('ds', 4, 0.25), 0.25)) mpf('4.0')
-
sage.functions.jacobi.jacobi(kind, z, m, **kwargs)¶ The 12 Jacobi elliptic functions.
INPUT:
kind– a string of the form'pq', wherep,qare inc,d,n,sz– a complex numberm– a complex number; note that
, where
is
the elliptic modulus
EXAMPLES:
sage: jacobi('sn', 1, 1) tanh(1) sage: jacobi('cd', 1, 1/2) jacobi_cd(1, 1/2) sage: RDF(jacobi('cd', 1, 1/2)) 0.7240097216593705 sage: (RDF(jacobi('cn', 1, 1/2)), RDF(jacobi('dn', 1, 1/2)), ....: RDF(jacobi('cn', 1, 1/2) / jacobi('dn', 1, 1/2))) (0.5959765676721407, 0.8231610016315962, 0.7240097216593705) sage: jsn = jacobi('sn', x, 1) sage: P = plot(jsn, 0, 1)
-
sage.functions.jacobi.jacobi_am_f(x, m)¶ Internal function for numeric evaluation of the Jacobi amplitude function for real arguments. Procedure described in [Ehrhardt13].
REFERENCES:
[Ehrhardt13] Ehrhardt, Wolfgang. “The AMath and DAMath Special Functions: Reference Manual and Implementation Notes, Version 1.3”. 2013. http://www.wolfgang-ehrhardt.de/specialfunctions.pdf. TESTS:
sage: from mpmath import ellipf sage: from sage.functions.jacobi import jacobi_am_f sage: ellipf(jacobi_am_f(0.5, 1), 1) mpf('0.5') sage: ellipf(jacobi_am(3, 0.3), 0.3) mpf('3.0') sage: ellipf(jacobi_am_f(2, -0.5), -0.5) mpf('2.0') sage: jacobi_am_f(2, -0.5) mpf('2.2680930777934176') sage: jacobi_am_f(-2, -0.5) mpf('-2.2680930777934176') sage: jacobi_am_f(-3, 2) mpf('0.36067407399586108')
