freealg 0.4.1__py3-none-any.whl → 0.5.0__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/freeform.py CHANGED
@@ -28,7 +28,7 @@ from ._decompress import decompress
28
28
  from ._sample import qmc_sample
29
29
  from ._support import detect_support
30
30
 
31
- # Fallback to previous API
31
+ # Fallback to previous numpy API
32
32
  if not hasattr(numpy, 'trapezoid'):
33
33
  numpy.trapezoid = numpy.trapz
34
34
 
@@ -142,7 +142,7 @@ class FreeForm(object):
142
142
 
143
143
  self.A = None
144
144
  self.eig = None
145
- self.delta = delta
145
+ self.delta = delta # Offset above real axis to apply Plemelj formula
146
146
 
147
147
  # Eigenvalues
148
148
  if A.ndim == 1:
@@ -167,20 +167,21 @@ class FreeForm(object):
167
167
  self.support = (self.lam_m, self.lam_p)
168
168
 
169
169
  # Initialize
170
- self.method = None
171
- self.psi = None
172
- self.alpha = None
173
- self.beta = None
174
- self._pade_sol = None
170
+ self.method = None # fitting rho: jacobi, chebyshev
171
+ self.continuation = None # analytic continuation: pade, wynn
172
+ self._pade_sol = None # result of pade approximation
173
+ self.psi = None # coefficients of estimating rho
174
+ self.alpha = None # Jacobi polynomials alpha parameter
175
+ self.beta = None # Jacobi polynomials beta parameter
175
176
 
176
177
  # ===
177
178
  # fit
178
179
  # ===
179
180
 
