freealg 0.1.6__py3-none-any.whl → 0.1.7__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/_plot_util.py +1 -37
- freealg/distributions/__init__.py +2 -3
- freealg/distributions/kesten_mckay.py +8 -8
- freealg/distributions/meixner.py +584 -0
- freealg/distributions/wachter.py +11 -8
- freealg/distributions/wigner.py +4 -4
- freealg/freeform.py +2 -9
- {freealg-0.1.6.dist-info → freealg-0.1.7.dist-info}/METADATA +2 -1
- freealg-0.1.7.dist-info/RECORD +23 -0
- freealg-0.1.7.dist-info/licenses/AUTHORS.txt +2 -0
- freealg-0.1.6.dist-info/RECORD +0 -21
- {freealg-0.1.6.dist-info → freealg-0.1.7.dist-info}/WHEEL +0 -0
- {freealg-0.1.6.dist-info → freealg-0.1.7.dist-info}/licenses/LICENSE.txt +0 -0
- {freealg-0.1.6.dist-info → freealg-0.1.7.dist-info}/top_level.txt +0 -0
freealg/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.7"
|
freealg/_plot_util.py
CHANGED
|
@@ -18,7 +18,6 @@ import matplotlib
|
|
|
18
18
|
import colorsys
|
|
19
19
|
import matplotlib.ticker as ticker
|
|
20
20
|
import matplotlib.gridspec as gridspec
|
|
21
|
-
from ._decompress import reverse_characteristics
|
|
22
21
|
|
|
23
22
|
__all__ = ['plot_fit', 'plot_density', 'plot_hilbert', 'plot_stieltjes',
|
|
24
23
|
'plot_stieltjes_on_disk']
|
|
@@ -244,42 +243,11 @@ def _value_formatter(v, pos):
|
|
|
244
243
|
return f"{m_val:.1f}"
|
|
245
244
|
|
|
246
245
|
|
|
247
|
-
# ================
|
|
248
|
-
# plot char curves
|
|
249
|
-
# ================
|
|
250
|
-
def _plot_char_curves(ax, char_curves):
|
|
251
|
-
"""
|
|
252
|
-
"""
|
|
253
|
-
|
|
254
|
-
curves = reverse_characteristics(char_curves['matrix'],
|
|
255
|
-
char_curves['z'], 4)
|
|
256
|
-
lw = 2
|
|
257
|
-
for idx in range(curves.shape[1]):
|
|
258
|
-
|
|
259
|
-
creal, cimag = curves[:, idx].real, curves[:, idx].imag
|
|
260
|
-
|
|
261
|
-
ax.plot(creal, cimag, ':', color='white', linewidth=lw,
|
|
262
|
-
alpha=0.75)
|
|
263
|
-
|
|
264
|
-
ax.annotate(
|
|
265
|
-
'', # no text
|
|
266
|
-
xy=(creal[-1], cimag[-1]), # arrow tip at final point
|
|
267
|
-
xytext=(creal[-2], cimag[-2]), # tail at penultimate point
|
|
268
|
-
arrowprops=dict(
|
|
269
|
-
arrowstyle='-|>', # simple arrow head
|
|
270
|
-
mutation_scale=5, # size of the head
|
|
271
|
-
color='white',
|
|
272
|
-
lw=lw, alpha=0.75, # arrow shaft line width
|
|
273
|
-
)
|
|
274
|
-
)
|
|
275
|
-
|
|
276
|
-
|
|
277
246
|
# ==============
|
|
278
247
|
# plot stieltjes
|
|
279
248
|
# ==============
|
|
280
249
|
|
|
281
|
-
def plot_stieltjes(x, y, m1, m2, support, latex=False,
|
|
282
|
-
save=False):
|
|
250
|
+
def plot_stieltjes(x, y, m1, m2, support, latex=False, save=False):
|
|
283
251
|
"""
|
|
284
252
|
"""
|
|
285
253
|
|
|
@@ -329,10 +297,6 @@ def plot_stieltjes(x, y, m1, m2, support, latex=False, char_curves=None,
|
|
|
329
297
|
ax1.set_xlim([x_min, x_max])
|
|
330
298
|
ax1.set_ylim([y_min, y_max])
|
|
331
299
|
|
|
332
|
-
# Plot characteristic curves
|
|
333
|
-
if char_curves is not None:
|
|
334
|
-
_plot_char_curves(ax1, char_curves)
|
|
335
|
-
|
|
336
300
|
pos = ax1.get_position()
|
|
337
301
|
cbar_width = 0.013
|
|
338
302
|
pad = 0.013
|
|
@@ -10,7 +10,6 @@ from .marchenko_pastur import MarchenkoPastur
|
|
|
10
10
|
from .wigner import Wigner
|
|
11
11
|
from .kesten_mckay import KestenMcKay
|
|
12
12
|
from .wachter import Wachter
|
|
13
|
-
|
|
13
|
+
from .meixner import Meixner
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
__all__ = ['MarchenkoPastur', 'Wigner', 'KestenMcKay', 'Wachter']
|
|
15
|
+
__all__ = ['MarchenkoPastur', 'Wigner', 'KestenMcKay', 'Wachter', 'Meixner']
|
|
@@ -61,7 +61,7 @@ class KestenMcKay(object):
|
|
|
61
61
|
Notes
|
|
62
62
|
-----
|
|
63
63
|
|
|
64
|
-
The
|
|
64
|
+
The Kesten-McKay distribution has the absolutely-continuous density
|
|
65
65
|
|
|
66
66
|
.. math::
|
|
67
67
|
|
|
@@ -236,10 +236,10 @@ class KestenMcKay(object):
|
|
|
236
236
|
x = numpy.linspace(x_min, x_max, 500)
|
|
237
237
|
|
|
238
238
|
def _P(x):
|
|
239
|
-
return (self.d - 2.0) * x
|
|
239
|
+
return (self.d - 2.0) * x / (self.d - 1.0)
|
|
240
240
|
|
|
241
241
|
def _Q(x):
|
|
242
|
-
return self.d**2 - x**2
|
|
242
|
+
return (self.d**2 - x**2) / (self.d - 1.0)
|
|
243
243
|
|
|
244
244
|
P = _P(x)
|
|
245
245
|
Q = _Q(x)
|
|
@@ -262,15 +262,15 @@ class KestenMcKay(object):
|
|
|
262
262
|
|
|
263
263
|
def _m_mp_numeric_vectorized(self, z, alt_branch=False, tol=1e-8):
|
|
264
264
|
"""
|
|
265
|
-
Stieltjes transform (principal or secondary branch)
|
|
266
|
-
|
|
265
|
+
Stieltjes transform (principal or secondary branch) for Kesten-McKay
|
|
266
|
+
distribution on upper half-plane.
|
|
267
267
|
"""
|
|
268
268
|
|
|
269
269
|
m = numpy.empty_like(z, dtype=complex)
|
|
270
270
|
|
|
271
271
|
sign = -1 if alt_branch else 1
|
|
272
|
-
A = self.d**2 - z**2
|
|
273
|
-
B = (self.d - 2.0) * z
|
|
272
|
+
A = (self.d**2 - z**2) / (self.d - 1.0)
|
|
273
|
+
B = ((self.d - 2.0) * z) / (self.d - 1.0)
|
|
274
274
|
D = B**2 - 4 * A
|
|
275
275
|
sqrtD = numpy.sqrt(D)
|
|
276
276
|
m1 = (-B + sqrtD) / (2 * A)
|
|
@@ -370,7 +370,7 @@ class KestenMcKay(object):
|
|
|
370
370
|
|
|
371
371
|
.. code-block:: python
|
|
372
372
|
|
|
373
|
-
>>> m1, m2 =
|
|
373
|
+
>>> m1, m2 = km.stieltjes(plot=True, on_disk=True)
|
|
374
374
|
|
|
375
375
|
.. image:: ../_static/images/plots/km_stieltjes_disk.png
|
|
376
376
|
:align: center
|
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright 2025, Siavash Ameli <sameli@berkeley.edu>
|
|
2
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
3
|
+
# SPDX-FileType: SOURCE
|
|
4
|
+
#
|
|
5
|
+
# This program is free software: you can redistribute it and/or modify it
|
|
6
|
+
# under the terms of the license found in the LICENSE.txt file in the root
|
|
7
|
+
# directory of this source tree.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# =======
|
|
11
|
+
# Imports
|
|
12
|
+
# =======
|
|
13
|
+
|
|
14
|
+
import numpy
|
|
15
|
+
from scipy.interpolate import interp1d
|
|
16
|
+
from .._plot_util import plot_density, plot_hilbert, plot_stieltjes, \
|
|
17
|
+
plot_stieltjes_on_disk, plot_samples
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
from scipy.integrate import cumtrapz
|
|
21
|
+
except ImportError:
|
|
22
|
+
from scipy.integrate import cumulative_trapezoid as cumtrapz
|
|
23
|
+
from scipy.stats import qmc
|
|
24
|
+
|
|
25
|
+
__all__ = ['Meixner']
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# =======
|
|
29
|
+
# Meixner
|
|
30
|
+
# =======
|
|
31
|
+
|
|
32
|
+
class Meixner(object):
|
|
33
|
+
"""
|
|
34
|
+
Meixner distribution.
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
|
|
39
|
+
a : float
|
|
40
|
+
Parameter :math:`a` of the distribution. See Notes.
|
|
41
|
+
|
|
42
|
+
b : float
|
|
43
|
+
Parameter :math:`b` of the distribution. See Notes.
|
|
44
|
+
|
|
45
|
+
Methods
|
|
46
|
+
-------
|
|
47
|
+
|
|
48
|
+
density
|
|
49
|
+
Spectral density of distribution.
|
|
50
|
+
|
|
51
|
+
hilbert
|
|
52
|
+
Hilbert transform of distribution.
|
|
53
|
+
|
|
54
|
+
stieltjes
|
|
55
|
+
Stieltjes transform of distribution.
|
|
56
|
+
|
|
57
|
+
sample
|
|
58
|
+
Sample from distribution.
|
|
59
|
+
|
|
60
|
+
matrix
|
|
61
|
+
Generate matrix with its empirical spectral density of distribution
|
|
62
|
+
|
|
63
|
+
Notes
|
|
64
|
+
-----
|
|
65
|
+
|
|
66
|
+
The Meixner distribution has the absolutely-continuous density
|
|
67
|
+
|
|
68
|
+
.. math::
|
|
69
|
+
|
|
70
|
+
\\mathrm{d} \\rho(x) =
|
|
71
|
+
\\frac{4(1+b) - (x-a)^2}{2 \\pi (b x^2 + a x + 1)}
|
|
72
|
+
\\mathbf{1}_{x \\in [\\lambda_{-}, \\lambda_{+}]} \\mathrm{d}{x}
|
|
73
|
+
|
|
74
|
+
where :math:`a, b` are the shape parameters of the distributon. The edges
|
|
75
|
+
of the support are
|
|
76
|
+
|
|
77
|
+
.. math::
|
|
78
|
+
|
|
79
|
+
\\lambda_{\\pm} = a \\pm 2 \\sqrt{1 + b}.
|
|
80
|
+
|
|
81
|
+
References
|
|
82
|
+
----------
|
|
83
|
+
|
|
84
|
+
.. [1] Saitoh, N. & Yosnida, M. (2001). The infinite divisibility and
|
|
85
|
+
orthogonal polynomials with a constant recursion formula in free
|
|
86
|
+
probability theory. Probab. Math. Statist., 21, 159–170.
|
|
87
|
+
|
|
88
|
+
Examples
|
|
89
|
+
--------
|
|
90
|
+
|
|
91
|
+
.. code-block:: python
|
|
92
|
+
|
|
93
|
+
>>> from freealg.distributions import Meixner
|
|
94
|
+
>>> mx = Meixner(2, 3)
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
# ====
|
|
98
|
+
# init
|
|
99
|
+
# ====
|
|
100
|
+
|
|
101
|
+
def __init__(self, a, b):
|
|
102
|
+
"""
|
|
103
|
+
Initialization.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
self.a = a
|
|
107
|
+
self.b = b
|
|
108
|
+
self.lam_p = self.a + 2.0 * numpy.sqrt(1.0 + self.b)
|
|
109
|
+
self.lam_m = self.a - 2.0 * numpy.sqrt(1.0 + self.b)
|
|
110
|
+
self.support = (self.lam_m, self.lam_p)
|
|
111
|
+
|
|
112
|
+
# =======
|
|
113
|
+
# density
|
|
114
|
+
# =======
|
|
115
|
+
|
|
116
|
+
def density(self, x=None, plot=False, latex=False, save=False):
|
|
117
|
+
"""
|
|
118
|
+
Density of distribution.
|
|
119
|
+
|
|
120
|
+
Parameters
|
|
121
|
+
----------
|
|
122
|
+
|
|
123
|
+
x : numpy.array, default=None
|
|
124
|
+
The locations where density is evaluated at. If `None`, an interval
|
|
125
|
+
slightly larger than the support interval of the spectral density
|
|
126
|
+
is used.
|
|
127
|
+
|
|
128
|
+
rho : numpy.array, default=None
|
|
129
|
+
Density. If `None`, it will be computed.
|
|
130
|
+
|
|
131
|
+
plot : bool, default=False
|
|
132
|
+
If `True`, density is plotted.
|
|
133
|
+
|
|
134
|
+
latex : bool, default=False
|
|
135
|
+
If `True`, the plot is rendered using LaTeX. This option is
|
|
136
|
+
relevant only if ``plot=True``.
|
|
137
|
+
|
|
138
|
+
save : bool, default=False
|
|
139
|
+
If not `False`, the plot is saved. If a string is given, it is
|
|
140
|
+
assumed to the save filename (with the file extension). This option
|
|
141
|
+
is relevant only if ``plot=True``.
|
|
142
|
+
|
|
143
|
+
Returns
|
|
144
|
+
-------
|
|
145
|
+
|
|
146
|
+
rho : numpy.array
|
|
147
|
+
Density.
|
|
148
|
+
|
|
149
|
+
Examples
|
|
150
|
+
--------
|
|
151
|
+
|
|
152
|
+
.. code-block::python
|
|
153
|
+
|
|
154
|
+
>>> from freealg.distributions import Meixner
|
|
155
|
+
>>> mx = Meixner(2, 3)
|
|
156
|
+
>>> rho = mx.density(plot=True)
|
|
157
|
+
|
|
158
|
+
.. image:: ../_static/images/plots/mx_density.png
|
|
159
|
+
:align: center
|
|
160
|
+
:class: custom-dark
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
# Create x if not given
|
|
164
|
+
if x is None:
|
|
165
|
+
radius = 0.5 * (self.lam_p - self.lam_m)
|
|
166
|
+
center = 0.5 * (self.lam_p + self.lam_m)
|
|
167
|
+
scale = 1.25
|
|
168
|
+
x_min = numpy.floor(center - radius * scale)
|
|
169
|
+
x_max = numpy.ceil(center + radius * scale)
|
|
170
|
+
x = numpy.linspace(x_min, x_max, 500)
|
|
171
|
+
|
|
172
|
+
rho = numpy.zeros_like(x)
|
|
173
|
+
mask = numpy.logical_and(x > self.lam_m, x < self.lam_p)
|
|
174
|
+
|
|
175
|
+
rho[mask] = \
|
|
176
|
+
numpy.sqrt(4.0 * (1.0 + self.b) - (x[mask] - self.a)**2) / \
|
|
177
|
+
(2.0 * numpy.pi * (self.b * x[mask]**2 + self.a * x[mask] + 1))
|
|
178
|
+
|
|
179
|
+
if plot:
|
|
180
|
+
plot_density(x, rho, label='', latex=latex, save=save)
|
|
181
|
+
|
|
182
|
+
return rho
|
|
183
|
+
|
|
184
|
+
# =======
|
|
185
|
+
# hilbert
|
|
186
|
+
# =======
|
|
187
|
+
|
|
188
|
+
def hilbert(self, x=None, plot=False, latex=False, save=False):
|
|
189
|
+
"""
|
|
190
|
+
Hilbert transform of the distribution.
|
|
191
|
+
|
|
192
|
+
Parameters
|
|
193
|
+
----------
|
|
194
|
+
|
|
195
|
+
x : numpy.array, default=None
|
|
196
|
+
The locations where Hilbert transform is evaluated at. If `None`,
|
|
197
|
+
an interval slightly larger than the support interval of the
|
|
198
|
+
spectral density is used.
|
|
199
|
+
|
|
200
|
+
plot : bool, default=False
|
|
201
|
+
If `True`, Hilbert transform is plotted.
|
|
202
|
+
|
|
203
|
+
latex : bool, default=False
|
|
204
|
+
If `True`, the plot is rendered using LaTeX. This option is
|
|
205
|
+
relevant only if ``plot=True``.
|
|
206
|
+
|
|
207
|
+
save : bool, default=False
|
|
208
|
+
If not `False`, the plot is saved. If a string is given, it is
|
|
209
|
+
assumed to the save filename (with the file extension). This option
|
|
210
|
+
is relevant only if ``plot=True``.
|
|
211
|
+
|
|
212
|
+
Returns
|
|
213
|
+
-------
|
|
214
|
+
|
|
215
|
+
hilb : numpy.array
|
|
216
|
+
Hilbert transform.
|
|
217
|
+
|
|
218
|
+
Examples
|
|
219
|
+
--------
|
|
220
|
+
|
|
221
|
+
.. code-block::python
|
|
222
|
+
|
|
223
|
+
>>> from freealg.distributions import Meixner
|
|
224
|
+
>>> mx = Meixner(2, 3)
|
|
225
|
+
>>> hilb = mx.hilbert(plot=True)
|
|
226
|
+
|
|
227
|
+
.. image:: ../_static/images/plots/mx_hilbert.png
|
|
228
|
+
:align: center
|
|
229
|
+
:class: custom-dark
|
|
230
|
+
"""
|
|
231
|
+
|
|
232
|
+
# Create x if not given
|
|
233
|
+
if x is None:
|
|
234
|
+
radius = 0.5 * (self.lam_p - self.lam_m)
|
|
235
|
+
center = 0.5 * (self.lam_p + self.lam_m)
|
|
236
|
+
scale = 1.25
|
|
237
|
+
x_min = numpy.floor(center - radius * scale)
|
|
238
|
+
x_max = numpy.ceil(center + radius * scale)
|
|
239
|
+
x = numpy.linspace(x_min, x_max, 500)
|
|
240
|
+
|
|
241
|
+
def _P(x):
|
|
242
|
+
denom = 1.0 + self.b
|
|
243
|
+
return ((1.0 + 2.0 * self.b) * x + self.a) / denom
|
|
244
|
+
|
|
245
|
+
def _Q(x):
|
|
246
|
+
denom = 1.0 + self.b
|
|
247
|
+
return (self.b * x**2 + self.a * x + 1.0) / denom
|
|
248
|
+
|
|
249
|
+
P = _P(x)
|
|
250
|
+
Q = _Q(x)
|
|
251
|
+
Delta2 = P**2 - 4.0 * Q
|
|
252
|
+
Delta = numpy.sqrt(numpy.maximum(Delta2, 0))
|
|
253
|
+
sign = numpy.sign(P)
|
|
254
|
+
hilb = (P - sign * Delta) / (2.0 * Q)
|
|
255
|
+
|
|
256
|
+
# using negative sign convention
|
|
257
|
+
hilb = -hilb
|
|
258
|
+
|
|
259
|
+
if plot:
|
|
260
|
+
plot_hilbert(x, hilb, support=self.support, latex=latex, save=save)
|
|
261
|
+
|
|
262
|
+
return hilb
|
|
263
|
+
|
|
264
|
+
# =======================
|
|
265
|
+
# m mp numeric vectorized
|
|
266
|
+
# =======================
|
|
267
|
+
|
|
268
|
+
def _m_mp_numeric_vectorized(self, z, alt_branch=False, tol=1e-8):
|
|
269
|
+
"""
|
|
270
|
+
Stieltjes transform (principal or secondary branch) for Meixner
|
|
271
|
+
distribution on upper half-plane.
|
|
272
|
+
"""
|
|
273
|
+
|
|
274
|
+
sign = -1 if alt_branch else 1
|
|
275
|
+
denom = 1.0 + self.b
|
|
276
|
+
A = (self.b * z**2 + self.a * z + 1.0) / denom
|
|
277
|
+
B = ((1.0 + 2.0 * self.b) * z + self.a) / denom
|
|
278
|
+
D = B**2 - 4 * A
|
|
279
|
+
sqrtD = numpy.sqrt(D)
|
|
280
|
+
m1 = (-B + sqrtD) / (2 * A)
|
|
281
|
+
m2 = (-B - sqrtD) / (2 * A)
|
|
282
|
+
|
|
283
|
+
# pick correct branch only for non‑masked entries
|
|
284
|
+
upper = z.imag >= 0
|
|
285
|
+
branch = numpy.empty_like(m1)
|
|
286
|
+
branch[upper] = numpy.where(sign*m1[upper].imag > 0, m1[upper],
|
|
287
|
+
m2[upper])
|
|
288
|
+
branch[~upper] = numpy.where(sign*m1[~upper].imag < 0, m1[~upper],
|
|
289
|
+
m2[~upper])
|
|
290
|
+
m = branch
|
|
291
|
+
|
|
292
|
+
return m
|
|
293
|
+
|
|
294
|
+
# ============
|
|
295
|
+
# m mp reflect
|
|
296
|
+
# ============
|
|
297
|
+
|
|
298
|
+
def _m_mp_reflect(self, z, alt_branch=False):
|
|
299
|
+
"""
|
|
300
|
+
Analytic continuation using Schwarz reflection.
|
|
301
|
+
"""
|
|
302
|
+
|
|
303
|
+
mask_p = z.imag >= 0.0
|
|
304
|
+
mask_n = z.imag < 0.0
|
|
305
|
+
|
|
306
|
+
m = numpy.zeros_like(z)
|
|
307
|
+
|
|
308
|
+
f = self._m_mp_numeric_vectorized
|
|
309
|
+
m[mask_p] = f(z[mask_p], alt_branch=False)
|
|
310
|
+
m[mask_n] = f(z[mask_n], alt_branch=alt_branch)
|
|
311
|
+
|
|
312
|
+
return m
|
|
313
|
+
|
|
314
|
+
# =========
|
|
315
|
+
# stieltjes
|
|
316
|
+
# =========
|
|
317
|
+
|
|
318
|
+
def stieltjes(self, x=None, y=None, plot=False, on_disk=False, latex=False,
|
|
319
|
+
save=False):
|
|
320
|
+
"""
|
|
321
|
+
Stieltjes transform of distribution.
|
|
322
|
+
|
|
323
|
+
Parameters
|
|
324
|
+
----------
|
|
325
|
+
|
|
326
|
+
x : numpy.array, default=None
|
|
327
|
+
The x axis of the grid where the Stieltjes transform is evaluated.
|
|
328
|
+
If `None`, an interval slightly larger than the support interval of
|
|
329
|
+
the spectral density is used.
|
|
330
|
+
|
|
331
|
+
y : numpy.array, default=None
|
|
332
|
+
The y axis of the grid where the Stieltjes transform is evaluated.
|
|
333
|
+
If `None`, a grid on the interval ``[-1, 1]`` is used.
|
|
334
|
+
|
|
335
|
+
plot : bool, default=False
|
|
336
|
+
If `True`, Stieltjes transform is plotted.
|
|
337
|
+
|
|
338
|
+
on_disk : bool, default=False
|
|
339
|
+
If `True`, the Stieltjes transform is mapped on unit disk. This
|
|
340
|
+
option relevant only if ``plot=True``.
|
|
341
|
+
|
|
342
|
+
latex : bool, default=False
|
|
343
|
+
If `True`, the plot is rendered using LaTeX. This option is
|
|
344
|
+
relevant only if ``plot=True``.
|
|
345
|
+
|
|
346
|
+
save : bool, default=False
|
|
347
|
+
If not `False`, the plot is saved. If a string is given, it is
|
|
348
|
+
assumed to the save filename (with the file extension). This option
|
|
349
|
+
is relevant only if ``plot=True``.
|
|
350
|
+
|
|
351
|
+
Returns
|
|
352
|
+
-------
|
|
353
|
+
|
|
354
|
+
m1 : numpy.array
|
|
355
|
+
Stieltjes transform on principal branch.
|
|
356
|
+
|
|
357
|
+
m12 : numpy.array
|
|
358
|
+
Stieltjes transform on secondary branch.
|
|
359
|
+
|
|
360
|
+
Examples
|
|
361
|
+
--------
|
|
362
|
+
|
|
363
|
+
.. code-block:: python
|
|
364
|
+
|
|
365
|
+
>>> from freealg.distributions import Meixner
|
|
366
|
+
>>> mx = Meixner(2, 3)
|
|
367
|
+
>>> m1, m2 = mx.stieltjes(plot=True)
|
|
368
|
+
|
|
369
|
+
.. image:: ../_static/images/plots/mx_stieltjes.png
|
|
370
|
+
:align: center
|
|
371
|
+
:class: custom-dark
|
|
372
|
+
|
|
373
|
+
Plot on unit disk using Cayley transform:
|
|
374
|
+
|
|
375
|
+
.. code-block:: python
|
|
376
|
+
|
|
377
|
+
>>> m1, m2 = mx.stieltjes(plot=True, on_disk=True)
|
|
378
|
+
|
|
379
|
+
.. image:: ../_static/images/plots/mx_stieltjes_disk.png
|
|
380
|
+
:align: center
|
|
381
|
+
:class: custom-dark
|
|
382
|
+
"""
|
|
383
|
+
|
|
384
|
+
if (plot is True) and (on_disk is True):
|
|
385
|
+
n_r = 1000
|
|
386
|
+
n_t = 1000
|
|
387
|
+
r_min, r_max = 0, 2.5
|
|
388
|
+
t_min, t_max = 0, 2.0 * numpy.pi
|
|
389
|
+
r = numpy.linspace(r_min, r_max, n_r)
|
|
390
|
+
t = numpy.linspace(t_min, t_max, n_t + 1)[:-1]
|
|
391
|
+
grid_r, grid_t = numpy.meshgrid(r, t)
|
|
392
|
+
|
|
393
|
+
grid_x_D = grid_r * numpy.cos(grid_t)
|
|
394
|
+
grid_y_D = grid_r * numpy.sin(grid_t)
|
|
395
|
+
zeta = grid_x_D + 1j * grid_y_D
|
|
396
|
+
|
|
397
|
+
# Cayley transform mapping zeta on D to z on H
|
|
398
|
+
z_H = 1j * (1 + zeta) / (1 - zeta)
|
|
399
|
+
|
|
400
|
+
m1_D = self._m_mp_reflect(z_H, alt_branch=False)
|
|
401
|
+
m2_D = self._m_mp_reflect(z_H, alt_branch=True)
|
|
402
|
+
|
|
403
|
+
plot_stieltjes_on_disk(r, t, m1_D, m2_D, support=self.support,
|
|
404
|
+
latex=latex, save=save)
|
|
405
|
+
|
|
406
|
+
return m1_D, m2_D
|
|
407
|
+
|
|
408
|
+
# Create x if not given
|
|
409
|
+
if x is None:
|
|
410
|
+
radius = 0.5 * (self.lam_p - self.lam_m)
|
|
411
|
+
center = 0.5 * (self.lam_p + self.lam_m)
|
|
412
|
+
scale = 2.0
|
|
413
|
+
x_min = numpy.floor(2.0 * (center - 2.0 * radius * scale)) / 2.0
|
|
414
|
+
x_max = numpy.ceil(2.0 * (center + 2.0 * radius * scale)) / 2.0
|
|
415
|
+
x = numpy.linspace(x_min, x_max, 500)
|
|
416
|
+
|
|
417
|
+
# Create y if not given
|
|
418
|
+
if y is None:
|
|
419
|
+
y = numpy.linspace(-1, 1, 400)
|
|
420
|
+
|
|
421
|
+
x_grid, y_grid = numpy.meshgrid(x, y)
|
|
422
|
+
z = x_grid + 1j * y_grid # shape (Ny, Nx)
|
|
423
|
+
|
|
424
|
+
m1 = self._m_mp_reflect(z, alt_branch=False)
|
|
425
|
+
m2 = self._m_mp_reflect(z, alt_branch=True)
|
|
426
|
+
|
|
427
|
+
if plot:
|
|
428
|
+
plot_stieltjes(x, y, m1, m2, support=self.support, latex=latex,
|
|
429
|
+
save=save)
|
|
430
|
+
|
|
431
|
+
return m1, m2
|
|
432
|
+
|
|
433
|
+
# ======
|
|
434
|
+
# sample
|
|
435
|
+
# ======
|
|
436
|
+
|
|
437
|
+
def sample(self, size, x_min=None, x_max=None, method='qmc', plot=False,
|
|
438
|
+
latex=False, save=False):
|
|
439
|
+
"""
|
|
440
|
+
Sample from distribution.
|
|
441
|
+
|
|
442
|
+
Parameters
|
|
443
|
+
----------
|
|
444
|
+
|
|
445
|
+
size : int
|
|
446
|
+
Size of sample.
|
|
447
|
+
|
|
448
|
+
x_min : float, default=None
|
|
449
|
+
Minimum of sample values. If `None`, the left edge of the support
|
|
450
|
+
is used.
|
|
451
|
+
|
|
452
|
+
x_max : float, default=None
|
|
453
|
+
Maximum of sample values. If `None`, the right edge of the support
|
|
454
|
+
is used.
|
|
455
|
+
|
|
456
|
+
method : {``'mc'``, ``'qmc'``}, default= ``'qmc'``
|
|
457
|
+
Method of drawing samples from uniform distirbution:
|
|
458
|
+
|
|
459
|
+
* ``'mc'``: Monte Carlo
|
|
460
|
+
* ``'qmc'``: Quasi Monte Carlo
|
|
461
|
+
|
|
462
|
+
plot : bool, default=False
|
|
463
|
+
If `True`, samples histogram is plotted.
|
|
464
|
+
|
|
465
|
+
latex : bool, default=False
|
|
466
|
+
If `True`, the plot is rendered using LaTeX. This option is
|
|
467
|
+
relevant only if ``plot=True``.
|
|
468
|
+
|
|
469
|
+
save : bool, default=False
|
|
470
|
+
If not `False`, the plot is saved. If a string is given, it is
|
|
471
|
+
assumed to the save filename (with the file extension). This option
|
|
472
|
+
is relevant only if ``plot=True``.
|
|
473
|
+
|
|
474
|
+
Returns
|
|
475
|
+
-------
|
|
476
|
+
|
|
477
|
+
s : numpy.ndarray
|
|
478
|
+
Samples.
|
|
479
|
+
|
|
480
|
+
Notes
|
|
481
|
+
-----
|
|
482
|
+
|
|
483
|
+
This method uses inverse transform sampling.
|
|
484
|
+
|
|
485
|
+
Examples
|
|
486
|
+
--------
|
|
487
|
+
|
|
488
|
+
.. code-block::python
|
|
489
|
+
|
|
490
|
+
>>> from freealg.distributions import Meixner
|
|
491
|
+
>>> mx = Meixner(2, 3)
|
|
492
|
+
>>> s = mx.sample(2000)
|
|
493
|
+
|
|
494
|
+
.. image:: ../_static/images/plots/mx_samples.png
|
|
495
|
+
:align: center
|
|
496
|
+
:class: custom-dark
|
|
497
|
+
"""
|
|
498
|
+
|
|
499
|
+
if x_min is None:
|
|
500
|
+
x_min = self.lam_m
|
|
501
|
+
|
|
502
|
+
if x_max is None:
|
|
503
|
+
x_max = self.lam_p
|
|
504
|
+
|
|
505
|
+
# Grid and PDF
|
|
506
|
+
xs = numpy.linspace(x_min, x_max, size)
|
|
507
|
+
pdf = self.density(xs)
|
|
508
|
+
|
|
509
|
+
# CDF (using cumulative trapezoidal rule)
|
|
510
|
+
cdf = cumtrapz(pdf, xs, initial=0)
|
|
511
|
+
cdf /= cdf[-1] # normalize CDF to 1
|
|
512
|
+
|
|
513
|
+
# Inverse CDF interpolator
|
|
514
|
+
inv_cdf = interp1d(cdf, xs, bounds_error=False,
|
|
515
|
+
fill_value=(x_min, x_max))
|
|
516
|
+
|
|
517
|
+
# Draw from uniform distribution
|
|
518
|
+
if method == 'mc':
|
|
519
|
+
u = numpy.random.rand(size)
|
|
520
|
+
elif method == 'qmc':
|
|
521
|
+
engine = qmc.Halton(d=1)
|
|
522
|
+
u = engine.random(size)
|
|
523
|
+
else:
|
|
524
|
+
raise ValueError('"method" is invalid.')
|
|
525
|
+
|
|
526
|
+
# Draw from distribution by mapping from inverse CDF
|
|
527
|
+
samples = inv_cdf(u).ravel()
|
|
528
|
+
|
|
529
|
+
if plot:
|
|
530
|
+
radius = 0.5 * (self.lam_p - self.lam_m)
|
|
531
|
+
center = 0.5 * (self.lam_p + self.lam_m)
|
|
532
|
+
scale = 1.25
|
|
533
|
+
x_min = numpy.floor(center - radius * scale)
|
|
534
|
+
x_max = numpy.ceil(center + radius * scale)
|
|
535
|
+
x = numpy.linspace(x_min, x_max, 500)
|
|
536
|
+
rho = self.density(x)
|
|
537
|
+
plot_samples(x, rho, x_min, x_max, samples, latex=latex, save=save)
|
|
538
|
+
|
|
539
|
+
return samples
|
|
540
|
+
|
|
541
|
+
# ======
|
|
542
|
+
# matrix
|
|
543
|
+
# ======
|
|
544
|
+
|
|
545
|
+
def matrix(self, size):
|
|
546
|
+
"""
|
|
547
|
+
Generate matrix with the spectral density of the distribution.
|
|
548
|
+
|
|
549
|
+
Parameters
|
|
550
|
+
----------
|
|
551
|
+
|
|
552
|
+
size : int
|
|
553
|
+
Size :math:`n` of the matrix.
|
|
554
|
+
|
|
555
|
+
Returns
|
|
556
|
+
-------
|
|
557
|
+
|
|
558
|
+
Sx : numpy.ndarray
|
|
559
|
+
A matrix of the size :math:`n \\times n`.
|
|
560
|
+
|
|
561
|
+
Sy : numpy.ndarray
|
|
562
|
+
A matrix of the size :math:`n \\times n`.
|
|
563
|
+
|
|
564
|
+
Examples
|
|
565
|
+
--------
|
|
566
|
+
|
|
567
|
+
.. code-block::python
|
|
568
|
+
|
|
569
|
+
>>> from freealg.distributions import Meixner
|
|
570
|
+
>>> mx = Meixner(2, 3)
|
|
571
|
+
>>> A = mx.matrix(2000)
|
|
572
|
+
"""
|
|
573
|
+
|
|
574
|
+
n = size
|
|
575
|
+
m1 = int(self.a * n)
|
|
576
|
+
m2 = int(self.b * n)
|
|
577
|
+
|
|
578
|
+
X = numpy.random.randn(n, m1)
|
|
579
|
+
Y = numpy.random.randn(n, m2)
|
|
580
|
+
|
|
581
|
+
Sx = X @ X.T
|
|
582
|
+
Sy = Y @ Y.T
|
|
583
|
+
|
|
584
|
+
return Sx, Sy
|
freealg/distributions/wachter.py
CHANGED
|
@@ -63,7 +63,7 @@ class Wachter(object):
|
|
|
63
63
|
Notes
|
|
64
64
|
-----
|
|
65
65
|
|
|
66
|
-
The
|
|
66
|
+
The Wachter distribution has the absolutely-continuous density
|
|
67
67
|
|
|
68
68
|
.. math::
|
|
69
69
|
|
|
@@ -241,10 +241,12 @@ class Wachter(object):
|
|
|
241
241
|
x = numpy.linspace(x_min, x_max, 500)
|
|
242
242
|
|
|
243
243
|
def _P(x):
|
|
244
|
-
|
|
244
|
+
denom = self.a + self.b - 1.0
|
|
245
|
+
return (1.0 - self.a + (self.a + self.b - 2.0) * x) / denom
|
|
245
246
|
|
|
246
247
|
def _Q(x):
|
|
247
|
-
|
|
248
|
+
denom = self.a + self.b - 1.0
|
|
249
|
+
return x * (1.0 - x) / denom
|
|
248
250
|
|
|
249
251
|
P = _P(x)
|
|
250
252
|
Q = _Q(x)
|
|
@@ -267,13 +269,14 @@ class Wachter(object):
|
|
|
267
269
|
|
|
268
270
|
def _m_mp_numeric_vectorized(self, z, alt_branch=False, tol=1e-8):
|
|
269
271
|
"""
|
|
270
|
-
Stieltjes transform (principal or secondary branch)
|
|
271
|
-
|
|
272
|
+
Stieltjes transform (principal or secondary branch) for Wachter
|
|
273
|
+
distribution on upper half-plane.
|
|
272
274
|
"""
|
|
273
275
|
|
|
274
276
|
sign = -1 if alt_branch else 1
|
|
275
|
-
|
|
276
|
-
|
|
277
|
+
denom = self.a + self.b - 1.0
|
|
278
|
+
A = (z * (1.0 - z)) / denom
|
|
279
|
+
B = (1.0 - self.a + (self.a + self.b - 2.0) * z) / denom
|
|
277
280
|
D = B**2 - 4 * A
|
|
278
281
|
sqrtD = numpy.sqrt(D)
|
|
279
282
|
m1 = (-B + sqrtD) / (2 * A)
|
|
@@ -373,7 +376,7 @@ class Wachter(object):
|
|
|
373
376
|
|
|
374
377
|
.. code-block:: python
|
|
375
378
|
|
|
376
|
-
>>> m1, m2 =
|
|
379
|
+
>>> m1, m2 = wa.stieltjes(plot=True, on_disk=True)
|
|
377
380
|
|
|
378
381
|
.. image:: ../_static/images/plots/wa_stieltjes_disk.png
|
|
379
382
|
:align: center
|
freealg/distributions/wigner.py
CHANGED
|
@@ -55,7 +55,7 @@ class Wigner(object):
|
|
|
55
55
|
Notes
|
|
56
56
|
-----
|
|
57
57
|
|
|
58
|
-
The
|
|
58
|
+
The Wigner distribution has the absolutely-continuous density
|
|
59
59
|
|
|
60
60
|
.. math::
|
|
61
61
|
|
|
@@ -248,8 +248,8 @@ class Wigner(object):
|
|
|
248
248
|
|
|
249
249
|
def _m_mp_numeric_vectorized(self, z, alt_branch=False, tol=1e-8):
|
|
250
250
|
"""
|
|
251
|
-
Stieltjes transform (principal or secondary branch)
|
|
252
|
-
|
|
251
|
+
Stieltjes transform (principal or secondary branch) for Wigner
|
|
252
|
+
distribution on upper half-plane.
|
|
253
253
|
"""
|
|
254
254
|
|
|
255
255
|
m = numpy.empty_like(z, dtype=complex)
|
|
@@ -357,7 +357,7 @@ class Wigner(object):
|
|
|
357
357
|
|
|
358
358
|
.. code-block:: python
|
|
359
359
|
|
|
360
|
-
>>> m1, m2 =
|
|
360
|
+
>>> m1, m2 = wg.stieltjes(plot=True, on_disk=True)
|
|
361
361
|
|
|
362
362
|
.. image:: ../_static/images/plots/wg_stieltjes_disk.png
|
|
363
363
|
:align: center
|
freealg/freeform.py
CHANGED
|
@@ -631,8 +631,7 @@ class FreeForm(object):
|
|
|
631
631
|
# stieltjes
|
|
632
632
|
# =========
|
|
633
633
|
|
|
634
|
-
def stieltjes(self, x, y, plot=False, latex=False,
|
|
635
|
-
save=False):
|
|
634
|
+
def stieltjes(self, x, y, plot=False, latex=False, save=False):
|
|
636
635
|
"""
|
|
637
636
|
Compute Stieltjes transform of the spectral density over a 2D Cartesian
|
|
638
637
|
grid on the complex plane.
|
|
@@ -656,10 +655,6 @@ class FreeForm(object):
|
|
|
656
655
|
If `True`, the plot is rendered using LaTeX. This option is
|
|
657
656
|
relevant only if ``plot=True``.
|
|
658
657
|
|
|
659
|
-
char_curves : numpy.array, default=None
|
|
660
|
-
If ``plot=True``, also plot characteristic curves starting from
|
|
661
|
-
these locations.
|
|
662
|
-
|
|
663
658
|
save : bool, default=False
|
|
664
659
|
If not `False`, the plot is saved. If a string is given, it is
|
|
665
660
|
assumed to the save filename (with the file extension). This option
|
|
@@ -747,9 +742,7 @@ class FreeForm(object):
|
|
|
747
742
|
m2[mask_m, :] = -m1[mask_m, :] + self._glue(z[mask_m, :])
|
|
748
743
|
|
|
749
744
|
if plot:
|
|
750
|
-
plot_stieltjes(x, y, m1, m2, self.support, latex=latex,
|
|
751
|
-
char_curves={'matrix': self, 'z': char_curves},
|
|
752
|
-
save=save)
|
|
745
|
+
plot_stieltjes(x, y, m1, m2, self.support, latex=latex, save=save)
|
|
753
746
|
|
|
754
747
|
return m1, m2
|
|
755
748
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: freealg
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
4
4
|
Summary: Free probability for large matrices
|
|
5
5
|
Keywords: leaderboard bot chat
|
|
6
6
|
Platform: Linux
|
|
@@ -24,6 +24,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
24
24
|
Requires-Python: >=3.9
|
|
25
25
|
Description-Content-Type: text/x-rst
|
|
26
26
|
License-File: LICENSE.txt
|
|
27
|
+
License-File: AUTHORS.txt
|
|
27
28
|
Requires-Dist: numpy
|
|
28
29
|
Requires-Dist: scipy
|
|
29
30
|
Requires-Dist: texplot
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
freealg/__init__.py,sha256=K92neXJZ9VE1U_j_pj28Qyq1MzlMXhOuYK2ZihgwCaU,463
|
|
2
|
+
freealg/__version__.py,sha256=YpKDcdV7CqL8n45u267wKtyloM13FSVbOdrqgNZnSLM,22
|
|
3
|
+
freealg/_chebyshev.py,sha256=X6u5pKjR1HPZ-KbCfr7zT6HRwB6pZMADvVS3sT5LTkA,5638
|
|
4
|
+
freealg/_damp.py,sha256=k2vtBtWOxQBf4qXaWu_En81lQBXbEO4QbxxWpvuVhdE,1802
|
|
5
|
+
freealg/_decompress.py,sha256=7U2lL8F5z76aFuZJBsPj70jEVRuzvJHnIh5FSw-aLME,4680
|
|
6
|
+
freealg/_jacobi.py,sha256=AT4ONSHGGDxVKE3MGMLyMR8uDFiO-e9u3x5udYfdJJk,5635
|
|
7
|
+
freealg/_pade.py,sha256=mP96wEPfIzHLZ6PDB5OyhmSA8N1uVPVUkmJa3ebXXiU,13623
|
|
8
|
+
freealg/_plot_util.py,sha256=wVx99GRdIFu_wzmG8f5JSDZ65BJohnuSBm3mZ58wElg,18426
|
|
9
|
+
freealg/_sample.py,sha256=K1ZxKoiuPbEKyh-swL5X7gz1kYcQno6Mof0o1xF38tg,2323
|
|
10
|
+
freealg/_util.py,sha256=alJ9s1U_sHL7dXq7hI10fa8CF_AZ6Xmy_QsoyDYPSDQ,3677
|
|
11
|
+
freealg/freeform.py,sha256=kbh7UoOJkAVFKj2Zmddy803-asoslkqn-gWJ-HpLN7U,28750
|
|
12
|
+
freealg/distributions/__init__.py,sha256=ufiL5OG_Jyma3D2il0BedhGuilROilbmSjxqoiz45GE,574
|
|
13
|
+
freealg/distributions/kesten_mckay.py,sha256=nvCEPKVjZCYNt-MLlFSzTfj8PTlcLmmGW9AefvYJxuU,15977
|
|
14
|
+
freealg/distributions/marchenko_pastur.py,sha256=GwDTN-7au2h7H7PnZkQfs6bas8fNhgEnQ-hTWsBMZuE,16403
|
|
15
|
+
freealg/distributions/meixner.py,sha256=y_iLB5LqvkT9P_rGa46ZCmk_EFfPS_3VuFCZpeD2ooI,16172
|
|
16
|
+
freealg/distributions/wachter.py,sha256=IYKok4stONv0RrigSRDWGLEyBmg6j3hS8c9_fw31kZw,16276
|
|
17
|
+
freealg/distributions/wigner.py,sha256=LE-KDxFb8q7-ifWUv7_LrEpOGYYTMdVPFfzIhm4vJKg,15426
|
|
18
|
+
freealg-0.1.7.dist-info/licenses/AUTHORS.txt,sha256=0b67Nz4_JgIzUupHJTAZxu5QdSUM_HRM_X_w4xCb17o,30
|
|
19
|
+
freealg-0.1.7.dist-info/licenses/LICENSE.txt,sha256=J-EEYEtxb3VVf_Bn1TYfWnpY5lMFIM15iLDDcnaDTPA,1443
|
|
20
|
+
freealg-0.1.7.dist-info/METADATA,sha256=zCRGrnjGgjLlx9WToqSyBR_jqFsMzZIxPbWOM4fMgYE,2965
|
|
21
|
+
freealg-0.1.7.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
|
22
|
+
freealg-0.1.7.dist-info/top_level.txt,sha256=eR2wrgYwDdnnJ9Zf5PruPqe4kQav0GMvRsqct6y00Q8,8
|
|
23
|
+
freealg-0.1.7.dist-info/RECORD,,
|
freealg-0.1.6.dist-info/RECORD
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
freealg/__init__.py,sha256=K92neXJZ9VE1U_j_pj28Qyq1MzlMXhOuYK2ZihgwCaU,463
|
|
2
|
-
freealg/__version__.py,sha256=n3oM6B_EMz93NsTI18NNZd-jKFcUPzUkbIKj5VFK5ok,22
|
|
3
|
-
freealg/_chebyshev.py,sha256=X6u5pKjR1HPZ-KbCfr7zT6HRwB6pZMADvVS3sT5LTkA,5638
|
|
4
|
-
freealg/_damp.py,sha256=k2vtBtWOxQBf4qXaWu_En81lQBXbEO4QbxxWpvuVhdE,1802
|
|
5
|
-
freealg/_decompress.py,sha256=7U2lL8F5z76aFuZJBsPj70jEVRuzvJHnIh5FSw-aLME,4680
|
|
6
|
-
freealg/_jacobi.py,sha256=AT4ONSHGGDxVKE3MGMLyMR8uDFiO-e9u3x5udYfdJJk,5635
|
|
7
|
-
freealg/_pade.py,sha256=mP96wEPfIzHLZ6PDB5OyhmSA8N1uVPVUkmJa3ebXXiU,13623
|
|
8
|
-
freealg/_plot_util.py,sha256=Ng9c_U9kxsRb16GsvVa2u4AiXUKw0oD4E3BB_e9d9h8,19575
|
|
9
|
-
freealg/_sample.py,sha256=K1ZxKoiuPbEKyh-swL5X7gz1kYcQno6Mof0o1xF38tg,2323
|
|
10
|
-
freealg/_util.py,sha256=alJ9s1U_sHL7dXq7hI10fa8CF_AZ6Xmy_QsoyDYPSDQ,3677
|
|
11
|
-
freealg/freeform.py,sha256=pZM4IUVegXjKCi9484Gz4bPkYt0tRvslTrha_yKW7y4,29042
|
|
12
|
-
freealg/distributions/__init__.py,sha256=Hnk9bJi4Wy8I_1uuskRyrT2DUpPN1YmBY5uK7XI3U_o,644
|
|
13
|
-
freealg/distributions/kesten_mckay.py,sha256=Oq2FCX60seojy7LDn8nYPrbqinmXv4YC-93VxlmDQ6M,15913
|
|
14
|
-
freealg/distributions/marchenko_pastur.py,sha256=GwDTN-7au2h7H7PnZkQfs6bas8fNhgEnQ-hTWsBMZuE,16403
|
|
15
|
-
freealg/distributions/wachter.py,sha256=2eqbJY4S1MqLjgqO6qY06m3-_s-bKTuSiryS_ZH_xvI,16136
|
|
16
|
-
freealg/distributions/wigner.py,sha256=MSrB-HLMzOwnWDDzw5XPLsoL4LEIV35w5jWeL-qDn9Y,15448
|
|
17
|
-
freealg-0.1.6.dist-info/licenses/LICENSE.txt,sha256=J-EEYEtxb3VVf_Bn1TYfWnpY5lMFIM15iLDDcnaDTPA,1443
|
|
18
|
-
freealg-0.1.6.dist-info/METADATA,sha256=eIE88q1eRccGUJdZmKYfjoP6p-XTP4y7tBkKrCb3jfU,2939
|
|
19
|
-
freealg-0.1.6.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
|
20
|
-
freealg-0.1.6.dist-info/top_level.txt,sha256=eR2wrgYwDdnnJ9Zf5PruPqe4kQav0GMvRsqct6y00Q8,8
|
|
21
|
-
freealg-0.1.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|