// (C) 2018 University of Bristol. See License.txt #include "DiscreteGauss.h" #include "math.h" void DiscreteGauss::set(double RR) { R=RR; e=exp(1); e1=exp(0.25); e2=exp(-1.35); } /* Return a value distributed normaly with std dev R */ int DiscreteGauss::sample(PRNG& G, int stretch) const { /* Uses the ratio method from Wikipedia to get a Normal(0,1) variable X Then multiplies X by R */ double U,V,X,R1,R2,R3,X2; int ans; while (true) { U=G.get_double(); V=G.get_double(); R1=5-4*e1*U; R2=4*e2/U+1.4; R3=-4/log(U); X=sqrt(8/e)*(V-0.5)/U; X2=X*X; if (X2<=R1 || (X2 RandomVectors::sample_Gauss(PRNG& G, int stretch) const { vector ans(n); for (int i=0; i RandomVectors::sample_Hwt(PRNG& G) const { if (h>n/2) { return sample_Gauss(G); } vector ans(n); for (int i=0; i RandomVectors::sample_Half(PRNG& G) const { vector ans(n); for (int i=0; i RandomVectors::sample_Uniform(PRNG& G,const bigint& B) const { vector ans(n); bigint v; for (int i=0; i