freealg 0.1.11__py3-none-any.whl → 0.7.12__py3-none-any.whl
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.
- freealg/__init__.py +8 -2
- freealg/__version__.py +1 -1
- freealg/_algebraic_form/__init__.py +12 -0
- freealg/_algebraic_form/_branch_points.py +288 -0
- freealg/_algebraic_form/_constraints.py +139 -0
- freealg/_algebraic_form/_continuation_algebraic.py +706 -0
- freealg/_algebraic_form/_decompress.py +641 -0
- freealg/_algebraic_form/_decompress2.py +204 -0
- freealg/_algebraic_form/_edge.py +330 -0
- freealg/_algebraic_form/_homotopy.py +323 -0
- freealg/_algebraic_form/_moments.py +448 -0
- freealg/_algebraic_form/_sheets_util.py +145 -0
- freealg/_algebraic_form/_support.py +309 -0
- freealg/_algebraic_form/algebraic_form.py +1232 -0
- freealg/_free_form/__init__.py +16 -0
- freealg/{_chebyshev.py → _free_form/_chebyshev.py} +75 -43
- freealg/_free_form/_decompress.py +993 -0
- freealg/_free_form/_density_util.py +243 -0
- freealg/_free_form/_jacobi.py +359 -0
- freealg/_free_form/_linalg.py +508 -0
- freealg/{_pade.py → _free_form/_pade.py} +42 -208
- freealg/{_plot_util.py → _free_form/_plot_util.py} +37 -22
- freealg/{_sample.py → _free_form/_sample.py} +58 -22
- freealg/_free_form/_series.py +454 -0
- freealg/_free_form/_support.py +214 -0
- freealg/_free_form/free_form.py +1362 -0
- freealg/_geometric_form/__init__.py +13 -0
- freealg/_geometric_form/_continuation_genus0.py +175 -0
- freealg/_geometric_form/_continuation_genus1.py +275 -0
- freealg/_geometric_form/_elliptic_functions.py +174 -0
- freealg/_geometric_form/_sphere_maps.py +63 -0
- freealg/_geometric_form/_torus_maps.py +118 -0
- freealg/_geometric_form/geometric_form.py +1094 -0
- freealg/_util.py +56 -110
- freealg/distributions/__init__.py +7 -1
- freealg/distributions/_chiral_block.py +494 -0
- freealg/distributions/_deformed_marchenko_pastur.py +726 -0
- freealg/distributions/_deformed_wigner.py +386 -0
- freealg/distributions/_kesten_mckay.py +29 -15
- freealg/distributions/_marchenko_pastur.py +224 -95
- freealg/distributions/_meixner.py +47 -37
- freealg/distributions/_wachter.py +29 -17
- freealg/distributions/_wigner.py +27 -14
- freealg/visualization/__init__.py +12 -0
- freealg/visualization/_glue_util.py +32 -0
- freealg/visualization/_rgb_hsv.py +125 -0
- freealg-0.7.12.dist-info/METADATA +172 -0
- freealg-0.7.12.dist-info/RECORD +53 -0
- {freealg-0.1.11.dist-info → freealg-0.7.12.dist-info}/WHEEL +1 -1
- freealg/_decompress.py +0 -180
- freealg/_jacobi.py +0 -218
- freealg/_support.py +0 -85
- freealg/freeform.py +0 -967
- freealg-0.1.11.dist-info/METADATA +0 -140
- freealg-0.1.11.dist-info/RECORD +0 -24
- /freealg/{_damp.py → _free_form/_damp.py} +0 -0
- {freealg-0.1.11.dist-info → freealg-0.7.12.dist-info}/licenses/AUTHORS.txt +0 -0
- {freealg-0.1.11.dist-info → freealg-0.7.12.dist-info}/licenses/LICENSE.txt +0 -0
- {freealg-0.1.11.dist-info → freealg-0.7.12.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright 2026, Siavash Ameli <sameli@berkeley.edu>
|
|
2
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
3
|
+
# SPDX-FileType: SOURCE
|
|
4
|
+
#
|
|
5
|
+
# This program is free software: you can redistribute it and/or modify it
|
|
6
|
+
# under the terms of the license found in the LICENSE.txt file in the root
|
|
7
|
+
# directory of this source tree.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# =======
|
|
11
|
+
# Imports
|
|
12
|
+
# =======
|
|
13
|
+
|
|
14
|
+
import numpy
|
|
15
|
+
import scipy
|
|
16
|
+
from ._elliptic_functions import ellipj
|
|
17
|
+
from ._continuation_genus1 import _poly_eval
|
|
18
|
+
|
|
19
|
+
__all__ = ['make_torus_grid', 'u_from_angles', 'eval_fitted_m_on_torus']
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# ===============
|
|
23
|
+
# make torus grid
|
|
24
|
+
# ===============
|
|
25
|
+
|
|
26
|
+
def make_torus_grid(n_theta=101, n_phi=101, R=1.0, r=0.35):
|
|
27
|
+
"""
|
|
28
|
+
Returns an embedded torus mesh (X,Y,Z) with angles (TH,PH).
|
|
29
|
+
TH: around major circle, PH: around tube.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
if n_phi % 2 == 0:
|
|
33
|
+
raise ValueError('n_phi should be odd number to avoid rendering ' +
|
|
34
|
+
'issue at phi=0.')
|
|
35
|
+
|
|
36
|
+
# fundamental angles (no endpoint duplicates)
|
|
37
|
+
theta = numpy.linspace(0.0, 2.0*numpy.pi, int(n_theta), endpoint=False)
|
|
38
|
+
phi = numpy.linspace(0.0, 2.0*numpy.pi, int(n_phi), endpoint=False)
|
|
39
|
+
|
|
40
|
+
TH, PH = numpy.meshgrid(theta, phi) # shapes (n_phi, n_theta)
|
|
41
|
+
|
|
42
|
+
# --- wrap/close the grid by appending first row/col ---
|
|
43
|
+
TH = numpy.vstack([TH, TH[0:1, :]]) # add phi seam row
|
|
44
|
+
PH = numpy.vstack([PH, PH[0:1, :]])
|
|
45
|
+
|
|
46
|
+
TH = numpy.hstack([TH, TH[:, 0:1]]) # add theta seam col
|
|
47
|
+
PH = numpy.hstack([PH, PH[:, 0:1]])
|
|
48
|
+
|
|
49
|
+
# torus embedding
|
|
50
|
+
X = (R + r*numpy.cos(PH)) * numpy.cos(TH)
|
|
51
|
+
Y = (R + r*numpy.cos(PH)) * numpy.sin(TH)
|
|
52
|
+
Z = r * numpy.sin(PH)
|
|
53
|
+
|
|
54
|
+
return X, Y, Z, TH, PH
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# =============
|
|
58
|
+
# u from angles
|
|
59
|
+
# =============
|
|
60
|
+
|
|
61
|
+
def u_from_angles(TH, PH, lam, center=(0.0, 0.0)):
|
|
62
|
+
"""
|
|
63
|
+
Map angles (TH,PH) in [0,2pi)^2 to the elliptic u-plane fundamental cell.
|
|
64
|
+
|
|
65
|
+
u = u0 + (omega1/2pi)*TH + (omega2/2pi)*PH,
|
|
66
|
+
omega1 = 2K(m), omega2 = 2 i K(1-m).
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
m = float(lam)
|
|
70
|
+
K = scipy.special.ellipk(m)
|
|
71
|
+
Kp = scipy.special.ellipk(1.0 - m)
|
|
72
|
+
omega1 = 2.0 * K
|
|
73
|
+
omega2 = 2.0j * Kp
|
|
74
|
+
|
|
75
|
+
u0 = complex(center[0], center[1]) # shift inside the fundamental domain
|
|
76
|
+
u = u0 + (omega1/(2.0*numpy.pi))*TH + (omega2/(2.0*numpy.pi))*PH
|
|
77
|
+
|
|
78
|
+
return u
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# ==========================
|
|
82
|
+
# evaluate fitted m on torus
|
|
83
|
+
# ==========================
|
|
84
|
+
|
|
85
|
+
def eval_fitted_m_on_torus(u, a1, b1, a2, b2, p0, p1, q, lam):
|
|
86
|
+
"""
|
|
87
|
+
Evaluate the *uniformized* branch m(u) = (p0(X)+Y p1(X))/q(X)
|
|
88
|
+
with X = lam * sn(u)^2 and Y chosen to match the elliptic derivative sign.
|
|
89
|
+
|
|
90
|
+
Requires jacobi_ellipj(u, m) that supports complex arrays and returns
|
|
91
|
+
(sn,cn,dn).
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
sn, cn, dn, _ = ellipj(u, lam)
|
|
95
|
+
|
|
96
|
+
X = lam * (sn * sn)
|
|
97
|
+
|
|
98
|
+
# canonical algebraic Y from curve: Y^2 = X(1-X)(X-lam)
|
|
99
|
+
D = X * (1.0 - X) * (X - lam)
|
|
100
|
+
|
|
101
|
+
Y = numpy.sqrt(D)
|
|
102
|
+
|
|
103
|
+
# enforce "positive imag" convention first
|
|
104
|
+
Y = numpy.where(numpy.imag(Y) < 0.0, -Y, Y)
|
|
105
|
+
|
|
106
|
+
# now align sign with elliptic reference:
|
|
107
|
+
# for Legendre normalization: dX/du = 2 i Y_ref, where Y_ref is equal to
|
|
108
|
+
# i*lam*sn*cn*dn (up to consistent conventions)
|
|
109
|
+
Y_ref = 1j * lam * (sn * cn * dn)
|
|
110
|
+
flip = numpy.real(Y * numpy.conjugate(Y_ref)) < 0.0
|
|
111
|
+
Y = numpy.where(flip, -Y, Y)
|
|
112
|
+
|
|
113
|
+
num0 = _poly_eval(X, p0)
|
|
114
|
+
num1 = _poly_eval(X, p1)
|
|
115
|
+
den = _poly_eval(X, q)
|
|
116
|
+
|
|
117
|
+
m = (num0 + Y * num1) / den
|
|
118
|
+
return m
|