//-------------------------------------------------------------------------------- double binomial(unsigned long n, unsigned long k) { { NTA_ASSERT(k <= n) << "binomial: Wrong arguments: n= " << n << " k= " << k; } if (n < 171) return floor(0.5 + fact(n) / (fact(k) * fact(n-k))); else return floor(0.5 + exp(lfact(n) - lfact(k) - lfact(n-k))); }
/* generates a success * trials table of bionomial probability densities (log transformed) */ static double* logbinomial_table( const int n_size ) { /* prob distribution for binom var is p(k) = {n! \over k! (n-k)! } p^k (1-p)^{n-k} */ /* this calcs p(k) = {log(n!) - log(k!) - log((n-k)!) */ int k, n; double *logbinom = (double*)calloc(n_size * n_size, sizeof(double)); for (n = 1; n < n_size; ++n) { double lfn = lfact(n); for (k = 1; k <= n; ++k) logbinom[n<<8|k] = lfn - lfact(k) - lfact(n-k); } return logbinom; }
/* * Computes the hypergeometric function 1F1(a;b;z1,z2) in canonical form (z1 > z2 > 0) */ static double compute_1F1_2d_canon(double a, double b, double z1, double z2, int iter) { int i, j; double g, F = 0.0, logz1 = log(z1), logz2 = log(z2); for (i = 0; i < iter; i++) { for (j = 0; j < iter; j++) { g = lgamma(i+a) + lgamma(j+a) - lgamma(i+j+b) + i*logz1 + j*logz2 - lfact(i) - lfact(j); if ((i > z1 || j > z2) && exp(g) < EPSILON * F) // exp(g) < 2e-9 break; F += exp(g); } } return 2*sqrt(M_PI)*F; }
long lfact ( int n ) { if ( n < 0 ) return -1 ; if ( n < 1 ) return 1 ; return n * lfact ( n - 1 ) ; }
/* * Computes the hypergeometric function 1F1(a;b;z) in canonical form (z > 0) */ static double compute_1F1_1d_canon(double a, double b, double z, int iter) { //printf("compute_1F1_1d_canon(%f, %f, %f, %d)\n", a, b, z, iter); int i; double g, F = 0.0, logz = log(z); for (i = 0; i < iter; i++) { g = lgamma(i+a) - lgamma(i+b) + i*logz - lfact(i); if (i > z && exp(g) < EPSILON * F) // exp(g) < 1e-8 * F break; F += exp(g); } return 2*sqrt(M_PI)*F; }
/* * Computes the hypergeometric function 1F1(a;b;z1,z2,z3) in canonical form (z1 > z2 > z3 > 0) */ static double compute_1F1_3d_canon(double a, double b, double z1, double z2, double z3, int iter) { int i, j, k; double g, F = 0.0, logz1 = log(z1), logz2 = log(z2), logz3 = log(z3); for (i = 0; i < iter; i++) { for (j = 0; j < iter; j++) { for (k = 0; k < iter; k++) { g = lgamma(i+a) + lgamma(j+a) + lgamma(k+a) - lgamma(i+j+k+b) + i*logz1 + j*logz2 + k*logz3 - lfact(i) - lfact(j) - lfact(k); if ((i > z1 || j > z2 || k > z3) && exp(g) < EPSILON * F) // exp(g) < 2e-9 break; F += exp(g); } } } return 2*sqrt(M_PI)*F; }