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
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
|
|
14
14
|
import numpy
|
|
15
15
|
from scipy.interpolate import interp1d
|
|
16
|
-
from .._plot_util import plot_density, plot_hilbert,
|
|
17
|
-
plot_stieltjes_on_disk, plot_samples
|
|
16
|
+
from .._free_form._plot_util import plot_density, plot_hilbert, \
|
|
17
|
+
plot_stieltjes, plot_stieltjes_on_disk, plot_samples
|
|
18
18
|
|
|
19
19
|
try:
|
|
20
20
|
from scipy.integrate import cumtrapz
|
|
@@ -115,7 +115,7 @@ class Wachter(object):
|
|
|
115
115
|
# density
|
|
116
116
|
# =======
|
|
117
117
|
|
|
118
|
-
def density(self, x=None, plot=False, latex=False, save=False):
|
|
118
|
+
def density(self, x=None, plot=False, latex=False, save=False, eig=None):
|
|
119
119
|
"""
|
|
120
120
|
Density of distribution.
|
|
121
121
|
|
|
@@ -142,6 +142,10 @@ class Wachter(object):
|
|
|
142
142
|
assumed to the save filename (with the file extension). This option
|
|
143
143
|
is relevant only if ``plot=True``.
|
|
144
144
|
|
|
145
|
+
eig : numpy.array, default=None
|
|
146
|
+
A collection of eigenvalues to compare to via histogram. This
|
|
147
|
+
option is relevant only if ``plot=True``.
|
|
148
|
+
|
|
145
149
|
Returns
|
|
146
150
|
-------
|
|
147
151
|
|
|
@@ -179,7 +183,11 @@ class Wachter(object):
|
|
|
179
183
|
numpy.sqrt((self.lam_p - x[mask]) * (x[mask] - self.lam_m))
|
|
180
184
|
|
|
181
185
|
if plot:
|
|
182
|
-
|
|
186
|
+
if eig is not None:
|
|
187
|
+
label = 'Theoretical'
|
|
188
|
+
else:
|
|
189
|
+
label = ''
|
|
190
|
+
plot_density(x, rho, label=label, latex=latex, save=save, eig=eig)
|
|
183
191
|
|
|
184
192
|
return rho
|
|
185
193
|
|
|
@@ -282,7 +290,7 @@ class Wachter(object):
|
|
|
282
290
|
m1 = (-B + sqrtD) / (2 * A)
|
|
283
291
|
m2 = (-B - sqrtD) / (2 * A)
|
|
284
292
|
|
|
285
|
-
# pick correct branch only for non
|
|
293
|
+
# pick correct branch only for non-masked entries
|
|
286
294
|
upper = z.imag >= 0
|
|
287
295
|
branch = numpy.empty_like(m1)
|
|
288
296
|
branch[upper] = numpy.where(sign*m1[upper].imag > 0, m1[upper],
|
|
@@ -501,9 +509,6 @@ class Wachter(object):
|
|
|
501
509
|
:class: custom-dark
|
|
502
510
|
"""
|
|
503
511
|
|
|
504
|
-
if seed is not None:
|
|
505
|
-
numpy.random.seed(seed)
|
|
506
|
-
|
|
507
512
|
if x_min is None:
|
|
508
513
|
x_min = self.lam_m
|
|
509
514
|
|
|
@@ -522,14 +527,23 @@ class Wachter(object):
|
|
|
522
527
|
inv_cdf = interp1d(cdf, xs, bounds_error=False,
|
|
523
528
|
fill_value=(x_min, x_max))
|
|
524
529
|
|
|
530
|
+
# Random generator
|
|
531
|
+
rng = numpy.random.default_rng(seed)
|
|
532
|
+
|
|
525
533
|
# Draw from uniform distribution
|
|
526
534
|
if method == 'mc':
|
|
527
|
-
u =
|
|
535
|
+
u = rng.random(size)
|
|
536
|
+
|
|
528
537
|
elif method == 'qmc':
|
|
529
|
-
|
|
530
|
-
|
|
538
|
+
try:
|
|
539
|
+
engine = qmc.Halton(d=1, scramble=True, rng=rng)
|
|
540
|
+
except TypeError:
|
|
541
|
+
# Older scipy versions
|
|
542
|
+
engine = qmc.Halton(d=1, scramble=True, seed=rng)
|
|
543
|
+
u = engine.random(size).ravel()
|
|
544
|
+
|
|
531
545
|
else:
|
|
532
|
-
raise
|
|
546
|
+
raise NotImplementedError('"method" is invalid.')
|
|
533
547
|
|
|
534
548
|
# Draw from distribution by mapping from inverse CDF
|
|
535
549
|
samples = inv_cdf(u).ravel()
|
|
@@ -582,15 +596,13 @@ class Wachter(object):
|
|
|
582
596
|
>>> A = wa.matrix(2000)
|
|
583
597
|
"""
|
|
584
598
|
|
|
585
|
-
if seed is not None:
|
|
586
|
-
numpy.random.seed(seed)
|
|
587
|
-
|
|
588
599
|
n = size
|
|
589
600
|
m1 = int(self.a * n)
|
|
590
601
|
m2 = int(self.b * n)
|
|
591
602
|
|
|
592
|
-
|
|
593
|
-
|
|
603
|
+
rng = numpy.random.default_rng(seed)
|
|
604
|
+
X = rng.standard_normal((n, m1))
|
|
605
|
+
Y = rng.standard_normal((n, m2))
|
|
594
606
|
|
|
595
607
|
Sx = X @ X.T
|
|
596
608
|
Sy = Y @ Y.T
|
freealg/distributions/_wigner.py
CHANGED
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
|
|
14
14
|
import numpy
|
|
15
15
|
from scipy.interpolate import interp1d
|
|
16
|
-
from .._plot_util import plot_density, plot_hilbert,
|
|
17
|
-
plot_stieltjes_on_disk, plot_samples
|
|
16
|
+
from .._free_form._plot_util import plot_density, plot_hilbert, \
|
|
17
|
+
plot_stieltjes, plot_stieltjes_on_disk, plot_samples
|
|
18
18
|
|
|
19
19
|
try:
|
|
20
20
|
from scipy.integrate import cumtrapz
|
|
@@ -96,7 +96,7 @@ class Wigner(object):
|
|
|
96
96
|
# density
|
|
97
97
|
# =======
|
|
98
98
|
|
|
99
|
-
def density(self, x=None, plot=False, latex=False, save=False):
|
|
99
|
+
def density(self, x=None, plot=False, latex=False, save=False, eig=None):
|
|
100
100
|
"""
|
|
101
101
|
Density of distribution.
|
|
102
102
|
|
|
@@ -123,6 +123,10 @@ class Wigner(object):
|
|
|
123
123
|
assumed to the save filename (with the file extension). This option
|
|
124
124
|
is relevant only if ``plot=True``.
|
|
125
125
|
|
|
126
|
+
eig : numpy.array, default=None
|
|
127
|
+
A collection of eigenvalues to compare to via histogram. This
|
|
128
|
+
option is relevant only if ``plot=True``.
|
|
129
|
+
|
|
126
130
|
Returns
|
|
127
131
|
-------
|
|
128
132
|
|
|
@@ -159,7 +163,11 @@ class Wigner(object):
|
|
|
159
163
|
numpy.sqrt(self.r**2 - x[mask]**2)
|
|
160
164
|
|
|
161
165
|
if plot:
|
|
162
|
-
|
|
166
|
+
if eig is not None:
|
|
167
|
+
label = 'Theoretical'
|
|
168
|
+
else:
|
|
169
|
+
label = ''
|
|
170
|
+
plot_density(x, rho, label=label, latex=latex, save=save, eig=eig)
|
|
163
171
|
|
|
164
172
|
return rho
|
|
165
173
|
|
|
@@ -478,9 +486,6 @@ class Wigner(object):
|
|
|
478
486
|
:class: custom-dark
|
|
479
487
|
"""
|
|
480
488
|
|
|
481
|
-
if seed is not None:
|
|
482
|
-
numpy.random.seed(seed)
|
|
483
|
-
|
|
484
489
|
if x_min is None:
|
|
485
490
|
x_min = self.lam_m
|
|
486
491
|
|
|
@@ -499,14 +504,23 @@ class Wigner(object):
|
|
|
499
504
|
inv_cdf = interp1d(cdf, xs, bounds_error=False,
|
|
500
505
|
fill_value=(x_min, x_max))
|
|
501
506
|
|
|
507
|
+
# Random generator
|
|
508
|
+
rng = numpy.random.default_rng(seed)
|
|
509
|
+
|
|
502
510
|
# Draw from uniform distribution
|
|
503
511
|
if method == 'mc':
|
|
504
|
-
u =
|
|
512
|
+
u = rng.random(size)
|
|
513
|
+
|
|
505
514
|
elif method == 'qmc':
|
|
506
|
-
|
|
507
|
-
|
|
515
|
+
try:
|
|
516
|
+
engine = qmc.Halton(d=1, scramble=True, rng=rng)
|
|
517
|
+
except TypeError:
|
|
518
|
+
# Older scipy versions
|
|
519
|
+
engine = qmc.Halton(d=1, scramble=True, seed=rng)
|
|
520
|
+
u = engine.random(size).ravel()
|
|
521
|
+
|
|
508
522
|
else:
|
|
509
|
-
raise
|
|
523
|
+
raise NotImplementedError('"method" is invalid.')
|
|
510
524
|
|
|
511
525
|
# Draw from distribution by mapping from inverse CDF
|
|
512
526
|
samples = inv_cdf(u).ravel()
|
|
@@ -556,12 +570,11 @@ class Wigner(object):
|
|
|
556
570
|
>>> A = wg.matrix(2000)
|
|
557
571
|
"""
|
|
558
572
|
|
|
559
|
-
|
|
560
|
-
numpy.random.seed(seed)
|
|
573
|
+
rng = numpy.random.default_rng(seed)
|
|
561
574
|
|
|
562
575
|
# Parameters
|
|
563
576
|
n = size
|
|
564
|
-
X =
|
|
577
|
+
X = rng.standard_normal(size=(n, n))
|
|
565
578
|
X = (numpy.triu(X, 0) + numpy.triu(X, 1).T)
|
|
566
579
|
|
|
567
580
|
return X * (self.r / (2.0 * numpy.sqrt(n)))
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
from ._rgb_hsv import rgb_hsv
|
|
10
|
+
from ._glue_util import glue_branches
|
|
11
|
+
|
|
12
|
+
__all__ = ['rgb_hsv', 'glue_branches']
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
|
|
16
|
+
__all__ = ['glue_branches']
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# =============
|
|
20
|
+
# glue branches
|
|
21
|
+
# =============
|
|
22
|
+
|
|
23
|
+
def glue_branches(z, m1, m2):
|
|
24
|
+
"""
|
|
25
|
+
m12 is the mixing of m1 and m2 where it contains m1 on C^+ and m2 on C^-.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
m12 = numpy.array(m2, copy=True)
|
|
29
|
+
mask_p = numpy.imag(z) >= 0.0
|
|
30
|
+
m12[mask_p] = m1[mask_p]
|
|
31
|
+
|
|
32
|
+
return m12
|
|
@@ -0,0 +1,125 @@
|
|
|
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 under
|
|
6
|
+
# the terms of the license found in the LICENSE.txt file in the root directory
|
|
7
|
+
# of this source tree.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# =======
|
|
11
|
+
# Imports
|
|
12
|
+
# =======
|
|
13
|
+
|
|
14
|
+
import numpy
|
|
15
|
+
import matplotlib
|
|
16
|
+
|
|
17
|
+
__all__ = ['rgb_hsv']
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# =======
|
|
21
|
+
# rgb hsv
|
|
22
|
+
# =======
|
|
23
|
+
|
|
24
|
+
def rgb_hsv(c, shift=0.0, thresh=numpy.inf, n_mod=12.0, n_ph=12.0, vmin=0.35,
|
|
25
|
+
vmax=1.0, tile_gamma=1.0, tile_mix=1.0):
|
|
26
|
+
"""
|
|
27
|
+
Convert complex field c to RGB via HSV domain coloring.
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
c : array_like of complex
|
|
32
|
+
Complex field.
|
|
33
|
+
|
|
34
|
+
shift : float, default 0.0
|
|
35
|
+
Phase offset in turns (1.0 = full 2*pi rotation). Applied to hue.
|
|
36
|
+
|
|
37
|
+
thresh : float, default numpy.inf
|
|
38
|
+
Optional cap on |c| used for magnitude-related terms. Use to prevent
|
|
39
|
+
very large magnitudes from dominating the encoding.
|
|
40
|
+
|
|
41
|
+
n_mod : float, default 12.0
|
|
42
|
+
Number of modulus steps per 2*pi in log(|c|). Higher -> more concentric
|
|
43
|
+
rings. Set to 0.0 to disable modulus stepping.
|
|
44
|
+
|
|
45
|
+
n_ph : float, default 12.0
|
|
46
|
+
Number of phase steps per 2*pi in arg(c). Higher -> more angular
|
|
47
|
+
sectors. Set to 0.0 to disable phase stepping.
|
|
48
|
+
|
|
49
|
+
vmin : float, default 0.35
|
|
50
|
+
Minimum brightness for the tiling shading (darkest parts of tiles).
|
|
51
|
+
|
|
52
|
+
vmax : float, default 1.0
|
|
53
|
+
Maximum brightness for the tiling shading (brightest parts of tiles).
|
|
54
|
+
Lowering vmax (e.g. 0.8-0.9) can reduce the "neon" look.
|
|
55
|
+
|
|
56
|
+
tile_gamma : float, default 1.0
|
|
57
|
+
Shapes the within-tile ramp. 1.0 = linear sawtooth. >1.0 makes tiles
|
|
58
|
+
stay darker longer and brighten sharply near boundaries. <1.0 brightens
|
|
59
|
+
earlier.
|
|
60
|
+
|
|
61
|
+
tile_mix : float in [0, 1], default 1.0
|
|
62
|
+
Mix between original magnitude brightness and tiling shading:
|
|
63
|
+
0.0 -> value = 1 - exp(-|c|) (your original, no tiling influence)
|
|
64
|
+
1.0 -> value = tiling shading only (Wegert-style tiling look)
|
|
65
|
+
Intermediate values overlay tiling onto the original magnitude shading.
|
|
66
|
+
|
|
67
|
+
Notes
|
|
68
|
+
-----
|
|
69
|
+
|
|
70
|
+
The coloring technique is inspired from [1]_.
|
|
71
|
+
|
|
72
|
+
References
|
|
73
|
+
----------
|
|
74
|
+
|
|
75
|
+
[1] Wegert, E. (2015) "Visual Complex Functions: An Introduction +with
|
|
76
|
+
Phase Portraits", Springer.
|
|
77
|
+
doi: https://doi.org/10.1007/978-3-0348-0180-5
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
hue = (numpy.angle(c) + numpy.pi) / (2.0 * numpy.pi)
|
|
81
|
+
|
|
82
|
+
hue = (hue + shift) % 1.0
|
|
83
|
+
|
|
84
|
+
r = numpy.abs(c)
|
|
85
|
+
if numpy.isfinite(thresh):
|
|
86
|
+
r = numpy.minimum(r, thresh)
|
|
87
|
+
|
|
88
|
+
value0 = 1.0 - numpy.exp(-r)
|
|
89
|
+
|
|
90
|
+
eps = 1e-300
|
|
91
|
+
tau = 2.0 * numpy.pi
|
|
92
|
+
|
|
93
|
+
g = numpy.ones_like(hue)
|
|
94
|
+
|
|
95
|
+
if n_mod and n_mod > 0.0:
|
|
96
|
+
x_mod = (n_mod / tau) * numpy.log(r + eps)
|
|
97
|
+
g_mod = numpy.ceil(x_mod) - x_mod
|
|
98
|
+
g = g * g_mod
|
|
99
|
+
|
|
100
|
+
if n_ph and n_ph > 0.0:
|
|
101
|
+
theta = (numpy.angle(c) + numpy.pi) % tau
|
|
102
|
+
|
|
103
|
+
x_ph = (n_ph / tau) * theta
|
|
104
|
+
g_ph = numpy.ceil(x_ph) - x_ph
|
|
105
|
+
g = g * g_ph
|
|
106
|
+
|
|
107
|
+
g = numpy.clip(g, 0.0, 1.0)
|
|
108
|
+
if tile_gamma and tile_gamma != 1.0:
|
|
109
|
+
g = g ** float(tile_gamma)
|
|
110
|
+
|
|
111
|
+
vmin = float(numpy.clip(vmin, 0.0, 1.0))
|
|
112
|
+
vmax = float(numpy.clip(vmax, 0.0, 1.0))
|
|
113
|
+
if vmax < vmin:
|
|
114
|
+
vmin, vmax = vmax, vmin
|
|
115
|
+
|
|
116
|
+
value_tile = vmin + (vmax - vmin) * g
|
|
117
|
+
|
|
118
|
+
tile_mix = float(numpy.clip(tile_mix, 0.0, 1.0))
|
|
119
|
+
value = (1.0 - tile_mix) * value0 + tile_mix * value_tile
|
|
120
|
+
|
|
121
|
+
saturation = numpy.ones_like(hue)
|
|
122
|
+
hsv = numpy.stack((hue, saturation, numpy.clip(value, 0.0, 1.0)), axis=-1)
|
|
123
|
+
rgb = matplotlib.colors.hsv_to_rgb(hsv)
|
|
124
|
+
|
|
125
|
+
return rgb
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: freealg
|
|
3
|
+
Version: 0.7.12
|
|
4
|
+
Summary: Free probability for large matrices
|
|
5
|
+
Home-page: https://github.com/ameli/freealg
|
|
6
|
+
Download-URL: https://github.com/ameli/freealg/archive/main.zip
|
|
7
|
+
Project-URL: Documentation, https://ameli.github.io/freealg
|
|
8
|
+
Project-URL: Source, https://github.com/ameli/freealg
|
|
9
|
+
Project-URL: Tracker, https://github.com/ameli/freealg/issues
|
|
10
|
+
Keywords: linalg,free-probability
|
|
11
|
+
Platform: Linux
|
|
12
|
+
Platform: OSX
|
|
13
|
+
Platform: Windows
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
20
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
21
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
22
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
23
|
+
Classifier: Operating System :: MacOS
|
|
24
|
+
Classifier: Natural Language :: English
|
|
25
|
+
Classifier: Intended Audience :: Science/Research
|
|
26
|
+
Classifier: Intended Audience :: Developers
|
|
27
|
+
Classifier: Topic :: Software Development
|
|
28
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
29
|
+
Requires-Python: >=3.10
|
|
30
|
+
Description-Content-Type: text/x-rst
|
|
31
|
+
License-File: LICENSE.txt
|
|
32
|
+
License-File: AUTHORS.txt
|
|
33
|
+
Requires-Dist: numpy
|
|
34
|
+
Requires-Dist: scipy
|
|
35
|
+
Requires-Dist: texplot
|
|
36
|
+
Requires-Dist: matplotlib
|
|
37
|
+
Requires-Dist: colorcet
|
|
38
|
+
Requires-Dist: statsmodels
|
|
39
|
+
Requires-Dist: numba
|
|
40
|
+
Requires-Dist: tqdm
|
|
41
|
+
Provides-Extra: test
|
|
42
|
+
Provides-Extra: docs
|
|
43
|
+
Dynamic: classifier
|
|
44
|
+
Dynamic: description
|
|
45
|
+
Dynamic: description-content-type
|
|
46
|
+
Dynamic: download-url
|
|
47
|
+
Dynamic: home-page
|
|
48
|
+
Dynamic: keywords
|
|
49
|
+
Dynamic: license-file
|
|
50
|
+
Dynamic: platform
|
|
51
|
+
Dynamic: project-url
|
|
52
|
+
Dynamic: provides-extra
|
|
53
|
+
Dynamic: requires-dist
|
|
54
|
+
Dynamic: requires-python
|
|
55
|
+
Dynamic: summary
|
|
56
|
+
|
|
57
|
+
.. figure:: https://raw.githubusercontent.com/ameli/freealg/refs/heads/main/docs/source/_static/images/icons/logo-freealg-light.png
|
|
58
|
+
:align: left
|
|
59
|
+
:width: 240
|
|
60
|
+
|
|
61
|
+
`Paper <https://arxiv.org/abs/2506.11994>`__ |
|
|
62
|
+
`Slides <https://www.dropbox.com/scl/fi/03gjuyz17k9yhsqy0isoz/free_decomporession_slides.pdf?rlkey=8f82mhciyl2ju02l7hv1md5li&st=26xmhjga&dl=0>`__ |
|
|
63
|
+
`Docs <https://ameli.github.io/freealg>`__ |
|
|
64
|
+
`Live Demo <https://colab.research.google.com/github/ameli/freealg/blob/main/notebooks/quick_start.ipynb>`__
|
|
65
|
+
|
|
66
|
+
.. `Slides <https://ameli.github.io/freealg/_static/data/slides.pdf>`__ |
|
|
67
|
+
|
|
68
|
+
*freealg* is a Python package that employs **free** probability to evaluate the
|
|
69
|
+
spectral densities of large matrix **form**\ s. The fundamental algorithm
|
|
70
|
+
employed by *freealg* is **free decompression**, which extrapolates from the
|
|
71
|
+
empirical spectral densities of small submatrices to infer the eigenspectrum
|
|
72
|
+
of extremely large matrices.
|
|
73
|
+
|
|
74
|
+
Install
|
|
75
|
+
=======
|
|
76
|
+
|
|
77
|
+
|pypi|
|
|
78
|
+
|
|
79
|
+
Install with ``pip``:
|
|
80
|
+
|
|
81
|
+
.. code-block::
|
|
82
|
+
|
|
83
|
+
pip install freealg
|
|
84
|
+
|
|
85
|
+
Alternatively, clone the source code and install with
|
|
86
|
+
|
|
87
|
+
.. code-block::
|
|
88
|
+
|
|
89
|
+
cd source_dir
|
|
90
|
+
pip install .
|
|
91
|
+
|
|
92
|
+
Documentation
|
|
93
|
+
=============
|
|
94
|
+
|
|
95
|
+
|deploy-docs|
|
|
96
|
+
|
|
97
|
+
Documentation is available at `ameli.github.io/freealg <https://ameli.github.io/freealg>`__.
|
|
98
|
+
|
|
99
|
+
Quick Usage
|
|
100
|
+
===========
|
|
101
|
+
|
|
102
|
+
The following code estimates the eigenvalues of a very large Wishart matrix
|
|
103
|
+
using a much smaller Wishart matrix.
|
|
104
|
+
|
|
105
|
+
.. code-block:: python
|
|
106
|
+
|
|
107
|
+
>>> import freealg as fa
|
|
108
|
+
>>> mp = fa.distributions.MarchenkoPastur(1/50) # Wishart matrices with aspect ratio 1/50
|
|
109
|
+
>>> A = mp.matrix(1000) # Sample a 1000 x 1000 Wishart matrix
|
|
110
|
+
>>> eigs = fa.eigvalsh(A, 100_000) # Estimate the eigenvalues of 100000 x 100000
|
|
111
|
+
|
|
112
|
+
For more details on how to interface with *freealg* check out the
|
|
113
|
+
`Live Demo <https://colab.research.google.com/github/ameli/freealg/blob/main/notebooks/quick_start.ipynb>`__.
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
Test
|
|
117
|
+
====
|
|
118
|
+
|
|
119
|
+
|build-linux|
|
|
120
|
+
|
|
121
|
+
You may test the package with `tox <https://tox.wiki/>`__:
|
|
122
|
+
|
|
123
|
+
.. code-block::
|
|
124
|
+
|
|
125
|
+
cd source_dir
|
|
126
|
+
tox
|
|
127
|
+
|
|
128
|
+
Alternatively, test with `pytest <https://pytest.org>`__:
|
|
129
|
+
|
|
130
|
+
.. code-block::
|
|
131
|
+
|
|
132
|
+
cd source_dir
|
|
133
|
+
pytest
|
|
134
|
+
|
|
135
|
+
How to Contribute
|
|
136
|
+
=================
|
|
137
|
+
|
|
138
|
+
We welcome contributions via GitHub's pull request. Developers should review
|
|
139
|
+
our `Contributing Guidelines <https://github.com/ameli/freealg/blob/main/CONTRIBUTING.rst>`__
|
|
140
|
+
before submitting their code. If you do not feel comfortable modifying the
|
|
141
|
+
code, we also welcome feature requests and bug reports.
|
|
142
|
+
|
|
143
|
+
How to Cite
|
|
144
|
+
===========
|
|
145
|
+
|
|
146
|
+
If you use this work, please cite our `paper <https://openreview.net/pdf?id=2CeGVUpOd7>`__.
|
|
147
|
+
|
|
148
|
+
.. code::
|
|
149
|
+
|
|
150
|
+
@inproceedings{
|
|
151
|
+
AMELI-2025,
|
|
152
|
+
title={Spectral Estimation with Free Decompression},
|
|
153
|
+
author={Siavash Ameli and Chris van der Heide and Liam Hodgkinson and Michael W. Mahoney},
|
|
154
|
+
booktitle={The Thirty-ninth Annual Conference on Neural Information Processing Systems},
|
|
155
|
+
year={2025},
|
|
156
|
+
url={https://openreview.net/forum?id=2CeGVUpOd7}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
License
|
|
161
|
+
=======
|
|
162
|
+
|
|
163
|
+
|license|
|
|
164
|
+
|
|
165
|
+
.. |build-linux| image:: https://img.shields.io/github/actions/workflow/status/ameli/freealg/build-linux.yml
|
|
166
|
+
:target: https://github.com/ameli/freealg/actions?query=workflow%3Abuild-linux
|
|
167
|
+
.. |deploy-docs| image:: https://img.shields.io/github/actions/workflow/status/ameli/freealg/deploy-docs.yml?label=docs
|
|
168
|
+
:target: https://github.com/ameli/freealg/actions?query=workflow%3Adeploy-docs
|
|
169
|
+
.. |pypi| image:: https://img.shields.io/pypi/v/freealg
|
|
170
|
+
:target: https://pypi.org/project/freealg/
|
|
171
|
+
.. |license| image:: https://img.shields.io/github/license/ameli/freealg
|
|
172
|
+
:target: https://opensource.org/licenses/BSD-3-Clause
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
freealg/__init__.py,sha256=is4de7kygj1be0S3EAcAlW_vGriWjdjHCR-J9NN6wyk,873
|
|
2
|
+
freealg/__version__.py,sha256=PjQNisQKLFjBRbjgoDmIiFnMrUFWFPsbOBfj_imtP4Q,23
|
|
3
|
+
freealg/_util.py,sha256=RzccUCORgzrI9NdNqwMVugiHU0uDKkJFcIyjFMUOnv8,2518
|
|
4
|
+
freealg/_algebraic_form/__init__.py,sha256=etgaRiuipcmxtwHzMVxZwO_qbX8R7m9j39mKvgRyTZg,463
|
|
5
|
+
freealg/_algebraic_form/_branch_points.py,sha256=jzvHszw7xFe9B15a5RZV3pGfCGtndvrKJ4GIX6F3qhc,7814
|
|
6
|
+
freealg/_algebraic_form/_constraints.py,sha256=xBpsKAL0-Czxf9ZF9tspLpTaFJ1m2DDyqc2KH9bl5Xg,3601
|
|
7
|
+
freealg/_algebraic_form/_continuation_algebraic.py,sha256=vVHFlMJYeXm97pgwEceJB2rGJeGOVhk_Ywg6mjoIA-g,19390
|
|
8
|
+
freealg/_algebraic_form/_decompress.py,sha256=yCGTT3F-0NtGi3oENIS11Zcc7SVaMv_hxvzWuho5huw,22274
|
|
9
|
+
freealg/_algebraic_form/_decompress2.py,sha256=tTAxJMLQM4WJJ32UxYgv3rhTlBnn3GfFSCbse4W4S8A,6583
|
|
10
|
+
freealg/_algebraic_form/_edge.py,sha256=X91GeX8nZZ_Lf7C3l7u-JpESDmwRqACYA_G2l1KVs2Y,9604
|
|
11
|
+
freealg/_algebraic_form/_homotopy.py,sha256=FdKQhUTjdk6Rmdd5zb8IzDJN0pteHUcgJL3eG_ySUzM,10912
|
|
12
|
+
freealg/_algebraic_form/_moments.py,sha256=v_ahJIDDMgiiZEOiJ1yMYOVRIa-zQG4Gzmzp4QSHfE4,12432
|
|
13
|
+
freealg/_algebraic_form/_sheets_util.py,sha256=6OLzWQKu-gN8rxM2rbpbN8TjNZFmD8UJ-8t9kcZdkCo,4174
|
|
14
|
+
freealg/_algebraic_form/_support.py,sha256=9go_3NjmesSW1e08CiDu8oflpGmAbsh9iZRidMvlARI,7951
|
|
15
|
+
freealg/_algebraic_form/algebraic_form.py,sha256=rKxuPizOMsfJZlq0YRwud439tsNCt08uNPiUOLDnNKM,37223
|
|
16
|
+
freealg/_free_form/__init__.py,sha256=5cnSX7kHci3wKx6-BEFhmVY_NjjmQAq1JjWPTEqETTg,611
|
|
17
|
+
freealg/_free_form/_chebyshev.py,sha256=zkyVA8NLf7uUKlJdLz4ijd_SurdsqUgkA5nHGWSybaE,6916
|
|
18
|
+
freealg/_free_form/_damp.py,sha256=k2vtBtWOxQBf4qXaWu_En81lQBXbEO4QbxxWpvuVhdE,1802
|
|
19
|
+
freealg/_free_form/_decompress.py,sha256=_i37IToZ6oN9DdLXOM8r4y92EbazzcylhcnWwUOpaj0,32108
|
|
20
|
+
freealg/_free_form/_density_util.py,sha256=C_0lKA5QzKAdxPRLJvajNO9zaw2QliZ-n7SI8g2a53M,6745
|
|
21
|
+
freealg/_free_form/_jacobi.py,sha256=z0X6Ws_BEo_h8EQBzDNHGFhLF9F2PUmnGeBVs0bNL7w,10709
|
|
22
|
+
freealg/_free_form/_linalg.py,sha256=GNiQpT193VWxLOejVdAUPQdNJas4ms8US3YR8ZaYXGA,13143
|
|
23
|
+
freealg/_free_form/_pade.py,sha256=_y89r7rVc2E5lgiN_ZjnxzW2IaVevWwpq5ISor2NVOo,10310
|
|
24
|
+
freealg/_free_form/_plot_util.py,sha256=GKvmc1wjVGeqoomrULPbzBEt6P86FdoR2idBLYh5EDY,20068
|
|
25
|
+
freealg/_free_form/_sample.py,sha256=rhfd_83TCTvvJh8cG8TzEYO4OR8VbtND2YCNtWEhMa8,3205
|
|
26
|
+
freealg/_free_form/_series.py,sha256=33LLCUe4svmV0eWyzhP_XClfDzccQHTW9WBJlYlLfHY,11475
|
|
27
|
+
freealg/_free_form/_support.py,sha256=B6oSqW7MGikpJlTGzNbnMF63LhI5al2ccToqcncTPYs,6624
|
|
28
|
+
freealg/_free_form/free_form.py,sha256=UaRLYSvA0ib5wy1xnLy3_9ndCJ6gUdhNswSm0m9-7go,43571
|
|
29
|
+
freealg/_geometric_form/__init__.py,sha256=mWsXP0nXs3pY8RfUDhPRTgIfhOigKqw_VmoWnJOw2a0,485
|
|
30
|
+
freealg/_geometric_form/_continuation_genus0.py,sha256=4jiXfQaA6w3IhVkJgtKVVjqqtBmavq78FY_YTGUQyY0,4026
|
|
31
|
+
freealg/_geometric_form/_continuation_genus1.py,sha256=X8NZ1_6PxhJJLXZk5ASeGwxej_KwH3-ftuXkBrOFmgU,6021
|
|
32
|
+
freealg/_geometric_form/_elliptic_functions.py,sha256=Rr_pb1A_FjrJlraYQj2G5shdO6f77aVQN2eQzrvIygI,4109
|
|
33
|
+
freealg/_geometric_form/_sphere_maps.py,sha256=NlhTgWXKWXKdyR2dQxMmePsIwHp7IWyYh6uoxgW5Osc,1465
|
|
34
|
+
freealg/_geometric_form/_torus_maps.py,sha256=7m5QsbmnXTWHJE5rWjKG3_TnErHEEQ41vW-3hsOc3lo,3338
|
|
35
|
+
freealg/_geometric_form/geometric_form.py,sha256=whHKYQdakqShtR-jCEugevnje72JEr9M0HSvZ2BYoKs,33379
|
|
36
|
+
freealg/distributions/__init__.py,sha256=sCx2NVcRTaHwvxXpFRU_9unN98ZED6B-xFoFZ2eU9-E,875
|
|
37
|
+
freealg/distributions/_chiral_block.py,sha256=YSC_Sk1u1UKlWVE1GGJEjX6VrWqpEEYNxBZ2j8Csc3A,13897
|
|
38
|
+
freealg/distributions/_deformed_marchenko_pastur.py,sha256=iZixcZiXUKpe9Vi4I1_x_p_lIVqJeo7Tlb8ENqbZa94,20929
|
|
39
|
+
freealg/distributions/_deformed_wigner.py,sha256=0933XQAplP3mifJKdSU7qXgrndqUs1MUpYMJHR-NId8,9086
|
|
40
|
+
freealg/distributions/_kesten_mckay.py,sha256=Uv3QuUYsfXbPMovXSO_pN3wdkc1fTKGVX7iuHDgBRqk,20089
|
|
41
|
+
freealg/distributions/_marchenko_pastur.py,sha256=eemaxDosKpV37TAn9uSiYpljIkVNoTWDJ9ZfYb8tAeY,20646
|
|
42
|
+
freealg/distributions/_meixner.py,sha256=GbcWeHrXMxK3Hdj4pCTESlMts9dEPQE1DhClxYprWfg,17590
|
|
43
|
+
freealg/distributions/_wachter.py,sha256=5nP4iqxgxltEHhZdb1ytei1zy_bDEI1cvldZdxlIXRk,17090
|
|
44
|
+
freealg/distributions/_wigner.py,sha256=epgx6ne6R_7to5j6-QsWIAVFJQFquWMmYgnZYMN4wUI,16069
|
|
45
|
+
freealg/visualization/__init__.py,sha256=NLq_zwueF7ytZ8sl8zLPqm-AODxxXNvfMozHGmmklcE,435
|
|
46
|
+
freealg/visualization/_glue_util.py,sha256=2oKnEYjUOS4OZfivmciVLauVr53kyHMwi6c2zRKilTQ,693
|
|
47
|
+
freealg/visualization/_rgb_hsv.py,sha256=rEskxXxSlKKxIrHRslVkgxHtD010L3ge9YtcVsOPl8E,3650
|
|
48
|
+
freealg-0.7.12.dist-info/licenses/AUTHORS.txt,sha256=0b67Nz4_JgIzUupHJTAZxu5QdSUM_HRM_X_w4xCb17o,30
|
|
49
|
+
freealg-0.7.12.dist-info/licenses/LICENSE.txt,sha256=J-EEYEtxb3VVf_Bn1TYfWnpY5lMFIM15iLDDcnaDTPA,1443
|
|
50
|
+
freealg-0.7.12.dist-info/METADATA,sha256=vzphSfQr5LulLS_XcKV38zmgb0PFfRPhMhqO0XCrmQg,5537
|
|
51
|
+
freealg-0.7.12.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
52
|
+
freealg-0.7.12.dist-info/top_level.txt,sha256=eR2wrgYwDdnnJ9Zf5PruPqe4kQav0GMvRsqct6y00Q8,8
|
|
53
|
+
freealg-0.7.12.dist-info/RECORD,,
|