Weierstrass elliptic functions, in terms of (real) lattice invariants \(g_2, g_3\)#

The Weierstrass functions take real values on the real axis iff the lattice is fixed under complex conjugation, or, equivalently, when \(g_2, g_3 \in \mathbb{R}\).

See also: https://gist.github.com/stla/d771e0a8c351d16d186c79bc838b6c48

Weierstrass function \(\wp_g(z, g_2, g_3)\) (also DAMath)#

ctxflint.weierstrass_p_g(z, g2, g3)#

Computes Weierstrass’s elliptic function \(\wp_g(z; g_2, g_3)\).

We have \(\wp_g(tz; t^{-4} g_2, t^{-6} g_3) = t^{-2} \wp_g(z; g_2, g_3)\) and \(\wp_g(i z; g_2, g_3) = -\wp_g(z; g_2, -g_3)\).

See also MathWorld [1066], Flint [837].

Returns the Weierstrass function \(\wp_g(x, g_2, g_3)\) based on the lattice invariants \(g_2\), \(g_3\).

In AMath the computation of the Weierstass elliptic function (for real and imaginary arguments) is based on the lattice invariants \(g_2\), \(g_3\) or the lattice roots \(e_1, e_2, e_3 = -e_1-e_2\), if the discriminant of the cubic equation \(4x^3 - g_2x - g_3 = 0\) is positive

\[\Delta = g_2^3 - 27g_3^2 = 16(e_2-e_3)^2 (e_3-e_1)^2 (e_1-e_2)^2;\]

symbolically written as \(\wp_g(x, g_2, g_3)\) or \(\wp_e(x,e_1,e_2)\). See also

