[libmath-prime-util-perl] 06/16: Add add_factors
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:44:34 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.08
in repository libmath-prime-util-perl.
commit 4df961923c1b768485f3b5ce5ccc43f4c1163a14
Author: Dana Jacobsen <dana at acm.org>
Date: Tue Jun 19 02:07:12 2012 -0600
Add add_factors
---
Changes | 1 +
examples/test-nextprime-yafu.pl | 4 +--
lib/Math/Prime/Util.pm | 71 +++++++++++++++++++++++++++++++++++++----
3 files changed, 67 insertions(+), 9 deletions(-)
diff --git a/Changes b/Changes
index 7b3d91a..cf964d2 100644
--- a/Changes
+++ b/Changes
@@ -7,6 +7,7 @@ Revision history for Perl extension Math::Prime::Util.
performance comparisons.
- Static presieve for 7, 11, and 13. 1k of ROM used for prefilling sieve
memory, meaning we can skip the 7, 11, and 13 loops. ~15% speedup.
+ - Add all_factors function.
0.07 17 June 2012
- Fixed a bug in next_prime found by Lou Godio (thank you VERY much!).
diff --git a/examples/test-nextprime-yafu.pl b/examples/test-nextprime-yafu.pl
index e30c348..47e5bde 100755
--- a/examples/test-nextprime-yafu.pl
+++ b/examples/test-nextprime-yafu.pl
@@ -6,11 +6,11 @@ use File::Temp qw/tempfile/;
use autodie;
my $maxdigits = (~0 <= 4294967295) ? 10 : 20;
$| = 1; # fast pipes
-my $num = 10000;
+my $num = shift || 10000;
my $yafu_fname = "yafu_batchfile_$$.txt";
$SIG{'INT'} = \&gotsig;
-foreach my $digits (1 .. $maxdigits) {
+foreach my $digits (4 .. $maxdigits) {
printf "%2d-digit numbers", $digits;
my @narray = gendigits($digits, $num);
print ".";
diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index 64f290f..62bc48e 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -19,7 +19,7 @@ our @EXPORT_OK = qw(
prime_count prime_count_lower prime_count_upper prime_count_approx
nth_prime nth_prime_lower nth_prime_upper nth_prime_approx
random_prime random_ndigit_prime
- factor
+ factor all_factors
ExponentialIntegral LogarithmicIntegral RiemannR
);
our %EXPORT_TAGS = (all => [ @EXPORT_OK ]);
@@ -93,7 +93,7 @@ sub primes {
}
if ($method =~ /^Simple\w*$/i) {
- warn "Method 'Simple' is deprecated.";
+ carp "Method 'Simple' is deprecated.";
$method = 'Erat';
}
@@ -180,6 +180,21 @@ sub random_ndigit_prime {
# Perhaps a random_nbit_prime ? Definition?
+sub all_factors {
+ my $n = shift;
+ my @factors = factor($n);
+ my %all_factors;
+ foreach my $f1 (@factors) {
+ my @all = keys %all_factors;;
+ foreach my $f2 (@all) {
+ $all_factors{$f1*$f2} = 1 if ($f1*$f2) < $n;
+ }
+ $all_factors{$f1} = 1;
+ }
+ @factors = sort {$a<=>$b} keys %all_factors;
+ return @factors;
+}
+
# We use this object to let them control when memory is freed.
package Math::Prime::Util::MemFree;
use Carp qw/croak confess/;
@@ -193,6 +208,7 @@ sub DESTROY {
my $self = shift;
confess "instances count mismatch" unless $memfree_instances > 0;
Math::Prime::Util::prime_memfree if --$memfree_instances == 0;
+ return;
}
package Math::Prime::Util;
@@ -600,6 +616,15 @@ finally trial division for any survivors. This process is repeated for
each non-prime factor.
+=head2 all_factors
+
+ my @divisors = all_factors(30); # returns (2, 3, 5, 6, 10, 15)
+
+Produces all the divisors of a positive number input. Note that 1 and the
+input number are excluded. The divisors are a power set of multiplications
+of the prime factors, returned as a uniqued sorted list.
+
+
=head2 trial_factor
my @factors = trial_factor($n);
@@ -735,6 +760,8 @@ implementation.
Counting the primes to C<10^10> (10 billion), with time in seconds.
Pi(10^10) = 455,052,511.
+ External C programs in C / C++:
+
1.9 primesieve 3.6 forced to use only a single thread
2.2 yafu 1.31
5.6 Tomás Oliveira e Silva's segmented sieve v2 (Sep 2010)
@@ -742,7 +769,9 @@ Pi(10^10) = 455,052,511.
11.2 Tomás Oliveira e Silva's segmented sieve v1 (May 2003)
17.0 Pari 2.3.5 (primepi)
- 5.9 My segmented SoE
+ Small portable functions suitable for plugging into XS:
+
+ 5.3 My segmented SoE used in this module
15.6 My Sieve of Eratosthenes using a mod-30 wheel
17.2 A slightly modified verion of Terje Mathisen's mod-30 sieve
35.5 Basic Sieve of Eratosthenes on odd numbers
@@ -762,10 +791,38 @@ Perl modules, counting the primes to C<800_000_000> (800 million), in seconds:
[hours] Math::Primality 0.04
-C<is_prime> is slightly faster than M::P::XS for small inputs, but is much
-faster with larger ones (5x faster for 8-digit, over 50x for 14-digit).
-Math::Pari is relatively slow for small inputs, but becomes faster in the
-13-digit range.
+
+C<is_prime>: my impressions:
+
+ Module Small inputs Large inputs (10-20dig)
+ ----------------------- ------------- ----------------------
+ Math::Prime::Util Very fast Pretty fast
+ Math::Prime::XS Very fast Very, very slow if no small factors
+ Math::Pari Slow OK
+ Math::Prime::FastSieve Very fast N/A (too much memory)
+ Math::Primality Very slow Very slow
+
+The differences are in the implementations:
+ - L<Math::Prime::FastSieve> only works in a sieved range, which is really
+ fast if you can do it (M::P::U will do the same if you call
+ C<prime_precalc>). Larger inputs just need too much time and memory
+ for the sieve.
+ - L<Math::Primality> uses a GMP BPSW test which is overkill for our 64-bit
+ range. It's generally an order of magnitude or two slower than any
+ of the others.
+ - L<Math::Pari> has some very effective code, but it has some overhead to get
+ to it from Perl. That means for small numbers it is relatively slow: an
+ order of magnitude slower than M::P::XS and M::P::Util (though arguably
+ this is only important for benchmarking since "slow" is ~2 microseconds).
+ Large numbers transition over to smarter tests so don't slow down much.
+ - L<Math::Prime::XS> does trial divisions, which is wonderful if the input
+ has a small factor (or is small itself). But it can take 1000x longer
+ if given a large prime.
+ - L<Math::Prime::Util> looks in the sieve for a fast bit lookup if that
+ exists (default up to 30,000 but it can be expanded, e.g.
+ C<prime_precalc>), uses trial division for numbers higher than this but
+ not too large (0.1M on 64-bit machines, 100M on 32-bit machines), and a
+ deterministic set of Miller-Rabin tests for large numbers.
Factoring performance depends on the input, and the algorithm choices used
--
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