freealg 0.3.0__tar.gz → 0.3.2__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 (36) hide show
  1. {freealg-0.3.0 → freealg-0.3.2}/PKG-INFO +13 -4
  2. {freealg-0.3.0 → freealg-0.3.2}/README.rst +3 -2
  3. freealg-0.3.2/freealg/__version__.py +1 -0
  4. {freealg-0.3.0 → freealg-0.3.2}/freealg/_support.py +4 -2
  5. {freealg-0.3.0 → freealg-0.3.2}/freealg/eigh.py +51 -33
  6. {freealg-0.3.0 → freealg-0.3.2}/freealg.egg-info/PKG-INFO +13 -4
  7. {freealg-0.3.0 → freealg-0.3.2}/setup.py +14 -1
  8. freealg-0.3.0/freealg/__version__.py +0 -1
  9. {freealg-0.3.0 → freealg-0.3.2}/AUTHORS.txt +0 -0
  10. {freealg-0.3.0 → freealg-0.3.2}/CHANGELOG.rst +0 -0
  11. {freealg-0.3.0 → freealg-0.3.2}/LICENSE.txt +0 -0
  12. {freealg-0.3.0 → freealg-0.3.2}/MANIFEST.in +0 -0
  13. {freealg-0.3.0 → freealg-0.3.2}/freealg/__init__.py +0 -0
  14. {freealg-0.3.0 → freealg-0.3.2}/freealg/_chebyshev.py +0 -0
  15. {freealg-0.3.0 → freealg-0.3.2}/freealg/_damp.py +0 -0
  16. {freealg-0.3.0 → freealg-0.3.2}/freealg/_decompress.py +0 -0
  17. {freealg-0.3.0 → freealg-0.3.2}/freealg/_jacobi.py +0 -0
  18. {freealg-0.3.0 → freealg-0.3.2}/freealg/_pade.py +0 -0
  19. {freealg-0.3.0 → freealg-0.3.2}/freealg/_plot_util.py +0 -0
  20. {freealg-0.3.0 → freealg-0.3.2}/freealg/_sample.py +0 -0
  21. {freealg-0.3.0 → freealg-0.3.2}/freealg/_util.py +0 -0
  22. {freealg-0.3.0 → freealg-0.3.2}/freealg/distributions/__init__.py +0 -0
  23. {freealg-0.3.0 → freealg-0.3.2}/freealg/distributions/_kesten_mckay.py +0 -0
  24. {freealg-0.3.0 → freealg-0.3.2}/freealg/distributions/_marchenko_pastur.py +0 -0
  25. {freealg-0.3.0 → freealg-0.3.2}/freealg/distributions/_meixner.py +0 -0
  26. {freealg-0.3.0 → freealg-0.3.2}/freealg/distributions/_wachter.py +0 -0
  27. {freealg-0.3.0 → freealg-0.3.2}/freealg/distributions/_wigner.py +0 -0
  28. {freealg-0.3.0 → freealg-0.3.2}/freealg/freeform.py +0 -0
  29. {freealg-0.3.0 → freealg-0.3.2}/freealg.egg-info/SOURCES.txt +0 -0
  30. {freealg-0.3.0 → freealg-0.3.2}/freealg.egg-info/dependency_links.txt +0 -0
  31. {freealg-0.3.0 → freealg-0.3.2}/freealg.egg-info/not-zip-safe +0 -0
  32. {freealg-0.3.0 → freealg-0.3.2}/freealg.egg-info/requires.txt +0 -0
  33. {freealg-0.3.0 → freealg-0.3.2}/freealg.egg-info/top_level.txt +0 -0
  34. {freealg-0.3.0 → freealg-0.3.2}/pyproject.toml +0 -0
  35. {freealg-0.3.0 → freealg-0.3.2}/requirements.txt +0 -0
  36. {freealg-0.3.0 → freealg-0.3.2}/setup.cfg +0 -0
@@ -1,8 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: freealg
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: Free probability for large matrices
5
- Keywords: leaderboard bot chat
5
+ Home-page: https://github.com/ameli/freealg
6
+ Download-URL: https://github.com/ameli/freealg/archive/main.zip
7
+ Project-URL: Documentation, https://github.com/ameli/freealg/blob/main/README.rst
8
+ Project-URL: Source, https://github.com/ameli/freealg
9
+ Project-URL: Tracker, https://github.com/ameli/freealg/issues
10
+ Keywords: linalg,free-probability
6
11
  Platform: Linux
7
12
  Platform: OSX