When \(g_2=1, g_3=0\) the result is \(\wp_l(x)\) and for \(g_2=g_3=0\) it is \(x-2\). If \(g_2^2 - 27g_3^2>0\) all lattice roots are real, and \(\wp'_e(x,e_1,e_2)\) is returned, otherwise the following Jacobi relation is used:

\[\wp_g(x, g_2, g_3) = e_2 + H \frac{1+\mathrm{cn}(u,k)}{1-\mathrm{cn}(u,k)} , \quad k = \sqrt{\tfrac{1}{2}\frac{3e_2}{4H}}, \quad u = 2x \sqrt{H}, \quad H = \sqrt{(e_2-e_1)(e_2-e_3)}.\]

See also Wikipedia [1463], MathWorld [1066], Ehrhardt [309] (3.2.17.5).

Returns the Weierstrass function \(\wp_g(iy,g_2, g_3) = -\wp_g(y,g_2, -g_3)\). See also: MathWorld [1067], Ehrhardt [309] (3.2.17.7).

11a_TestWeierstrassP_re \(\quad\) 11b_TestWeierstrassP_im \(\quad\) 11c_TestWeierstrassP_abs

Left figure: real part of the Weierstrass function \(\wp_g(z, g_2, g_3)\). Camera angles are \(\theta=135^\circ\) and \(\phi = -12^\circ\), camera radius is -2.

Middle figure: imaginary part of the Weierstrass function \(\wp_g(z, g_2, g_3)\). Camera angles are \(\theta=135^\circ\) and \(\phi = -12^\circ\), camera radius is -2.

Right figure: absolute value of the Weierstrass function \(\wp_g(z, g_2, g_3)\), with color-coded phase. Camera angles are \(\theta=135^\circ\) and \(\phi = -12^\circ\), camera radius is -2.

For \(\Delta = g_2^3 - 27 g_3^2 \ne 0\), we first compute the elliptic half periods \(\omega_1, \omega_2\) from the lattice invariants \(g_2, g_3\) (see EllipticHalfPeriodsG), and set \(\omega = \omega_1, \tau = \omega_2/\omega_1\). Then \(\wp_g(z; g_2, g_3) = \wp(z| \omega, \tau)\) (see WeierstrassP).

For \(\Delta = 0, g_2 > 0, g_3 \ne 0\), the function \(\wp_g(\cdot)\) degenerates to a simply periodic function, which can be expressed in closed form in terms of elementary functions:

For \(\displaystyle \Delta = 0, g_2 > 0, g_3 < 0: \quad \wp_g(z; g_2, g_3) = c + \frac{3c}{\sinh^2\left(\sqrt{3c} z \right)}, \quad \text{where } c = \sqrt{g_2/12}\).

For \(\displaystyle \Delta = 0, g_2 > 0, g_3 > 0: \quad \wp_g(z; g_2, g_3) = c + \frac{3c}{\sin^2\left( \sqrt{3c}z \right)}, \quad \text{where } c = \sqrt{g_2/12}\).

If both \(g_2\) and \(g_3\) are zero, the function \(\wp_g(\cdot)\) degenerates to a function that is not periodic at all, namely \(\wp_g(z; 0, 0) = z^{-2}\).

An example with real input for \(z\) and with purely imaginary input for \(\tau\), producing real output:

>>> from xlcalcnet import dec, mpm, gmp, fpm, apm
>>> mpm.dps = 40; z = '0.1'; tau = '0.0 + 0.9j'
>>> \mathrm{d}x = dec.weierstrass_p(z, tau); mx = mpm.weierstrass_p(z, tau)
>>> gx = gmp.weierstrass_p(z, tau)
>>> fx = fpm.weierstrass_p(z, tau); ax = apm.weierstrass_p(z, tau)
>>> mpm.show([\mathrm{d}x, mx, gx, fx, ax])
dec:  1.001202913728593351620333736461324760825E+2
mpm:  1.001202913728593351620333736461324760825e+2
gmp:  1.001202913728593351620333736461324760825E+02
fpm:  1.00120291372859E+02
apm:  1.001202913728593351620333736461324760825e+2 (1.321e-38%)

An example with complex input for \(z\) and \(\tau\):

>>> from xlcalcnet import dec, mpm, gmp, fpm, apm
>>> mpm.dps = 20; z = '0.1 + 0.5j'; tau = '0.7 + 0.9j'
>>> \mathrm{d}x = dec.weierstrass_p(z, tau); mx = mpm.weierstrass_p(z, tau)
>>> gx = gmp.weierstrass_p(z, tau)
>>> fx = fpm.weierstrass_p(z, tau); ax = apm.weierstrass_p(z, tau)
>>> mpm.show([\mathrm{d}x, mx, gx, fx, ax], aligned=True)
dec:  -2.3859027427781674104E+0
mpm:  -2.3859027427781674104e+0
gmp:  -2.3859027427781674104E+00
fpm:  -2.38590274277817E+00
apm:  (-2.3859027427781674104e+0 (-2.038e-17%) + 2.4323666240267878020e-2 (1.982e-15%)j)

Weierstrass function, first derivative: \(\wp_g'(z, g_2, g_3)\)#

ctxflint.weierstrass_p_prime_(z, g2, g3)#

Computes the first derivative of the Weierstrass function, \(\wp_g'(z, g_2, g_3)\).

We have \(\wp_g'(tz; t^{-4} g_2, t^{-6} g_3) = t^{-3} \wp_g'(z; g_2, g_3)\) and \(\wp_g'(i z; g_2, g_3) = i\wp_g'(z; g_2, -g_3)\).

See also MathWorld [1067], Flint [837].

Returns the Weierstrass function \(\wp_g(x, g_2, g_3)\) based on the lattice invariants \(g_2\), \(g_3\).

\[\wp'_g(x, g_2, g_3) = -H^{3/2} \frac{\mathrm{cn}(u,k)\mathrm{dn}(u,k)}{1-\mathrm{cn}(u,k)} , \quad k = \sqrt{\tfrac{1}{2}\frac{3e_2}{4H}}, \quad u = 2x \sqrt{H}, \quad H = \sqrt{(e_2-e_1)(e_2-e_3)}.\]

See also: MathWorld [1067], Ehrhardt [309] (3.2.17.6).

12a_TestWeierstrassPPrime_re \(\quad\) 12b_TestWeierstrassPPrime_im \(\quad\) 12c_TestWeierstrassPPrime_abs

Left figure: real part of the Weierstrass function, first derivative: \(\wp_g'(z, g_2, g_3)\). Camera angles are \(\theta=135^\circ\) and \(\phi = -12^\circ\), camera radius is -2.

Middle figure: imaginary part of the Weierstrass function, first derivative: \(\wp_g'(z, g_2, g_3)\). Camera angles are \(\theta=135^\circ\) and \(\phi = -12^\circ\), camera radius is -2.

Right figure: absolute value of the Weierstrass function, first derivative: \(\wp_g'(z, g_2, g_3)\), with color-coded phase. Camera angles are \(\theta=135^\circ\) and \(\phi = -12^\circ\), camera radius is -2.

For \(\Delta = g_2^3 - 27 g_3^2 \ne 0\), we first compute the elliptic half periods \(\omega_1, \omega_2\) from the lattice invariants \(g_2, g_3\) (see EllipticHalfPeriodsG), and set \(\omega = \omega_1, \tau = \omega_2/\omega_1\). Then \(\wp_g'(z; g_2, g_3) = \wp'(z| \omega, \tau)\) (see WeierstrassPPrime).

For \(\Delta = 0, g_2 > 0, g_3 \ne 0\), the function \(\wp_g'(\cdot)\) degenerates to a simply periodic function, which can be expressed in closed form in terms of elementary functions:

For \(\Delta = 0, g_2 > 0, g_3 < 0: \quad \displaystyle \wp_g'(z; g_2, g_3) = -6 \sqrt{3} c^{3/2} \mathrm{coth}(\sqrt{3c}z) \mathrm{csch}^2(\sqrt{3c}z), \quad \text{where } c = \sqrt{g_2/12}\).

For \(\Delta = 0, g_2 > 0, g_3 > 0: \quad \displaystyle \wp_g'(z; g_2, g_3) = -6 \sqrt{3} c^{3/2} \mathrm{cot}(\sqrt{3c}z) \mathrm{csc}^2(\sqrt{3c}z), \quad \text{where } c = \sqrt{g_2/12}\).

If both \(g_2\) and \(g_3\) are zero, the function \(\wp_g'(\cdot)\) degenerates to a function that is not periodic at all, namely \(\wp_g'(z; 0, 0) = -2 z^{-3}\).

An example with real input for \(z\) and with purely imaginary input for \(\tau\), producing real output:

>>> from xlcalcnet import dec, mpm, gmp, fpm, apm
>>> mpm.dps = 40; z = '0.1'; tau = '0.0 + 0.9j'
>>> \mathrm{d}x = dec.weierstrass_p_prime(z, tau); mx = mpm.weierstrass_p_prime(z, tau)
>>> gx = gmp.weierstrass_p_prime(z, tau)
>>> fx = fpm.weierstrass_p_prime(z, tau); ax = apm.weierstrass_p_prime(z, tau)
>>> mpm.show([\mathrm{d}x, mx, gx, fx, ax])
dec:  -1.997612036772329460780279347633189585828E+3
mpm:  -1.997612036772329460780279347633189585828e+3
gmp:  -1.997612036772329460780279347633189585828E+03
fpm:  -1.99761203677233E+03
apm:  -1.997612036772329460780279347633189585828e+3 (-1.883e-38%)

An example with complex input for \(z\) and \(\tau\):

>>> from xlcalcnet import dec, mpm, gmp, fpm, apm
>>> mpm.dps = 20; z = '0.1 + 0.5j'; tau = '0.7 + 0.9j'
>>> \mathrm{d}x = dec.weierstrass_p_prime(z, tau); mx = mpm.weierstrass_p_prime(z, tau)
>>> gx = gmp.weierstrass_p_prime(z, tau)
>>> fx = fpm.weierstrass_p_prime(z, tau); ax = apm.weierstrass_p_prime(z, tau)
>>> mpm.show([\mathrm{d}x, mx, gx, fx, ax], aligned=True)
dec: 1.4787544521497118400E+1
mpm: 1.4787544521497118400e+1
gmp: 1.4787544521497118400E+01
fpm: 1.47875445214971E+01
apm: 1.4787544521497118399e+1 (5.664e-17%) - 2.3205214399360215619e+1 (-3.609e-17%)j

Inverse Weierstrass function \(\wp_g^{-1}(z, g_2, g_3)\)#

ctxflint.weierstrass_p_invG(z, g2, g3)#

Computes the Inverse Weierstrass function \(\wp_g^{-1}(z, g_2, g_3)\)

See also MathWorld [1062], Flint [837].

\[\wp_g^{-1}(z; g_2, g_3) = \wp^{-1}(z| \tau = \omega_2/\omega_1, \omega = \omega_1)\]

Returns the functional inverse \(\wp^{-1}_g\) of the Weierstrass function for \(y \ge e_1\), i.e. the smallest positive \(x\) with \(\wp^{-1}_g(y,g_2,g_3) = y\), if it exists. See also: MathWorld [1062], Ehrhardt [309] (3.2.17.9).

An example with real input for \(z\) and with purely imaginary input for \(\tau\), producing real output:

>>> from xlcalcnet import dec, mpm, gmp, fpm, apm
>>> mpm.dps = 40; z = '100'; tau = '0.0 + 0.9j'
>>> \mathrm{d}x = dec.weierstrass_p_inv(z, tau); mx = mpm.weierstrass_p_inv(z, tau)
>>> gx = gmp.weierstrass_p_inv(z, tau)
>>> fx = fpm.weierstrass_p_inv(z, tau); ax = apm.weierstrass_p_inv(z, tau)
>>> mpm.show([\mathrm{d}x, mx, gx, fx, ax])
dec:  1.000602721184701332310197413726890982085E-1
mpm:  1.000602721184701332310197413726890982085e-1
gmp:  1.000602721184701332310197413726890982085E-01
fpm:  1.00060272118470E-01
apm:  1.000602721184701332310197413726890982085e-1 (7.17e-40%)

An example with complex input for \(z\) and \(\tau\):

>>> from xlcalcnet import dec, mpm, gmp, fpm, apm
>>> mpm.dps = 20; z = '0.1 + 0.5j'; tau = '0.7 + 0.9j'
>>> \mathrm{d}x = dec.weierstrass_p_inv(z, tau); mx = mpm.weierstrass_p_inv(z, tau)
>>> gx = gmp.weierstrass_p_inv(z, tau)
>>> fx = fpm.weierstrass_p_inv(z, tau); ax = apm.weierstrass_p_inv(z, tau)
>>> mpm.show([\mathrm{d}x, mx, gx, fx, ax], aligned=True)
dec: 4.2630465458606458544E-1              - 3.0967048559182771279E-1j
mpm: 4.2630465458606458544e-1              - 3.0967048559182771279e-1j
gmp: 4.2630465458606458544E-01             - 3.0967048559182771279E-01j
fpm: 4.26304654586065E-01                  - 3.09670485591828E-01j
apm: 4.2630465458606458544e-1 (1.265e-16%) - 3.0967048559182771279e-1 (-1.063e-16%)j

Weierstrass Zeta function \(\zeta_g(z, g_2, g_3)\)#

ctxflint.weierstrass_zeta_g(z, g2, g3)#

Computes the Weierstrass zeta function \(\zeta_g(z; g_2, g_3)\).

We have \(\zeta_g(tz; t^{-4} g_2, t^{-6} g_3) = t^{-1} \zeta_g(z; g_2, g_3)\) and \(\zeta_g(i z; g_2, g_3) = -i\zeta_g(z; g_2, -g_3)\).

The function is related to \(\wp(z; g_2, g_3)\) by \(\displaystyle \frac{d \zeta(z; g_2, g_3)}{\mathrm{d}z} = -\wp(z; g_2, g_3)\) and \(\displaystyle \zeta(z; g_2, g_3) - z^{-1} = \int_0^z \left(\wp(z; g_2, g_3) - z^{-2} \right)\).

See also MathWorld [1069], Flint [837].

13a_TestWeierstrassZeta_re \(\quad\) 13b_TestWeierstrassZeta_im \(\quad\) 13c_TestWeierstrassZeta_abs

Left figure: real part of the Weierstrass Zeta function \(\zeta_g(z, g_2, g_3)\). Camera angles are \(\theta=135^\circ\) and \(\phi = -12^\circ\), camera radius is -2.

Middle figure: imaginary part of the Weierstrass Zeta function \(\zeta_g(z, g_2, g_3)\). Camera angles are \(\theta=135^\circ\) and \(\phi = -12^\circ\), camera radius is -2.

Right figure: absolute value of the Weierstrass Zeta function \(\zeta_g(z, g_2, g_3)\), with color-coded phase. Camera angles are \(\theta=135^\circ\) and \(\phi = -12^\circ\), camera radius is -2.

For \(\Delta = g_2^3 - 27 g_3^2 \ne 0\), we first compute the elliptic half periods \(\omega_1, \omega_2\) from the lattice invariants \(g_2, g_3\) (see EllipticHalfPeriodsG), and set \(\omega = \omega_1, \tau = \omega_2/\omega_1\). Then \(\zeta_g(z; g_2, g_3) = \zeta(z| \omega, \tau)\) (see WeierstrassZeta).

For \(\Delta = 0, g_2 > 0, g_3 \ne 0\), the function \(\zeta_g(\cdot)\) can be expressed in closed form in terms of elementary functions:

For \(\Delta = 0, g_2 > 0, g_3 < 0: \quad \displaystyle \zeta_g(z; g_2, g_3) = -cz + \sqrt{3c} \coth( \sqrt{3c}z ), \quad \text{where } c = \sqrt{g_2/12}\).

For \(\Delta = 0, g_2 > 0, g_3 > 0: \quad \displaystyle \zeta_g(z; g_2, g_3) = cz + \sqrt{3c} \cot( \sqrt{3c}z ), \quad \text{where } c = \sqrt{g_2/12}\).

If both \(g_2\) and \(g_3\) are zero, the function \(\zeta_g(\cdot)\) becomes \(\zeta_g(z; 0, 0) = z^{-1}\).

An example with real input for \(z\) and with purely imaginary input for \(\tau\), producing real output:

>>> from xlcalcnet import dec, mpm, gmp, fpm, apm
>>> mpm.dps = 40; z = '0.1'; tau = '0.0 + 0.9j'
>>> \mathrm{d}x = dec.weierstrass_zeta(z, tau); mx = mpm.weierstrass_zeta(z, tau)
>>> gx = gmp.weierstrass_zeta(z, tau)
>>> fx = fpm.weierstrass_zeta(z, tau); ax = apm.weierstrass_zeta(z, tau)
>>> mpm.show([\mathrm{d}x, mx, gx, fx, ax])
dec:  9.995978010353406976694591385190992698486E+0
mpm:  9.995978010353406976694591385190992698486e+0
gmp:  9.995978010353406976694591385190992698486E+00
fpm:  9.99597801035341E+00
apm:  9.995978010353406976694591385190992698486e+0 (1.654e-38%)

Weierstrass Sigma function \(\sigma_g(z, g_2, g_3\))#

ctxflint.weierstrass_sigma_g(z, g2, g3)#

Computes the Weierstrass sigma function, \(\sigma_g(z; g_2, g_3)\). We have \(\sigma_g(tz; t^{-4} g_2, t^{-6} g_3) = t \sigma_g(z; g_2, g_3)\).

The function is related to \(\zeta(z; g_2, g_3)\) by \(\displaystyle \frac{d}{\mathrm{d}z} \log \sigma(z; g_2, g_3) = \zeta(z; g_2, g_3)\).

See also MathWorld [1068], Flint [837].

See also: https://dlmf.nist.gov/23.2

14a_TestWeierstrassSigma_re \(\quad\) 14b_TestWeierstrassSigma_im \(\quad\) 14c_TestWeierstrassSigma_abs

Left figure: real part of the Weierstrass Sigma function \(\sigma_g(z, g_2, g_3\)). Camera angles are \(\theta=135^\circ\) and \(\phi = -12^\circ\), camera radius is -2.

Middle figure: imaginary part of the Weierstrass Sigma function \(\sigma_g(z, g_2, g_3\)). Camera angles are \(\theta=135^\circ\) and \(\phi = -12^\circ\), camera radius is -2.

Right figure: absolute value of the Weierstrass Sigma function \(\sigma_g(z, g_2, g_3\)), with color-coded phase. Camera angles are \(\theta=135^\circ\) and \(\phi = -12^\circ\), camera radius is -2.

For \(\Delta = g_2^3 - 27 g_3^2 \ne 0\), we first compute the elliptic half periods \(\omega_1, \omega_2\) from the lattice invariants \(g_2, g_3\) (see EllipticHalfPeriodsG), and set \(\omega = \omega_1, \tau = \omega_2/\omega_1\). Then \(\sigma_g(z; g_2, g_3) = \sigma(z| \omega, \tau)\) (see WeierstrassSigma).

For \(\Delta = 0, g_2 > 0, g_3 \ne 0\), the function \(\sigma_g(\cdot)\) can be expressed in closed form in terms of elementary functions:

For \(\Delta = 0, g_2 > 0, g_3 < 0: \quad \displaystyle \sigma_g(z; g_2, g_3) = \frac{\sinh( \sqrt{3c}z )}{\sqrt{3c} \cdot e^{cx^2 /2}}, \quad \text{where } c = \sqrt{g_2/12}\).

For \(\Delta = 0, g_2 > 0, g_3 > 0: \quad \displaystyle \sigma_g(z; g_2, g_3) = \frac{\sin( \sqrt{3c}z )}{\sqrt{3c} \cdot e^{cx^2 /2}}, \quad \text{where } c = \sqrt{g_2/12}\).

If both \(g_2\) and \(g_3\) are zero, the function \(\sigma_g(\cdot)\) becomes \(\sigma_g(z; 0, 0) = z\).

An example with real input for \(z\) and with purely imaginary input for \(\tau\), producing real output:

>>> from xlcalcnet import dec, mpm, gmp, fpm, apm
>>> mpm.dps = 40; z = '0.1'; tau = '0.0 + 0.9j'
>>> \mathrm{d}x = dec.weierstrass_sigma(z, tau); mx = mpm.weierstrass_sigma(z, tau)
>>> gx = gmp.weierstrass_sigma(z, tau)
>>> fx = fpm.weierstrass_sigma(z, tau); ax = apm.weierstrass_sigma(z, tau)
>>> mpm.show([\mathrm{d}x, mx, gx, fx, ax])
dec:  9.998992989830383649264433694319757846077E-2
mpm:  9.998992989830383649264433694319757846077e-2
gmp:  9.998992989830383649264433694319757846077E-02
fpm:  9.99899298983038E-02
apm:  9.998992989830383649264433694319757846077e-2 (5.023e-39%)