180
181
  def fit(self, method='jacobi', K=10, alpha=0.0, beta=0.0, reg=0.0,
181
- projection='gaussian', kernel_bw=None, damp=None, force=False,
182
- pade_p=0, pade_q=1, odd_side='left', pade_reg=0.0, optimizer='ls',
183
- plot=False, latex=False, save=False):
182
+ projection='gaussian', kernel_bw=0.001, damp=None, force=False,
183
+ continuation='pade', pade_p=0, pade_q=1, odd_side='left',
184
+ pade_reg=0.0, optimizer='ls', plot=False, latex=False, save=False):
184
185
  """
185
186
  Fit model to eigenvalues.
186
187
 
@@ -233,12 +234,22 @@ class FreeForm(object):
233
234
  If `True`, it forces the density to have unit mass and to be
234
235
  strictly positive.
235
236
 
237
+ continuation : {``'pade'``, ``wynn``}, default= ``'pade'``
238
+ Method of analytic continuation to construct the second branch of
239
+ Steltjes transform in the lower-half complex plane:
240
+
241
+ * ``'pade'``: using Reimann-Hilbert problem witth Pade
242
+ approximation.
243
+ * ``'wynn'``: Wynn's epsilon algorithm.
244
+
236
245
  pade_p : int, default=0
237
246
  Degree of polynomial :math:`P(z)` is :math:`q+p` where :math:`p`
238
- can only be ``-1``, ``0``, or ``1``. See notes below.
247
+ can only be ``-1``, ``0``, or ``1``. See notes below. This option
248
+ is applicable if ``continuation='pade'``.
239
249
 
240
250
  pade_q : int, default=1
241
251
  Degree of polynomial :math:`Q(z)` is :math:`q`. See notes below.
252
+ This option is applicable if ``continuation='pade'``.
242
253
 
243
254
  odd_side : {``'left'``, ``'right'``}, default= ``'left'``
244
255
  In case of odd number of poles (when :math:`q` is odd), the extra
@@ -246,10 +257,12 @@ class FreeForm(object):
246
257
  while all other poles are split in half to the left and right. Note
247
258
  that this is only for the initialization of the poles. The
248
259
  optimizer will decide best location by moving them to the left or
249
- right of the support.
260
+ right of the support. This option is applicable if
261
+ ``continuation='pade'``.
250
262
 
251
263
  pade_reg : float, default=0.0
252
- Regularization for Pade approximation.
264
+ Regularization for Pade approximation. This option is applicable if
265
+ ``continuation='pade'``.
253
266
 
254
267
  optimizer : {``'ls'``, ``'de'``}, default= ``'ls'``
255
268
  Optimizer for Pade approximation, including:
@@ -257,9 +270,11 @@ class FreeForm(object):
257
270
  * ``'ls'``: least square (local, fast)
258
271
  * ``'de'``: differential evolution (global, slow)
259
272
 
273
+ This option is applicable if ``continuation='pade'``.
274
+
260
275
  plot : bool, default=False
261
276
  If `True`, the approximation coefficients and Pade approximation to
262
- the Hilbert transform are plotted.
277
+ the Hilbert transform (if applicable) are plotted.
263
278
 
264
279
  latex : bool, default=False
265
280
  If `True`, the plot is rendered using LaTeX. This option is
@@ -332,7 +347,6 @@ class FreeForm(object):
332
347
  # adaptive=True)
333
348
  # pdf = k.evaluate(xs)
334
349
 
335
- # TEST
336
350
  # import matplotlib.pyplot as plt
337
351
  # plt.plot(xs, pdf)
338
352
  # plt.grid(True)
@@ -365,7 +379,7 @@ class FreeForm(object):
365
379
  psi = chebyshev_kernel_proj(xs, pdf, support=self.support,
366
380
  K=K, reg=reg)
367
381
  else:
368
- raise ValueError('"method" is invalid.')
382
+ raise NotImplementedError('"method" is invalid.')
369
383
 
370
384
  # Damping
371
385
  if damp is not None:
@@ -404,8 +418,14 @@ class FreeForm(object):
404
418
  self.alpha = alpha
405
419
  self.beta = beta
406
420
 
407
- # Fit a pade approximation
408
- if method != 'chebyshev' or projection != 'sample':
421
+ # Analytic continuation
422
+ if continuation not in ['pade', 'wynn']:
423
+ raise NotImplementedError('"continuation" method is invalid.')
424
+
425
+ self.continuation = continuation
426
+
427
+ if self.continuation == 'pade':
428
+
409
429
  # For holomorphic continuation for the lower half-plane
410
430
  x_supp = numpy.linspace(self.lam_m, self.lam_p, 1000)
411
431
  g_supp = 2.0 * numpy.pi * self.hilbert(x_supp)
@@ -414,21 +434,36 @@ class FreeForm(object):
414
434
  pade_reg=pade_reg, safety=1.0,
415
435
  max_outer=40, xtol=1e-12, ftol=1e-12,
416
436
  optimizer=optimizer, verbose=0)
437
+ else:
438
+ # Do nothing. Make sure _pade_sol is still None
439
+ self._pade_sol = None
440
+
441
+ if method != 'chebyshev':
442
+ raise NotImplementedError(
443
+ 'Up to the current version, the analytic continuation ' +
444
+ 'using "wynn" is only implemented for "chebyshev" ' +
445
+ 'estimation method.')
417
446
 
418
447
  if plot:
419
- g_supp_approx = eval_pade(x_supp[None, :], self._pade_sol)[0, :]
448
+ if self._pade_sol is not None:
449
+ g_supp_approx = eval_pade(x_supp[None, :],
450
+ self._pade_sol)[0, :]
451
+ else:
452
+ x_supp = None
453
+ g_supp = None
454
+ g_supp_approx = None
420
455
  plot_fit(psi, x_supp, g_supp, g_supp_approx, support=self.support,
421
456
  latex=latex, save=save)
422
457
 
423
458
  return self.psi
424
459
 
425
- # =======
426
- # density
427
- # =======
460
+ # =============
461
+ # generate grid
462
+ # =============
428
463
 
429
- def _grid(self, scale, extend=1.0, N=500):
464
+ def _generate_grid(self, scale, extend=1.0, N=500):
430
465
  """
431
- Return a grid of points to evaluate density / Hilbert / Stieltjes
466
+ Generate a grid of points to evaluate density / Hilbert / Stieltjes
432
467
  transforms.
433
468
  """
434
469
 
@@ -490,12 +525,12 @@ class FreeForm(object):
490
525
  """
491
526
 
492
527
  if self.psi is None:
493
- raise RuntimeError('The spectral density needs to be fit using ' +
494
- 'the .fit() function.')
528
+ raise RuntimeError('The model needs to be fit using the .fit() ' +
529
+ 'function.')
495
530
 
496
531
  # Create x if not given
497
532
  if x is None:
498
- x = self._grid(1.25)
533
+ x = self._generate_grid(1.25)
499
534
 
500
535
  # Preallocate density to zero
501
536
  rho = numpy.zeros_like(x)
