[libmath-prime-util-perl] 03/17: Speedups for Pillai primes
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:47:13 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.21
in repository libmath-prime-util-perl.
commit 40cdc701b02fbc2900d70ed4c232577523019516
Author: Dana Jacobsen <dana at acm.org>
Date: Sun Feb 10 15:36:21 2013 -0800
Speedups for Pillai primes
---
Changes | 6 ++++
TODO | 2 --
bin/primes.pl | 61 +++++++++++++++++++++++++++------------
examples/make-script-test-data.pl | 3 +-
4 files changed, 51 insertions(+), 21 deletions(-)
diff --git a/Changes b/Changes
index 04eaa0b..cb1b56d 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,11 @@
Revision history for Perl extension Math::Prime::Util.
+0.21 ? February 2012
+
+ - primes.pl changes:
+ - add circular and Panaitopol primes
+ - big Pillai primes speedup by not using bigints if not necessary
+
0.20 3 February 2012
- Speedup for PP AKS, and turn off test on 32-bit machines.
diff --git a/TODO b/TODO
index de31039..80ecaae 100644
--- a/TODO
+++ b/TODO
@@ -44,5 +44,3 @@
tinymt32, seed it using the system rand (multiple calls, just use 8-bits
each), then use it to get 32-bit irands. This would only be used if they
didn't give us a RNG (so they don't care about strict crypto).
-
-- Add PE 291 Panatoipal primes to bin/primes.pl
diff --git a/bin/primes.pl b/bin/primes.pl
index ae9e272..7dceaff 100755
--- a/bin/primes.pl
+++ b/bin/primes.pl
@@ -92,6 +92,7 @@ GetOptions(\%opts,
'pnm1|A006794',
'euclid|A018239',
'circular|A068652',
+ 'panaitopol|A027862',
'provable',
'nompugmp', # turn off MPU::GMP for debugging
'version',
@@ -158,6 +159,9 @@ if ($start > $end) {
if (exists $opts{'palindromic'}) {
$segment_size = 10**length($start) - $start - 1; # all n-digit numbers
}
+ if (exists $opts{'panaitopol'}) {
+ $segment_size = (~0 == 4294967295) ? 2147483648 : int(10**12);
+ }
my $seg_start = $start;
my $seg_end = int($start + $segment_size);
@@ -277,6 +281,25 @@ sub cuban_primes {
@cprimes;
}
+sub panaitopol_primes {
+ my ($start, $end) = @_;
+
+ my @init;
+ push @init, 5 if $start <= 5 && $end >= 5;
+ push @init, 13 if $start <= 13 && $end >= 13;
+ return @init if $end < 41;
+ my $nbeg = ($start <= 41) ? 4 : int( sqrt( ($start-1)/2) );
+ my $nend = int( sqrt(($end-1)/2) );
+ $nbeg++ while (2*$nbeg*($nbeg+1)+1) < $start;
+ $nend-- while (2*$nend*($nend+1)+1) > $end;
+ # TODO: BigInts
+ return @init,
+ grep { is_prime($_) }
+ grep { ($_%5) && ($_%13) && ($_%17) && ($_%29) && ($_%37) }
+ map { 2*$_*($_+1)+1 }
+ $nbeg .. $nend;
+}
+
sub lucky_primes {
my ($start, $end) = @_;
# First do a (very basic) lucky number sieve to generate A000959.
@@ -333,26 +356,23 @@ sub ndig_palindromes {
}
# See: http://en.wikipedia.org/wiki/Pillai_prime
-# This is quite slow.
sub is_pillai {
my $p = shift;
- return 0 if $p < 2;
- # Simpler but much slower:
- # foreach my $n (grep { ($p % $_) != 1 } (2 .. $p-1)) {
- # return 1 if Math::BigInt->new($n)->bfac()->bmod($p) == ($p-1);
- # }
- # About 20% faster but sucks memory:
- # foreach my $n (grep { ($p % $_) != 1 } (2 .. $p-1)) {
- # $fac_c[$n] = Math::BigInt->new($n)->bfac() if !defined $fac_c[$n];
- # return 1 if ($fac_c[$n] % $p) == ($p-1);
- # }
- # Once p gets large (say 20,000+), then calculating and storing n! is
- # unreasonable, and the code below will be much faster.
- my $n_factorial_mod_p = Math::BigInt->bone();
- for (my $n = 2; $n < $p; $n++) {
- $n_factorial_mod_p->bmul($n)->bmod($p);
- next if $p % $n == 1;
- return 1 if $n_factorial_mod_p == ($p-1);
+ return 0 if $p <= 2;
+ my $half_word = (~0 == 4294967295) ? 65535 : 4294967295;
+ if ($p <= $half_word) {
+ my $nfac = 1;
+ for (my $n = 2; $n < $p; $n++) {
+ $nfac = ($nfac * $n) % $p;
+ return 1 if $nfac == $p-1 && ($p % $n) != 1;
+ }
+ } else {
+ # Must use bigints. Very slow.
+ my $n_factorial_mod_p = Math::BigInt->bone();
+ for (my $n = Math::BigInt->new(2); $n < $p; $n++) {
+ $n_factorial_mod_p->bmul($n)->bmod($p);
+ return 1 if $n_factorial_mod_p == ($p-1) && ($p % $n) != 1;
+ }
}
0;
}
@@ -423,6 +443,9 @@ sub gen_and_filter {
if (exists $opts{'cuban2'}) {
merge_primes(\$gen, $p, 'cuban2', cuban_primes($start, $end, 2));
}
+ if (exists $opts{'panaitopol'}) {
+ merge_primes(\$gen, $p, 'panaitopol', panaitopol_primes($start, $end));
+ }
if (exists $opts{'palindromic'}) {
if (!defined $gen) {
foreach my $d (length($start) .. length($end)) {
@@ -527,6 +550,7 @@ sub find_mod210_restriction {
sexy => {min=> 7, mod=>[11,13,17,23,31,37,41,47,53,61,67,73,83,97,101,103,107,121,131,137,143,151,157,163,167,173,181,187,191,193]},
safe => {min=>11, mod=>[17,23,47,53,59,83,89,107,137,143,149,167,173,179,209]},
sophie => {min=> 5, mod=>[11,23,29,41,53,71,83,89,113,131,149,173,179,191,209]},
+ panaitopol => {min=> 5, mod=>[1,11,13,41,43,53,61,71,83,103,113,131,151,173,181,193]},
# Nothing for good, pillai, palindromic, fib, lucas, mersenne, primorials
);
@@ -596,6 +620,7 @@ to only those primes additionally meeting these conditions:
--pnm1 Primorial-1 p#-1 is prime
--euclid Euclid pn#+1 is prime
--circular Circular all digit rotations of p are prime
+ --panaitopol Panaitopol p = (x^4-y^4)/(x^3+y^3) for some x,y
--provable Ensure all primes are provably prime
Note that options can be combined, e.g. display only safe twin primes.
diff --git a/examples/make-script-test-data.pl b/examples/make-script-test-data.pl
index 9e60a0f..4bcfe7c 100755
--- a/examples/make-script-test-data.pl
+++ b/examples/make-script-test-data.pl
@@ -22,13 +22,14 @@ my @test_data = (
[ 5385, "Safe", "safe", 0],
[ 5384, "SG", "sophie", 0],
[68652, "Circular", "circular", 0],
+ [27862, "Panaitopol", "panaitopol", 0],
[ 2407, "Cuban y+1", "cuban1", 0],
[ 2648, "Cuban y+2", "cuban2", 0],
[ 2385, "Palindromic", "palin", 32_965_656_923],
[ 668, "Mersenne", "mersenne", 10**100],
[ 5479, "Lucas", "lucas", 0],
[ 5478, "Fibonacci", "fibonacci", 0],
- [63980, "Pillai", "pillai", 2000],
+ [63980, "Pillai", "pillai", 0],
[28388, "Good", "good", 20000],
[31157, "Lucky", "lucky", 0],
[ 5234, "Primorial+1", "pnp1", 2500],
--
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