[libmath-prime-util-perl] 06/35: Update partitions function
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:50:02 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.33
in repository libmath-prime-util-perl.
commit 82894f097d2d4c4beb46633e4f9c32cd938bc5b5
Author: Dana Jacobsen <dana at acm.org>
Date: Mon Oct 21 08:22:26 2013 -0700
Update partitions function
---
Changes | 8 +++----
lib/Math/Prime/Util.pm | 62 ++++++++++++++++++++++++++++----------------------
2 files changed, 39 insertions(+), 31 deletions(-)
diff --git a/Changes b/Changes
index a9d976a..0b6784a 100644
--- a/Changes
+++ b/Changes
@@ -4,10 +4,10 @@ Revision history for Perl module Math::Prime::Util
[API Changes]
- - all_factors now includes 1 and n, making it identical to Pari's
- divisors(n) function, but no longer identical to Math::Factor::XS's
- factors(n) function. This change allows consistency between
- divisor_sum(n,0) and scalar all_factors(n).
+ - all_factors now includes 1 and n, making it identical to Pari's
+ divisors(n) function, but no longer identical to Math::Factor::XS's
+ factors(n) function. This change allows consistency between
+ divisor_sum(n,0) and scalar all_factors(n).
[ADDED]
diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index 8d128a3..d8301a3 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -1660,35 +1660,43 @@ sub liouville {
return $l;
}
-{
- my @pent = (0, 1);
- my @part = (1);
- # TODO: make this faster. Pari is almost instant for n < 1000000.
- # We do seem to be faster than the stackoverflow or praxis solutions.
- sub partitions {
- my($n) = @_;
- return 1 if defined $n && $n <= 0;
- _validate_num($n) || _validate_positive_integer($n);
- return abs($part[$n]) if defined $part[$n];
- if ($n >= 128 && !defined $Math::BigInt::VERSION) {
- eval { require Math::BigInt; Math::BigInt->import(try=>'GMP,Pari'); 1; }
- or do { croak "Cannot load Math::BigInt"; };
- }
- my $d = int(sqrt($n+1));
- foreach my $i ( int((scalar @pent)/2) .. $d ) {
- push @pent, int(($i*(3*$i+1))/2), int((($i+1)*(3*$i+2))/2);
- }
- foreach my $j (scalar @part .. $n) {
- my $psum = ($n < 128) ? 0 : Math::BigInt->bzero;
- foreach my $k (1 .. $n) {
- last if $pent[$k] > $j;
- my $gk = $part[ $j - $pent[$k] ];
- $psum += (($k+1) & 2) ? $gk : -$gk;
- }
- $part[$j] = $psum;
+# This is faster than most regular implementations I've seen, e.g. the ones
+# on stackoverflow or praxis. The same algorithm in C+GMP is 300x faster.
+# It's much slower than Pari's floating point Rademacher algorithm.
+# See 2011+ FLINT and Fredrik Johansson's work for state of the art.
+# Perl-comb partitions(10^5) ~ 300 seconds
+# GMP-comb partitions(10^6) ~ 120 seconds ( ~300x faster than Perl-comb)
+# Pari partitions(10^8) ~ 100 seconds (~1000x faster than GMP-comb)
+# Bober partitions(10^9) ~ 20 seconds (~ 50x faster than Pari)
+# Johansson partitions(10^12) ~ 10 seconds (>1000x faster than Pari)
+sub partitions {
+ my($n) = @_;
+ return 1 if defined $n && $n <= 0;
+ _validate_num($n) || _validate_positive_integer($n);
+ if (!defined $Math::BigInt::VERSION) {
+ eval { require Math::BigInt; Math::BigInt->import(try=>'GMP,Pari'); 1; }
+ or do { croak "Cannot load Math::BigInt"; };
+ }
+ if ($_HAVE_GMP && defined &Math::Prime::Util::GMP::partitions) {
+ return Math::BigInt->new( '' . Math::Prime::Util::GMP::partitions($n) );
+ }
+ my $d = int(sqrt($n+1));
+ my @pent = (1);
+ foreach my $i ( 1 .. $d ) {
+ push @pent, int(($i*(3*$i+1))/2), int((($i+1)*(3*$i+2))/2);
+ }
+ my @part = (Math::BigInt->bone);
+ foreach my $j (scalar @part .. $n) {
+ my $psum = Math::BigInt->bzero;
+ my $k = 1;
+ foreach my $p (@pent) {
+ last if $p > $j;
+ if ((++$k) & 2) { $psum->badd( $part[ $j - $p ] ); }
+ else { $psum->bsub( $part[ $j - $p ] ); }
}
- return $part[$n];
+ $part[$j] = $psum;
}
+ return $part[$n];
}
sub chebyshev_theta {
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git
More information about the Pkg-perl-cvs-commits
mailing list