freealg 0.4.0__tar.gz → 0.5.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 (38) hide show
  1. {freealg-0.4.0 → freealg-0.5.0}/PKG-INFO +13 -1
  2. {freealg-0.4.0 → freealg-0.5.0}/README.rst +12 -0
  3. freealg-0.5.0/freealg/__version__.py +1 -0
  4. {freealg-0.4.0 → freealg-0.5.0}/freealg/_chebyshev.py +36 -14
  5. freealg-0.5.0/freealg/_decompress.py +998 -0
  6. {freealg-0.4.0 → freealg-0.5.0}/freealg/_linalg.py +24 -10
  7. {freealg-0.4.0 → freealg-0.5.0}/freealg/_pade.py +3 -59
  8. {freealg-0.4.0 → freealg-0.5.0}/freealg/_plot_util.py +30 -18
  9. {freealg-0.4.0 → freealg-0.5.0}/freealg/_sample.py +13 -6
  10. freealg-0.5.0/freealg/_series.py +123 -0
  11. {freealg-0.4.0 → freealg-0.5.0}/freealg/_support.py +2 -0
  12. {freealg-0.4.0 → freealg-0.5.0}/freealg/_util.py +1 -1
  13. {freealg-0.4.0 → freealg-0.5.0}/freealg/distributions/_kesten_mckay.py +6 -6
  14. {freealg-0.4.0 → freealg-0.5.0}/freealg/distributions/_marchenko_pastur.py +9 -11
  15. {freealg-0.4.0 → freealg-0.5.0}/freealg/distributions/_meixner.py +6 -6
  16. {freealg-0.4.0 → freealg-0.5.0}/freealg/distributions/_wachter.py +9 -11
  17. {freealg-0.4.0 → freealg-0.5.0}/freealg/distributions/_wigner.py +8 -9
  18. {freealg-0.4.0 → freealg-0.5.0}/freealg/freeform.py +208 -90
  19. {freealg-0.4.0 → freealg-0.5.0}/freealg.egg-info/PKG-INFO +13 -1
  20. {freealg-0.4.0 → freealg-0.5.0}/freealg.egg-info/SOURCES.txt +1 -0
  21. freealg-0.4.0/freealg/__version__.py +0 -1
  22. freealg-0.4.0/freealg/_decompress.py +0 -358
  23. {freealg-0.4.0 → freealg-0.5.0}/AUTHORS.txt +0 -0
  24. {freealg-0.4.0 → freealg-0.5.0}/CHANGELOG.rst +0 -0
  25. {freealg-0.4.0 → freealg-0.5.0}/LICENSE.txt +0 -0
  26. {freealg-0.4.0 → freealg-0.5.0}/MANIFEST.in +0 -0
  27. {freealg-0.4.0 → freealg-0.5.0}/freealg/__init__.py +0 -0
  28. {freealg-0.4.0 → freealg-0.5.0}/freealg/_damp.py +0 -0
  29. {freealg-0.4.0 → freealg-0.5.0}/freealg/_jacobi.py +0 -0
  30. {freealg-0.4.0 → freealg-0.5.0}/freealg/distributions/__init__.py +0 -0
  31. {freealg-0.4.0 → freealg-0.5.0}/freealg.egg-info/dependency_links.txt +0 -0
  32. {freealg-0.4.0 → freealg-0.5.0}/freealg.egg-info/not-zip-safe +0 -0
  33. {freealg-0.4.0 → freealg-0.5.0}/freealg.egg-info/requires.txt +0 -0
  34. {freealg-0.4.0 → freealg-0.5.0}/freealg.egg-info/top_level.txt +0 -0
  35. {freealg-0.4.0 → freealg-0.5.0}/pyproject.toml +0 -0
  36. {freealg-0.4.0 → freealg-0.5.0}/requirements.txt +0 -0
  37. {freealg-0.4.0 → freealg-0.5.0}/setup.cfg +0 -0
  38. {freealg-0.4.0 → freealg-0.5.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: freealg
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Free probability for large matrices
5
5
  Home-page: https://github.com/ameli/freealg
6
6
  Download-URL: https://github.com/ameli/freealg/archive/main.zip
@@ -94,6 +94,8 @@ of extremely large matrices.
94
94
  Install
95
95
  =======
96
96
 
97
+ |pypi|
98
+
97
99
  Install with ``pip``:
98
100
 
99
101
  .. code-block::
@@ -110,6 +112,8 @@ Alternatively, clone the source code and install with
110
112
  Documentation
111
113
  =============
112
114
 
115
+ |deploy-docs|
116
+
113
117
  Documentation is available at `ameli.github.io/freealg <https://ameli.github.io/freealg>`__.
114
118
 
115
119
  Quick Usage
@@ -132,6 +136,8 @@ For more details on how to interface with *freealg* check out the
132
136
  Test
133
137
  ====
134
138
 
139
+ |build-linux|
140
+
135
141
  You may test the package with `tox <https://tox.wiki/>`__:
136
142
 
137
143
  .. code-block::
@@ -178,5 +184,11 @@ License
178
184
 
179
185
  |license|
180
186
 
187
+ .. |build-linux| image:: https://img.shields.io/github/actions/workflow/status/ameli/freealg/build-linux.yml
188
+ :target: https://github.com/ameli/freealg/actions?query=workflow%3Abuild-linux
189
+ .. |deploy-docs| image:: https://img.shields.io/github/actions/workflow/status/ameli/freealg/deploy-docs.yml?label=docs
190
+ :target: https://github.com/ameli/freealg/actions?query=workflow%3Adeploy-docs
191
+ .. |pypi| image:: https://img.shields.io/pypi/v/freealg
192
+ :target: https://pypi.org/project/freealg/
181
193
  .. |license| image:: https://img.shields.io/github/license/ameli/freealg
182
194
  :target: https://opensource.org/licenses/BSD-3-Clause
@@ -18,6 +18,8 @@ of extremely large matrices.
18
18
  Install
19
19
  =======
20
20
 
21
+ |pypi|
22
+
21
23
  Install with ``pip``:
22
24
 
23
25
  .. code-block::
@@ -34,6 +36,8 @@ Alternatively, clone the source code and install with
34
36
  Documentation
35
37
  =============
36
38
 
39
+ |deploy-docs|
40
+
37
41
  Documentation is available at `ameli.github.io/freealg <https://ameli.github.io/freealg>`__.
38
42
 
39
43
  Quick Usage
@@ -56,6 +60,8 @@ For more details on how to interface with *freealg* check out the
56
60
  Test
57
61
  ====
58
62
 
63
+ |build-linux|
64
+
59
65
  You may test the package with `tox <https://tox.wiki/>`__:
60
66
 
61
67
  .. code-block::
@@ -102,5 +108,11 @@ License
102
108
 
103
109
  |license|
104
110
 
111
+ .. |build-linux| image:: https://img.shields.io/github/actions/workflow/status/ameli/freealg/build-linux.yml
112
+ :target: https://github.com/ameli/freealg/actions?query=workflow%3Abuild-linux
113
+ .. |deploy-docs| image:: https://img.shields.io/github/actions/workflow/status/ameli/freealg/deploy-docs.yml?label=docs
114
+ :target: https://github.com/ameli/freealg/actions?query=workflow%3Adeploy-docs
115
+ .. |pypi| image:: https://img.shields.io/pypi/v/freealg
116
+ :target: https://pypi.org/project/freealg/
105
117
  .. |license| image:: https://img.shields.io/github/license/ameli/freealg
106
118
  :target: https://opensource.org/licenses/BSD-3-Clause
@@ -0,0 +1 @@
1
+ __version__ = "0.5.0"
@@ -13,7 +13,7 @@
13
13
 
14
14
  import numpy
15
15
  from scipy.special import eval_chebyu
16
- from ._pade import wynn_pade
16
+ from ._series import partial_sum, wynn_epsilon
17
17
 
18
18
  __all__ = ['chebyshev_sample_proj', 'chebyshev_kernel_proj',
19
19
  'chebyshev_approx', 'chebyshev_stieltjes']
@@ -29,7 +29,7 @@ def chebyshev_sample_proj(eig, support, K=10, reg=0.0):
29
29
 
30
30
  \\rho(x) = w(t) \\sum_{k=0}^K \\psi_k U_k(t),
31
31
 
32
- where t = (2x(\\lambda_{-} + \\lambda_{+}))/ (\\lambda_{+} - \\lambda_{-})
32
+ where t = (2x-(\\lambda_{-} + \\lambda_{+}))/ (\\lambda_{+} - \\lambda_{-})
33
33
  in [-1, 1] and w(t) = \\sqrt{(1 - t^2}.
34
34
 
35
35
  Parameters
@@ -164,7 +164,7 @@ def chebyshev_approx(x, psi, support):
164
164
  # chebushev stieltjes
165
165
  # ===================
166
166
 
167
- def chebyshev_stieltjes(z, psi, support):
167
+ def chebyshev_stieltjes(z, psi, support, use_wynn_epsilon=False):
168
168
  """
169
169
  Compute the Stieltjes transform m(z) for a Chebyshev‐II expansion
170
170
 
@@ -197,6 +197,9 @@ def chebyshev_stieltjes(z, psi, support):
197
197
  support : tuple
198
198
  The support interval of the original density.
199
199
 
200
+ use_wynn_epsilon : bool, default=False
201
+ Use Wynn epsilon, otherwise assumes Pade is used.
202
+
200
203
  Returns
201
204
  -------
202
205
 
@@ -209,22 +212,41 @@ def chebyshev_stieltjes(z, psi, support):
209
212
  span = lam_p - lam_m
210
213
  center = 0.5 * (lam_m + lam_p)
211
214
 
212
- # map z -> u in the standard [-1,1] domain
215
+ # Map z -> u in the standard [-1,1] domain
213
216
  u = (2.0 * (z - center)) / span
214
217
 
215
- # inverse-Joukowski: pick branch sqrt with +Im
216
- root = numpy.sqrt(u*u - 1)
218
+ # Inverse-Joukowski: pick branch sqrt with +Im
219
+ root = numpy.sqrt(u*u - 1.0)
217
220
  Jm = u - root
218
221
  Jp = u + root
219
222
 
220
223
  # Make sure J is Herglotz
221
- J = numpy.zeros_like(Jm)
222
- J = numpy.where(root.imag < 0, Jp, Jm)
223
-
224
- psi_zero = numpy.concatenate([[0], psi])
225
- S = wynn_pade(psi_zero, J)
226
-
227
- # assemble m(z)
228
- m_z = -2 / span * numpy.pi * S
224
+ J = numpy.zeros_like(Jp)
225
+ J = numpy.where(Jp.imag > 0, Jm, Jp)
226
+
227
+ # This depends on the method of analytic continuation
228
+ if use_wynn_epsilon:
229
+ # Flatten J before passing to Wynn method.
230
+ psi_zero = numpy.concatenate([[0], psi])
231
+ Sn = partial_sum(psi_zero, J.ravel())
232
+ S = wynn_epsilon(Sn)
233
+ S = S.reshape(J.shape)
234
+
235
+ else:
236
+ # Build powers J^(k+1) for k = 0, ..., K
237
+ K = len(psi) - 1
238
+ Jpow = J[..., None] ** numpy.arange(1, K+2) # shape: (..., K+1)
239
+
240
+ # Summing psi_k * J^(k+1)
241
+ S = numpy.sum(psi * Jpow, axis=-1)
242
+
243
+ # Assemble m(z)
244
+ m_z = -(2.0 / span) * numpy.pi * S
245
+
246
+ # Check nan or inf
247
+ if numpy.any(numpy.isinf(m_z)):
248
+ raise RuntimeError('"m" is nan.')
249
+ elif numpy.any(numpy.isnan(numpy.abs(m_z))):
250
+ raise RuntimeError('"m" is inf.')
229
251
 
230
252
  return m_z