[libmath-prime-util-perl] 05/08: Put segment mutex back

Partha P. Mukherjee ppm-guest at moszumanska.debian.org
Thu May 21 18:47:22 UTC 2015


This is an automated email from the git hooks/post-receive script.

ppm-guest pushed a commit to annotated tag v0.22
in repository libmath-prime-util-perl.

commit 11422a594d692d8194756c7e5405dd8d977087bd
Author: Dana Jacobsen <dana at acm.org>
Date:   Mon Feb 25 20:50:40 2013 -0800

    Put segment mutex back
---
 MANIFEST                    |   4 +-
 TODO                        |  11 ++-
 XS.xs                       |   2 +-
 cache.c                     |   2 +
 examples/test-euler-pari.pl |   2 +-
 xt/factor-holf.pl           |  27 +++++++
 xt/make-script-test-data.pl | 179 ++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 219 insertions(+), 8 deletions(-)

diff --git a/MANIFEST b/MANIFEST
index bcd426f..945ec81 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -46,7 +46,6 @@ examples/test-factor-yafu.pl
 examples/test-factor-mpxs.pl
 examples/test-nextprime-yafu.pl
 examples/test-primes-yafu.pl
-examples/test-holf.pl
 examples/test-nthapprox.pl
 examples/test-pcapprox.pl
 examples/sophie_germain.pl
@@ -56,7 +55,6 @@ examples/parallel_fibprime.pl
 examples/test-bpsw.pl
 examples/test-euler-pari.pl
 examples/test-factor-gnufactor.pl
-examples/make-script-test-data.pl
 examples/test-primes-script.pl
 examples/test-primes-script2.pl
 bin/primes.pl
@@ -88,4 +86,6 @@ t/91-release-pod-syntax.t
 t/92-release-pod-coverage.t
 xt/moebius-mertens.pl
 xt/primality-small.pl
+xt/factor-holf.pl
+xt/make-script-test-data.pl
 .travis.yml
diff --git a/TODO b/TODO
index 80ecaae..a3df769 100644
--- a/TODO
+++ b/TODO
@@ -40,7 +40,10 @@
 - Dynamically use a mulmodadd in PP aks, just like the new C code does.
   This will mean it'll work for full-size native ints.
 
