freealg 0.7.15__tar.gz → 0.7.17__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.
- {freealg-0.7.15 → freealg-0.7.17}/PKG-INFO +1 -1
- freealg-0.7.17/freealg/__version__.py +1 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/algebraic_form.py +4 -4
- {freealg-0.7.15 → freealg-0.7.17}/freealg/distributions/_compound_poisson.py +27 -17
- {freealg-0.7.15 → freealg-0.7.17}/freealg/distributions/_deformed_marchenko_pastur.py +16 -72
- {freealg-0.7.15 → freealg-0.7.17}/freealg/distributions/_deformed_wigner.py +5 -42
- {freealg-0.7.15 → freealg-0.7.17}/freealg.egg-info/PKG-INFO +1 -1
- freealg-0.7.15/freealg/__version__.py +0 -1
- {freealg-0.7.15 → freealg-0.7.17}/AUTHORS.txt +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/CHANGELOG.rst +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/LICENSE.txt +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/MANIFEST.in +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/README.rst +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/__init__.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/__init__.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_branch_points.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_constraints.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_continuation_algebraic.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_cusp.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_cusp_wrap.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_decompress.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_decompress2.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_decompress4.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_decompress5.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_decompress6.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_decompress7.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_decompress8.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_decompress9.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_decompress_new.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_decompress_new_2.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_decompress_util.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_edge.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_homotopy.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_homotopy2.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_homotopy3.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_homotopy4.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_homotopy5.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_moments.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_sheets_util.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_algebraic_form/_support.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/__init__.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/_chebyshev.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/_damp.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/_decompress.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/_density_util.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/_jacobi.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/_linalg.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/_pade.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/_plot_util.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/_sample.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/_series.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/_support.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_free_form/free_form.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_geometric_form/__init__.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_geometric_form/_continuation_genus0.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_geometric_form/_continuation_genus1.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_geometric_form/_elliptic_functions.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_geometric_form/_sphere_maps.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_geometric_form/_torus_maps.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_geometric_form/geometric_form.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/_util.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/distributions/__init__.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/distributions/_chiral_block.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/distributions/_kesten_mckay.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/distributions/_marchenko_pastur.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/distributions/_meixner.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/distributions/_wachter.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/distributions/_wigner.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/visualization/__init__.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/visualization/_glue_util.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg/visualization/_rgb_hsv.py +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg.egg-info/SOURCES.txt +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg.egg-info/dependency_links.txt +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg.egg-info/not-zip-safe +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg.egg-info/requires.txt +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/freealg.egg-info/top_level.txt +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/pyproject.toml +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/requirements.txt +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/setup.cfg +0 -0
- {freealg-0.7.15 → freealg-0.7.17}/setup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.7.17"
|
|
@@ -245,15 +245,15 @@ class AlgebraicForm(object):
|
|
|
245
245
|
----------
|
|
246
246
|
|
|
247
247
|
deg_m : int
|
|
248
|
-
Degree :math:`\\
|
|
248
|
+
Degree :math:`\\mathrm{deg}_m(P)`
|
|
249
249
|
|
|
250
250
|
deg_z : int
|
|
251
|
-
Degree :math:`\\
|
|
251
|
+
Degree :math:`\\mathrm{deg}_z(P)`
|
|
252
252
|
|
|
253
253
|
mu : array_like, default=None
|
|
254
|
-
If an array :math:`[\\mu_0, \\
|
|
254
|
+
If an array :math:`[\\mu_0, \\mu_1`, \\dots, \\mu_r]` is given,
|
|
255
255
|
it enforces the first :math:`r+1` moments. Note that :math:`\\mu_0`
|
|
256
|
-
should be :math:`1` to ensure unit mass. See also ``mu_reg
|
|
256
|
+
should be :math:`1` to ensure unit mass. See also ``mu_reg``.
|
|
257
257
|
|
|
258
258
|
mu_reg: float, default=None
|
|
259
259
|
If `None`, the constraints ``mu`` are applied as hard constraint.
|
|
@@ -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
|
|
@@ -334,7 +297,7 @@ class DeformedWigner(object):
|
|
|
334
297
|
|
|
335
298
|
# W part: Symmetric Wigner with variance 1/n (up to symmetry)
|
|
336
299
|
G = rng.standard_normal((n, n))
|
|
337
|
-
W = (G + G.T)
|
|
300
|
+
W = (G + G.T) / numpy.sqrt(2.0 * n)
|
|
338
301
|
|
|
339
302
|
# Compose
|
|
340
303
|
A = T + sigma * W
|
|
@@ -373,7 +336,7 @@ class DeformedWigner(object):
|
|
|
373
336
|
a[1, 1] = -(t1 + t2)
|
|
374
337
|
a[2, 1] = 1.0
|
|
375
338
|
|
|
376
|
-
# m^2 column (a2(z) = s2 z - s2 (t1+t2))
|
|
339
|
+
# m^2 column (a2(z) = 2 s2 z - s2 (t1+t2))
|
|
377
340
|
a[0, 2] = -s2 * (t1 + t2)
|
|
378
341
|
a[1, 2] = 2.0 * s2
|
|
379
342
|
a[2, 2] = 0.0
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.7.15"
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|