freealg 0.7.15__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 CHANGED
@@ -1 +1 @@
1
- __version__ = "0.7.15"
1
+ __version__ = "0.7.17"
@@ -245,15 +245,15 @@ class AlgebraicForm(object):
245
245
  ----------
246
246
 
247
247
  deg_m : int
248
- Degree :math:`\\deg_m(P)`
248
+ Degree :math:`\\mathrm{deg}_m(P)`
249
249
 
250
250
  deg_z : int
251
- Degree :math:`\\deg_z(P)`
251
+ Degree :math:`\\mathrm{deg}_z(P)`
252
252
 
253
253
  mu : array_like, default=None
254
- If an array :math:`[\\mu_0, \\mu_`, \\dots, \\mu_r]` is given,
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
- # Unpack parameters
261
- t1 = self.t1
262
- t2 = self.t2
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
- rho = numpy.zeros_like(x, dtype=numpy.float64)
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 = (u + (1.0 - c) / zf) / c
327
- rh = numpy.maximum(numpy.imag(m) / numpy.pi, 0.0)
268
+ m = self.stieltjes(z)
269
+ rho = numpy.imag(m) / numpy.pi
328
270
 
329
- # Unsort back
330
- rh = rh.reshape(xp_sorted.shape)
331
- rho[mask] = rh[inv]
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
- zf = z.ravel()
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
- rho = numpy.maximum(rho, 0.0)
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) * (0.5 / numpy.sqrt(n))
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: freealg
3
- Version: 0.7.15
3
+ Version: 0.7.17
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
@@ -1,5 +1,5 @@
1
1
  freealg/__init__.py,sha256=is4de7kygj1be0S3EAcAlW_vGriWjdjHCR-J9NN6wyk,873
2
- freealg/__version__.py,sha256=7TV8ktpkocjy2CbaPP0e82unkG7763a7BOPYX37gato,23
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
@@ -27,7 +27,7 @@ freealg/_algebraic_form/_homotopy5.py,sha256=lHWA5tknnZBMymcWt_KQXcI0qLrd_ftUGgd
27
27
  freealg/_algebraic_form/_moments.py,sha256=R1-EepGsni4he-kNfiP3E3tFqR2Z27fz-ixtSVU2fSE,12427
28
28
  freealg/_algebraic_form/_sheets_util.py,sha256=6OLzWQKu-gN8rxM2rbpbN8TjNZFmD8UJ-8t9kcZdkCo,4174
29
29
  freealg/_algebraic_form/_support.py,sha256=Gjp4nVQJb_Syou3M_uroSl52bPTafqKk6IUSJgglKu4,6791
30
- freealg/_algebraic_form/algebraic_form.py,sha256=14bKYTLdYb4F1vgIdEeFHi-PI_-AZGoAaEfzf5HAaJk,37762
30
+ freealg/_algebraic_form/algebraic_form.py,sha256=NshXrMXJBxqfiwMckBD7tmgNjQ4TpawPUKNJuVIS4Gw,37780
31
31
  freealg/_free_form/__init__.py,sha256=5cnSX7kHci3wKx6-BEFhmVY_NjjmQAq1JjWPTEqETTg,611
32
32
  freealg/_free_form/_chebyshev.py,sha256=zkyVA8NLf7uUKlJdLz4ijd_SurdsqUgkA5nHGWSybaE,6916
33
33
  freealg/_free_form/_damp.py,sha256=k2vtBtWOxQBf4qXaWu_En81lQBXbEO4QbxxWpvuVhdE,1802
@@ -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=TjeyfJod5ghPHtr-tbD8e4cbo-JhkSRvJUOFyfn8m2g,12676
54
- freealg/distributions/_deformed_marchenko_pastur.py,sha256=hrA2U_LBw7eB0QBqAwZtLuAU6Tq1nQsJgX2Y1_Y3ae8,20926
55
- freealg/distributions/_deformed_wigner.py,sha256=0933XQAplP3mifJKdSU7qXgrndqUs1MUpYMJHR-NId8,9086
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.15.dist-info/licenses/AUTHORS.txt,sha256=0b67Nz4_JgIzUupHJTAZxu5QdSUM_HRM_X_w4xCb17o,30
65
- freealg-0.7.15.dist-info/licenses/LICENSE.txt,sha256=J-EEYEtxb3VVf_Bn1TYfWnpY5lMFIM15iLDDcnaDTPA,1443
66
- freealg-0.7.15.dist-info/METADATA,sha256=NRK-E0Ni96OuonpfAX_PAGCZIbHZ_A_kVRzQ4TmfTRQ,5537
67
- freealg-0.7.15.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
68
- freealg-0.7.15.dist-info/top_level.txt,sha256=eR2wrgYwDdnnJ9Zf5PruPqe4kQav0GMvRsqct6y00Q8,8
69
- freealg-0.7.15.dist-info/RECORD,,
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,,