elliptic-functions 4.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. elliptic_functions-4.0.0/.gitignore +6 -0
  2. elliptic_functions-4.0.0/PKG-INFO +160 -0
  3. elliptic_functions-4.0.0/README.md +137 -0
  4. elliptic_functions-4.0.0/bench.py +514 -0
  5. elliptic_functions-4.0.0/bench_results.csv +136 -0
  6. elliptic_functions-4.0.0/bench_results_gpu2.csv +103 -0
  7. elliptic_functions-4.0.0/elliptic/__init__.py +101 -0
  8. elliptic_functions-4.0.0/elliptic/_agm.py +57 -0
  9. elliptic_functions-4.0.0/elliptic/_utils.py +86 -0
  10. elliptic_functions-4.0.0/elliptic/_xputils.py +13 -0
  11. elliptic_functions-4.0.0/elliptic/agm.py +19 -0
  12. elliptic_functions-4.0.0/elliptic/applications.py +61 -0
  13. elliptic_functions-4.0.0/elliptic/bulirsch.py +70 -0
  14. elliptic_functions-4.0.0/elliptic/carlson.py +186 -0
  15. elliptic_functions-4.0.0/elliptic/complex_elliptic.py +142 -0
  16. elliptic_functions-4.0.0/elliptic/ellipj.py +77 -0
  17. elliptic_functions-4.0.0/elliptic/elliptic12.py +102 -0
  18. elliptic_functions-4.0.0/elliptic/elliptic3.py +67 -0
  19. elliptic_functions-4.0.0/elliptic/ellipticBD.py +54 -0
  20. elliptic_functions-4.0.0/elliptic/ellipticBDJ.py +74 -0
  21. elliptic_functions-4.0.0/elliptic/inverse.py +62 -0
  22. elliptic_functions-4.0.0/elliptic/jacobi_edj.py +48 -0
  23. elliptic_functions-4.0.0/elliptic/nome.py +75 -0
  24. elliptic_functions-4.0.0/elliptic/theta.py +250 -0
  25. elliptic_functions-4.0.0/elliptic/weierstrass.py +209 -0
  26. elliptic_functions-4.0.0/pyproject.toml +34 -0
  27. elliptic_functions-4.0.0/tests/conftest.py +43 -0
  28. elliptic_functions-4.0.0/tests/test_associate.py +239 -0
  29. elliptic_functions-4.0.0/tests/test_elliptic12.py +87 -0
  30. elliptic_functions-4.0.0/tests/test_parity.py +343 -0
  31. elliptic_functions-4.0.0/tests/test_reference_tables.py +342 -0
