freealg 0.0.3__py3-none-any.whl → 0.1.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 +39 -5
- freealg/_jacobi.py +37 -5
- freealg/_pade.py +356 -8
- freealg/_plot_util.py +6 -28
- freealg/_sample.py +85 -0
- freealg/distributions/__init__.py +4 -4
- freealg/distributions/kesten_mckay.py +559 -0
- freealg/distributions/marchenko_pastur.py +4 -3
- freealg/distributions/wachter.py +568 -0
- freealg/distributions/wigner.py +552 -0
- freealg/freeform.py +122 -32
- {freealg-0.0.3.dist-info → freealg-0.1.1.dist-info}/METADATA +3 -1
- freealg-0.1.1.dist-info/RECORD +21 -0
- freealg-0.0.3.dist-info/RECORD +0 -17
- {freealg-0.0.3.dist-info → freealg-0.1.1.dist-info}/WHEEL +0 -0
- {freealg-0.0.3.dist-info → freealg-0.1.1.dist-info}/licenses/LICENSE.txt +0 -0
- {freealg-0.0.3.dist-info → freealg-0.1.1.dist-info}/top_level.txt +0 -0
freealg/freeform.py
CHANGED
|
@@ -13,15 +13,19 @@
|
|
|
13
13
|
|
|
14
14
|
import numpy
|
|
15
15
|
from scipy.stats import gaussian_kde
|
|
16
|
+
# from statsmodels.nonparametric.kde import KDEUnivariate
|
|
16
17
|
from functools import partial
|
|
17
18
|
from ._util import compute_eig, force_density
|
|
18
|
-
from ._jacobi import
|
|
19
|
-
|
|
19
|
+
from ._jacobi import jacobi_sample_proj, jacobi_kernel_proj, jacobi_approx, \
|
|
20
|
+
jacobi_stieltjes
|
|
21
|
+
from ._chebyshev import chebyshev_sample_proj, chebyshev_kernel_proj, \
|
|
22
|
+
chebyshev_approx, chebyshev_stieltjes
|
|
20
23
|
from ._damp import jackson_damping, lanczos_damping, fejer_damping, \
|
|
21
24
|
exponential_damping, parzen_damping
|
|
22
25
|
from ._plot_util import plot_fit, plot_density, plot_hilbert, plot_stieltjes
|
|
23
26
|
from ._pade import fit_pade, eval_pade
|
|
24
27
|
from ._decompress import decompress
|
|
28
|
+
from ._sample import qmc_sample
|
|
25
29
|
|
|
26
30
|
__all__ = ['FreeForm']
|
|
27
31
|
|
|
@@ -173,8 +177,9 @@ class FreeForm(object):
|
|
|
173
177
|
# ===
|
|
174
178
|
|
|
175
179
|
def fit(self, method='jacobi', K=10, alpha=0.0, beta=0.0, reg=0.0,
|
|
176
|
-
|
|
177
|
-
|
|
180
|
+
projection='kernel', kernel_bw=None, damp=None, force=False,
|
|
181
|
+
pade_p=0, pade_q=1, odd_side='left', pade_reg=0.0, optimizer='ls',
|
|
182
|
+
plot=False, latex=False, save=False):
|
|
178
183
|
"""
|
|
179
184
|
Fit model to eigenvalues.
|
|
180
185
|
|
|
@@ -201,6 +206,19 @@ class FreeForm(object):
|
|
|
201
206
|
reg : float, default=0.0
|
|
202
207
|
Tikhonov regularization coefficient.
|
|
203
208
|
|
|
209
|
+
projection : {``'sample'``, ``'kernel'``}, default= ``'kernel'``
|
|
210
|
+
The method of Galerkin projection:
|
|
211
|
+
|
|
212
|
+
* ``'sample'``: directly project samples (eigenvalues) to the
|
|
213
|
+
orthogonal polynomials. This method is highly unstable as it
|
|
214
|
+
treats each sample as a delta Dirac function.
|
|
215
|
+
* ``'kernel'``: computes KDE from the samples and project a
|
|
216
|
+
smooth KDE to the orthogonal polynomials. This method is stable.
|
|
217
|
+
|
|
218
|
+
kernel_bw : float, default=None
|
|
219
|
+
Kernel band-wdth. See scipy.stats.gaussian_kde. This argument is
|
|
220
|
+
relevant if ``projection='kernel'`` is set.
|
|
221
|
+
|
|
204
222
|
damp : {``'jackson'``, ``'lanczos'``, ``'fejer``, ``'exponential'``,\
|
|
205
223
|
``'parzen'``}, default=None
|
|
206
224
|
Damping method to eliminate Gibbs oscillation.
|
|
@@ -209,15 +227,33 @@ class FreeForm(object):
|
|
|
209
227
|
If `True`, it forces the density to have unit mass and to be
|
|
210
228
|
strictly positive.
|
|
211
229
|
|
|
212
|
-
pade_p : int, default=
|
|
213
|
-
Degree of polynomial :math:`P(z)
|
|
230
|
+
pade_p : int, default=0
|
|
231
|
+
Degree of polynomial :math:`P(z)` is :math:`q+p` where :math:`p`
|
|
232
|
+
can only be ``-1``, ``0``, or ``1``. See notes below.
|
|
214
233
|
|
|
215
234
|
pade_q : int, default=1
|
|
216
|
-
Degree of polynomial :math:`Q(z)`. See notes below.
|
|
235
|
+
Degree of polynomial :math:`Q(z)` is :math:`q`. See notes below.
|
|
236
|
+
|
|
237
|
+
odd_side : {``'left'``, ``'right'``}, default= ``'left'``
|
|
238
|
+
In case of odd number of poles (when :math:`q` is odd), the extra
|
|
239
|
+
pole is set to the left or right side of the support interval,
|
|
240
|
+
while all other poles are split in half to the left and right. Note
|
|
241
|
+
that this is only for the initialization of the poles. The
|
|
242
|
+
optimizer will decide best location by moving them to the left or
|
|
243
|
+
right of the support.
|
|
244
|
+
|
|
245
|
+
pade_reg : float, default=0.0
|
|
246
|
+
Regularization for Pade approximation.
|
|
247
|
+
|
|
248
|
+
optimizer : {``'ls'``, ``'de'``}, default= ``'ls'``
|
|
249
|
+
Optimizer for Pade approximation, including:
|
|
250
|
+
|
|
251
|
+
* ``'ls'``: least square (local, fast)
|
|
252
|
+
* ``'de'``: differential evolution (global, slow)
|
|
217
253
|
|
|
218
254
|
plot : bool, default=False
|
|
219
|
-
If `True`, the approximation coefficients and
|
|
220
|
-
the Hilbert
|
|
255
|
+
If `True`, the approximation coefficients and Pade approximation to
|
|
256
|
+
the Hilbert transform are plotted.
|
|
221
257
|
|
|
222
258
|
latex : bool, default=False
|
|
223
259
|
If `True`, the plot is rendered using LaTeX. This option is
|
|
@@ -234,6 +270,20 @@ class FreeForm(object):
|
|
|
234
270
|
psi : (K+1, ) numpy.ndarray
|
|
235
271
|
Coefficients of fitting Jacobi polynomials
|
|
236
272
|
|
|
273
|
+
Notes
|
|
274
|
+
-----
|
|
275
|
+
|
|
276
|
+
The Pade approximation for the glue function :math:`G(z)` is
|
|
277
|
+
|
|
278
|
+
.. math::
|
|
279
|
+
|
|
280
|
+
G(z) = \\frac{P(z)}{Q(z)},
|
|
281
|
+
|
|
282
|
+
where :math:`P(z)` and :math:`Q(z)` are polynomials of order
|
|
283
|
+
:math:`p+q` and :math:`q` respectively. Note that :math:`p` can only
|
|
284
|
+
be -1, 0, or 1, effectively making Pade approximation of order
|
|
285
|
+
:math:`q-1:q`, :math:`q:q`, or :math:`q-1:q`.
|
|
286
|
+
|
|
237
287
|
Examples
|
|
238
288
|
--------
|
|
239
289
|
|
|
@@ -248,12 +298,50 @@ class FreeForm(object):
|
|
|
248
298
|
if beta <= -1:
|
|
249
299
|
raise ValueError('"beta" should be greater then "-1".')
|
|
250
300
|
|
|
301
|
+
if not (method in ['jacobi', 'chebyshev']):
|
|
302
|
+
raise ValueError('"method" is invalid.')
|
|
303
|
+
|
|
304
|
+
if not (projection in ['sample', 'kernel']):
|
|
305
|
+
raise ValueError('"projection" is invalid.')
|
|
306
|
+
|
|
251
307
|
# Project eigenvalues to Jacobi polynomials basis
|
|
252
308
|
if method == 'jacobi':
|
|
253
|
-
|
|
254
|
-
|
|
309
|
+
|
|
310
|
+
if projection == 'sample':
|
|
311
|
+
psi = jacobi_sample_proj(self.eig, support=self.support, K=K,
|
|
312
|
+
alpha=alpha, beta=beta, reg=reg)
|
|
313
|
+
else:
|
|
314
|
+
# smooth KDE on a fixed grid
|
|
315
|
+
xs = numpy.linspace(self.lam_m, self.lam_p, 2000)
|
|
316
|
+
pdf = gaussian_kde(self.eig, bw_method=kernel_bw)(xs)
|
|
317
|
+
|
|
318
|
+
# Adaptive KDE
|
|
319
|
+
# k = KDEUnivariate(self.eig)
|
|
320
|
+
# k.fit(bw="silverman", fft=False, weights=None, gridsize=1024,
|
|
321
|
+
# adaptive=True)
|
|
322
|
+
# pdf = k.evaluate(xs)
|
|
323
|
+
|
|
324
|
+
psi = jacobi_kernel_proj(xs, pdf, support=self.support, K=K,
|
|
325
|
+
alpha=alpha, beta=beta, reg=reg)
|
|
326
|
+
|
|
255
327
|
elif method == 'chebyshev':
|
|
256
|
-
|
|
328
|
+
|
|
329
|
+
if projection == 'sample':
|
|
330
|
+
psi = chebyshev_sample_proj(self.eig, support=self.support,
|
|
331
|
+
K=K, reg=reg)
|
|
332
|
+
else:
|
|
333
|
+
# smooth KDE on a fixed grid
|
|
334
|
+
xs = numpy.linspace(self.lam_m, self.lam_p, 2000)
|
|
335
|
+
pdf = gaussian_kde(self.eig, bw_method=kernel_bw)(xs)
|
|
336
|
+
|
|
337
|
+
# Adaptive KDE
|
|
338
|
+
# k = KDEUnivariate(self.eig)
|
|
339
|
+
# k.fit(bw="silverman", fft=False, weights=None, gridsize=1024,
|
|
340
|
+
# adaptive=True)
|
|
341
|
+
# pdf = k.evaluate(xs)
|
|
342
|
+
|
|
343
|
+
psi = chebyshev_kernel_proj(xs, pdf, support=self.support,
|
|
344
|
+
K=K, reg=reg)
|
|
257
345
|
else:
|
|
258
346
|
raise ValueError('"method" is invalid.')
|
|
259
347
|
|
|
@@ -299,17 +387,17 @@ class FreeForm(object):
|
|
|
299
387
|
g_supp = 2.0 * numpy.pi * self.hilbert(x_supp)
|
|
300
388
|
|
|
301
389
|
# Fit a pade approximation
|
|
302
|
-
self._pade_sol = fit_pade(x_supp, g_supp, self.lam_m,
|
|
303
|
-
|
|
304
|
-
|
|
390
|
+
# self._pade_sol = fit_pade(x_supp, g_supp, self.lam_m,
|
|
391
|
+
# self.lam_p, pade_p, pade_q, delta=1e-8,
|
|
392
|
+
# B=numpy.inf, S=numpy.inf)
|
|
393
|
+
self._pade_sol = fit_pade(x_supp, g_supp, self.lam_m, self.lam_p,
|
|
394
|
+
p=pade_p, q=pade_q, odd_side=odd_side,
|
|
395
|
+
pade_reg=pade_reg, safety=1.0, max_outer=40,
|
|
396
|
+
xtol=1e-12, ftol=1e-12, optimizer=optimizer,
|
|
397
|
+
verbose=0)
|
|
305
398
|
|
|
306
399
|
if plot:
|
|
307
|
-
|
|
308
|
-
s = self._pade_sol['s']
|
|
309
|
-
a = self._pade_sol['a']
|
|
310
|
-
b = self._pade_sol['b']
|
|
311
|
-
|
|
312
|
-
g_supp_approx = eval_pade(x_supp[None, :], s, a, b)[0, :]
|
|
400
|
+
g_supp_approx = eval_pade(x_supp[None, :], self._pade_sol)[0, :]
|
|
313
401
|
plot_fit(psi, x_supp, g_supp, g_supp_approx, support=self.support,
|
|
314
402
|
latex=latex, save=save)
|
|
315
403
|
|
|
@@ -513,13 +601,8 @@ class FreeForm(object):
|
|
|
513
601
|
"""
|
|
514
602
|
"""
|
|
515
603
|
|
|
516
|
-
# Unpack optimized parameters
|
|
517
|
-
s = self._pade_sol['s']
|
|
518
|
-
a = self._pade_sol['a']
|
|
519
|
-
b = self._pade_sol['b']
|
|
520
|
-
|
|
521
604
|
# Glue function
|
|
522
|
-
g = eval_pade(z,
|
|
605
|
+
g = eval_pade(z, self._pade_sol)
|
|
523
606
|
|
|
524
607
|
return g
|
|
525
608
|
|
|
@@ -633,7 +716,7 @@ class FreeForm(object):
|
|
|
633
716
|
m1[mask_m, :] = numpy.conjugate(
|
|
634
717
|
stieltjes(numpy.conjugate(z[mask_m, :])))
|
|
635
718
|
|
|
636
|
-
# Second
|
|
719
|
+
# Second Riemann sheet
|
|
637
720
|
m2[mask_p, :] = m1[mask_p, :]
|
|
638
721
|
m2[mask_m, :] = -m1[mask_m, :] + self._glue(z[mask_m, :])
|
|
639
722
|
|
|
@@ -721,7 +804,7 @@ class FreeForm(object):
|
|
|
721
804
|
m1[mask_m] = numpy.conjugate(
|
|
722
805
|
stieltjes(numpy.conjugate(z[mask_m].reshape(-1, 1)))).reshape(-1)
|
|
723
806
|
|
|
724
|
-
# Second
|
|
807
|
+
# Second Riemann sheet
|
|
725
808
|
m2[mask_p] = m1[mask_p]
|
|
726
809
|
m2[mask_m] = -m1[mask_m] + self._glue(
|
|
727
810
|
z[mask_m].reshape(-1, 1)).reshape(-1)
|
|
@@ -734,7 +817,7 @@ class FreeForm(object):
|
|
|
734
817
|
# decompress
|
|
735
818
|
# ==========
|
|
736
819
|
|
|
737
|
-
def decompress(self, size, x=None, delta=1e-
|
|
820
|
+
def decompress(self, size, x=None, delta=1e-6, iterations=500,
|
|
738
821
|
step_size=0.1, tolerance=1e-4, plot=False, latex=False,
|
|
739
822
|
save=False):
|
|
740
823
|
"""
|
|
@@ -782,6 +865,10 @@ class FreeForm(object):
|
|
|
782
865
|
rho : numpy.array
|
|
783
866
|
Spectral density
|
|
784
867
|
|
|
868
|
+
eigs : numpy.array
|
|
869
|
+
Estimated eigenvalues as low-discrepancy samples of the estimated
|
|
870
|
+
spectral density.
|
|
871
|
+
|
|
785
872
|
See Also
|
|
786
873
|
--------
|
|
787
874
|
|
|
@@ -809,9 +896,12 @@ class FreeForm(object):
|
|
|
809
896
|
rho, x, (lb, ub) = decompress(self, size, x=x, delta=delta,
|
|
810
897
|
iterations=iterations,
|
|
811
898
|
step_size=step_size, tolerance=tolerance)
|
|
899
|
+
x, rho = x.ravel(), rho.ravel()
|
|
812
900
|
|
|
813
901
|
if plot:
|
|
814
|
-
plot_density(x
|
|
902
|
+
plot_density(x, rho, support=(lb, ub),
|
|
815
903
|
label='Decompression', latex=latex, save=save)
|
|
816
904
|
|
|
817
|
-
|
|
905
|
+
eigs = numpy.sort(qmc_sample(x, rho, size))
|
|
906
|
+
|
|
907
|
+
return rho, eigs
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: freealg
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Free probability for large matrices
|
|
5
5
|
Keywords: leaderboard bot chat
|
|
6
6
|
Platform: Linux
|
|
@@ -29,6 +29,8 @@ Requires-Dist: scipy
|
|
|
29
29
|
Requires-Dist: texplot
|
|
30
30
|
Requires-Dist: matplotlib
|
|
31
31
|
Requires-Dist: colorcet
|
|
32
|
+
Requires-Dist: networkx
|
|
33
|
+
Requires-Dist: statsmodels
|
|
32
34
|
Provides-Extra: test
|
|
33
35
|
Provides-Extra: docs
|
|
34
36
|
Dynamic: classifier
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
freealg/__init__.py,sha256=K92neXJZ9VE1U_j_pj28Qyq1MzlMXhOuYK2ZihgwCaU,463
|
|
2
|
+
freealg/__version__.py,sha256=rnObPjuBcEStqSO0S6gsdS_ot8ITOQjVj_-P1LUUYpg,22
|
|
3
|
+
freealg/_chebyshev.py,sha256=X6u5pKjR1HPZ-KbCfr7zT6HRwB6pZMADvVS3sT5LTkA,5638
|
|
4
|
+
freealg/_damp.py,sha256=k2vtBtWOxQBf4qXaWu_En81lQBXbEO4QbxxWpvuVhdE,1802
|
|
5
|
+
freealg/_decompress.py,sha256=H7ocq09gQnCY-q_8xHi6qyYj3qp239MCgj406hn0yeE,3344
|
|
6
|
+
freealg/_jacobi.py,sha256=AT4ONSHGGDxVKE3MGMLyMR8uDFiO-e9u3x5udYfdJJk,5635
|
|
7
|
+
freealg/_pade.py,sha256=mP96wEPfIzHLZ6PDB5OyhmSA8N1uVPVUkmJa3ebXXiU,13623
|
|
8
|
+
freealg/_plot_util.py,sha256=aL0u7FHdCwLTj4dZ4SSGA00wab0Voem2nBAsBVvo6XY,18400
|
|
9
|
+
freealg/_sample.py,sha256=K1ZxKoiuPbEKyh-swL5X7gz1kYcQno6Mof0o1xF38tg,2323
|
|
10
|
+
freealg/_util.py,sha256=wJ-t8LMZZFEr2PsZEVqTJP_jQTQ3rHUf0dO27F6L7YQ,2310
|
|
11
|
+
freealg/freeform.py,sha256=MintRRVsEwIrur7KC4tvYa8nBVpNeaajphIqUCmGnLs,27910
|
|
12
|
+
freealg/distributions/__init__.py,sha256=Hnk9bJi4Wy8I_1uuskRyrT2DUpPN1YmBY5uK7XI3U_o,644
|
|
13
|
+
freealg/distributions/kesten_mckay.py,sha256=SFYg2_6_MEX9NGfOIW_rRfM9kgF-bdjQiVS0ENJBemQ,15379
|
|
14
|
+
freealg/distributions/marchenko_pastur.py,sha256=0XHhjw1ZDkigGfjU9lmPRgmwecM1-n6VBkGjRJbxpeY,15869
|
|
15
|
+
freealg/distributions/wachter.py,sha256=cG-3XTP5CHSK5o6SQfa3lqQR__ZibeWZ9AoeMxr3Nnk,15602
|
|
16
|
+
freealg/distributions/wigner.py,sha256=gj3XWK4X7wLsB-inoVpn4pHUUM7NOQdgMGw01LEqkcw,14914
|
|
17
|
+
freealg-0.1.1.dist-info/licenses/LICENSE.txt,sha256=J-EEYEtxb3VVf_Bn1TYfWnpY5lMFIM15iLDDcnaDTPA,1443
|
|
18
|
+
freealg-0.1.1.dist-info/METADATA,sha256=WMUZ2N2ZDfTLNuByAjNyP3e7QpCOF-tyV3ImcwUAZY4,2939
|
|
19
|
+
freealg-0.1.1.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
|
|
20
|
+
freealg-0.1.1.dist-info/top_level.txt,sha256=eR2wrgYwDdnnJ9Zf5PruPqe4kQav0GMvRsqct6y00Q8,8
|
|
21
|
+
freealg-0.1.1.dist-info/RECORD,,
|
freealg-0.0.3.dist-info/RECORD
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
freealg/__init__.py,sha256=K92neXJZ9VE1U_j_pj28Qyq1MzlMXhOuYK2ZihgwCaU,463
|
|
2
|
-
freealg/__version__.py,sha256=4GZKi13lDTD25YBkGakhZyEQZWTER_OWQMNPoH_UM2c,22
|
|
3
|
-
freealg/_chebyshev.py,sha256=Cw48gXF6kd3IAQuLTEWadySeKGnY9TynzX9MNmycMUU,4697
|
|
4
|
-
freealg/_damp.py,sha256=k2vtBtWOxQBf4qXaWu_En81lQBXbEO4QbxxWpvuVhdE,1802
|
|
5
|
-
freealg/_decompress.py,sha256=H7ocq09gQnCY-q_8xHi6qyYj3qp239MCgj406hn0yeE,3344
|
|
6
|
-
freealg/_jacobi.py,sha256=HVnaujwAcaILVFGEgxk26UyIaLdP2FZMY44C8TG3Qcc,4763
|
|
7
|
-
freealg/_pade.py,sha256=rWILLpEL910YdixC2c5Cw77HqogAYoxi2YZgRVXEELM,4022
|
|
8
|
-
freealg/_plot_util.py,sha256=Q_LWLbqJefjympbcF2ylpeiYupbj5YAvTLwnpjEDeC4,19009
|
|
9
|
-
freealg/_util.py,sha256=wJ-t8LMZZFEr2PsZEVqTJP_jQTQ3rHUf0dO27F6L7YQ,2310
|
|
10
|
-
freealg/freeform.py,sha256=PsI0cnN38J-97jXDMSqERxgJZw-Tr13pPbIGmpgnRcc,23846
|
|
11
|
-
freealg/distributions/__init__.py,sha256=7t4HbP_EofiFDYLH6jbD94AIumOdcHn1y_Qo54mpLFM,614
|
|
12
|
-
freealg/distributions/marchenko_pastur.py,sha256=k8SoEgB2DFXLqGF-Hyqm8Sfh1DlF3khMssuxak5Uaqw,15827
|
|
13
|
-
freealg-0.0.3.dist-info/licenses/LICENSE.txt,sha256=J-EEYEtxb3VVf_Bn1TYfWnpY5lMFIM15iLDDcnaDTPA,1443
|
|
14
|
-
freealg-0.0.3.dist-info/METADATA,sha256=Z1wF6CU_RomE2Q9ICEuYyNr6R3vQgrW0eZ3HIuEkRs8,2888
|
|
15
|
-
freealg-0.0.3.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
|
|
16
|
-
freealg-0.0.3.dist-info/top_level.txt,sha256=eR2wrgYwDdnnJ9Zf5PruPqe4kQav0GMvRsqct6y00Q8,8
|
|
17
|
-
freealg-0.0.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|