int ranhprob(int n, int a, int m) // hypergeometric sampling // rejection sampling. Devroye. Computing (1987) General method for log-concave densities // where mode is known /** urn with n balls . a black balls. Pick m without replacement. Return number of black balls picked. */ { double y ; double pm, logpm, w, ru, rw, rat ; int mode, x, zans ; mode = modehprob(n, a, m) ; logpm = loghprob(n, a, m, mode) ; pm = exp(logpm) ; w = 1 + pm ; for (;;) { ru = DRAND() ; rw = DRAND() ; if (ru <= w/(1+w)) y = DRAND()*w/pm ; else y = (w+ranexp())/pm ; x = nnint(y) ; if (ranmod(2)==0) x = -x ; zans = mode+x ; if (zans<0) continue ; if (zans>a) continue ; rat = exp(loghprob(n, a, m, zans)-logpm) ; rw *= MIN(1, exp(w-pm*y)) ; if (rw <= rat) break ; } return zans ; }
int ranhprob(int n, int a, int m) // rejection sampling. Devroye { double v, y ; double pm, logpm, w, ru, rw, rat ; int mode, k, x, zans ; v = (double) (a+1)*(m+1) / (double) (n+1) ; mode = (int) v ; /** for (k=-5; k<=5; ++k) { x = mode+k ; y = exp(loghprob(n, a, m, x)) ; printf("%4d %4d %12.6f\n", mode, x, y) ; } */ logpm = loghprob(n, a, m, mode) ; pm = exp(logpm) ; w = 1 + pm ; for (;;) { ru = DRAND() ; rw = DRAND() ; if (ru <= w/(1+w)) y = DRAND()*w/pm ; else y = (w+ranexp())/pm ; x = nnint(y) ; if (ranmod(2)==0) x = -x ; zans = mode+x ; if (zans<0) continue ; if (zans>a) continue ; rat = exp(loghprob(n, a, m, zans)-logpm) ; rw *= MIN(1, exp(1.0-pm*y)) ; if (rw <= rat) break ; } return zans ; }
void ewens(int *a, int n, double theta) /** implements the Ewens sampler. Categories 1...K */ { int i, k, maxcat=0 ; double t, x ; if (n==0) return ; a[0] = maxcat = 1 ; for (i=1 ; i< n ; i++) { t = theta/ ((double) i + theta) ; x = DRAND2() ; if (x > t) { k = ranmod(i) ; a[i] = a[k] ; } else { ++maxcat ; a[i] = maxcat ; } } }