Binomial -- faster for large args
abbott at module.dima.unige.it
abbott at module.dima.unige.it
Fri May 14 15:22:30 CEST 2004
Hi,
The following routine (called "binomial") seems to be usefully
faster than that supplied with GMP 4.1.3 (on my Linux/Athlon box)
at least for larger values of n and r -- I didn't compare then for
smaller values.
I have NOT put in special case code (e.g. r=0 or r=1 or r > n/2)
Hope it is clean enough for you to use.
John.
---------------------------------------------------------------------
void binomial(mpz_t ans, unsigned long n, unsigned long r)
{
/* The following value for chunk worked well in my tests */
const unsigned chunk = 10+int(floor(2*sqrt(double(n))));
mpz_t num, den, g;
mpz_init(num);
mpz_init(den);
mpz_init(g);
mpz_set_ui(ans,1);
unsigned int k=0;
while (k < r)
{
mpz_set_ui(num,1);
mpz_set_ui(den,1);
for (unsigned int i=0; i < chunk; ++i)
{
mpz_mul_ui(num,num,n-k);
mpz_mul_ui(den,den,k+1);
++k;
if (k >= r) break;
}
mpz_gcd(g,num,den);
mpz_divexact(num,num,g);
mpz_divexact(den,den,g);
mpz_mul(ans,ans,num);
mpz_divexact(ans,ans,den);
}
}
More information about the gmp-devel
mailing list