This is an automated email from the git hooks/post-receive script. ppm-guest pushed a commit to annotated tag v0.13 in repository libmath-prime-util-perl.
commit a892e8f4d90530832f4ae674d56dcba9055ff914 Author: Dana Jacobsen <d...@acm.org> Date: Sat Oct 20 03:29:17 2012 -0600 Enhancements to primes.pl tests --- examples/make-script-test-data.pl | 66 +++++++++++++++-------- examples/test-primes-script.pl | 110 ++++++++++++++++++++------------------ examples/test-primes-script2.pl | 84 +++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+), 74 deletions(-) diff --git a/examples/make-script-test-data.pl b/examples/make-script-test-data.pl index bfee664..760f4eb 100755 --- a/examples/make-script-test-data.pl +++ b/examples/make-script-test-data.pl @@ -6,28 +6,33 @@ use FindBin; use bigint; use Data::BitStream::XS; use Math::Prime::Util qw/is_prime/; -$|++; #flush the output buffer after every write() or print() function +$|++; +# Encode all the OEIS text files for our primes.pl testing into a bitstream. +# This not only makes the test script run much faster, but it turns 18 text +# files of 5MB into one ~300k file. my @test_data = ( - [ 668, "Mersenne", "--mersenne", 10**100], - [ 7529, "Triplet", "--triplet", 0], - [ 7530, "Quadruplet", "--quadruplet", 0], - [23200, "Cousin", "--cousin", 0], - [23201, "Sexy", "--sexy", 0], - [ 1359, "Twin", "--twin", 0], - [ 5385, "Safe", "--safe", 0], - [ 5384, "SG", "--sophie", 0], - [ 2385, "Palindromic", "--palin", 32_965_656_923], - [ 5479, "Lucas", "--lucas", 0], - [ 5478, "Fibonacci", "--fibonacci", 0], - [63980, "Pillai", "--pillai", 2000], - [28388, "Good", "--good", 20000], - [ 2407, "Cuban y+1", "--cuban1", 0], - [ 2648, "Cuban y+2", "--cuban2", 100_000_000], - [ 5234, "Primorial+1", "--pnp1", 2500], - [ 6794, "Primorial-1", "--pnm1", 2500], - [18239, "Euclid", "--euclid", 0], + # OEIS# TEXT NAME script-arg skip if > this + [ 7529, "Triplet", "triplet", 0], + [ 7530, "Quadruplet", "quadruplet", 0], + [23200, "Cousin", "cousin", 0], + [23201, "Sexy", "sexy", 0], + [ 1359, "Twin", "twin", 0], + [ 5385, "Safe", "safe", 0], + [ 5384, "SG", "sophie", 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], + [28388, "Good", "good", 20000], + [31157, "Lucky", "lucky", 0], + [ 5234, "Primorial+1", "pnp1", 2500], + [ 6794, "Primorial-1", "pnm1", 2500], + [18239, "Euclid", "euclid", 0], ); foreach my $test (@test_data) { @@ -45,7 +50,7 @@ foreach my $test (@test_data) { my $stream = Data::BitStream::XS->new( file => 'script-test-data.bs', mode => 'w' ); foreach my $test (@test_data) { - test_oeis(@$test); + encode_oeis(@$test); } $stream->write_close(); @@ -102,12 +107,15 @@ sub read_oeis { return \@ref; } -sub test_oeis { +sub encode_oeis { my($oeis_no, $name, $script_arg, $restrict, $ref_data) = @_; my @ref = @$ref_data; printf "%12s primes: stream..", $name; + put_text_string($stream, $script_arg); + put_text_string($stream, $name); + if ($ref[-1] > 18446744073709551615) { print ","; # Store the first two values, then a list of deltas @@ -151,3 +159,19 @@ sub test_oeis { print "done\n"; } + +sub put_text_string { + my ($stream, $str) = @_; + $stream->put_gamma(ord($_)) for (split "", $str); + $stream->put_gamma(0); + 1; +} + +sub get_text_string { + my ($stream) = @_; + my $str = ''; + while (my $c = $stream->get_gamma) { + $str .= chr($c); + } + $str; +} diff --git a/examples/test-primes-script.pl b/examples/test-primes-script.pl index 7f3390f..052b6af 100755 --- a/examples/test-primes-script.pl +++ b/examples/test-primes-script.pl @@ -8,50 +8,29 @@ use bigint; use Data::BitStream::XS; $|++; #flush the output buffer after every write() or print() function -# Should use a "put_test_string" sort of call on the test data, so we -# wouldn't need this. -my @test_data = ( - [ 668, "Mersenne", "--mersenne", 10**100], - [ 7529, "Triplet", "--triplet", 0], - [ 7530, "Quadruplet", "--quadruplet", 0], - [23200, "Cousin", "--cousin", 0], - [23201, "Sexy", "--sexy", 0], - [ 1359, "Twin", "--twin", 0], - [ 5385, "Safe", "--safe", 0], - [ 5384, "SG", "--sophie", 0], - [ 2385, "Palindromic", "--palin", 32_965_656_923], - [ 5479, "Lucas", "--lucas", 0], - [ 5478, "Fibonacci", "--fibonacci", 0], - [63980, "Pillai", "--pillai", 2000], - [28388, "Good", "--good", 20000], - [ 2407, "Cuban y+1", "--cuban1", 0], - [ 2648, "Cuban y+2", "--cuban2", 100_000_000], - [ 5234, "Primorial+1", "--pnp1", 2500], - [ 6794, "Primorial-1", "--pnm1", 2500], - [18239, "Euclid", "--euclid", 0], -); -my %oeis_name = map { $_->[0] => $_->[1] } @test_data; -my %oeis_number = map { my $n=$_->[2]; $n=~s/^--//; $n => $_->[0] } @test_data; +# Maps between oeis name and number, filled in as we read sequences. +my %oeis_number; # short-name -> no +my %oeis_data; # no -> ref to info+data + +# returned array contains elements of: +# [$oeis_no, $name, $script_arg, $num_entries, \@ref_data]; +my $test_data = read_script_data('script-test-data.bs'); # Verify additional filters my @additional_filters; foreach my $name (@ARGV) { $name =~ s/^--//; - die "Unknown filter: $name\n" unless defined $oeis_number{$name}; - push @additional_filters, $name; + my $oeis_no = $oeis_number{$name}; + die "Unknown filter: $name\n" unless defined $oeis_no; + push @additional_filters, $oeis_no; } - -my $test_data_hash = read_script_data('script-test-data.bs'); - if (@additional_filters > 0) { - print "Additional Filters: ", join(" ", @additional_filters), "\n"; + print "Additional Filters: ", + join(" ", map { $oeis_data{$_}->[2] } @additional_filters), "\n"; } -foreach my $test (@test_data) { - my $oeis_no = $test->[0]; - if (!defined $test_data_hash->{$oeis_no}) { - die "No test data found for OEIS $oeis_no : $test->[1] primes\n"; - } - test_oeis(@$test, $test_data_hash); + +foreach my $test (@$test_data) { + test_oeis(@$test); } @@ -64,11 +43,13 @@ sub read_script_data { unless -r $filename; my $stream = Data::BitStream::XS->new( file => $filename, mode => 'ro' ); - my %hash; + my @data; while (!$stream->exhausted) { + my $script_arg = get_text_string($stream); + my $name = get_text_string($stream); my ($oeis_no, $is_bigint, $num_entries, @ref) = $stream->get_gamma(5); - printf "%12s primes (OEIS A%06d): reading %7d entries..", $oeis_name{$oeis_no}, $oeis_no, $num_entries; + printf "%12s primes (OEIS A%06d): reading %7d entries..", $name, $oeis_no, $num_entries; if ($is_bigint) { print ","; my $k = 2; @@ -76,7 +57,7 @@ sub read_script_data { print "."; # Check to see if we have any giant deltas foreach my $d (@deltas) { - if ($d >= 18446744073709551614) { + if ( $d >= '18446744073709551614' ) { my $len = $stream->get_gamma; my $binstr = $stream->read_string($len); $d = Math::BigInt->new('0b' . $binstr); @@ -85,7 +66,6 @@ sub read_script_data { print "."; my $prev = $ref[1]; push @ref, map { $prev = $_*2+$prev+2; } @deltas; - $hash{$oeis_no} = \@ref; print ".\n"; } else { no bigint; @@ -95,25 +75,31 @@ sub read_script_data { print "."; my $prev = $ref[1]; push @ref, map { $prev = $_*2+$prev+2; } @deltas; - $hash{$oeis_no} = \@ref; print ".\n"; } + my $row = [$oeis_no, $name, $script_arg, $num_entries, \@ref]; + push @data, $row; + $oeis_data{$oeis_no} = $row; + $oeis_number{$script_arg} = $oeis_no; } - \%hash; + \@data; } sub test_oeis { - my($oeis_no, $name, $script_arg, $restrict, $test_data_hash) = @_; + my($oeis_no, $name, $script_arg, $num_entries, $ref_data) = @_; - my @ref = @{ $test_data_hash->{$oeis_no} }; + my @ref = @$ref_data; my $end = $ref[-1]; - - foreach my $filter_name (@additional_filters) { - my $filter_no = $oeis_number{$filter_name}; - my %filter_data; - undef @filter_data{ @{$test_data_hash->{$filter_no}} }; - my $filter_end = $test_data_hash->{$filter_no}->[-1]; - @ref = grep { exists $filter_data{$_} } @ref; + $script_arg = '--' . $script_arg; + + foreach my $filter_no (@additional_filters) { + #my $row = [$oeis_no, $name, $script_arg, $num_entries, \@ref]; + my $filter_name = $oeis_data{$filter_no}->[2]; + my $filter_data_ref = $oeis_data{$filter_no}->[4]; + my %filter_data_hash; + undef @filter_data_hash{ @$filter_data_ref }; + my $filter_end = $filter_data_ref->[-1]; + @ref = grep { exists $filter_data_hash{$_} } @ref; $script_arg .= " --$filter_name"; $end = $filter_end if $end > $filter_end; # bring endpoint down } @@ -130,11 +116,29 @@ sub test_oeis { printf " %7d. %7.2f ms/prime\n", $num_generated, $msperprime; } - die "Not equal numbers: ", scalar @ref, " - ", scalar @scr, "\n" - unless @ref == @scr; + if (scalar @ref != scalar @scr) { + warn " $FindBin::Bin/../bin/primes.pl $script_arg 1 $end\n"; + die "Not equal numbers: ", scalar @ref, " - ", scalar @scr, "\n"; + } foreach my $i (0 .. $#ref) { die "$name prime $i not equal: $ref[$i] - $scr[$i]\n" if $ref[$i] != $scr[$i]; } } + +sub put_text_string { + my ($stream, $str) = @_; + $stream->put_gamma(ord($_)) for (split "", $str); + $stream->put_gamma(0); + 1; +} + +sub get_text_string { + my ($stream) = @_; + my $str = ''; + while (my $c = $stream->get_gamma) { + $str .= chr($c); + } + $str; +} diff --git a/examples/test-primes-script2.pl b/examples/test-primes-script2.pl new file mode 100755 index 0000000..5de579d --- /dev/null +++ b/examples/test-primes-script2.pl @@ -0,0 +1,84 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use File::Spec::Functions; +use FindBin; +use Time::HiRes qw(gettimeofday tv_interval); +use bigint; +use Math::NumSeq; +$|++; #flush the output buffer after every write() or print() function + +compare('Primes', + 10000000, + "$FindBin::Bin/../bin/primes.pl 1 LASTNUM", + q/perl -MMath::NumSeq::Primes -e 'my $seq = Math::NumSeq::Primes->new; while (1) { my $v = ($seq->next)[1]; last if $v > LASTNUM; print "$v\n"; }'/); + +compare('Twin', + 10000000, + "$FindBin::Bin/../bin/primes.pl --twin 1 LASTNUM", + q/perl -MMath::NumSeq::TwinPrimes -e 'my $seq = Math::NumSeq::TwinPrimes->new; while (1) { my $v = ($seq->next)[1]; last if $v > LASTNUM; print "$v\n"; }'/); + +compare('Sophie Germain', + 10000000, + "$FindBin::Bin/../bin/primes.pl --sophie 1 LASTNUM", + q/perl -MMath::NumSeq::SophieGermainPrimes -e 'my $seq = Math::NumSeq::SophieGermainPrimes->new; while (1) { my $v = ($seq->next)[1]; last if $v > LASTNUM; print "$v\n"; }'/); + +# Why Math::Prime::Util::is_prime instead of Math::Prime::XS::is_prime? +# 1) it's much faster for the palindrome tests +# 2) it supports bignums, which is required for Fib, Euclid, Lucas, etc. + +compare('Palindromic', + '10**11', + "$FindBin::Bin/../bin/primes.pl --palin 1 LASTNUM", + q/perl -MMath::Prime::Util=is_prime -MMath::NumSeq::Palindromes -e 'my $seq = Math::NumSeq::Palindromes->new; while (1) { my $v = ($seq->next)[1]; last if $v > LASTNUM; print "$v\n" if is_prime($v); }'/); + +# Sadly Math::NumSeq::LucasNumbers uses OEIS 204 (1,3) instead of OEIS 32 (-1,2) +# and neither package offers a way to adjust. +#compare('Lucas', +# '10**100', +# "$FindBin::Bin/../bin/primes.pl --lucas 1 LASTNUM", +# q/perl -MMath::Prime::Util=is_prime -MMath::NumSeq::LucasNumbers -e 'my $seq = Math::NumSeq::LucasNumbers->new; while (1) { my $v = ($seq->next)[1]; last if $v > LASTNUM; print "$v\n" if is_prime($v); }'/); + +compare('Fibonacci', + '10**100', + "$FindBin::Bin/../bin/primes.pl --fib 1 LASTNUM", + q/perl -MMath::Prime::Util=is_prime -MMath::NumSeq::Fibonacci -e 'my $seq = Math::NumSeq::Fibonacci->new; while (1) { my $v = ($seq->next)[1]; last if $v > LASTNUM; print "$v\n" if is_prime($v); }'/); + +compare('Euclid', + '10**200', + "$FindBin::Bin/../bin/primes.pl --euclid 1 LASTNUM", + q/perl -MMath::Prime::Util=is_prime -MMath::NumSeq::Primorials -e 'my $seq = Math::NumSeq::Primorials->new; while (1) { my $v = ($seq->next)[1] + 1; last if $v > LASTNUM; print "$v\n" if is_prime($v); }'/); + +compare('Lucky', + '100000', + "$FindBin::Bin/../bin/primes.pl --lucky 1 LASTNUM", + q/perl -MMath::Prime::Util=is_prime -MMath::NumSeq::LuckyNumbers -e 'my $seq = Math::NumSeq::LuckyNumbers->new; while (1) { my $v = ($seq->next)[1]; last if $v > LASTNUM; print "$v\n" if is_prime($v); }'/); + + +sub compare { + my($name, $end, $command_scr, $command_mns) = @_; + no bigint; + $command_scr =~ s/LASTNUM/$end/; + $command_mns =~ s/LASTNUM/$end/; + + printf "%15s to %8s", $name, $end; + + my $start_scr = [gettimeofday]; + my @scr = split /\s+/, qx/$command_scr/; + my $seconds_scr = tv_interval($start_scr); + + printf " (%7d). primes.pl %6.2fs", scalar @scr, $seconds_scr; + + my $start_mns = [gettimeofday]; + my @mns = split /\s+/, qx/$command_mns/; + my $seconds_mns = tv_interval($start_mns); + + printf " Math::NumSeq %6.2fs\n", $seconds_mns; + + die "$name: primes.pl generated ", scalar @scr, " results. MNS generated ", scalar @mns, " results." if scalar @scr != scalar @mns; + + foreach my $i (0 .. $#scr) { + die "$name prime $i not equal:\n primes.pl: $scr[$i]\n MNumSeq: $mns[$i]\n" + if $scr[$i] != $mns[$i]; + } +} -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git _______________________________________________ Pkg-perl-cvs-commits mailing list Pkg-perl-cvs-commits@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-perl-cvs-commits