8
13
  Platform: Windows
@@ -57,9 +62,12 @@ Requires-Dist: sphinx-argparse; extra == "docs"
57
62
  Dynamic: classifier
58
63
  Dynamic: description
59
64
  Dynamic: description-content-type
65
+ Dynamic: download-url
66
+ Dynamic: home-page
60
67
  Dynamic: keywords
61
68
  Dynamic: license-file
62
69
  Dynamic: platform
70
+ Dynamic: project-url
63
71
  Dynamic: provides-extra
64
72
  Dynamic: requires-dist
65
73
  Dynamic: requires-python
@@ -72,7 +80,8 @@ Dynamic: summary
72
80
 
73
81
  `Paper <https://arxiv.org/abs/2506.11994>`__ |
74
82
  `Slides <https://www.dropbox.com/scl/fi/03gjuyz17k9yhsqy0isoz/free_decomporession_slides.pdf?rlkey=8f82mhciyl2ju02l7hv1md5li&st=26xmhjga&dl=0>`__ |
75
- `Docs <https://ameli.github.io/freealg>`__
83
+ `Docs <https://ameli.github.io/freealg>`__ |
84
+ `Live Demo <https://colab.research.google.com/github/ameli/freealg/blob/main/notebooks/quick_start.ipynb>`__
76
85
 
77
86
  .. `Slides <https://ameli.github.io/freealg/_static/data/slides.pdf>`__ |
78
87
 
@@ -146,7 +155,7 @@ requests and bug reports.
146
155
  How to Cite
147
156
  ===========
148
157
 
149
- If you use this work, please cite the `arXiv paper <https://arxiv.org/abs/2506.11994>`__.
158
+ If you use this work, please cite our `arXiv paper <https://arxiv.org/abs/2506.11994>`__.
150
159
 
151
160
  .. code::
152
161
 
@@ -5,7 +5,8 @@
5
5
 
6
6
  `Paper <https://arxiv.org/abs/2506.11994>`__ |
7
7
  `Slides <https://www.dropbox.com/scl/fi/03gjuyz17k9yhsqy0isoz/free_decomporession_slides.pdf?rlkey=8f82mhciyl2ju02l7hv1md5li&st=26xmhjga&dl=0>`__ |
8
- `Docs <https://ameli.github.io/freealg>`__
8
+ `Docs <https://ameli.github.io/freealg>`__ |
9
+ `Live Demo <https://colab.research.google.com/github/ameli/freealg/blob/main/notebooks/quick_start.ipynb>`__
9
10
 
10
11
  .. `Slides <https://ameli.github.io/freealg/_static/data/slides.pdf>`__ |
11
12
 
@@ -79,7 +80,7 @@ requests and bug reports.
79
80
  How to Cite
80
81
  ===========
81
82
 
82
- If you use this work, please cite the `arXiv paper <https://arxiv.org/abs/2506.11994>`__.
83
+ If you use this work, please cite our `arXiv paper <https://arxiv.org/abs/2506.11994>`__.
83
84
 
84
85
  .. code::
85
86
 
@@ -0,0 +1 @@
1
+ __version__ = "0.3.2"
@@ -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.
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'``.
@@ -142,10 +142,12 @@ def detect_support(eigs, method='asymp', k=None, p=0.001, **kwargs):
142
142
  References
143
143
  ----------
144
144
 
145
- .. [1] Quenouille, M. H. (1949, July). Approximate tests of correlation in
145
+ .. [1] Quenouille, M. H. (1949). Approximate tests of correlation in
146
146
  time-series. In Mathematical Proceedings of the Cambridge
147
147
  Philosophical Society (Vol. 45, No. 3, pp. 483-484). Cambridge
148
148
  University Press.
