-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add kernel implementation of Binomial()
This uses the GMP functions mpz_bin_ui and mpz_bin_uiui. The following timings for certain central binomial coefficients illustrates the speedup: gap> n:=2^14;; a:=BINOMIAL_INT(2*n,n);; time; b:=Binomial_GAP(2*n,n);; time; 0 51 gap> n:=2^16;; a:=BINOMIAL_INT(2*n,n);; time; b:=Binomial_GAP(2*n,n);; time; 2 719 gap> n:=2^18;; a:=BINOMIAL_INT(2*n,n);; time; b:=Binomial_GAP(2*n,n);; time; 8 11470 gap> n:=2^19;; a:=BINOMIAL_INT(2*n,n);; time; b:=Binomial_GAP(2*n,n);; time; 14 51386 gap> n:=2^20;; a:=BINOMIAL_INT(2*n,n);; time; b:=Binomial_GAP(2*n,n);; time; 33 190444 The main reason the C version is so much faster is that it can accumulate the result in-place, whereas GAP creates tons and tons of temporary integer objects which then need to be garbage collected. Of course some other tricks employed by GMP help, too.
- Loading branch information
1 parent
3afa20b
commit 7a1953c
Showing
3 changed files
with
168 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
gap> START_TEST("Binomial.tst"); | ||
|
||
# | ||
gap> Binomial_GAP := function ( n, k ) | ||
> local bin, i, j; | ||
> if k < 0 then | ||
> bin := 0; | ||
> elif k = 0 then | ||
> bin := 1; | ||
> elif n < 0 then | ||
> bin := (-1)^k * Binomial_GAP( -n+k-1, k ); | ||
> elif n < k then | ||
> bin := 0; | ||
> elif n = k then | ||
> bin := 1; | ||
> elif n-k < k then | ||
> bin := Binomial_GAP( n, n-k ); | ||
> else | ||
> bin := 1; j := 1; | ||
> for i in [0..k-1] do | ||
> bin := bin * (n-i) / j; | ||
> j := j + 1; | ||
> od; | ||
> fi; | ||
> return bin; | ||
> end;; | ||
|
||
# compared C Binomial against GAP version | ||
gap> ForAll([-100..100], n->ForAll([-1..100], | ||
> k->Binomial_GAP(n,k) = BINOMIAL_INT(n,k))); | ||
true | ||
|
||
# | ||
gap> STOP_TEST("Binomial.tst", 1); |
7a1953c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If that works, and the gigantic speedup mentioned above is real, then -- that's a great improvement!!