int ranbinom(int n, double p) { /** Knuth Vol 2, p 131 */ #define BTHRESH 50 int a, b ; double x ; if (p>=1) return n ; if (p<=0) return 0 ; if (n<=0) return 0 ; if (n<=BTHRESH) { return ranb1(n,p) ; /** small case */ } a = 1 + n/2 ; b = n + 1 - a ; x = ranbeta((double) a, (double) b) ; if (x>=p) return ranbinom(a-1, p/x) ; return (a + ranbinom(b-1, (p-x)/(1.0-x)) ) ; }
static void vbinom(long count, double n[], long lengthN, double p[], long lengthP, double * rvec) { long i, iN, iP; long incN = (lengthN == 1) ? 0 : 1; long incP = (lengthP == 1) ? 0 : 1; WHERE("vbinom"); for (i = iN = iP = 0; i < count; i++, iN += incN, iP += incP) { rvec[i] = ranbinom((long) n[iN], p[iP]); } /*for (i = 0; i < count; i++)*/ } /*vbinom()*/
void ranmultinom(int *samp, int n, double *p, int len) // multinomial sample p is prob dist n samples returned // work is O(len^2) which is silly { int x ; double *pp ; if (len==0) return ; ivzero(samp, len) ; if (n<=0) return ; if (len==1) { samp[0] = n ; return ; } ZALLOC(pp, len, double) ; copyarr(p, pp, len) ; bal1(pp, len) ; samp[0] = x = ranbinom(n, pp[0]) ; ranmultinom(samp+1, n-x, p+1, len-1) ; free(pp) ; }