Skip to content

Instantly share code, notes, and snippets.

@kellrott
Created January 28, 2013 18:33
Show Gist options
  • Save kellrott/4657894 to your computer and use it in GitHub Desktop.
Save kellrott/4657894 to your computer and use it in GitHub Desktop.
A GO implementation of the hyper geometric value calculation algorithm found at http://www.sciencedirect.com/science/article/pii/S1570866706000499
package hypergeometric
func invJm(n, x, N, m float64) float64 {
return (1-x/(m+1))/(1-(n-1-x)/(N-1-m));
}
func HyperQuick(n,x,N,M int64) float64 {
/*
Given N balls, M of which are black and the rest are white,
what is the probability C(n,x,N,M) that out of n balls selected
uniformly at random without replacement, at most x are black?
HyperQuick algorithm
http://www.sciencedirect.com/science/article/pii/S1570866706000499
*/
n_float := float64(n)
x_float := float64(x)
N_float := float64(N)
//accuracy e
var e float64
e = 0.000001
//loop1: fixed number of steps
var s, ak, bk float64
var k int64
s =1.0
for k=x; k < M-1; k++ {
s = s * invJm(float64(n_float), float64(x), float64(N), float64(k)) + 1.0
}
//loop2: variable number of steps according to accuracy e
ak = s;
bk = s;
k = M-2
epsk:=2*e;
for ((k<N-(n-x)-1) && (epsk>e)) {
ck := ak/bk;
k = k+1;
jjm := invJm(n_float,x_float,N_float,float64(k));
bk = bk*jjm+1.0;
ak = ak*jjm;
epsk = (N_float-(n_float-x_float)-1-float64(k))*(ck-ak/bk);
}
result := 1 - (ak/bk-epsk/2);
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment