freealg 0.7.16__py3-none-any.whl → 0.7.17__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/distributions/_compound_poisson.py +27 -17
- freealg/distributions/_deformed_marchenko_pastur.py +16 -72
- freealg/distributions/_deformed_wigner.py +3 -40
- {freealg-0.7.16.dist-info → freealg-0.7.17.dist-info}/METADATA +1 -1
- {freealg-0.7.16.dist-info → freealg-0.7.17.dist-info}/RECORD +10 -10
- {freealg-0.7.16.dist-info → freealg-0.7.17.dist-info}/WHEEL +0 -0
- {freealg-0.7.16.dist-info → freealg-0.7.17.dist-info}/licenses/AUTHORS.txt +0 -0
- {freealg-0.7.16.dist-info → freealg-0.7.17.dist-info}/licenses/LICENSE.txt +0 -0
- {freealg-0.7.16.dist-info → freealg-0.7.17.dist-info}/top_level.txt +0 -0
freealg/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.7.
|
|
1
|
+
__version__ = "0.7.17"
|
|
@@ -372,23 +372,6 @@ class CompoundPoisson(object):
|
|
|
372
372
|
"""
|
|
373
373
|
Generate a symmetric random matrix whose ESD approximates this law.
|
|
374
374
|
|
|
375
|
-
Construction
|
|
376
|
-
------------
|
|
377
|
-
Use a sum of two independent (rotationally invariant) Wishart terms,
|
|
378
|
-
which are asymptotically free:
|
|
379
|
-
|
|
380
|
-
A = s1 * (1/m1) Z1 Z1^T + s2 * (1/m2) Z2 Z2^T,
|
|
381
|
-
|
|
382
|
-
where Zi are n x mi i.i.d. N(0,1). Choose aspect ratios ci = n/mi and
|
|
383
|
-
scales si so each term has R-transform
|
|
384
|
-
|
|
385
|
-
Ri(w) = lam_i * a_i / (1 - a_i w),
|
|
386
|
-
|
|
387
|
-
with lam_1 = lam*w1, lam_2 = lam*(1-w1). This is achieved by setting
|
|
388
|
-
|
|
389
|
-
c_i = 1/lam_i,
|
|
390
|
-
s_i = a_i * lam_i.
|
|
391
|
-
|
|
392
375
|
Parameters
|
|
393
376
|
----------
|
|
394
377
|
size : int
|
|
@@ -401,6 +384,33 @@ class CompoundPoisson(object):
|
|
|
401
384
|
-------
|
|
402
385
|
A : numpy.ndarray
|
|
403
386
|
Symmetric matrix (n x n).
|
|
387
|
+
|
|
388
|
+
Notes
|
|
389
|
+
-----
|
|
390
|
+
|
|
391
|
+
Use a sum of two independent (rotationally invariant) Wishart terms,
|
|
392
|
+
which are asymptotically free:
|
|
393
|
+
|
|
394
|
+
.. math::
|
|
395
|
+
|
|
396
|
+
A = s_1 \\frac{1}{m_1} \\mathbf{Z}_1 \\mathbf{Z}_1^{\\intercal} +
|
|
397
|
+
s_2 * \\frac{1}{m_2} \\mathbf{Z}_2 \\mathbf{Z}_2^{\\intefcal},
|
|
398
|
+
|
|
399
|
+
where :math:`\\mathbf{Z}_i` are :math:`n \\times m_`i` i.i.d.
|
|
400
|
+
:math:`N(0,1)`. Choose aspect ratios :math:`c_i = n/m_i` and
|
|
401
|
+
scales :math:`s_i` so each term has R-transform
|
|
402
|
+
|
|
403
|
+
.. math::
|
|
404
|
+
|
|
405
|
+
R_i(w) = \\lambda_i \\frac{a_i}{(1 - a_i w},
|
|
406
|
+
|
|
407
|
+
with :math:`\\lambda_1 = \\lambda w1`,
|
|
408
|
+
:math:`\\lambda_2 = \\lambda (1-w_1)`. This is achieved by setting
|
|
409
|
+
|
|
410
|
+
.. math::
|
|
411
|
+
|
|
412
|
+
c_i = 1 / \\lambda_i,
|
|
413
|
+
s_i = a_i * \\lambda_i.
|
|
404
414
|
"""
|
|
405
415
|
|
|
406
416
|
n = int(size)
|
|
@@ -246,91 +246,35 @@ class DeformedMarchenkoPastur(object):
|
|
|
246
246
|
# density
|
|
247
247
|
# =======
|
|
248
248
|
|
|
249
|
-
def density(self, x, eta=1e-3):
|
|
249
|
+
def density(self, x, eta=1e-3, ac_only=True):
|
|
250
250
|
"""
|
|
251
251
|
Density via Stieltjes inversion with robust x-continuation.
|
|
252
252
|
|
|
253
|
-
Notes
|
|
253
|
+
Notes
|
|
254
|
+
-----
|
|
255
|
+
|
|
254
256
|
- Do not warm-start across x<0 (MP-type support is >=0).
|
|
255
257
|
- Reset warm-start when previous u is (nearly) real.
|
|
256
258
|
- If Newton lands on a non-Herglotz root, fall back to cubic roots +
|
|
257
259
|
pick.
|
|
258
|
-
"""
|
|
259
260
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
w1 = self.w1
|
|
264
|
-
c = self.c
|
|
261
|
+
If ac_only is True and c < 1, subtract the smeared atom at zero of mass
|
|
262
|
+
(1-c) for visualization.
|
|
263
|
+
"""
|
|
265
264
|
|
|
266
265
|
x = numpy.asarray(x, dtype=numpy.float64)
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
c = float(c)
|
|
270
|
-
if c < 0.0:
|
|
271
|
-
raise ValueError("c must be >= 0.")
|
|
272
|
-
if c == 0.0:
|
|
273
|
-
# Degenerate: μ = H when c=0, so m(z)=E[1/(t-z)] and rho from Im m.
|
|
274
|
-
z = x + 1j * float(eta)
|
|
275
|
-
w2 = 1.0 - w1
|
|
276
|
-
m = (w1 / (t1 - z)) + (w2 / (t2 - z))
|
|
277
|
-
rho = numpy.maximum(numpy.imag(m) / numpy.pi, 0.0)
|
|
278
|
-
return rho
|
|
279
|
-
|
|
280
|
-
# MP-type spectra live on x>=0; probing code includes x<0 (x_min<0),
|
|
281
|
-
# so we keep rho(x<0)=0 and DO NOT carry warm-start across 0.
|
|
282
|
-
mask = (x >= 0.0)
|
|
283
|
-
if not numpy.any(mask):
|
|
284
|
-
return rho
|
|
285
|
-
|
|
286
|
-
xp = x[mask]
|
|
287
|
-
|
|
288
|
-
# Preserve original order (support probing uses increasing xp).
|
|
289
|
-
order = numpy.argsort(xp)
|
|
290
|
-
inv = numpy.empty_like(order)
|
|
291
|
-
inv[order] = numpy.arange(order.size)
|
|
292
|
-
|
|
293
|
-
xp_sorted = xp[order]
|
|
294
|
-
z = xp_sorted + 1j * float(eta)
|
|
295
|
-
zf = z.ravel()
|
|
296
|
-
|
|
297
|
-
u = numpy.empty_like(zf, dtype=numpy.complex128)
|
|
298
|
-
u_prev = None
|
|
299
|
-
|
|
300
|
-
# thresholds
|
|
301
|
-
imag_eps = 1e-14
|
|
302
|
-
|
|
303
|
-
w2 = 1.0 - w1
|
|
304
|
-
|
|
305
|
-
for i in range(zf.size):
|
|
306
|
-
zi = zf[i]
|
|
307
|
-
|
|
308
|
-
# Warm start only if previous iterate had meaningful imaginary part
|
|
309
|
-
# (otherwise we risk sticking to a real branch across the bulk).
|
|
310
|
-
if (u_prev is None) or (abs(u_prev.imag) <= imag_eps):
|
|
311
|
-
ui0 = -1.0 / zi
|
|
312
|
-
else:
|
|
313
|
-
ui0 = complex(u_prev)
|
|
314
|
-
|
|
315
|
-
ui, _ = self._solve_u_newton(zi, u0=ui0, max_iter=120, tol=1e-13)
|
|
316
|
-
|
|
317
|
-
# Enforce Herglotz: sign(Im z) == sign(Im u) (eta>0 => Im u must be
|
|
318
|
-
# >0)
|
|
319
|
-
if (not numpy.isfinite(ui)) or (ui.imag <= 0.0):
|
|
320
|
-
u_roots = self._roots_cubic_u_scalar(zi)
|
|
321
|
-
ui = _pick_physical_root_scalar(zi, u_roots)
|
|
322
|
-
|
|
323
|
-
u[i] = ui
|
|
324
|
-
u_prev = ui
|
|
266
|
+
z = x + 1j * float(eta)
|
|
325
267
|
|
|
326
|
-
m = (
|
|
327
|
-
|
|
268
|
+
m = self.stieltjes(z)
|
|
269
|
+
rho = numpy.imag(m) / numpy.pi
|
|
328
270
|
|
|
329
|
-
#
|
|
330
|
-
|
|
331
|
-
|
|
271
|
+
# Optional: remove the atom at zero (only for visualization of AC part)
|
|
272
|
+
if ac_only and (self.c > 1.0):
|
|
273
|
+
w0 = 1.0 - 1.0 / self.c
|
|
274
|
+
rho = rho - w0 * (float(eta) / numpy.pi) / \
|
|
275
|
+
(x * x + float(eta) * float(eta))
|
|
332
276
|
|
|
333
|
-
return rho
|
|
277
|
+
return numpy.maximum(rho, 0.0)
|
|
334
278
|
|
|
335
279
|
# =====
|
|
336
280
|
# roots
|
|
@@ -139,50 +139,13 @@ class DeformedWigner(object):
|
|
|
139
139
|
"""
|
|
140
140
|
"""
|
|
141
141
|
|
|
142
|
-
# Unpack parameters
|
|
143
|
-
t1 = self.t1
|
|
144
|
-
t2 = self.t2
|
|
145
|
-
w1 = self.w1
|
|
146
|
-
sigma = self.sigma
|
|
147
|
-
|
|
148
142
|
x = numpy.asarray(x, dtype=numpy.float64)
|
|
149
143
|
z = x + 1j * float(eta)
|
|
150
144
|
|
|
151
|
-
|
|
152
|
-
m = numpy.empty_like(zf, dtype=numpy.complex128)
|
|
153
|
-
|
|
154
|
-
m_prev = None
|
|
155
|
-
for i in range(zf.size):
|
|
156
|
-
zi = zf[i]
|
|
157
|
-
if m_prev is None:
|
|
158
|
-
mi = -1.0 / zi
|
|
159
|
-
else:
|
|
160
|
-
mi = complex(m_prev)
|
|
161
|
-
|
|
162
|
-
for _ in range(80):
|
|
163
|
-
d1 = (t1 - zi - (sigma * sigma) * mi)
|
|
164
|
-
d2 = (t2 - zi - (sigma * sigma) * mi)
|
|
165
|
-
|
|
166
|
-
f = mi - (w1 / d1 + (1.0 - w1) / d2)
|
|
167
|
-
fp = 1.0 - (
|
|
168
|
-
w1 * (sigma * sigma) / (d1 * d1) +
|
|
169
|
-
(1.0 - w1) * (sigma * sigma) / (d2 * d2)
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
step = f / fp
|
|
173
|
-
mi2 = mi - step
|
|
174
|
-
if abs(step) < 1e-12 * (1.0 + abs(mi2)):
|
|
175
|
-
mi = mi2
|
|
176
|
-
break
|
|
177
|
-
mi = mi2
|
|
178
|
-
|
|
179
|
-
m[i] = mi
|
|
180
|
-
m_prev = mi
|
|
181
|
-
|
|
182
|
-
m = m.reshape(z.shape)
|
|
145
|
+
m = self.stieltjes(z)
|
|
183
146
|
rho = numpy.imag(m) / numpy.pi
|
|
184
|
-
|
|
185
|
-
return rho
|
|
147
|
+
|
|
148
|
+
return numpy.maximum(rho, 0.0)
|
|
186
149
|
|
|
187
150
|
# =====
|
|
188
151
|
# roots
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
freealg/__init__.py,sha256=is4de7kygj1be0S3EAcAlW_vGriWjdjHCR-J9NN6wyk,873
|
|
2
|
-
freealg/__version__.py,sha256=
|
|
2
|
+
freealg/__version__.py,sha256=OaW7Nqbk6j_afc_1rZbViV0T5t8K2yQ3XoJdd50o-lc,23
|
|
3
3
|
freealg/_util.py,sha256=RzccUCORgzrI9NdNqwMVugiHU0uDKkJFcIyjFMUOnv8,2518
|
|
4
4
|
freealg/_algebraic_form/__init__.py,sha256=etgaRiuipcmxtwHzMVxZwO_qbX8R7m9j39mKvgRyTZg,463
|
|
5
5
|
freealg/_algebraic_form/_branch_points.py,sha256=jzvHszw7xFe9B15a5RZV3pGfCGtndvrKJ4GIX6F3qhc,7814
|
|
@@ -50,9 +50,9 @@ freealg/_geometric_form/_torus_maps.py,sha256=7m5QsbmnXTWHJE5rWjKG3_TnErHEEQ41vW
|
|
|
50
50
|
freealg/_geometric_form/geometric_form.py,sha256=whHKYQdakqShtR-jCEugevnje72JEr9M0HSvZ2BYoKs,33379
|
|
51
51
|
freealg/distributions/__init__.py,sha256=sCx2NVcRTaHwvxXpFRU_9unN98ZED6B-xFoFZ2eU9-E,875
|
|
52
52
|
freealg/distributions/_chiral_block.py,sha256=YSC_Sk1u1UKlWVE1GGJEjX6VrWqpEEYNxBZ2j8Csc3A,13897
|
|
53
|
-
freealg/distributions/_compound_poisson.py,sha256=
|
|
54
|
-
freealg/distributions/_deformed_marchenko_pastur.py,sha256=
|
|
55
|
-
freealg/distributions/_deformed_wigner.py,sha256=
|
|
53
|
+
freealg/distributions/_compound_poisson.py,sha256=SFjplOK6NRl3YwFfV3t1TVR_yTn55hQBboFAjHve_ZA,12951
|
|
54
|
+
freealg/distributions/_deformed_marchenko_pastur.py,sha256=9WyAYDhpzR2JLqWA8-yUpw6pWvPC5bu4FxrWof17NSM,19249
|
|
55
|
+
freealg/distributions/_deformed_wigner.py,sha256=yMA-d2cDsRLyIWUjTlh0Aqh29mw68LNJHOnUUYSkVms,8067
|
|
56
56
|
freealg/distributions/_kesten_mckay.py,sha256=Uv3QuUYsfXbPMovXSO_pN3wdkc1fTKGVX7iuHDgBRqk,20089
|
|
57
57
|
freealg/distributions/_marchenko_pastur.py,sha256=eemaxDosKpV37TAn9uSiYpljIkVNoTWDJ9ZfYb8tAeY,20646
|
|
58
58
|
freealg/distributions/_meixner.py,sha256=GbcWeHrXMxK3Hdj4pCTESlMts9dEPQE1DhClxYprWfg,17590
|
|
@@ -61,9 +61,9 @@ freealg/distributions/_wigner.py,sha256=epgx6ne6R_7to5j6-QsWIAVFJQFquWMmYgnZYMN4
|
|
|
61
61
|
freealg/visualization/__init__.py,sha256=NLq_zwueF7ytZ8sl8zLPqm-AODxxXNvfMozHGmmklcE,435
|
|
62
62
|
freealg/visualization/_glue_util.py,sha256=2oKnEYjUOS4OZfivmciVLauVr53kyHMwi6c2zRKilTQ,693
|
|
63
63
|
freealg/visualization/_rgb_hsv.py,sha256=rEskxXxSlKKxIrHRslVkgxHtD010L3ge9YtcVsOPl8E,3650
|
|
64
|
-
freealg-0.7.
|
|
65
|
-
freealg-0.7.
|
|
66
|
-
freealg-0.7.
|
|
67
|
-
freealg-0.7.
|
|
68
|
-
freealg-0.7.
|
|
69
|
-
freealg-0.7.
|
|
64
|
+
freealg-0.7.17.dist-info/licenses/AUTHORS.txt,sha256=0b67Nz4_JgIzUupHJTAZxu5QdSUM_HRM_X_w4xCb17o,30
|
|
65
|
+
freealg-0.7.17.dist-info/licenses/LICENSE.txt,sha256=J-EEYEtxb3VVf_Bn1TYfWnpY5lMFIM15iLDDcnaDTPA,1443
|
|
66
|
+
freealg-0.7.17.dist-info/METADATA,sha256=aRVcV7-c3J0nYZgltd6sSnqeczyVL8deqHHKJ9LV1SQ,5537
|
|
67
|
+
freealg-0.7.17.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
68
|
+
freealg-0.7.17.dist-info/top_level.txt,sha256=eR2wrgYwDdnnJ9Zf5PruPqe4kQav0GMvRsqct6y00Q8,8
|
|
69
|
+
freealg-0.7.17.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|