@@ -580,12 +615,12 @@ class FreeForm(object):
580
615
  """
581
616
 
582
617
  if self.psi is None:
583
- raise RuntimeError('The spectral density needs to be fit using ' +
584
- 'the .fit() function.')
618
+ raise RuntimeError('The model needs to be fit using the .fit() ' +
619
+ 'function.')
585
620
 
586
621
  # Create x if not given
587
622
  if x is None:
588
- x = self._grid(1.25)
623
+ x = self._generate_grid(1.25)
589
624
 
590
625
  # if (numpy.min(x) > self.lam_m) or (numpy.max(x) < self.lam_p):
591
626
  # raise ValueError('"x" does not encompass support interval.')
@@ -626,10 +661,23 @@ class FreeForm(object):
626
661
  # ====
627
662
 
628
663
  def _glue(self, z):
629
- # Glue function
664
+ """
665
+ Glue function.
666
+
667
+ Notes
668
+ -----
669
+
670
+ This function needs self._pade_sol to be initialized in .fit()
671
+ function. This only works when continuation method is set to "pade".
672
+ """
673
+
630
674
  if self._pade_sol is None:
631
- return numpy.zeros_like(z)
675
+ raise RuntimeError('"_glue" is called but "_pade_sol" is not' +
676
+ 'initialized. This is likely a ' +
677
+ 'development bug.')
678
+
632
679
  g = eval_pade(z, self._pade_sol)
680
+
633
681
  return g
634
682
 
635
683
  # =========
@@ -700,30 +748,25 @@ class FreeForm(object):
700
748
  """
701
749
 
702
750
  if self.psi is None:
703
- raise RuntimeError('The spectral density needs to be fit using ' +
704
- 'the .fit() function.')
705
-
706
- # Determine whether the Stieltjes transform is to be computed on a
707
- # Cartesian grid
708
- cartesian = plot | (y is not None)
751
+ raise RuntimeError('The model needs to be fit using the .fit() ' +
752
+ 'function.')
709
753
 
710
754
  # Create x if not given
711
755
  if x is None:
712
- x = self._grid(2.0, extend=2.0)
713
-
714
- if not cartesian:
715
- # Evaluate slightly above the real line
716
- x = x.astype(complex)
717
- x += self.delta * 1j
756
+ x = self._generate_grid(2.0, extend=2.0)
718
757
 
719
758
  # Create y if not given
720
- if cartesian:
759
+ if (plot is False) and (y is None):
760
+ # Do no tuse a Cartesian grid. Create a 1D array z slightly above
761
+ # the real line.
762
+ y = self.delta * 1j
763
+ z = x.astype(complex) + y # shape (Nx,)
764
+ else:
765
+ # Use a Cartesian grid
721
766
  if y is None:
722
767
  y = numpy.linspace(-1, 1, 400)
723
768
  x_grid, y_grid = numpy.meshgrid(x.real, y.real)
724
769
  z = x_grid + 1j * y_grid # shape (Ny, Nx)
725
- else:
726
- z = x
727
770
 
728
771
  m1, m2 = self._eval_stieltjes(z, branches=True)
729
772
 
@@ -752,7 +795,6 @@ class FreeForm(object):
752
795
  transform. The default ``branches=False`` will return only
753
796
  the secondary branch.
754
797
 
755
-
756
798
  Returns
757
799
  -------
758
800
 
@@ -764,7 +806,8 @@ class FreeForm(object):
764
806
  The Stieltjes transform continued to the secondary branch.
