freealg 0.3.1__py3-none-any.whl → 0.3.3__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/__version__.py +1 -1
- freealg/_support.py +1 -1
- freealg/eigh.py +58 -29
- {freealg-0.3.1.dist-info → freealg-0.3.3.dist-info}/METADATA +29 -15
- {freealg-0.3.1.dist-info → freealg-0.3.3.dist-info}/RECORD +9 -9
- {freealg-0.3.1.dist-info → freealg-0.3.3.dist-info}/WHEEL +0 -0
- {freealg-0.3.1.dist-info → freealg-0.3.3.dist-info}/licenses/AUTHORS.txt +0 -0
- {freealg-0.3.1.dist-info → freealg-0.3.3.dist-info}/licenses/LICENSE.txt +0 -0
- {freealg-0.3.1.dist-info → freealg-0.3.3.dist-info}/top_level.txt +0 -0
freealg/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.3.
|
|
1
|
+
__version__ = "0.3.3"
|
freealg/_support.py
CHANGED
|
@@ -127,7 +127,7 @@ def detect_support(eigs, method='asymp', k=None, p=0.001, **kwargs):
|
|
|
127
127
|
* ``'interior'``: estimates a support assuming the range overestimates;
|
|
128
128
|
uses quantiles (p, 1-p).
|
|
129
129
|
* ``'interior_smooth'``: same as ``'interior'`` but using kernel
|
|
130
|
-
density estimation, from [2].
|
|
130
|
+
density estimation, from [2]_.
|
|
131
131
|
|
|
132
132
|
k : int, default = None
|
|
133
133
|
Number of extreme order statistics to use for ``method='regression'``.
|
freealg/eigh.py
CHANGED
|
@@ -17,6 +17,42 @@ from .freeform import FreeForm
|
|
|
17
17
|
__all__ = ['eigh', 'cond', 'norm', 'trace', 'slogdet']
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
# ===============
|
|
21
|
+
# subsample apply
|
|
22
|
+
# ===============
|
|
23
|
+
|
|
24
|
+
def _subsample_apply(f, A, output_array=False):
|
|
25
|
+
"""
|
|
26
|
+
Compute f(A_n) over subsamples A_n of A. If the output of
|
|
27
|
+
f is an array (e.g. eigvals), specify output_array to be True.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
if A.ndim != 2 or A.shape[0] != A.shape[1]:
|
|
31
|
+
raise RuntimeError("Only square matrices are permitted.")
|
|
32
|
+
|
|
33
|
+
n = A.shape[0]
|
|
34
|
+
|
|
35
|
+
# Size of sample matrix
|
|
36
|
+
n_s = int(80*(1 + numpy.log(n)))
|
|
37
|
+
# If matrix is not large enough, return eigenvalues
|
|
38
|
+
if n < n_s:
|
|
39
|
+
return f(A), n, n
|
|
40
|
+
|
|
41
|
+
# Number of samples
|
|
42
|
+
num_samples = int(10 * (n / n_s)**0.5)
|
|
43
|
+
|
|
44
|
+
# Collect eigenvalue samples
|
|
45
|
+
samples = []
|
|
46
|
+
for _ in range(num_samples):
|
|
47
|
+
indices = numpy.random.choice(n, n_s, replace=False)
|
|
48
|
+
samples.append(f(A[numpy.ix_(indices, indices)]))
|
|
49
|
+
|
|
50
|
+
if output_array:
|
|
51
|
+
return numpy.concatenate(samples).ravel(), n, n_s
|
|
52
|
+
|
|
53
|
+
return numpy.array(samples), n, n_s
|
|
54
|
+
|
|
55
|
+
|
|
20
56
|
# ====
|
|
21
57
|
# eigh
|
|
22
58
|
# ====
|
|
@@ -87,28 +123,11 @@ def eigh(A, N=None, psd=None, plots=False):
|
|
|
87
123
|
>>> eigs = eigh(A)
|
|
88
124
|
"""
|
|
89
125
|
|
|
90
|
-
|
|
91
|
-
raise RuntimeError("Only square matrices are permitted.")
|
|
92
|
-
n = A.shape[0]
|
|
126
|
+
samples, n, n_s = _subsample_apply(compute_eig, A, output_array=True)
|
|
93
127
|
|
|
94
128
|
if N is None:
|
|
95
129
|
N = n
|
|
96
130
|
|
|
97
|
-
# Size of sample matrix
|
|
98
|
-
n_s = int(80*(1 + numpy.log(n)))
|
|
99
|
-
# If matrix is not large enough, return eigenvalues
|
|
100
|
-
if n < n_s:
|
|
101
|
-
return compute_eig(A)
|
|
102
|
-
# Number of samples
|
|
103
|
-
num_samples = int(10 * (n / n_s)**0.5)
|
|
104
|
-
|
|
105
|
-
# Collect eigenvalue samples
|
|
106
|
-
samples = []
|
|
107
|
-
for _ in range(num_samples):
|
|
108
|
-
indices = numpy.random.choice(n, n_s, replace=False)
|
|
109
|
-
samples.append(compute_eig(A[numpy.ix_(indices, indices)]))
|
|
110
|
-
samples = numpy.concatenate(samples).ravel()
|
|
111
|
-
|
|
112
131
|
# If all eigenvalues are positive, set PSD flag
|
|
113
132
|
if psd is None:
|
|
114
133
|
psd = samples.min() > 0
|
|
@@ -224,7 +243,7 @@ def norm(A, N=None, order=None):
|
|
|
224
243
|
order : {float, ``''inf``, ``'-inf'``, ``'fro'``, ``'nuc'``}, default=2
|
|
225
244
|
Order of the norm.
|
|
226
245
|
|
|
227
|
-
* float :math:`p`:
|
|
246
|
+
* float :math:`p`: Schatten p-norm.
|
|
228
247
|
* ``'inf'``: Largest absolute eigenvalue
|
|
229
248
|
:math:`\\max \\vert \\lambda_i \\vert)`
|
|
230
249
|
* ``'-inf'``: Smallest absolute eigenvalue
|
|
@@ -300,19 +319,19 @@ def norm(A, N=None, order=None):
|
|
|
300
319
|
# trace
|
|
301
320
|
# =====
|
|
302
321
|
|
|
303
|
-
def trace(A, N=None):
|
|
322
|
+
def trace(A, N=None, p=1.0):
|
|
304
323
|
"""
|
|
305
|
-
Estimate the trace of a Hermitian matrix.
|
|
324
|
+
Estimate the trace of a power of a Hermitian matrix.
|
|
306
325
|
|
|
307
|
-
This function estimates the trace of the matrix :math:`\\mathbf{A}`
|
|
308
|
-
larger matrix containing :math:`\\mathbf{A}
|
|
326
|
+
This function estimates the trace of the matrix power :math:`\\mathbf{A}^p`
|
|
327
|
+
or that of a larger matrix containing :math:`\\mathbf{A}`.
|
|
309
328
|
|
|
310
329
|
Parameters
|
|
311
330
|
----------
|
|
312
331
|
|
|
313
332
|
A : numpy.ndarray
|
|
314
|
-
The symmetric real-valued matrix :math:`\\mathbf{A}` whose
|
|
315
|
-
|
|
333
|
+
The symmetric real-valued matrix :math:`\\mathbf{A}` whose trace of
|
|
334
|
+
a power (or that of a matrix containing :math:`\\mathbf{A}`) is to be
|
|
316
335
|
computed.
|
|
317
336
|
|
|
318
337
|
N : int, default=None
|
|
@@ -320,6 +339,10 @@ def trace(A, N=None):
|
|
|
320
339
|
eigenvalues of. If None, returns estimates of the eigenvalues of
|
|
321
340
|
:math:`\\mathbf{A}` itself.
|
|
322
341
|
|
|
342
|
+
p : float, default=1.0
|
|
343
|
+
The exponent :math:`p` in :math:`\\mathbf{A}^p`.
|
|
344
|
+
|
|
345
|
+
|
|
323
346
|
Returns
|
|
324
347
|
-------
|
|
325
348
|
|
|
@@ -337,7 +360,9 @@ def trace(A, N=None):
|
|
|
337
360
|
Notes
|
|
338
361
|
-----
|
|
339
362
|
|
|
340
|
-
|
|
363
|
+
The trace is highly amenable to subsampling: under free decompression
|
|
364
|
+
the average eigenvalue is assumed constant, so the trace increases
|
|
365
|
+
linearly. Traces of powers fall back to :func:`freealg.eigh`.
|
|
341
366
|
|
|
342
367
|
Examples
|
|
343
368
|
--------
|
|
@@ -353,10 +378,14 @@ def trace(A, N=None):
|
|
|
353
378
|
>>> trace(A, 100_000)
|
|
354
379
|
"""
|
|
355
380
|
|
|
356
|
-
|
|
357
|
-
|
|
381
|
+
if numpy.isclose(p, 1.0):
|
|
382
|
+
samples, n, n_s = _subsample_apply(numpy.trace, A, output_array=False)
|
|
383
|
+
if N is None:
|
|
384
|
+
N = n
|
|
385
|
+
return numpy.mean(samples) * (N / n_s)
|
|
358
386
|
|
|
359
|
-
|
|
387
|
+
eig = eigh(A, N)
|
|
388
|
+
return numpy.sum(eig ** p)
|
|
360
389
|
|
|
361
390
|
|
|
362
391
|
# =======
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: freealg
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
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
|
|
5
10
|
Keywords: linalg,free-probability
|
|
6
11
|
Platform: Linux
|
|
7
12
|
Platform: OSX
|
|
@@ -37,30 +42,38 @@ Provides-Extra: docs
|
|
|
37
42
|
Dynamic: classifier
|
|
38
43
|
Dynamic: description
|
|
39
44
|
Dynamic: description-content-type
|
|
45
|
+
Dynamic: download-url
|
|
46
|
+
Dynamic: home-page
|
|
40
47
|
Dynamic: keywords
|
|
41
48
|
Dynamic: license-file
|
|
42
49
|
Dynamic: platform
|
|
50
|
+
Dynamic: project-url
|
|
43
51
|
Dynamic: provides-extra
|
|
44
52
|
Dynamic: requires-dist
|
|
45
53
|
Dynamic: requires-python
|
|
46
54
|
Dynamic: summary
|
|
47
55
|
|
|
48
|
-
.. image:: https://raw.githubusercontent.com/ameli/freealg/refs/heads/main/docs/source/_static/images/icons/logo-freealg-light.png
|
|
56
|
+
.. .. image:: https://raw.githubusercontent.com/ameli/freealg/refs/heads/main/docs/source/_static/images/icons/logo-freealg-light.png
|
|
57
|
+
.. :align: left
|
|
58
|
+
.. :width: 240
|
|
59
|
+
.. :class: custom-dark
|
|
60
|
+
|
|
61
|
+
.. figure:: https://raw.githubusercontent.com/ameli/freealg/refs/heads/main/docs/source/_static/images/icons/logo-freealg-light.png
|
|
49
62
|
:align: left
|
|
50
63
|
:width: 240
|
|
51
|
-
:class: custom-dark
|
|
52
64
|
|
|
53
65
|
`Paper <https://arxiv.org/abs/2506.11994>`__ |
|
|
54
66
|
`Slides <https://www.dropbox.com/scl/fi/03gjuyz17k9yhsqy0isoz/free_decomporession_slides.pdf?rlkey=8f82mhciyl2ju02l7hv1md5li&st=26xmhjga&dl=0>`__ |
|
|
55
67
|
`Docs <https://ameli.github.io/freealg>`__ |
|
|
56
|
-
`Live Demo <https://
|
|
68
|
+
`Live Demo <https://colab.research.google.com/github/ameli/freealg/blob/main/notebooks/quick_start.ipynb>`__
|
|
57
69
|
|
|
58
70
|
.. `Slides <https://ameli.github.io/freealg/_static/data/slides.pdf>`__ |
|
|
59
71
|
|
|
60
|
-
*freealg* is a Python package that employs **free** probability to evaluate the
|
|
61
|
-
densities of large matrix **form**\ s. The fundamental algorithm
|
|
62
|
-
**free decompression**, which extrapolates from the
|
|
63
|
-
submatrices to infer the eigenspectrum
|
|
72
|
+
*freealg* is a Python package that employs **free** probability to evaluate the
|
|
73
|
+
spectral densities of large matrix **form**\ s. The fundamental algorithm
|
|
74
|
+
employed by *freealg* is **free decompression**, which extrapolates from the
|
|
75
|
+
empirical spectral densities of small submatrices to infer the eigenspectrum
|
|
76
|
+
of extremely large matrices.
|
|
64
77
|
|
|
65
78
|
Install
|
|
66
79
|
=======
|
|
@@ -86,8 +99,8 @@ Documentation is available at `ameli.github.io/freealg <https://ameli.github.io/
|
|
|
86
99
|
Quick Usage
|
|
87
100
|
===========
|
|
88
101
|
|
|
89
|
-
The following code estimates the eigenvalues of a very large Wishart matrix
|
|
90
|
-
smaller Wishart matrix.
|
|
102
|
+
The following code estimates the eigenvalues of a very large Wishart matrix
|
|
103
|
+
using a much smaller Wishart matrix.
|
|
91
104
|
|
|
92
105
|
.. code-block:: python
|
|
93
106
|
|
|
@@ -96,7 +109,8 @@ smaller Wishart matrix.
|
|
|
96
109
|
>>> A = mp.matrix(1000) # Sample a 1000 x 1000 Wishart matrix
|
|
97
110
|
>>> eigs = fa.eigfree(A, 100_000) # Estimate the eigenvalues of 100000 x 100000
|
|
98
111
|
|
|
99
|
-
For more details on how to interface with *freealg* check out the
|
|
112
|
+
For more details on how to interface with *freealg* check out the
|
|
113
|
+
`Quick Start Guide <https://github.com/ameli/freealg/blob/main/notebooks/quick_start.ipynb>`__.
|
|
100
114
|
|
|
101
115
|
|
|
102
116
|
Test
|
|
@@ -120,14 +134,14 @@ How to Contribute
|
|
|
120
134
|
=================
|
|
121
135
|
|
|
122
136
|
We welcome contributions via GitHub's pull request. Developers should review
|
|
123
|
-
our [Contributing Guidelines](CONTRIBUTING.rst)
|
|
124
|
-
If you do not feel comfortable modifying the
|
|
125
|
-
requests and bug reports.
|
|
137
|
+
our [Contributing Guidelines](https://github.com/ameli/freealg/blob/main/CONTRIBUTING.rst)
|
|
138
|
+
before submitting their code. If you do not feel comfortable modifying the
|
|
139
|
+
code, we also welcome feature requests and bug reports.
|
|
126
140
|
|
|
127
141
|
How to Cite
|
|
128
142
|
===========
|
|
129
143
|
|
|
130
|
-
If you use this work, please cite
|
|
144
|
+
If you use this work, please cite our `arXiv paper <https://arxiv.org/abs/2506.11994>`__.
|
|
131
145
|
|
|
132
146
|
.. code::
|
|
133
147
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
freealg/__init__.py,sha256=AM0G2tX7sBgzCTcOVbWynA9NFkQZKyphL9IR1tKOoK4,614
|
|
2
|
-
freealg/__version__.py,sha256=
|
|
2
|
+
freealg/__version__.py,sha256=8KcCYTXH99C2-gCLuPILJvtT9YftRWJsartIx6TQ2ZY,22
|
|
3
3
|
freealg/_chebyshev.py,sha256=dsAj3YEpmkzB65smluZ0Fi5IZSdpnQXBSIuKMg19grA,5523
|
|
4
4
|
freealg/_damp.py,sha256=k2vtBtWOxQBf4qXaWu_En81lQBXbEO4QbxxWpvuVhdE,1802
|
|
5
5
|
freealg/_decompress.py,sha256=0MYoO3lqwMgNYlVriaRNUqUwY3XYyZZsDAtNRBq6rhE,10470
|
|
@@ -7,9 +7,9 @@ freealg/_jacobi.py,sha256=AT4ONSHGGDxVKE3MGMLyMR8uDFiO-e9u3x5udYfdJJk,5635
|
|
|
7
7
|
freealg/_pade.py,sha256=Diw850oH2OLQeUrBR-q19TmjSBoBvXl6ogp4o1s2UIo,15184
|
|
8
8
|
freealg/_plot_util.py,sha256=U4alp7Pzg315_7jJdu1UB0tIUcxUovQgHDHsUYoa2Z0,19728
|
|
9
9
|
freealg/_sample.py,sha256=ckC75eqv-mRP1F5BnhvsjfLTaoAzHK8bebl9bCRZYDo,2561
|
|
10
|
-
freealg/_support.py,sha256=
|
|
10
|
+
freealg/_support.py,sha256=mYlrsdLbniqFgFofbHrZIiYSyJudPqtyMQQTPBD9Y6M,6439
|
|
11
11
|
freealg/_util.py,sha256=8Tvz-XODtKYoU76ODmF1TBaIYLlr6-AXiyoMDwDSxVg,3779
|
|
12
|
-
freealg/eigh.py,sha256=
|
|
12
|
+
freealg/eigh.py,sha256=ybUCE8Qi-H8r-QxDvbeSP9Ow-q8xTuq5o-LNhPvBvIE,10926
|
|
13
13
|
freealg/freeform.py,sha256=8emyCQ6AUjp_HB1gWQ-ecddlDgfxHGr3PqXSyoPxeMo,28593
|
|
14
14
|
freealg/distributions/__init__.py,sha256=t_yZyEkW_W_tSV9IvgYXtVASxD2BEdiNVXcV2ebMy8M,579
|
|
15
15
|
freealg/distributions/_kesten_mckay.py,sha256=210RF2OQEYLZBeLB6wmbdHnZPs_9ldDNHm_FMlg5tis,19881
|
|
@@ -17,9 +17,9 @@ freealg/distributions/_marchenko_pastur.py,sha256=kchFccRMuVF2Cus_99vdEwuRimkHzE
|
|
|
17
17
|
freealg/distributions/_meixner.py,sha256=ws7t_EUa7V0s97dgMQIJLv1b6qMLqf9fLLbTJQudf_8,17512
|
|
18
18
|
freealg/distributions/_wachter.py,sha256=Hna_MXqAPjuRkeilLPMf4Xg_3C6tTu5oZLEQnA-RuE4,16897
|
|
19
19
|
freealg/distributions/_wigner.py,sha256=SxgPLtvIVBi9m4De-oBD0x6-2Je_eBqpDrpDYcoLuis,15871
|
|
20
|
-
freealg-0.3.
|
|
21
|
-
freealg-0.3.
|
|
22
|
-
freealg-0.3.
|
|
23
|
-
freealg-0.3.
|
|
24
|
-
freealg-0.3.
|
|
25
|
-
freealg-0.3.
|
|
20
|
+
freealg-0.3.3.dist-info/licenses/AUTHORS.txt,sha256=0b67Nz4_JgIzUupHJTAZxu5QdSUM_HRM_X_w4xCb17o,30
|
|
21
|
+
freealg-0.3.3.dist-info/licenses/LICENSE.txt,sha256=J-EEYEtxb3VVf_Bn1TYfWnpY5lMFIM15iLDDcnaDTPA,1443
|
|
22
|
+
freealg-0.3.3.dist-info/METADATA,sha256=DADdzlak4svhV-GaZCt5NohqxbJCk1KXN9hk33Vs9_c,5178
|
|
23
|
+
freealg-0.3.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
24
|
+
freealg-0.3.3.dist-info/top_level.txt,sha256=eR2wrgYwDdnnJ9Zf5PruPqe4kQav0GMvRsqct6y00Q8,8
|
|
25
|
+
freealg-0.3.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|