@@ -0,0 +1,6 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .pytest_cache/
@@ -0,0 +1,160 @@
1
+ Metadata-Version: 2.4
2
+ Name: elliptic-functions
3
+ Version: 4.0.0
4
+ Summary: Elliptic integrals and functions — NumPy, PyTorch, JAX
5
+ Author-email: Igor Moiseev <moiseev.igor@gmail.com>
6
+ License: GPL-2.0
7
+ Keywords: elliptic functions,elliptic integrals,mathematics,special functions
8
+ Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
11
+ Requires-Python: >=3.10
12
+ Requires-Dist: array-api-compat>=1.9
13
+ Requires-Dist: numpy>=1.24
14
+ Provides-Extra: dev
15
+ Requires-Dist: mpmath>=1.3; extra == 'dev'
16
+ Requires-Dist: pytest>=7; extra == 'dev'
17
+ Requires-Dist: scipy>=1.8; extra == 'dev'
18
+ Provides-Extra: jax
19
+ Requires-Dist: jax>=0.4; extra == 'jax'
20
+ Provides-Extra: torch
21
+ Requires-Dist: torch>=2.0; extra == 'torch'
22
+ Description-Content-Type: text/markdown
23
+
24
+
25
+ # elliptic (Python)
26
+
27
+ Standalone Python implementation of elliptic integrals and functions.
28
+ Works identically on NumPy arrays, PyTorch tensors (CPU and CUDA), and JAX arrays — no scipy runtime dependency.
29
+
30
+ [![tests](https://github.com/moiseevigor/elliptic/actions/workflows/python.yml/badge.svg)](https://github.com/moiseevigor/elliptic/actions/workflows/python.yml)
31
+
32
+ ## Install
33
+
34
+ ```bash
35
+ pip install elliptic-functions # NumPy only
36
+ pip install "elliptic-functions[torch]" # + PyTorch backend
37
+ pip install "elliptic-functions[jax]" # + JAX backend
38
+ pip install "elliptic-functions[dev]" # + test deps (scipy, mpmath, pytest)
39
+ ```
40
+
41
+ ## Quick start
42
+
43
+ ```python
44
+ import numpy as np
45
+ import elliptic
46
+
47
+ phi = np.linspace(0, np.pi/2, 200)
48
+ m = 0.7
49
+
50
+ # Incomplete integrals F(φ|m), E(φ|m), Jacobi zeta Z(φ|m)
51
+ F, E, Z = elliptic.elliptic12(phi, m)
52
+
53
+ # Third kind Π(φ,m,n) — missing from scipy (issue #4452)
54
+ Pi = elliptic.elliptic3(phi, m, 0.3)
55
+
56
+ # Jacobi elliptic functions sn, cn, dn, am
57
+ sn, cn, dn, am = elliptic.ellipj(np.linspace(0, 3, 100), m)
58
+
59
+ # Associate incomplete integrals B, D, J (DLMF §19.2)
60
+ B, D, J = elliptic.ellipticBDJ(phi, m, 0.3)
61
+ # identities: F = B+D, E = B+(1-m)D, Pi = B+D+n*J
62
+
63
+ # Complete associate integrals B(m), D(m), S(m)
64
+ B_c, D_c, S_c = elliptic.ellipticBD(np.array([0.3, 0.5, 0.7]))
65
+
66
+ # Carlson symmetric forms (DLMF §19.16)
67
+ RF = elliptic.carlsonRF(0.0, 1.0 - m, 1.0) # = K(m)
68
+ RD = elliptic.carlsonRD(0.0, 1.0 - m, 1.0) # = 3D(m)
69
+
70
+ # Bulirsch generalised complete integrals
71
+ K = elliptic.cel1(np.sqrt(1 - m)) # = K(m)
72
+ E2 = elliptic.cel2(np.sqrt(1 - m), 1.0, 1-m) # = E(m)
73
+
74
+ # Jacobi theta functions (4 types)
75
+ Th3 = elliptic.theta(3, phi, m)
76
+ Th, H = elliptic.jacobiThetaEta(np.linspace(0, 1, 50), m)
77
+ Th3, dTh3 = elliptic.theta_prime(3, phi, m)
78
+
79
+ # Weierstrass functions
80
+ e1, e2, e3 = 2.0, 0.5, -2.5
81
+ P = elliptic.weierstrassP(0.4, e1, e2, e3)
82
+ Zf = elliptic.weierstrassZeta(0.4, e1, e2, e3)
83
+ S = elliptic.weierstrassSigma(0.4, e1, e2, e3)
84
+ dP = elliptic.weierstrassPPrime(0.4, e1, e2, e3)
85
+ g2, g3, Delta = elliptic.weierstrassInvariants(e1, e2, e3)
86
+
87
+ # Nome and inverse
88
+ q = elliptic.nomeq(m)
89
+ m_back = elliptic.inversenomeq(q)
90
+
91
+ # Inverse E(phi|m): given E value, solve for phi
92
+ phi_inv = elliptic.inverselliptic2(E, m)
93
+
94
+ # Arithmetic-geometric mean
95
+ agm_val = elliptic.agm(1.0, np.sqrt(1 - m)) # = π/(2K(m))
96
+
97
+ # Complex arguments
98
+ import numpy as np
99
+ u_c = np.array([0.4 + 0.3j, 0.8 - 0.2j])
100
+ Fi, Ei, Zi = elliptic.elliptic12i(u_c, m)
101
+ sni, cni, dni = elliptic.ellipji(u_c, m)
102
+
103
+ # Application: ellipse arc length
104
+ arc = elliptic.arclength_ellipse(5, 10) # full perimeter ≈ 48.44
105
+ arc = elliptic.arclength_ellipse(5, 10, 0, np.pi/4) # quarter arc
106
+ ```
107
+
108
+ ## GPU (PyTorch)
109
+
110
+ Pass a `torch.Tensor` on any device:
111
+
112
+ ```python
113
+ import torch, elliptic
114
+
115
+ phi = torch.linspace(0.01, 1.5, 1_000_000, dtype=torch.float64, device="cuda")
116
+ F, E, Z = elliptic.elliptic12(phi, torch.full_like(phi, 0.7))
117
+ ```
118
+
119
+ ## JAX (jit / vmap)
120
+
121
+ ```python
122
+ import jax, jax.numpy as jnp, elliptic
123
+
124
+ phi = jnp.linspace(0.01, 1.5, 10_000)
125
+ F, E, Z = jax.jit(elliptic.elliptic12)(phi, 0.7)
126
+ ```
127
+
128
+ ## Comparison with scipy.special
129
+
130
+ | Function | scipy | elliptic |
131
+ |---|:---:|:---:|
132
+ | K(m), E(m) | ✓ | ✓ |
133
+ | F(φ,m), E(φ,m) | ✓ | ✓ |
134
+ | Jacobi sn/cn/dn (real) | ✓ | ✓ |
135
+ | Jacobi sn/cn/dn (complex) | ✗ | ✓ |
136
+ | F(u,m), E(u,m) (complex) | ✗ | ✓ |
137
+ | **Π(φ,m,n) — 3rd kind** | ✗ (open since 2015) | ✓ |
138
+ | Carlson RF/RD/RJ/RC | ✓ since v1.8 | ✓ |
139
+ | **B, D, J associate** | ✗ | ✓ |
140
+ | **Bulirsch cel** | ✗ | ✓ |
141
+ | **Jacobi theta θ₁…θ₄** | ✗ | ✓ |
142
+ | **Weierstrass P/ζ/σ/℘′** | ✗ | ✓ |
143
+ | **Weierstrass invariants g₂,g₃** | ✗ | ✓ |
144
+ | **Nome q(m) and m(q)** | ✗ | ✓ |
145
+ | **Inverse E(φ,m)** | ✗ | ✓ |
146
+ | **AGM** | ✗ | ✓ |
147
+ | **Ellipse arc length** | ✗ | ✓ |
148
+ | **PyTorch GPU** | ✗ | ✓ |
149
+ | **JAX jit/vmap** | ✗ | ✓ |
150
+
151
+ All algorithms run identically across backends — the same Python code dispatches to NumPy, PyTorch CUDA, or JAX TPU.
152
+
153
+ ## References
154
+
155
+ - Abramowitz & Stegun, *Handbook of Mathematical Functions*, §16–18
156
+ - NIST DLMF §19, §22, §23 — https://dlmf.nist.gov
157
+ - Fukushima (2015), "Elliptic functions and elliptic integrals for celestial mechanics"
158
+ - Bulirsch (1965), "Numerical computation of elliptic integrals"
159
+ - Carlson (1995), "Numerical Computation of Real or Complex Elliptic Integrals"
160
+ - Boyd (2012), "Numerical inversion of the incomplete elliptic integral of the second kind"
@@ -0,0 +1,137 @@
1
+
2
+ # elliptic (Python)
3
+
4
+ Standalone Python implementation of elliptic integrals and functions.
5
+ Works identically on NumPy arrays, PyTorch tensors (CPU and CUDA), and JAX arrays — no scipy runtime dependency.
6
+
7
+ [![tests](https://github.com/moiseevigor/elliptic/actions/workflows/python.yml/badge.svg)](https://github.com/moiseevigor/elliptic/actions/workflows/python.yml)
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ pip install elliptic-functions # NumPy only
13
+ pip install "elliptic-functions[torch]" # + PyTorch backend
14
+ pip install "elliptic-functions[jax]" # + JAX backend
15
+ pip install "elliptic-functions[dev]" # + test deps (scipy, mpmath, pytest)
16
+ ```
17
+
18
+ ## Quick start
19
+
20
+ ```python
21
+ import numpy as np
22
+ import elliptic
23
+
24
+ phi = np.linspace(0, np.pi/2, 200)
25
+ m = 0.7
26
+
27
+ # Incomplete integrals F(φ|m), E(φ|m), Jacobi zeta Z(φ|m)
28
+ F, E, Z = elliptic.elliptic12(phi, m)
29
+
30
+ # Third kind Π(φ,m,n) — missing from scipy (issue #4452)
31
+ Pi = elliptic.elliptic3(phi, m, 0.3)
32
+
33
+ # Jacobi elliptic functions sn, cn, dn, am
34
+ sn, cn, dn, am = elliptic.ellipj(np.linspace(0, 3, 100), m)
35
+
36
+ # Associate incomplete integrals B, D, J (DLMF §19.2)
37
+ B, D, J = elliptic.ellipticBDJ(phi, m, 0.3)
38
+ # identities: F = B+D, E = B+(1-m)D, Pi = B+D+n*J
39
+
40
+ # Complete associate integrals B(m), D(m), S(m)
41
+ B_c, D_c, S_c = elliptic.ellipticBD(np.array([0.3, 0.5, 0.7]))
42
+
43
+ # Carlson symmetric forms (DLMF §19.16)
44
+ RF = elliptic.carlsonRF(0.0, 1.0 - m, 1.0) # = K(m)
45
+ RD = elliptic.carlsonRD(0.0, 1.0 - m, 1.0) # = 3D(m)
46
+
47
+ # Bulirsch generalised complete integrals
48
+ K = elliptic.cel1(np.sqrt(1 - m)) # = K(m)
49
+ E2 = elliptic.cel2(np.sqrt(1 - m), 1.0, 1-m) # = E(m)
50
+
51
+ # Jacobi theta functions (4 types)
52
+ Th3 = elliptic.theta(3, phi, m)
53
+ Th, H = elliptic.jacobiThetaEta(np.linspace(0, 1, 50), m)
54
+ Th3, dTh3 = elliptic.theta_prime(3, phi, m)
55
+
56
+ # Weierstrass functions
57
+ e1, e2, e3 = 2.0, 0.5, -2.5
58
+ P = elliptic.weierstrassP(0.4, e1, e2, e3)
59
+ Zf = elliptic.weierstrassZeta(0.4, e1, e2, e3)
60
+ S = elliptic.weierstrassSigma(0.4, e1, e2, e3)
61
+ dP = elliptic.weierstrassPPrime(0.4, e1, e2, e3)
62
+ g2, g3, Delta = elliptic.weierstrassInvariants(e1, e2, e3)
63
+
64
+ # Nome and inverse
65
+ q = elliptic.nomeq(m)
66
+ m_back = elliptic.inversenomeq(q)
67
+
68
+ # Inverse E(phi|m): given E value, solve for phi
69
+ phi_inv = elliptic.inverselliptic2(E, m)
70
+
71
+ # Arithmetic-geometric mean
72
+ agm_val = elliptic.agm(1.0, np.sqrt(1 - m)) # = π/(2K(m))
73
+
74
+ # Complex arguments
75
+ import numpy as np
76
+ u_c = np.array([0.4 + 0.3j, 0.8 - 0.2j])
77
+ Fi, Ei, Zi = elliptic.elliptic12i(u_c, m)
78
+ sni, cni, dni = elliptic.ellipji(u_c, m)
79
+
80
+ # Application: ellipse arc length
81
+ arc = elliptic.arclength_ellipse(5, 10) # full perimeter ≈ 48.44
82
+ arc = elliptic.arclength_ellipse(5, 10, 0, np.pi/4) # quarter arc
83
+ ```
84
+
85
+ ## GPU (PyTorch)
86
+
87
+ Pass a `torch.Tensor` on any device:
88
+
89
+ ```python
90
+ import torch, elliptic
91
+
92
+ phi = torch.linspace(0.01, 1.5, 1_000_000, dtype=torch.float64, device="cuda")
93
+ F, E, Z = elliptic.elliptic12(phi, torch.full_like(phi, 0.7))
94
+ ```
95
+
96
+ ## JAX (jit / vmap)
97
+
98
+ ```python
99
+ import jax, jax.numpy as jnp, elliptic
100
+
101
+ phi = jnp.linspace(0.01, 1.5, 10_000)
102
+ F, E, Z = jax.jit(elliptic.elliptic12)(phi, 0.7)
103
+ ```
104
+
105
+ ## Comparison with scipy.special
106
+
107
+ | Function | scipy | elliptic |
108
+ |---|:---:|:---:|
109
+ | K(m), E(m) | ✓ | ✓ |
110
+ | F(φ,m), E(φ,m) | ✓ | ✓ |
111
+ | Jacobi sn/cn/dn (real) | ✓ | ✓ |
112
+ | Jacobi sn/cn/dn (complex) | ✗ | ✓ |
113
+ | F(u,m), E(u,m) (complex) | ✗ | ✓ |
114
+ | **Π(φ,m,n) — 3rd kind** | ✗ (open since 2015) | ✓ |
115
+ | Carlson RF/RD/RJ/RC | ✓ since v1.8 | ✓ |
116
+ | **B, D, J associate** | ✗ | ✓ |
117
+ | **Bulirsch cel** | ✗ | ✓ |
118
+ | **Jacobi theta θ₁…θ₄** | ✗ | ✓ |
119
+ | **Weierstrass P/ζ/σ/℘′** | ✗ | ✓ |
120
+ | **Weierstrass invariants g₂,g₃** | ✗ | ✓ |
121
+ | **Nome q(m) and m(q)** | ✗ | ✓ |
122
+ | **Inverse E(φ,m)** | ✗ | ✓ |
123
+ | **AGM** | ✗ | ✓ |
124
+ | **Ellipse arc length** | ✗ | ✓ |
125
+ | **PyTorch GPU** | ✗ | ✓ |
126
+ | **JAX jit/vmap** | ✗ | ✓ |
127
+
128
+ All algorithms run identically across backends — the same Python code dispatches to NumPy, PyTorch CUDA, or JAX TPU.
129
+
130
+ ## References
131
+
132
+ - Abramowitz & Stegun, *Handbook of Mathematical Functions*, §16–18
133
+ - NIST DLMF §19, §22, §23 — https://dlmf.nist.gov
134
+ - Fukushima (2015), "Elliptic functions and elliptic integrals for celestial mechanics"
135
+ - Bulirsch (1965), "Numerical computation of elliptic integrals"
136
+ - Carlson (1995), "Numerical Computation of Real or Complex Elliptic Integrals"
137
+ - Boyd (2012), "Numerical inversion of the incomplete elliptic integral of the second kind"