765
807
  """
766
808
 
767
- assert self.psi is not None, "The fit function has not been called."
809
+ if self.psi is None:
810
+ raise RuntimeError('"fit" the model first.')
768
811
 
769
812
  # Allow for arbitrary input shapes
770
813
  z = numpy.asarray(z)
@@ -783,9 +826,17 @@ class FreeForm(object):
783
826
  stieltjes = partial(jacobi_stieltjes, psi=self.psi,
784
827
  support=self.support, alpha=self.alpha,
785
828
  beta=self.beta) # n_base = n_base
829
+
786
830
  elif self.method == 'chebyshev':
831
+
832
+ if self.continuation == 'wynn':
833
+ use_wynn_epsilon = True
834
+ else:
835
+ use_wynn_epsilon = False
836
+
787
837
  stieltjes = partial(chebyshev_stieltjes, psi=self.psi,
788
- support=self.support)
838
+ support=self.support,
839
+ use_wynn_epsilon=use_wynn_epsilon)
789
840
 
790
841
  mask_p = z.imag >= 0.0
791
842
  mask_m = z.imag < 0.0
@@ -793,7 +844,7 @@ class FreeForm(object):
793
844
  m1 = numpy.zeros_like(z)
794
845
  m2 = numpy.zeros_like(z)
795
846
 
796
- if self._pade_sol is not None:
847
+ if self.continuation == 'pade':
797
848
  # Upper half-plane
798
849
  m1[mask_p] = stieltjes(z[mask_p].reshape(-1, 1)).ravel()
799
850
 
@@ -806,47 +857,55 @@ class FreeForm(object):
806
857
  m2[mask_m] = -m1[mask_m] + self._glue(
807
858
  z[mask_m].reshape(-1, 1)).ravel()
808
859
 
809
- else:
860
+ elif self.continuation == 'wynn':
810
861
  m2[:] = stieltjes(z.reshape(-1, 1)).reshape(*m2.shape)
811
862
  if branches:
812
863
  m1[mask_p] = m2[mask_p]
813
- m1[mask_m] = numpy.conjugate(
814
- stieltjes(numpy.conjugate(z[mask_m].reshape(-1, 1)))
815
- ).ravel()
864
+ z_conj = numpy.conjugate(z[mask_m].reshape(-1, 1))
865
+ m1[mask_m] = numpy.conjugate(stieltjes(z_conj)).ravel()
866
+
867
+ else:
868
+ raise NotImplementedError('Invalid continuation method.')
816
869
 
817
870
  if not branches:
818
871
  return m2.reshape(*shape)
819
872
  else:
820
- m1, m2 = m1.reshape(*shape), m2.reshape(*shape)
873
+ m1 = m1.reshape(*shape)
874
+ m2 = m2.reshape(*shape)
821
875
  return m1, m2
822
876
 
823
877
  # ==========
824
878
  # decompress
825
879
  # ==========
826
880
 
827
- def decompress(self, size, x=None, max_iter=500, eigvals=True,
828
- tolerance=1e-9, plot=False,
829
- latex=False, save=False):
881
+ def decompress(self, size, x=None, method='newton', max_iter=500,
882
+ step_size=0.1, tolerance=1e-4, plot=False, latex=False,
883
+ save=False, plot_diagnostics=False):
830
884
  """
831
885
  Free decompression of spectral density.
832
886
 
833
887
  Parameters
834
888
  ----------
835
889
 
836
- size : int
837
- Size of the decompressed matrix.
890
+ size : int or array_like
891
+ Size(s) of the decompressed matrix. This can be a scalar or an
892
+ array of sizes. For each matrix size in ``size`` array, a density
893
+ is produced.
838
894
 
839
895
  x : numpy.array, default=None
840
896
  Positions where density to be evaluated at. If `None`, an interval
841
897
  slightly larger than the support interval will be used.
842
898
 
899
+ method : {``'newton'``, ``'secant'``}, default= ``'newton'``
900
+ Root-finding method.
901
+
843
902
  max_iter: int, default=500
844
- Maximum number of secant method iterations.
903
+ Maximum number of root-finding method iterations.
845
904
 
846
- eigvals: bool, default=True
847
- Return estimated (sampled) eigenvalues as well as the density.
905
+ step_size: float, default=0.1
906
+ Step size for Newton iterations.
848
907
 
849
- tolerance: float, default=1e-9
908
+ tolerance: float, default=1e-4
850
909
  Tolerance for the solution obtained by the Newton solver. Also
851
910
  used for the finite difference approximation to the derivative.
852
911
 
@@ -862,18 +921,25 @@ class FreeForm(object):
862
921
  assumed to the save filename (with the file extension). This option
863
922
  is relevant only if ``plot=True``.
864
923
 
924
+ plot_diagnostics : bool, default=False
925
+ Plots diagnostics including convergence and number of iterations
926
+ of root finding method.
927
+
865
928
  Returns
866
929
  -------
867
930
 
868
- x : numpy.array
869
- Locations where the spectral density is estimated
931
+ rho : numpy.array or numpy.ndarray
932
+ Estimated spectral density at locations x. ``rho`` can be a 1D or
933
+ 2D array output:
870
934
 