149
+ .. [2] Cuevas, A., & Fraiman, R. (1997). A plug-in approach to support
150
+ estimation. The Annals of Statistics, 2300-2312.
149
151
  """
150
152
 
151
153
  if method == 'range':
@@ -17,6 +17,33 @@ from .freeform import FreeForm
17
17
  __all__ = ['eigh', 'cond', 'norm', 'trace', 'slogdet']
18
18
 
19
19
 
20
+ def _subsample_apply(f, A, output_array=False):
21
+ """Compute f(A_n) over subsamples A_n of A. If the output of
22
+ f is an array (e.g. eigvals), specify output_array to be True."""
23
+
24
+ if A.ndim != 2 or A.shape[0] != A.shape[1]:
25
+ raise RuntimeError("Only square matrices are permitted.")
26
+ n = A.shape[0]
27
+
28
+ # Size of sample matrix
29
+ n_s = int(80*(1 + numpy.log(n)))
30
+ # If matrix is not large enough, return eigenvalues
31
+ if n < n_s:
32
+ return f(A), n, n
33
+ # Number of samples
34
+ num_samples = int(10 * (n / n_s)**0.5)
35
+
36
+ # Collect eigenvalue samples
37
+ samples = []
38
+ for _ in range(num_samples):
39
+ indices = numpy.random.choice(n, n_s, replace=False)
40
+ samples.append(f(A[numpy.ix_(indices, indices)]))
41
+ if output_array:
42
+ return numpy.concatenate(samples).ravel(), n, n_s
43
+
44
+ return numpy.array(samples), n, n_s
45
+
46
+
20
47
  # ====
21
48
  # eigh
22
49
  # ====
@@ -86,29 +113,11 @@ def eigh(A, N=None, psd=None, plots=False):
86
113
  >>> A = mp.matrix(3000)
87
114
  >>> eigs = eigh(A)
88
115
  """
89
-
90
- if A.ndim != 2 or A.shape[0] != A.shape[1]:
91
- raise RuntimeError("Only square matrices are permitted.")
92
- n = A.shape[0]
116
+ samples, n, n_s = _subsample_apply(compute_eig, A, output_array=True)
93
117
 
94
118
  if N is None:
95
119
  N = n
96
120
 
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
121
  # If all eigenvalues are positive, set PSD flag
113
122
  if psd is None:
114
123
  psd = samples.min() > 0
@@ -193,7 +202,7 @@ def cond(A, N=None):
193
202
  >>> cond(A)
194
203
  """
195
204
 
196
- eigs = eigh(A, N)
205
+ eigs = eigh(A, N, psd=True)
197
206
  return eigs.max() / eigs.min()
198
207
 
199
208
 
@@ -224,7 +233,7 @@ def norm(A, N=None, order=None):
224
233
  order : {float, ``''inf``, ``'-inf'``, ``'fro'``, ``'nuc'``}, default=2
225
234
  Order of the norm.
226
235
 
227
- * float :math:`p`: Schtten p-norm.
236
+ * float :math:`p`: Schatten p-norm.
228
237
  * ``'inf'``: Largest absolute eigenvalue
229
238
  :math:`\\max \\vert \\lambda_i \\vert)`
230
239
  * ``'-inf'``: Smallest absolute eigenvalue
@@ -300,19 +309,19 @@ def norm(A, N=None, order=None):
300
309
  # trace
301
310
  # =====
302
311
 
303
- def trace(A, N=None):
312
+ def trace(A, N=None, p=1.0):
304
313
  """
305
- Estimate the trace of a Hermitian matrix.
314
+ Estimate the trace of a power of a Hermitian matrix.
306
315
 
307
- This function estimates the trace of the matrix :math:`\\mathbf{A}` or a
308
- larger matrix containing :math:`\\mathbf{A}` using free decompression.
316
+ This function estimates the trace of the matrix power :math:`\\mathbf{A}^p`
317
+ or that of a larger matrix containing :math:`\\mathbf{A}`.
309
318
 
310
319
  Parameters
311
320
  ----------
312
321
 
313
322
  A : numpy.ndarray
314
- The symmetric real-valued matrix :math:`\\mathbf{A}` whose condition
315
- number (or that of a matrix containing :math:`\\mathbf{A}`) are to be
323
+ The symmetric real-valued matrix :math:`\\mathbf{A}` whose trace of
324
+ a power (or that of a matrix containing :math:`\\mathbf{A}`) is to be
316
325
  computed.
317
326
 
318
327
  N : int, default=None
@@ -320,6 +329,10 @@ def trace(A, N=None):
320
329
  eigenvalues of. If None, returns estimates of the eigenvalues of
321
330
  :math:`\\mathbf{A}` itself.
322
331
 
332
+ p : float, default=1.0
333
+ The exponent :math:`p` in :math:`\\mathbf{A}^p`.
334
+
335
+
323
336
  Returns
324
337
  -------
325
338
 
@@ -337,7 +350,9 @@ def trace(A, N=None):
337
350
  Notes
338
351
  -----
339
352
 
340
- This is a convenience function using :func:`freealg.eigh`.
353
+ The trace is highly amenable to subsampling: under free decompression
354
+ the average eigenvalue is assumed constant, so the trace increases
355
+ linearly. Traces of powers fall back to :func:`freealg.eigh`.
341
356
 
