int Ray::tail(xorshift64& rand){ double x,y,r; r = xsigma/sigma; for(;;){ x = rand_exp(rand,r); y = rand_exp(rand,1); if(2*y > x*x) break; } x = x*sigma+xsigma; x = floor(x+0.5); return int(x); }
value gamma_CAML_randexp( value m ) { CAMLparam1( m ); CAMLlocal1( r ); r = caml_copy_double( rand_exp( Double_val(m) ) ); CAMLreturn( r ); }
int rand_poisson ( double lambda ) { int v; if (lambda>10000) { v = (int) (lambda + rand_gaussian()*sqrt(lambda) + 0.5); } else { v = 0; for (;;) { lambda -= rand_exp(); if (lambda<=0) break; v += 1; } } return v; }
double rand_gamma ( double a ) { double b, c, X, Y, Z, U, V, W; if (a<0.00001) { X = a; } else if (a<=1) { U = rand_uniopen(); X = rand_gamma(1+a) * pow(U,1/a); } else if (a<1.00001) { X = rand_exp(); } else { b = a-1; c = 3*a - 0.75; for (;;) { U = rand_uniopen(); V = rand_uniopen(); W = U*(1-U); Y = sqrt(c/W) * (U-0.5); X = b+Y; if (X>=0) { Z = 64*W*W*W*V*V; if (Z <= 1 - 2*Y*Y/X || log(Z) <= 2 * (b*log(X/b) - Y)) break; } } } return X<1e-30 && X<a ? (a<1e-30 ? a : 1e-30) : X; }
double rexp_inv(void) { double x = rand_exp(rng); return exp(-x); }