Skip to content

Commit ad02163

Browse files
committed
Add doctest to ._maximal_r()
1 parent d43a17e commit ad02163

File tree

1 file changed

+65
-53
lines changed

1 file changed

+65
-53
lines changed

src/sage/stats/distributions/discrete_gaussian_lattice.py

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
1919
EXAMPLES::
2020
21-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
22-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^10, 3.0)
21+
sage: from sage.stats.all import DGL
22+
sage: D = DGL(ZZ^10, 3.0)
2323
sage: D(), D(), D() # random
2424
((3, 0, -5, 0, -1, -3, 3, 3, -7, 2), (4, 0, 1, -2, -4, -4, 4, 0, 1, -4), (-3, 0, 4, 5, 0, 1, 3, 2, 0, -1))
2525
sage: a = D()
@@ -120,8 +120,8 @@ class DiscreteGaussianDistributionLatticeSampler(SageObject):
120120
121121
EXAMPLES::
122122
123-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
124-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^10, 3.0); D
123+
sage: from sage.stats.all import DGL
124+
sage: D = DGL(ZZ^10, 3.0); D
125125
Discrete Gaussian sampler with Gaussian parameter σ = 3.00000000000000, c=(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) over lattice with basis
126126
<BLANKLINE>
127127
[1 0 0 0 0 0 0 0 0 0]
@@ -138,10 +138,10 @@ class DiscreteGaussianDistributionLatticeSampler(SageObject):
138138
139139
We plot a histogram::
140140
141-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
141+
sage: from sage.stats.all import DGL
142142
sage: import warnings
143143
sage: warnings.simplefilter('ignore', UserWarning)
144-
sage: D = DiscreteGaussianDistributionLatticeSampler(identity_matrix(2), 3.0)
144+
sage: D = DGL(identity_matrix(2), 3.0)
145145
sage: S = [D() for _ in range(2^12)]
146146
sage: l = [vector(v.list() + [S.count(v)]) for v in set(S)]
147147
sage: list_plot3d(l, point_list=True, interpolation='nn')
@@ -167,18 +167,18 @@ def compute_precision(precision, sigma):
167167
168168
EXAMPLES::
169169
170-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
171-
sage: DiscreteGaussianDistributionLatticeSampler.compute_precision(100, RR(3))
170+
sage: from sage.stats.all import DGL
171+
sage: DGL.compute_precision(100, RR(3))
172172
100
173-
sage: DiscreteGaussianDistributionLatticeSampler.compute_precision(100, RealField(200)(3))
173+
sage: DGL.compute_precision(100, RealField(200)(3))
174174
100
175-
sage: DiscreteGaussianDistributionLatticeSampler.compute_precision(100, 3)
175+
sage: DGL.compute_precision(100, 3)
176176
100
177-
sage: DiscreteGaussianDistributionLatticeSampler.compute_precision(None, RR(3))
177+
sage: DGL.compute_precision(None, RR(3))
178178
53
179-
sage: DiscreteGaussianDistributionLatticeSampler.compute_precision(None, RealField(200)(3))
179+
sage: DGL.compute_precision(None, RealField(200)(3))
180180
200
181-
sage: DiscreteGaussianDistributionLatticeSampler.compute_precision(None, 3)
181+
sage: DGL.compute_precision(None, 3)
182182
53
183183
184184
"""
@@ -207,9 +207,9 @@ def _normalisation_factor_zz(self, tau=None, prec=None):
207207
208208
EXAMPLES::
209209
210-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
210+
sage: from sage.stats.all import DGL
211211
sage: n = 3; sigma = 1.0
212-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^n, sigma)
212+
sage: D = DGL(ZZ^n, sigma)
213213
sage: f = D.f
214214
sage: nf = D._normalisation_factor_zz(); nf
215215
15.7496...
@@ -235,22 +235,22 @@ def _normalisation_factor_zz(self, tau=None, prec=None):
235235
236236
sage: while abs(m*f(v)*1.0/nf/counter[v] - 1.0) >= 0.2: add_samples(1000) # long time
237237
238-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^8, 0.5)
238+
sage: D = DGL(ZZ^8, 0.5)
239239
sage: D._normalisation_factor_zz(tau=3)
240240
3.1653...
241241
sage: D._normalisation_factor_zz()
242242
6.8249...
243-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^8, 1000)
243+
sage: D = DGL(ZZ^8, 1000)
244244
sage: round(D._normalisation_factor_zz(prec=100))
245245
1558545456544038969634991553
246246
247247
sage: M = Matrix(ZZ, [[1, 3, 0], [-2, 5, 1], [3, -4, 2]])
248-
sage: D = DiscreteGaussianDistributionLatticeSampler(M, 1.7)
248+
sage: D = DGL(M, 1.7)
249249
sage: D._normalisation_factor_zz() # long time
250250
7247.1975...
251251
252252
sage: M = Matrix(ZZ, [[1, 3, 0], [-2, 5, 1]])
253-
sage: D = DiscreteGaussianDistributionLatticeSampler(M, 3)
253+
sage: D = DGL(M, 3)
254254
sage: D._normalisation_factor_zz()
255255
Traceback (most recent call last):
256256
...
@@ -297,11 +297,11 @@ def f_or_hat(x):
297297
if self.is_spherical and not self._c_in_lattice:
298298
raise NotImplementedError("Lattice must contain 0 for now.")
299299

300-
if self.B.base_ring() not in (ZZ, QQ):
300+
if self.B.base_ring() not in ZZ:
301301
raise NotImplementedError("Lattice must be integral for now.")
302302

303303
sigma = self._sigma
304-
prec = DiscreteGaussianDistributionLatticeSampler.compute_precision(
304+
prec = DGL.compute_precision(
305305
prec, sigma
306306
)
307307
R = RealField(prec=prec)
@@ -341,6 +341,18 @@ def _maximal_r(self):
341341
342342
This is equivalent to finding `λ₁(Σ / Q) = 1 / λₙ(Q / Σ)`, which is done
343343
via the Power iteration method.
344+
345+
EXAMPLES::
346+
347+
sage: from sage.stats.all import DGL
348+
sage: n = 3
349+
sage: Sigma = Matrix(ZZ, [[5, -2, 4], [-2, 10, -5], [4, -5, 5]])
350+
sage: c = vector(ZZ, [7, 2, 5])
351+
sage: D = DGL(ZZ^n, Sigma, c)
352+
sage: r = D._maximal_r(); r
353+
0.58402...
354+
sage: e_vals = (D.sigma - r^2 * D.Q).eigenvalues()
355+
sage: assert all(e_val >= -1e-12 for e_val in e_vals)
344356
"""
345357
# TODO: Write doctest
346358
if self.is_spherical:
@@ -399,9 +411,9 @@ def __init__(self, B, sigma=1, c=None, r=None, precision=None):
399411
400412
EXAMPLES::
401413
402-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
414+
sage: from sage.stats.all import DGL
403415
sage: n = 2; sigma = 3.0
404-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^n, sigma)
416+
sage: D = DGL(ZZ^n, sigma)
405417
sage: f = D.f
406418
sage: nf = D._normalisation_factor_zz(); nf
407419
56.5486677646...
@@ -432,7 +444,7 @@ def __init__(self, B, sigma=1, c=None, r=None, precision=None):
432444
sage: n = 3
433445
sage: Sigma = Matrix(ZZ, [[5, -2, 4], [-2, 10, -5], [4, -5, 5]])
434446
sage: c = vector(ZZ, [7, 2, 5])
435-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^n, Sigma, c)
447+
sage: D = DGL(ZZ^n, Sigma, c)
436448
sage: nf = D._normalisation_factor_zz(); nf # This has not been properly implemented
437449
63.76927...
438450
sage: while v not in counter: add_samples(1000)
@@ -451,9 +463,9 @@ def __init__(self, B, sigma=1, c=None, r=None, precision=None):
451463
452464
We can also initialise with matrix-like objects:
453465
454-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
466+
sage: from sage.stats.all import DGL
455467
sage: qf = QuadraticForm(matrix(3, [2, 1, 1, 1, 2, 1, 1, 1, 2]))
456-
sage: D = DiscreteGaussianDistributionLatticeSampler(qf, 3.0); D
468+
sage: D = DGL(qf, 3.0); D
457469
Discrete Gaussian sampler with Gaussian parameter σ = 3.00000000000000, c=(0, 0, 0) over lattice with basis
458470
<BLANKLINE>
459471
[2 1 1]
@@ -462,7 +474,7 @@ def __init__(self, B, sigma=1, c=None, r=None, precision=None):
462474
sage: D().parent() is D.c.parent()
463475
True
464476
"""
465-
precision = DiscreteGaussianDistributionLatticeSampler.compute_precision(precision, sigma)
477+
precision = DGL.compute_precision(precision, sigma)
466478

467479
self._RR = RealField(precision)
468480
# Check if sigma is a (real) number or a scaled identity matrix
@@ -498,12 +510,12 @@ def __init__(self, B, sigma=1, c=None, r=None, precision=None):
498510
self._c_in_lattice = False
499511

500512
try:
501-
c = vector(ZZ, B.ncols(), c)
513+
c = vector(ZZ, self.n, c)
502514
except TypeError:
503515
try:
504-
c = vector(QQ, B.ncols(), c)
516+
c = vector(QQ, self.n, c)
505517
except TypeError:
506-
c = vector(self._RR, B.ncols(), c)
518+
c = vector(self._RR, self.n, c)
507519

508520
self._c = c
509521

@@ -562,14 +574,14 @@ def __call__(self):
562574
563575
EXAMPLES::
564576
565-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
566-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0))
577+
sage: from sage.stats.all import DGL
578+
sage: D = DGL(ZZ^3, 3.0, c=(1,0,0))
567579
sage: L = [D() for _ in range(2^12)]
568580
sage: mean_L = sum(L) / len(L)
569581
sage: norm(mean_L.n() - D.c) < 0.25
570582
True
571583
572-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1/2,0,0))
584+
sage: D = DGL(ZZ^3, 3.0, c=(1/2,0,0))
573585
sage: L = [D() for _ in range(2^12)] # long time
574586
sage: mean_L = sum(L) / len(L) # long time
575587
sage: norm(mean_L.n() - D.c) < 0.25 # long time
@@ -614,8 +626,8 @@ def sigma(self):
614626
615627
EXAMPLES::
616628
617-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
618-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0))
629+
sage: from sage.stats.all import DGL
630+
sage: D = DGL(ZZ^3, 3.0, c=(1,0,0))
619631
sage: D.sigma
620632
3.00000000000000
621633
"""
@@ -630,8 +642,8 @@ def c(self):
630642
631643
EXAMPLES::
632644
633-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
634-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0)); D
645+
sage: from sage.stats.all import DGL
646+
sage: D = DGL(ZZ^3, 3.0, c=(1,0,0)); D
635647
Discrete Gaussian sampler with Gaussian parameter σ = 3.00000000000000, c=(1, 0, 0) over lattice with basis
636648
<BLANKLINE>
637649
[1 0 0]
@@ -650,8 +662,8 @@ def c(self, _):
650662
651663
EXAMPLES::
652664
653-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
654-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0))
665+
sage: from sage.stats.all import DGL
666+
sage: D = DGL(ZZ^3, 3.0, c=(1,0,0))
655667
sage: D.c = 5
656668
Traceback (most recent call last):
657669
...
@@ -665,16 +677,16 @@ def __repr__(self):
665677
r"""
666678
EXAMPLES::
667679
668-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
669-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0)); D
680+
sage: from sage.stats.all import DGL
681+
sage: D = DGL(ZZ^3, 3.0, c=(1,0,0)); D
670682
Discrete Gaussian sampler with Gaussian parameter σ = 3.00000000000000, c=(1, 0, 0) over lattice with basis
671683
<BLANKLINE>
672684
[1 0 0]
673685
[0 1 0]
674686
[0 0 1]
675687
676688
sage: Sigma = Matrix(ZZ, [[10, -6, 1], [-6, 5, -1], [1, -1, 2]])
677-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^3, Sigma); D
689+
sage: D = DGL(ZZ^3, Sigma); D
678690
Discrete Gaussian sampler with Gaussian parameter Σ =
679691
[ 10.0000000000000 -6.00000000000000 1.00000000000000]
680692
[-6.00000000000000 5.00000000000000 -1.00000000000000]
@@ -698,16 +710,16 @@ def _call_in_lattice(self):
698710
699711
EXAMPLES::
700712
701-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
702-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0))
713+
sage: from sage.stats.all import DGL
714+
sage: D = DGL(ZZ^3, 3.0, c=(1,0,0))
703715
sage: L = [D._call_in_lattice() for _ in range(2^12)]
704716
sage: mean_L = sum(L) / len(L)
705717
sage: norm(mean_L.n() - D.c) < 0.25
706718
True
707719
708720
.. note::
709721
710-
Do not call this method directly, call :func:`DiscreteGaussianDistributionLatticeSampler.__call__` instead.
722+
Do not call this method directly, call :func:`DGL.__call__` instead.
711723
"""
712724
w = self.VS([d() for d in self.D], check=False)
713725
return w * self.B + self.c
@@ -718,16 +730,16 @@ def _call(self):
718730
719731
EXAMPLES::
720732
721-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
722-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1/2,0,0))
733+
sage: from sage.stats.all import DGL
734+
sage: D = DGL(ZZ^3, 3.0, c=(1/2,0,0))
723735
sage: L = [D._call() for _ in range(2^12)]
724736
sage: mean_L = sum(L) / len(L)
725737
sage: norm(mean_L.n() - D.c) < 0.25
726738
True
727739
728740
.. note::
729741
730-
Do not call this method directly, call :func:`DiscreteGaussianDistributionLatticeSampler.__call__` instead.
742+
Do not call this method directly, call :func:`DGL.__call__` instead.
731743
"""
732744
v = 0
733745
c, sigma, B = self._c, self._sigma, self.B
@@ -751,9 +763,9 @@ def add_offline_samples(self, cnt=1):
751763
752764
EXAMPLES::
753765
754-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
766+
sage: from sage.stats.all import DGL
755767
sage: Sigma = Matrix([[5, -2, 4], [-2, 10, -5], [4, -5, 5]])
756-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^3, Sigma)
768+
sage: D = DGL(ZZ^3, Sigma)
757769
sage: assert not D.is_spherical
758770
sage: D.add_offline_samples(2^12)
759771
sage: L = [D() for _ in range(2^12)] # Takes less time
@@ -772,17 +784,17 @@ def _call_non_spherical(self):
772784
773785
EXAMPLES::
774786
775-
sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler
787+
sage: from sage.stats.all import DGL
776788
sage: Sigma = Matrix([[5, -2, 4], [-2, 10, -5], [4, -5, 5]])
777-
sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^3, Sigma, c=(1/2,0,0))
789+
sage: D = DGL(ZZ^3, Sigma, c=(1/2,0,0))
778790
sage: L = [D._call_non_spherical() for _ in range(2^12)]
779791
sage: mean_L = sum(L) / len(L)
780792
sage: norm(mean_L.n() - D.c) < 0.25
781793
True
782794
783795
.. note::
784796
785-
Do not call this method directly, call :func:`DiscreteGaussianDistributionLatticeSampler.__call__` instead.
797+
Do not call this method directly, call :func:`DGL.__call__` instead.
786798
"""
787799
if len(self.offline_samples) == 0:
788800
self.add_offline_samples()

0 commit comments

Comments
 (0)