freealg 0.4.1__py3-none-any.whl → 0.5.1__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/_chebyshev.py +36 -14
- freealg/_decompress.py +706 -66
- freealg/_linalg.py +24 -10
- freealg/_pade.py +3 -59
- freealg/_plot_util.py +31 -19
- freealg/_sample.py +13 -6
- freealg/_series.py +123 -0
- freealg/_support.py +2 -0
- freealg/_util.py +1 -1
- freealg/distributions/_kesten_mckay.py +6 -6
- freealg/distributions/_marchenko_pastur.py +9 -11
- freealg/distributions/_meixner.py +6 -6
- freealg/distributions/_wachter.py +9 -11
- freealg/distributions/_wigner.py +8 -9
- freealg/freeform.py +199 -82
- {freealg-0.4.1.dist-info → freealg-0.5.1.dist-info}/METADATA +1 -1
- freealg-0.5.1.dist-info/RECORD +26 -0
- freealg-0.4.1.dist-info/RECORD +0 -25
- {freealg-0.4.1.dist-info → freealg-0.5.1.dist-info}/WHEEL +0 -0
- {freealg-0.4.1.dist-info → freealg-0.5.1.dist-info}/licenses/AUTHORS.txt +0 -0
- {freealg-0.4.1.dist-info → freealg-0.5.1.dist-info}/licenses/LICENSE.txt +0 -0
- {freealg-0.4.1.dist-info → freealg-0.5.1.dist-info}/top_level.txt +0 -0
freealg/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.5.1"
|
freealg/_chebyshev.py
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import numpy
|
|
15
15
|
from scipy.special import eval_chebyu
|
|
16
|
-
from .
|
|
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
|
|
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
|
-
#
|
|
215
|
+
# Map z -> u in the standard [-1,1] domain
|
|
213
216
|
u = (2.0 * (z - center)) / span
|
|
214
217
|
|
|
215
|
-
#
|
|
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(
|
|
222
|
-
J = numpy.where(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|