342
357
  Examples
343
358
  --------
@@ -352,11 +367,14 @@ def trace(A, N=None):
352
367
  >>> A = mp.matrix(3000)
353
368
  >>> trace(A, 100_000)
354
369
  """
355
-
356
- eigs = eigh(A, N)
357
- trace_ = numpy.sum(eigs)
358
-
359
- return trace_
370
+ if numpy.isclose(p, 1.0):
371
+ samples, n, n_s = _subsample_apply(numpy.trace, A, output_array=False)
372
+ if N is None:
373
+ N = n
374
+ return numpy.mean(samples) * (N / n_s)
375
+
376
+ eig = eigh(A, N)
377
+ return numpy.sum(eig ** p)
360
378
 
361
379
 
362
380
  # =======
@@ -1,8 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: freealg
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: Free probability for large matrices
5
- Keywords: leaderboard bot chat
5
+ Home-page: https://github.com/ameli/freealg
6
+ Download-URL: https://github.com/ameli/freealg/archive/main.zip
7
+ Project-URL: Documentation, https://github.com/ameli/freealg/blob/main/README.rst
8
+ Project-URL: Source, https://github.com/ameli/freealg
9
+ Project-URL: Tracker, https://github.com/ameli/freealg/issues
10
+ Keywords: linalg,free-probability
6
11
  Platform: Linux
7
12
  Platform: OSX
8
13
  Platform: Windows
@@ -57,9 +62,12 @@ Requires-Dist: sphinx-argparse; extra == "docs"
57
62
  Dynamic: classifier
58
63
  Dynamic: description
59
64
  Dynamic: description-content-type
65
+ Dynamic: download-url
66
+ Dynamic: home-page
60
67
  Dynamic: keywords
61
68
  Dynamic: license-file
62
69
  Dynamic: platform
70
+ Dynamic: project-url
63
71
  Dynamic: provides-extra
64
72
  Dynamic: requires-dist
65
73
  Dynamic: requires-python
@@ -72,7 +80,8 @@ Dynamic: summary
72
80
 
73
81
  `Paper <https://arxiv.org/abs/2506.11994>`__ |
74
82
  `Slides <https://www.dropbox.com/scl/fi/03gjuyz17k9yhsqy0isoz/free_decomporession_slides.pdf?rlkey=8f82mhciyl2ju02l7hv1md5li&st=26xmhjga&dl=0>`__ |
75
- `Docs <https://ameli.github.io/freealg>`__
83
+ `Docs <https://ameli.github.io/freealg>`__ |
84
+ `Live Demo <https://colab.research.google.com/github/ameli/freealg/blob/main/notebooks/quick_start.ipynb>`__
76
85
 
77
86
  .. `Slides <https://ameli.github.io/freealg/_static/data/slides.pdf>`__ |
78
87
 
@@ -146,7 +155,7 @@ requests and bug reports.
146
155
  How to Cite
147
156
  ===========
148
157
 
149
- If you use this work, please cite the `arXiv paper <https://arxiv.org/abs/2506.11994>`__.
158
+ If you use this work, please cite our `arXiv paper <https://arxiv.org/abs/2506.11994>`__.
150
159
 
151
160
  .. code::
152
161
 
@@ -158,6 +158,12 @@ def main(argv):
158
158
  # Description
159
159
  description = 'Free probability for large matrices'
160
160
 
161
+ # URLs
162
+ url = 'https://github.com/ameli/freealg'
163
+ download_url = url + '/archive/main.zip'
164
+ documentation_url = url + '/blob/main/README.rst'
165
+ tracker_url = url + '/issues'
166
+
161
167
  # Inputs to setup
162
168
  metadata = dict(
163
169
  name=package_name,
@@ -165,7 +171,14 @@ def main(argv):
165
171
  description=description,
166
172
  long_description=long_description,
167
173
  long_description_content_type='text/x-rst',
168
- keywords="""leaderboard bot chat""",
174
+ keywords="""linalg, free-probability""",
175
+ url=url,
176
+ download_url=download_url,
177
+ project_urls={
178
+ "Documentation": documentation_url,
179
+ "Source": url,
180
+ "Tracker": tracker_url,
181
+ },
169
182
  platforms=['Linux', 'OSX', 'Windows'],
170
183
  packages=setuptools.find_packages(exclude=[
171
184
  'tests.*',
@@ -1 +0,0 @@
1
- __version__ = "0.3.0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes