freealg 0.7.9__py3-none-any.whl → 0.7.10__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.9"
1
+ __version__ = "0.7.10"
@@ -504,6 +504,7 @@ def decompress_newton(z_list, t_grid, a_coeffs, w0_list=None,
504
504
  ok : ndarray of bool, same shape as W
505
505
  Convergence flags from the accepted solve at each point.
506
506
  """
507
+
507
508
  z_list = numpy.asarray(z_list, dtype=complex).ravel()
508
509
  t_grid = numpy.asarray(t_grid, dtype=float).ravel()
509
510
  nt = t_grid.size
@@ -6,12 +6,12 @@ import numpy
6
6
  from ._moments import AlgebraicStieltjesMoments
7
7
  from tqdm import tqdm
8
8
 
9
- __all__ = ['stieltjes_poly']
9
+ __all__ = ['StieltjesPoly']
10
10
 
11
11
 
12
- # =====================
12
+ # ===========
13
13
  # select root
14
- # =====================
14
+ # ===========
15
15
 
16
16
  def select_root(roots, z, target):
17
17
  """
@@ -202,7 +202,7 @@ class StieltjesPoly(object):
202
202
 
203
203
  # Iterate over indices so we can pass Python scalars into evaluate()
204
204
  if progress:
205
- indices = tqdm(numpy.ndindex(z_arr.shape),total=z_arr.size)
205
+ indices = tqdm(numpy.ndindex(z_arr.shape), total=z_arr.size)
206
206
  else:
207
207
  indices = numpy.ndindex(z_arr.shape)
208
208
  for idx in indices:
@@ -265,7 +265,7 @@ class StieltjesPoly(object):
265
265
  # coeffs = numpy.asarray(poly_coeffs_m(z_val), dtype=numpy.complex128)
266
266
  # return numpy.roots(coeffs)
267
267
 
268
- # # If user asked for a real-axis value, interpret as boundary value from C+.
268
+ # # If user asked a real-axis value, interpret as boundary value from C+.
269
269
  # if z.imag == 0.0:
270
270
  # if eps is None:
271
271
  # eps = 1e-8 * max(1.0, abs(z))
@@ -1,9 +1,13 @@
1
+ # =======
2
+ # Imports
3
+ # =======
4
+
1
5
  import numpy
2
6
 
3
7
 
4
- # =========
8
+ # =======
5
9
  # Moments
6
- # =========
10
+ # =======
7
11
 
8
12
  class MomentsESD(object):
9
13
  """
@@ -85,9 +89,9 @@ class MomentsESD(object):
85
89
  # (a_{n,0},...,a_{n,n-1})
86
90
  self._a = {0: numpy.array([1.0])}
87
91
 
88
- # ----------
89
- # moments
90
- # ----------
92
+ # =
93
+ # m
94
+ # =
91
95
 
92
96
  def m(self, n):
93
97
  """
@@ -111,9 +115,9 @@ class MomentsESD(object):
111
115
  self._m[n] = numpy.mean(self.eig ** n)
112
116
  return self._m[n]
113
117
 
114
- # -------------
115
- # coefficients
116
- # -------------
118
+ # ======
119
+ # coeffs
120
+ # ======
117
121
 
118
122
  def coeffs(self, n):
119
123
  """
@@ -129,7 +133,8 @@ class MomentsESD(object):
129
133
  -------
130
134
 
131
135
  a_n : numpy.ndarray
132
- Array of shape ``(n,)`` containing :math:`(a_{n,0}, \\dots, a_{n,n-1})`.
136
+ Array of shape ``(n,)`` containing :math:`(a_{n,0},
137
+ \\dots, a_{n,n-1})`.
133
138
  """
134
139
 
135
140
  if n in self._a:
@@ -143,6 +148,10 @@ class MomentsESD(object):
143
148
  self._compute_row(n)
144
149
  return self._a[n]
145
150
 
151
+ # ===========
152
+ # compute row
153
+ # ===========
154
+
146
155
  def _compute_row(self, n):
147
156
  """
148
157
  Compute and memoize the coefficient row :math:`a_n`.
@@ -212,9 +221,9 @@ class MomentsESD(object):
212
221
 
213
222
  self._a[n] = a_n
214
223
 
215
- # ----------
224
+ # --------
216
225
  # evaluate
217
- # ----------
226
+ # --------
218
227
 
219
228
  def __call__(self, n, t=0.0):
220
229
  """
@@ -254,18 +263,18 @@ class MomentsESD(object):
254
263
  k = numpy.arange(n, dtype=float)
255
264
  return numpy.dot(a_n, numpy.exp(k * t))
256
265
 
266
+
257
267
  # ===========================
258
268
  # Algebraic Stieltjes Moments
259
269
  # ===========================
260
270
 
261
-
262
271
  class AlgebraicStieltjesMoments(object):
263
272
  """
264
273
  Given coefficients a[i,j] for P(z,m)=sum_{i,j} a[i,j] z^i m^j,
265
274
  compute the large-|z| branch
266
275
  m(z) = sum_{k>=0} mu_series[k] / z^{k+1}.
267
276
 
268
- Convention here: choose mu0 (the leading coefficient) by solving the
277
+ Convention here: choose mu0 (the leading coefficient) by solving the
269
278
  leading-diagonal equation and (by default) picking the root closest
270
279
  to -1, i.e. m(z) ~ -1/z.
271
280
 
@@ -281,7 +290,7 @@ class AlgebraicStieltjesMoments(object):
281
290
  if self.a.ndim != 2:
282
291
  raise ValueError("a must be a 2D NumPy array with a[i,j]=a_{ij}.")
283
292
 
284
- self.I = self.a.shape[0] - 1
293
+ self.I = self.a.shape[0] - 1 # noqa: E741
285
294
  self.J = self.a.shape[1] - 1
286
295
 
287
296
  nz = numpy.argwhere(self.a != 0)
@@ -320,7 +329,8 @@ class AlgebraicStieltjesMoments(object):
320
329
  if j > 0:
321
330
  self.A0 += j * coeff * self.mu0pow[j - 1]
322
331
  if self.A0 == 0:
323
- raise ValueError("A0 is zero for this mu0; the sequential recursion is degenerate.")
332
+ raise ValueError("A0 is zero for this mu0; the sequential " +
333
+ "recursion is degenerate.")
324
334
 
325
335
  # Stored series moments mu_series[0..]
326
336
  self._mu = [self.mu0]
@@ -344,14 +354,17 @@ class AlgebraicStieltjesMoments(object):
344
354
  coeffs[j] = self.a[i, j]
345
355
 
346
356
  if not numpy.any(coeffs != 0):
347
- raise ValueError("Leading diagonal polynomial is identically zero; cannot determine mu0.")
357
+ raise ValueError("Leading diagonal polynomial is identically " +
358
+ "zero; cannot determine mu0.")
348
359
 
349
360
  deg = int(numpy.max(numpy.nonzero(coeffs)[0]))
350
- roots = numpy.roots(coeffs[:deg + 1][::-1]) # descending powers for numpy.roots
361
+
362
+ # descending powers for numpy.roots
363
+ roots = numpy.roots(coeffs[:deg + 1][::-1])
351
364
 
352
365
  # Targetting mu0 = -1 for ~ -1/z asymptotics
353
366
  mu0 = roots[numpy.argmin(numpy.abs(roots + 1))]
354
-
367
+
355
368
  if abs(mu0.imag) < 1e-12:
356
369
  mu0 = mu0.real
357
370
  return mu0
@@ -363,7 +376,8 @@ class AlgebraicStieltjesMoments(object):
363
376
 
364
377
  # Compute f[j] = coefficient of w^k in (S_trunc(w))^j,
365
378
  # where S_trunc uses mu_0..mu_{k-1} only (i.e. mu_k treated as 0).
366
- # Key fact: in the true c[j,k], mu_k can only appear linearly as j*mu_k*mu0^{j-1}.
379
+ # Key fact: in the true c[j,k], mu_k can only appear linearly as
380
+ # j*mu_k*mu0^{j-1}.
367
381
  f = [0] * (self.J + 1)
368
382
  f[0] = 0
369
383
  for j in range(1, self.J + 1):
@@ -371,8 +385,9 @@ class AlgebraicStieltjesMoments(object):
371
385
  # sum_{t=1..k-1} mu_t * c[j-1, k-t]
372
386
  for t in range(1, k):
373
387
  ssum += self._mu[t] * self._c[j - 1][k - t]
374
- # recurrence: c[j,k] = mu0*c[j-1,k] + sum_{t=1..k-1} mu_t*c[j-1,k-t] + mu_k*c[j-1,0]
375
- # with mu_k=0 for f, and c[j-1,k]=f[j-1]
388
+ # recurrence: c[j,k] = mu0*c[j-1,k] + sum_{t=1..k-1}
389
+ # mu_t*c[j-1,k-t] + mu_k*c[j-1,0] with mu_k=0 for f,
390
+ # and c[j-1,k]=f[j-1]
376
391
  f[j] = self.mu0 * f[j - 1] + ssum
377
392
 
378
393
  # Build the linear equation for mu_k:
@@ -386,7 +401,8 @@ class AlgebraicStieltjesMoments(object):
386
401
  continue
387
402
  rest += coeff * f[j]
388
403
 
389
- # lower diagonals s=1..k contribute coeff*c[j,k-s] (already known since k-s < k)
404
+ # lower diagonals s=1..k contribute coeff*c[j,k-s] (already known
405
+ # since k-s < k)
390
406
  for s in range(1, k + 1):
391
407
  entries = self.diag.get(s)
392
408
  if not entries:
@@ -402,7 +418,8 @@ class AlgebraicStieltjesMoments(object):
402
418
  mu_k = -rest / self.A0
403
419
  self._mu.append(mu_k)
404
420
 
405
- # Now append the new column k to c using the full convolution recurrence:
421
+ # Now append the new column k to c using the full convolution
422
+ # recurrence:
406
423
  # c[j,k] = sum_{t=0..k} mu_t * c[j-1,k-t]
407
424
  for j in range(self.J + 1):
408
425
  self._c[j].append(0)
@@ -430,9 +447,10 @@ class AlgebraicStieltjesMoments(object):
430
447
  # Estimate the radius of convergence of the Stieltjes
431
448
  # series
432
449
  if N < 3:
433
- raise RuntimeError("Order is too small, choose a larger value of N")
450
+ raise RuntimeError("N is too small, choose a larger value.")
434
451
  self._ensure(N)
435
- return max([numpy.abs(self._mu[j] / self._mu[j-1]) for j in range(2,N+1)])
452
+ return max([numpy.abs(self._mu[j] / self._mu[j-1])
453
+ for j in range(2, N+1)])
436
454
 
437
455
  def stieltjes(self, z, N):
438
456
  # Estimate Stieltjes transform (root) using moment
@@ -63,7 +63,7 @@ class AlgebraicForm(object):
63
63
  * ``'complex128'``: 128-bit complex numbers, equivalent of two double
64
64
  precision floating point.
65
65
  * ``'complex256'``: 256-bit complex numbers, equivalent of two long
66
- double precision floating point. This optino is only available on
66
+ double precision floating point. This option is only available on
67
67
  Linux machines.
68
68
 
69
69
  When using series acceleration methods (such as setting
@@ -145,7 +145,7 @@ class AlgebraicForm(object):
145
145
  self.A = None
146
146
  self.eig = None
147
147
  self._stieltjes = None
148
- self.moments = None
148
+ self._moments = None
149
149
  self.support = support
150
150
  self.delta = delta # Offset above real axis to apply Plemelj formula
151
151
 
@@ -180,7 +180,7 @@ class AlgebraicForm(object):
180
180
  # Use empirical Stieltjes function
181
181
  self._stieltjes = lambda z: \
182
182
  numpy.mean(1.0/(self.eig-z[:, numpy.newaxis]), axis=-1)
183
- self.moments = MomentsESD(self.eig)
183
+ self._moments = MomentsESD(self.eig) # NOTE (never used)
184
184
 
185
185
  # Support
186
186
  if support is None:
@@ -271,7 +271,7 @@ class AlgebraicForm(object):
271
271
  triangular=triangular, normalize=normalize, mu=mu,
272
272
  mu_reg=mu_reg)
273
273
 
274
- # Compute global branhc points, zeros of leading a_j, and support
274
+ # Compute global branch points, zeros of leading a_j, and support
275
275
  branch_points, a_s_zero, support = compute_singular_points(a_coeffs)
276
276
 
277
277
  self.a_coeffs = a_coeffs
@@ -294,7 +294,7 @@ class AlgebraicForm(object):
294
294
  status['res_99_9'] = float(res_99_9)
295
295
  status['fit_metrics'] = fit_metrics
296
296
  self.status = status
297
- self._stieltjes = StieltjesPoly(self.a_coeffs)
297
+ self._stieltjes = StieltjesPoly(self.a_coeffs) # NOTE overwrite init
298
298
 
299
299
  if verbose:
300
300
  print(f'fit residual max : {res_max:>0.4e}')
@@ -462,11 +462,11 @@ class AlgebraicForm(object):
462
462
 
463
463
  # Preallocate density to zero
464
464
  hilb = -self._stieltjes(x).real / numpy.pi
465
-
465
+
466
466
  if plot:
467
467
  plot_hilbert(x, hilb, support=self.support, latex=latex,
468
468
  save=save)
469
-
469
+
470
470
  return hilb
471
471
 
472
472
  # =========
@@ -531,7 +531,7 @@ class AlgebraicForm(object):
531
531
  # Create x if not given
532
532
  if x is None:
533
533
  x = self._generate_grid(2.0, extend=2.0)[::2]
534
-
534
+
535
535
  # Create y if not given
536
536
  if (plot is False) and (y is None):
537
537
  # Do not use a Cartesian grid. Create a 1D array z slightly above
@@ -544,13 +544,13 @@ class AlgebraicForm(object):
544
544
  y = numpy.linspace(-1, 1, 200)
545
545
  x_grid, y_grid = numpy.meshgrid(x.real, y.real)
546
546
  z = x_grid + 1j * y_grid # shape (Ny, Nx)
547
-
547
+
548
548
  m = self._stieltjes(z, progress=True)
549
-
549
+
550
550
  if plot:
551
551
  plot_stieltjes(x, y, m, m, self.broad_support, latex=latex,
552
552
  save=save)
553
-
553
+
554
554
  return m
555
555
 
556
556
  # ==============
@@ -611,8 +611,10 @@ class AlgebraicForm(object):
611
611
  alpha = numpy.atleast_1d(size) / self.n
612
612
 
613
613
  # Lower and upper bound on new support
614
- hilb_lb = (1.0 / self._stieltjes(self.lam_m + self.delta * 1j).item()).real
615
- hilb_ub = (1.0 / self._stieltjes(self.lam_p + self.delta * 1j).item()).real
614
+ hilb_lb = \
615
+ (1.0 / self._stieltjes(self.lam_m + self.delta * 1j).item()).real
616
+ hilb_ub = \
617
+ (1.0 / self._stieltjes(self.lam_p + self.delta * 1j).item()).real
616
618
  lb = self.lam_m - (numpy.max(alpha) - 1) * hilb_lb
617
619
  ub = self.lam_p - (numpy.max(alpha) - 1) * hilb_ub
618
620
 
@@ -639,7 +641,8 @@ class AlgebraicForm(object):
639
641
  t = numpy.log(alpha)
640
642
 
641
643
  # Ensure it starts from t = 0
642
- t = numpy.concatenate([numpy.zeros(1), t])
644
+ if t[0] > 1.0:
645
+ t = numpy.concatenate([numpy.zeros(1), t])
643
646
 
644
647
  # Evolve
645
648
  W, ok = decompress_newton(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: freealg
3
- Version: 0.7.9
3
+ Version: 0.7.10
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,17 +1,17 @@
1
1
  freealg/__init__.py,sha256=SjcYb6HWmaclnnM-m1eC1honZRyfNBWYDYBx23kSdjo,833
2
- freealg/__version__.py,sha256=Plj3sh67uLqQt2X1uejJ0B3ggLdj4Fr1HPHcgyqtneU,22
2
+ freealg/__version__.py,sha256=-wENBv06wDArd9jlfvr1fdogsjPVMgMwskP7VuEz-2A,23
3
3
  freealg/_util.py,sha256=RzccUCORgzrI9NdNqwMVugiHU0uDKkJFcIyjFMUOnv8,2518
4
4
  freealg/_algebraic_form/__init__.py,sha256=MIB_jVgw2qI-JW_ypqaFSeNAB6c4GvpjNySnap_a6hg,398
5
5
  freealg/_algebraic_form/_constraints.py,sha256=37U7nvtCTocuS7l_nfUznkPi195PY7eXFzeiikrv3B0,2448
6
6
  freealg/_algebraic_form/_continuation_algebraic.py,sha256=KundB9VfX61a35VRxLFyuvB5A51QdT4PD2ffAMjrKR0,19383
7
- freealg/_algebraic_form/_decompress.py,sha256=gGtixLOVxlMy5S-NsXgoA7lIrB7u7nUZImQk1mIDo3s,21101
7
+ freealg/_algebraic_form/_decompress.py,sha256=EZ005k_a8wXFsyQZie_N-_hoOvQxj2eV8aUlsNNH7UQ,21102
8
8
  freealg/_algebraic_form/_decompress2.py,sha256=Ng9w9xmGe9M-DApp35IeNeQlvszfzT4NZx5BQn0lQ3I,2459
9
9
  freealg/_algebraic_form/_discriminant.py,sha256=755pproom6-xThFARaH20m4GuBwwZS2rc0Y80Yg6NzY,5331
10
10
  freealg/_algebraic_form/_edge.py,sha256=7l9QyLJDxaEY4WB6MCUFtfEZSf04wyHwH7YPHFJXSbM,10690
11
- freealg/_algebraic_form/_homotopy.py,sha256=LXDd30MNy8BdKr5-_1TCcL1OW74EIhqWWr3JomVSh2M,9532
12
- freealg/_algebraic_form/_moments.py,sha256=5lS0I7dFd15rE00FVi01ferOS77RHJdgLYf5pIzOiaw,12171
11
+ freealg/_algebraic_form/_homotopy.py,sha256=q5z8YmrT_8m7L3qw_4FD1Sd5eELIvAiAHr2ucOLW258,9508
12
+ freealg/_algebraic_form/_moments.py,sha256=u55RpvQhIMJFGsq8LZ3IlnTKxNgQPhwnPuYUS34YEyw,12400
13
13
  freealg/_algebraic_form/_sheets_util.py,sha256=6OLzWQKu-gN8rxM2rbpbN8TjNZFmD8UJ-8t9kcZdkCo,4174
14
- freealg/_algebraic_form/algebraic_form.py,sha256=us0cAzSy2CiESgJ1sse0Cw8n5m1f9VYaQilCHA1Aq3s,30620
14
+ freealg/_algebraic_form/algebraic_form.py,sha256=TXGgTPexOUx_uXhMF9dPA8kk_uNKXoOWn32TYvmCcO8,30677
15
15
  freealg/_free_form/__init__.py,sha256=5cnSX7kHci3wKx6-BEFhmVY_NjjmQAq1JjWPTEqETTg,611
16
16
  freealg/_free_form/_chebyshev.py,sha256=zkyVA8NLf7uUKlJdLz4ijd_SurdsqUgkA5nHGWSybaE,6916
17
17
  freealg/_free_form/_damp.py,sha256=k2vtBtWOxQBf4qXaWu_En81lQBXbEO4QbxxWpvuVhdE,1802
@@ -44,9 +44,9 @@ freealg/distributions/_wigner.py,sha256=epgx6ne6R_7to5j6-QsWIAVFJQFquWMmYgnZYMN4
44
44
  freealg/visualization/__init__.py,sha256=NLq_zwueF7ytZ8sl8zLPqm-AODxxXNvfMozHGmmklcE,435
45
45
  freealg/visualization/_glue_util.py,sha256=2oKnEYjUOS4OZfivmciVLauVr53kyHMwi6c2zRKilTQ,693
46
46
  freealg/visualization/_rgb_hsv.py,sha256=rEskxXxSlKKxIrHRslVkgxHtD010L3ge9YtcVsOPl8E,3650
47
- freealg-0.7.9.dist-info/licenses/AUTHORS.txt,sha256=0b67Nz4_JgIzUupHJTAZxu5QdSUM_HRM_X_w4xCb17o,30
48
- freealg-0.7.9.dist-info/licenses/LICENSE.txt,sha256=J-EEYEtxb3VVf_Bn1TYfWnpY5lMFIM15iLDDcnaDTPA,1443
49
- freealg-0.7.9.dist-info/METADATA,sha256=-Yx24ecrU6zjZ5XgN1HjMQPpGrU9PBrbaXq3idRoKC4,5516
50
- freealg-0.7.9.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
51
- freealg-0.7.9.dist-info/top_level.txt,sha256=eR2wrgYwDdnnJ9Zf5PruPqe4kQav0GMvRsqct6y00Q8,8
52
- freealg-0.7.9.dist-info/RECORD,,
47
+ freealg-0.7.10.dist-info/licenses/AUTHORS.txt,sha256=0b67Nz4_JgIzUupHJTAZxu5QdSUM_HRM_X_w4xCb17o,30
48
+ freealg-0.7.10.dist-info/licenses/LICENSE.txt,sha256=J-EEYEtxb3VVf_Bn1TYfWnpY5lMFIM15iLDDcnaDTPA,1443
49
+ freealg-0.7.10.dist-info/METADATA,sha256=zQjA9ZEsQiqu7ooVnkTrWqcMD7Hg29_Ig0xSxFEG3-Y,5517
50
+ freealg-0.7.10.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
51
+ freealg-0.7.10.dist-info/top_level.txt,sha256=eR2wrgYwDdnnJ9Zf5PruPqe4kQav0GMvRsqct6y00Q8,8
52
+ freealg-0.7.10.dist-info/RECORD,,