871
- rho : numpy.array
872
- Estimated spectral density at locations x
935
+ * If ``size`` is a scalar, ``rho`` is a 1D array od the same size
936
+ as ``x``.
937
+ * If ``size`` is an array of size `n`, ``rho`` is a 2D array with
938
+ `n` rows, where each row corresponds to decompression to a size.
939
+ Number of columns of ``rho`` is the same as the size of ``x``.
873
940
 
874
- eigs : numpy.array
875
- Estimated eigenvalues as low-discrepancy samples of the estimated
876
- spectral density. Only returns if ``eigvals=True``.
941
+ x : numpy.array
942
+ Locations where the spectral density is estimated
877
943
 
878
944
  See Also
879
945
  --------
@@ -899,17 +965,69 @@ class FreeForm(object):
899
965
  >>> from freealg import FreeForm
900
966
  """
901
967
 
902
- size = int(size)
968
+ # Check size argument
969
+ if numpy.isscalar(size):
970
+ size = int(size)
971
+ else:
972
+ # Check monotonic increment (either all increasing or decreasing)
973
+ diff = numpy.diff(size)
974
+ if not (numpy.all(diff >= 0) or numpy.all(diff <= 0)):
975
+ raise ValueError('"size" increment should be monotonic.')
976
+
977
+ # Decompression ratio equal to e^{t}.
978
+ alpha = numpy.atleast_1d(size) / self.n
903
979
 
904
- rho, x, (lb, ub) = decompress(self, size, x=x, delta=self.delta,
905
- max_iter=max_iter, tolerance=tolerance)
906
- x, rho = x.ravel(), rho.ravel()
980
+ # Lower and upper bound on new support
981
+ m = self._eval_stieltjes
982
+ hilb_lb = (1.0 / m(self.lam_m + self.delta * 1j).item()).real
983
+ hilb_ub = (1.0 / m(self.lam_p + self.delta * 1j).item()).real
984
+ lb = self.lam_m - (numpy.max(alpha) - 1) * hilb_lb
985
+ ub = self.lam_p - (numpy.max(alpha) - 1) * hilb_ub
907
986
 
987
+ # Create x if not given
988
+ if x is None:
989
+ radius = 0.5 * (ub - lb)
990
+ center = 0.5 * (ub + lb)
991
+ scale = 1.25
992
+ x_min = numpy.floor(center - radius * scale)
993
+ x_max = numpy.ceil(center + radius * scale)
994
+ x = numpy.linspace(x_min, x_max, 500)
995
+ else:
996
+ x = numpy.asarray(x)
997
+
998
+ if (alpha.size > 8) and plot_diagnostics:
999
+ raise RuntimeError(
1000
+ 'Too many diagnostic plots for %d sizes.' % alpha.size)
1001
+
1002
+ # Decompress to each alpha
1003
+ rho = numpy.zeros((alpha.size, x.size), dtype=float)
1004
+ for i in range(alpha.size):
1005
+
1006
+ # Initial guess for roots (only for the first iteration)
1007
+ # if i == 0:
1008
+ # roots = numpy.full(x.shape, numpy.mean(self.support) - 0.1j,
1009
+ # dtype=numpy.complex128)
1010
+ roots = None
1011
+
1012
+ rho[i, :], roots = decompress(
1013
+ self, alpha[i], x, roots_init=roots, method=method,
1014
+ delta=self.delta, max_iter=max_iter, step_size=step_size,
1015
+ tolerance=tolerance, plot_diagnostics=plot_diagnostics)
1016
+
1017
+ # If the input size was only a scalar, return a 1D rho, otherwise 2D.
1018
+ if numpy.isscalar(size):
1019
+ rho = numpy.squeeze(rho)
1020
+
1021
+ # Plot only the last size
908
1022
  if plot:
909
- plot_density(x, rho, support=(lb, ub),
1023
+ if numpy.isscalar(size):
1024
+ rho_last = rho
1025
+ else:
1026
+ rho_last = rho[-1, :]
1027
+ plot_density(x, rho_last, support=(lb, ub),
910
1028
  label='Decompression', latex=latex, save=save)
911
1029
 
912
- return x, rho
1030
+ return rho, x
913
1031
 
914
1032
  # ========
915
1033
  # eigvalsh
@@ -964,12 +1082,11 @@ class FreeForm(object):
964
1082
  """
965
1083
 
966
1084
  if size is None:
