[libmath-prime-util-perl] 10/29: pure perl factoring tweaks
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:48:16 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.27
in repository libmath-prime-util-perl.
commit 62e3e90f359942f88513bb7db7a17139584717b6
Author: Dana Jacobsen <dana at acm.org>
Date: Fri May 10 18:58:58 2013 -0700
pure perl factoring tweaks
---
lib/Math/Prime/Util/PP.pm | 53 ++++++++++++++++++++++-------------------------
1 file changed, 25 insertions(+), 28 deletions(-)
diff --git a/lib/Math/Prime/Util/PP.pm b/lib/Math/Prime/Util/PP.pm
index 5ed8e7b..783891f 100644
--- a/lib/Math/Prime/Util/PP.pm
+++ b/lib/Math/Prime/Util/PP.pm
@@ -1158,9 +1158,9 @@ sub trial_factor {
my $_holf_r;
my @_fsublist = (
sub { prho_factor (shift, 8*1024, 3) },
- sub { pbrent_factor (shift, 32*1024, 1) },
sub { pminus1_factor(shift, 10_000); },
- sub { pminus1_factor(shift, 600_000); },
+ sub { pbrent_factor (shift, 32*1024, 1) },
+ sub { pminus1_factor(shift, 1_000_000); },
sub { pbrent_factor (shift, 512*1024, 7) },
sub { ecm_factor (shift, 1_000, 5_000, 10) },
sub { pminus1_factor(shift, 4_000_000); },
@@ -1412,8 +1412,7 @@ sub pminus1_factor {
while (1) {
$pc_end = $B1 if $pc_end > $B1;
@bprimes = @{ primes($pc_beg, $pc_end) };
- while (@bprimes) {
- my $q = shift @bprimes;
+ foreach my $q (@bprimes) {
my $k = $q;
if ($q <= $sqrtb1) {
my $kmin = int($B1 / $q);
@@ -1433,6 +1432,7 @@ sub pminus1_factor {
}
# Stage 2 isn't really any faster than stage 1 for the examples I've tried.
+ # Perl's overhead is greater than the savings of multiply vs. powmod
if (!defined $B1) {
for my $mul (1, 100, 1000, 10_000, 100_000, 1_000_000) {
@@ -1451,7 +1451,7 @@ sub pminus1_factor {
$B2 = 1*$B1 unless defined $B2;
my $one = $n->copy->bone;
- my ($j, $q, $saveq) = (1, 2, 2);
+ my ($j, $q, $saveq) = (32, 2, 2);
my $t = $one->copy;
my $a = $one->copy->badd(1);
my $savea = $a->copy;
@@ -1463,26 +1463,23 @@ sub pminus1_factor {
while (1) {
$pc_end = $B1 if $pc_end > $B1;
@bprimes = @{ primes($pc_beg, $pc_end) };
- while (@bprimes) {
- $q = shift @bprimes;
- my $k = $q;
- my $kmin = int($B1 / $q);
+ foreach $q (@bprimes) {
+ my($k, $kmin) = ($q, int($B1 / $q));
while ($k <= $kmin) { $k *= $q; }
$t *= $k; # accumulate powers for a
- if ( ($j++ % 32) == 0) {
+ if ( ($j++ % 64) == 0) {
+ next if $pc_beg > 2 && ($j-1) % 256;
$a->bmodpow($t, $n);
$t = $one->copy;
if ($a == 0) { push @factors, $n; return @factors; }
$f = Math::BigInt::bgcd( $a-1, $n );
last if $f == $n;
- if ($f != 1) {
- push @factors, $f, $n/$f;
- return @factors;
- }
+ return _found_factor($f, $n, "pminus1", @factors) if $f != 1;
$saveq = $q;
$savea = $a->copy;
}
}
+ $q = $bprimes[-1];
last if $f != 1 || $pc_end >= $B1;
$pc_beg = $pc_end+1;
$pc_end += 500_000;
@@ -1495,8 +1492,7 @@ sub pminus1_factor {
$q = $saveq;
$a = $savea->copy;
while ($q <= $B1) {
- my $k = $q;
- my $kmin = int($B1 / $q);
+ my ($k, $kmin) = ($q, int($B1 / $q));
while ($k <= $kmin) { $k *= $q; }
$a->bmodpow($k, $n);
my $f = Math::BigInt::bgcd( $a-1, $n );
@@ -1521,17 +1517,17 @@ sub pminus1_factor {
while (1) {
$pc_end = $B2 if $pc_end > $B2;
@bprimes = @{ primes($pc_beg, $pc_end) };
- while (@bprimes) {
- my $lastq = $q;
- $q = shift @bprimes;
- my $qdiff = ($q - $lastq) / 2 - 1;
+ foreach my $i (0 .. $#bprimes) {
+ my $diff = $bprimes[$i] - $q;
+ $q = $bprimes[$i];
+ my $qdiff = ($diff >> 1) - 1;
if (!defined $precomp_bm[$qdiff]) {
- $precomp_bm[$qdiff] = $bm->copy->bmodpow($q-$lastq, $n);
+ $precomp_bm[$qdiff] = $bm->copy->bmodpow($diff, $n);
}
$a->bmul($precomp_bm[$qdiff])->bmod($n);
if ($a == 0) { push @factors, $n; return @factors; }
$b->bmul($a-1);
- if (($j++ % 64) == 0) {
+ if (($j++ % 128) == 0) {
$b->bmod($n);
$f = Math::BigInt::bgcd( $b, $n );
last if $f != 1;
@@ -1707,6 +1703,12 @@ sub ecm_factor {
# With multiple curves, it's better to get all the primes at once.
# The downside is this can kill memory with a very large B1.
my @bprimes = @{ primes(3, $B1) };
+ foreach my $q (@bprimes) {
+ last if $q > $sqrt_b1;
+ my($k,$kmin) = ($q, int($B1/$q));
+ while ($k <= $kmin) { $k *= $q; }
+ $q = $k;
+ }
my @b2primes = ($B2 > $B1) ? @{primes($B1+1, $B2)} : ();
my $irandf = Math::Prime::Util::_get_rand_func();
@@ -1728,12 +1730,7 @@ sub ecm_factor {
my $i = 15;
for (my $q = 2; $q < $B1; $q *= 2) { $ECP->double(); }
- foreach my $q (@bprimes) {
- my $k = $q;
- if ($k < $sqrt_b1) {
- my $kmin = int($B1 / $q);
- while ($k <= $kmin) { $k *= $q; }
- }
+ foreach my $k (@bprimes) {
$ECP->mul($k);
$fm = ($fm * $ECP->x() ) % $n;
if ($i++ % 32 == 0) {
--
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