-- Perl's rand() is a mess.  I believe a decent workaround is to include
-  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).
+- More efficient Mertens.  The current version has poor growth.
+
+- Add first and second Chebyshev functions.  See Planat and Solé (2011).
+
+- Keep speeding up factoring for very large values.
+
+- More efficient totient segment.  Do we really need primes to n/2?
diff --git a/XS.xs b/XS.xs
index 8c53bb2..fca7d50 100644
--- a/XS.xs
+++ b/XS.xs
@@ -387,7 +387,7 @@ _XS_totient(IN UV lo, IN UV hi = 0)
       Safefree(totients);
 
     } else {
-      UV facs[64];  /* maximum number of factors is log2n */
+      UV facs[MPU_MAX_FACTORS+1];  /* maximum number of factors is log2n */
       UV i, nfacs, totient, lastf;
       UV n = lo;
       if (n <= 1) XSRETURN_UV(n);
diff --git a/cache.c b/cache.c
index c6b9d2a..0e8b101 100644
--- a/cache.c
+++ b/cache.c
@@ -220,6 +220,7 @@ void release_prime_segment(unsigned char* mem) {
 void prime_precalc(UV n)
 {
   if (!mutex_init) {
+    MUTEX_INIT(&segment_mutex);
     MUTEX_INIT(&primary_cache_mutex);
     COND_INIT(&primary_cache_turn);
     mutex_init = 1;
@@ -257,6 +258,7 @@ void _prime_memfreeall(void)
 {
   /* No locks.  We're shutting everything down. */
   if (mutex_init) {
+    MUTEX_DESTROY(&segment_mutex);
     MUTEX_DESTROY(&primary_cache_mutex);
     COND_DESTROY(&primary_cache_turn);
     mutex_init = 0;
diff --git a/examples/test-euler-pari.pl b/examples/test-euler-pari.pl
index 2e86359..9be3147 100755
--- a/examples/test-euler-pari.pl
+++ b/examples/test-euler-pari.pl
@@ -9,7 +9,7 @@ use Math::Pari;
 Math::Prime::Util::prime_precalc(10_000_000);
 my $nlinear = 100000;
 my $nrandom = shift || 100000;
-my $randmax = ~0;
+my $randmax = 10**16;
 
 # Looks like MPU is 4x faster than Pari for 1 .. 1M, 5x faster for 1M - 10_000M.
 #
diff --git a/xt/factor-holf.pl b/xt/factor-holf.pl
new file mode 100755
index 0000000..b1b0f32
--- /dev/null
+++ b/xt/factor-holf.pl
@@ -0,0 +1,27 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Math::Prime::Util qw/is_prime/;
+use List::Util qw/min max/;
+my $count = shift || -2;
+my $is64bit = (~0 > 4294967295);
+my $maxdigits = ($is64bit) ? 20 : 10;  # Noting the range is limited for max.
+
+my $hrounds = 64*1024*1024;
+for (2 .. 100000000) {
+  my @fs;
+  my $s_fact = join(".",sort {$a<=>$b} Math::Prime::Util::factor($_));
+
+  my @p_holf;
+  push @fs, $_;
+  while (@fs) { 
+    my $n = pop @fs;
+    if (is_prime($n)) { push @p_holf, $n; }
+    else              { push @fs, Math::Prime::Util::holf_factor($n); }
+  }
+  my $s_holf = join(".",sort {$a<=>$b} @p_holf);
+
+  die "$_ $s_fact  holf $s_holf\n" unless $s_fact eq $s_holf;
+
+  print "$_\n" if ($_ % 100000) == 0;
+}
diff --git a/xt/make-script-test-data.pl b/xt/make-script-test-data.pl
new file mode 100755
index 0000000..d72f463
--- /dev/null
+++ b/xt/make-script-test-data.pl
@@ -0,0 +1,179 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use File::Spec::Functions;
+use FindBin;
+use bigint try => 'GMP';
+use Data::BitStream::XS;
+use Math::Prime::Util qw/is_prime/;
+$|++;
+
+# 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 = (
+  # 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],
+  [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",     0],
+  [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) {
+  my $oeis_no = $test->[0];
+  my $filename = sprintf("b%06d.txt", $oeis_no);
+  my $link     = sprintf("http://oeis.org/A%06d/b%06d.txt", $oeis_no, $oeis_no);
+  if (!-r $filename) {
+    warn "Getting $filename from $link\n";
+    qx/wget $link/;
+    die "Could not retrieve.  Bailing\n" unless -r $filename;
+  }
+  my $ref_data = read_oeis(@$test);
+  push @$test, $ref_data;
+}
+
+my $stream = Data::BitStream::XS->new( file => 'script-test-data.bs', mode => 'w' );
+foreach my $test (@test_data) {
+  encode_oeis(@$test);
+}
+$stream->write_close();
+
+sub read_oeis {
+  my($oeis_no, $name, $script_arg, $restrict) = @_;
+  die "Restrict isn't defined for $oeis_no : $name" unless defined $restrict;
+
+  my $filename = sprintf("b%06d.txt", $oeis_no);
+  my $link     = sprintf("http://oeis.org/A%06d/b%06d.txt", $oeis_no, $oeis_no);
+
+  my @ref;
+  {
+    open my $fh, '<', $filename
+        or die "Can't read $filename.\nYou should run:\n  wget $link\n";
+    printf "%12s primes: reading %12s...", $name, $filename;
+    my $char = " ";
+    while (<$fh>) {
+      next unless /^(\d+)\s+(\d+)/;
+      my $v = (length($2) < 20)  ?  $2  :  Math::BigInt->new("$2");
+      if ($restrict > 0 && $v > $restrict) {
+        $char = '*';
+        last;
+      }
+      push @ref, $v;
+    }
+    close $fh;
+    print "$char";
+  }
+  printf " %7d.", scalar @ref;
+  print "  Testing..";
+  if ($ref[-1] > 18446744073709551615) {
+    print ",";
+    # Check for monotonic and primeness
+    foreach my $i (0 .. $#ref) {
+      die "non-prime in $oeis_no $name\n" unless is_prime($ref[$i]);
+      if ($i > 0) {
+        die "non-monotonic sequence in $oeis_no $name ($i $ref[$i-1] $ref[$i])\n" if $ref[$i] <= $ref[$i-1];
+        die "even number in $oeis_no $name\n" if ($ref[$i] % 2) == 0;
+      }
+    }
+  } else {
+    no bigint;
+    print ".";
+    # Check for monotonic and primeness
+    foreach my $i (0 .. $#ref) {
+      die "non-prime in $oeis_no $name\n" unless is_prime($ref[$i]);
+      if ($i > 0) {
+        die "non-monotonic sequence in $oeis_no $name\n" if $ref[$i] <= $ref[$i-1];
+        die "even number in $oeis_no $name\n" if ($ref[$i] % 2) == 0;
+      }
+    }
+  }
+  print "done\n";
+  return \@ref;
+}
+
+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
+    $stream->put_gamma($oeis_no, 1, scalar @ref, $ref[0], $ref[1]);
+    print ".";
+    my @deltas = map { ($ref[$_] - $ref[$_-1] - 2)/2 } (2..$#ref);
+    print ".";
+    # Ugly...  Check for anything really big;
+    my @giant;
+    foreach my $d (@deltas) {
+      if ($d >= 18446744073709551614) {
+        push @giant, $d;
+        $d = 18446744073709551614;
+      }
+    }
+    print ".";
+    my $k = 2;
+    $stream->put_arice($k, @deltas);
+    print ".";
+    # Store giant deltas raw
+    foreach my $d (@giant) {
+      if (ref($d) ne 'Math::BigInt') {
+        warn "big delta $d isn't a bigint.\n";
+        $d = Math::BigInt->new(0);
+      }
+      my $binstr = substr($d->as_bin, 2);
+      $stream->put_gamma(length($binstr));
+      $stream->put_string($binstr);
+    }
+  } else {
+    no bigint;
+    print ".";
+    # Store the first two values, then a list of deltas
+    $stream->put_gamma($oeis_no, 0, scalar @ref, $ref[0], $ref[1]);
+    print ".";
+    my @deltas = map { ($ref[$_] - $ref[$_-1] - 2)/2 } (2..$#ref);
+    print ".";
+    my $k = 2;
+    $stream->put_arice($k, @deltas);
+  }
+
+  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;
+}

-- 
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