967
- x = self._grid(1.25)
968
- rho = self.density(x)
969
1085
  size = self.n
970
- else:
971
- x, rho = self.decompress(size, **kwargs)
1086
+
1087
+ rho, x = self.decompress(size, **kwargs)
972
1088
  eigs = numpy.sort(qmc_sample(x, rho, size, seed=seed))
1089
+
973
1090
  return eigs
974
1091
 
975
1092
  # ====
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: freealg
3
- Version: 0.4.1
3
+ Version: 0.5.0
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
@@ -0,0 +1,26 @@
1
+ freealg/__init__.py,sha256=KfzqG7qig6ZZCKqgHcC2ApTg4rTLkrbJsvVoJd8UFG8,625
2
+ freealg/__version__.py,sha256=LBK46heutvn3KmsCrKIYu8RQikbfnjZaj2xFrXaeCzQ,22
3
+ freealg/_chebyshev.py,sha256=-XiMKPra9pjkvMLjLusPo8n4NfjcJd9K0tAm5TF8PdA,6311
4
+ freealg/_damp.py,sha256=k2vtBtWOxQBf4qXaWu_En81lQBXbEO4QbxxWpvuVhdE,1802
5
+ freealg/_decompress.py,sha256=RKYnuLKMx1V6-XrFjYX1UkGMRbUD9Gmf9XTyS4ffPSc,31970
6
+ freealg/_jacobi.py,sha256=AT4ONSHGGDxVKE3MGMLyMR8uDFiO-e9u3x5udYfdJJk,5635
7
+ freealg/_linalg.py,sha256=khfRwdQIDtf45aOIq3QSeihAEtUCL-HgwEYtEs0YELc,13137
8
+ freealg/_pade.py,sha256=Ecm373RvBWznAaf8a5D9qtjcRA8O_8NQsePwto-dsP4,13656
9
+ freealg/_plot_util.py,sha256=mkvOZJDXCxIo8jUZoS8gsSDgieMCL8oZNZEo_-mYreQ,20052
10
+ freealg/_sample.py,sha256=MUY9ZkJbdhbC5thoy5_JMRWOHz_OfqMfaH0g2VhKPhg,2550
11
+ freealg/_series.py,sha256=x0_NNaNjv-_FSAnZzlp8BO5XI5q8ELF_kwnGlAUBZZg,2603
12
+ freealg/_support.py,sha256=ZfU0T7CCDaTXMdEHSbwOL-rMnCPvJWsRb6JtqUMsrzY,6441
13
+ freealg/_util.py,sha256=yerqBCedkglc9soWmRgxcm7HTnJGKeiDq9xxfKcE9WY,3780
14
+ freealg/freeform.py,sha256=zkjkkMkvCTn25k8QvefrvNBaGYQhIkPLBiV_Ij01l04,42286
15
+ freealg/distributions/__init__.py,sha256=t_yZyEkW_W_tSV9IvgYXtVASxD2BEdiNVXcV2ebMy8M,579
16
+ freealg/distributions/_kesten_mckay.py,sha256=4EvW0seBZUv-cZjuLzfVCredmrCiOJcQ_hJM0mJDl6g,19899
17
+ freealg/distributions/_marchenko_pastur.py,sha256=r-jmz8Wq5vG0-x7rB0qvVemqvu0Oq6S-BN67pqH0uiw,16992
18
+ freealg/distributions/_meixner.py,sha256=bZv-x4mwS4yjisKoYSZAffHXtvDEKEis-74BeAjK4_s,17530
19
+ freealg/distributions/_wachter.py,sha256=rkAmrBLqD2zvpBh0F32aQBscjXv8earXDH9_BITgFF0,16900
20
+ freealg/distributions/_wigner.py,sha256=w8OlZL9pSfGnXVSSB6A4KBiImr0Zz4iH2PDLCHFfpaY,15877
21
+ freealg-0.5.0.dist-info/licenses/AUTHORS.txt,sha256=0b67Nz4_JgIzUupHJTAZxu5QdSUM_HRM_X_w4xCb17o,30
22
+ freealg-0.5.0.dist-info/licenses/LICENSE.txt,sha256=J-EEYEtxb3VVf_Bn1TYfWnpY5lMFIM15iLDDcnaDTPA,1443
23
+ freealg-0.5.0.dist-info/METADATA,sha256=rKSfjasqwCCzpGbqmdfjs4y0jezvH6ylKDv_tEL4xZM,5529
24
+ freealg-0.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
+ freealg-0.5.0.dist-info/top_level.txt,sha256=eR2wrgYwDdnnJ9Zf5PruPqe4kQav0GMvRsqct6y00Q8,8
26
+ freealg-0.5.0.dist-info/RECORD,,
@@ -1,25 +0,0 @@
1
- freealg/__init__.py,sha256=KfzqG7qig6ZZCKqgHcC2ApTg4rTLkrbJsvVoJd8UFG8,625
2
- freealg/__version__.py,sha256=pMtTmSUht-XtbR_7Doz6bsQqopJJd8rZ8I8zy2HwwoA,22
3
- freealg/_chebyshev.py,sha256=dsAj3YEpmkzB65smluZ0Fi5IZSdpnQXBSIuKMg19grA,5523
4
- freealg/_damp.py,sha256=k2vtBtWOxQBf4qXaWu_En81lQBXbEO4QbxxWpvuVhdE,1802
5
- freealg/_decompress.py,sha256=0MYoO3lqwMgNYlVriaRNUqUwY3XYyZZsDAtNRBq6rhE,10470
6
- freealg/_jacobi.py,sha256=AT4ONSHGGDxVKE3MGMLyMR8uDFiO-e9u3x5udYfdJJk,5635
7
- freealg/_linalg.py,sha256=Vl1iB0rG-PVjEqoUbCXNxk6BmeujEbBucG2ZdBJoFjA,12490
8
- freealg/_pade.py,sha256=Diw850oH2OLQeUrBR-q19TmjSBoBvXl6ogp4o1s2UIo,15184
9
- freealg/_plot_util.py,sha256=U4alp7Pzg315_7jJdu1UB0tIUcxUovQgHDHsUYoa2Z0,19728
10
- freealg/_sample.py,sha256=ckC75eqv-mRP1F5BnhvsjfLTaoAzHK8bebl9bCRZYDo,2561
11
- freealg/_support.py,sha256=mYlrsdLbniqFgFofbHrZIiYSyJudPqtyMQQTPBD9Y6M,6439
12
- freealg/_util.py,sha256=8Tvz-XODtKYoU76ODmF1TBaIYLlr6-AXiyoMDwDSxVg,3779
13
- freealg/freeform.py,sha256=3_zAlmLbhwrmJrLqsghTUQQbJ9H0u7DI1fjdF84Sk_M,37145
14
- freealg/distributions/__init__.py,sha256=t_yZyEkW_W_tSV9IvgYXtVASxD2BEdiNVXcV2ebMy8M,579
15
- freealg/distributions/_kesten_mckay.py,sha256=210RF2OQEYLZBeLB6wmbdHnZPs_9ldDNHm_FMlg5tis,19881
16
- freealg/distributions/_marchenko_pastur.py,sha256=kchFccRMuVF2Cus_99vdEwuRimkHzEUV8xt5kZFg7ZI,16994
17
- freealg/distributions/_meixner.py,sha256=ws7t_EUa7V0s97dgMQIJLv1b6qMLqf9fLLbTJQudf_8,17512
18
- freealg/distributions/_wachter.py,sha256=Hna_MXqAPjuRkeilLPMf4Xg_3C6tTu5oZLEQnA-RuE4,16897
19
- freealg/distributions/_wigner.py,sha256=SxgPLtvIVBi9m4De-oBD0x6-2Je_eBqpDrpDYcoLuis,15871
20
- freealg-0.4.1.dist-info/licenses/AUTHORS.txt,sha256=0b67Nz4_JgIzUupHJTAZxu5QdSUM_HRM_X_w4xCb17o,30
21
- freealg-0.4.1.dist-info/licenses/LICENSE.txt,sha256=J-EEYEtxb3VVf_Bn1TYfWnpY5lMFIM15iLDDcnaDTPA,1443
22
- freealg-0.4.1.dist-info/METADATA,sha256=wN2_XUZz2mEfjMROOLmGY8-0xtflEKY40gL5RZBTElQ,5529
23
- freealg-0.4.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
24
- freealg-0.4.1.dist-info/top_level.txt,sha256=eR2wrgYwDdnnJ9Zf5PruPqe4kQav0GMvRsqct6y00Q8,8
25
- freealg-0.4.1.dist-info/RECORD,,