[libmath-prime-util-perl] 13/33: Start work on separate PP front end

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


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

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

commit 0297d2a5d56198ac12c760c5d52dc5ccf9f07911
Author: Dana Jacobsen <dana at acm.org>
Date:   Tue Jan 21 18:15:22 2014 -0800

    Start work on separate PP front end
---
 Changes                     |   2 +-
 MANIFEST                    |   1 +
 XS.xs                       |  12 ++--
 lib/Math/Prime/Util.pm      | 157 +-------------------------------------------
 lib/Math/Prime/Util/PP.pm   |  98 +++++++++++++++++++++++----
 lib/Math/Prime/Util/PPFE.pm | 149 +++++++++++++++++++++++++++++++++++++++++
 t/80-pp.t                   |   6 +-
 7 files changed, 247 insertions(+), 178 deletions(-)

diff --git a/Changes b/Changes
index f0b0955..4c11a57 100644
--- a/Changes
+++ b/Changes
@@ -10,7 +10,7 @@ Revision history for Perl module Math::Prime::Util
     - Dynamically loads the PP code and Math::BigInt only when needed.  This
       removes a lot of bloat for the usual cases:
         2.0 MB  perl -E 'say 1'
-        4.4 MB  MPU 0.37
+        4.3 MB  MPU 0.37
         4.5 MB  Math::Prime::XS + Math::Factor::XS
         5.3 MB  Math::Pari
         9.6 MB  MPU 0.36
diff --git a/MANIFEST b/MANIFEST
index d1a8f64..aaed7e6 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -5,6 +5,7 @@ lib/Math/Prime/Util/MemFree.pm
 lib/Math/Prime/Util/PrimeArray.pm
 lib/Math/Prime/Util/PrimeIterator.pm
 lib/Math/Prime/Util/PP.pm
+lib/Math/Prime/Util/PPFE.pm
 lib/Math/Prime/Util/ZetaBigFloat.pm
 lib/Math/Prime/Util/ECAffinePoint.pm
 lib/Math/Prime/Util/ECProjectivePoint.pm
diff --git a/XS.xs b/XS.xs
index d148121..5aee2e3 100644
--- a/XS.xs
+++ b/XS.xs
@@ -782,7 +782,7 @@ kronecker(IN SV* sva, IN SV* svb)
       int k = (abpositive) ? kronecker_uu(a,b) : kronecker_ss(a,b);
       RETURN_NPARITY(k);
     }
-    _vcallsub("_generic_kronecker");
+    _vcallsub_with_gmp("kronecker");
     return; /* skip implicit PUTBACK */
 
 double
@@ -855,9 +855,9 @@ euler_phi(IN SV* svlo, ...)
       /* Whatever we didn't handle above */
       U32 gimme_v = GIMME_V;
       switch (ix) {
-        case 0:  _vcallsubn(aTHX_ gimme_v, VCALL_ROOT,"_generic_euler_phi", items);break;
+        case 0:  _vcallsubn(aTHX_ gimme_v, VCALL_PP, "euler_phi", items);break;
         case 1:
-        default: _vcallsubn(aTHX_ gimme_v, VCALL_ROOT,"_generic_moebius", items);  break;
+        default: _vcallsubn(aTHX_ gimme_v, VCALL_PP, "moebius", items);  break;
       }
       return;
     }
@@ -874,10 +874,10 @@ carmichael_lambda(IN SV* svn)
     status = _validate_int(aTHX_ svn, (ix > 1) ? 1 : 0);
     switch (ix) {
       case 0: if (status == 1) XSRETURN_UV(carmichael_lambda(my_svuv(svn)));
-              _vcallsub("_generic_carmichael_lambda");
+              _vcallsub_with_gmp("carmichael_lambda");
               break;
       case 1: if (status == 1) XSRETURN_IV(mertens(my_svuv(svn)));
-              _vcallsub("_generic_mertens");
+              _vcallsub_with_pp("mertens");
               break;
       case 2: if (status ==-1) XSRETURN_UV(1);
               if (status == 1) XSRETURN_UV(exp_mangoldt(my_svuv(svn)));
@@ -893,7 +893,7 @@ carmichael_lambda(IN SV* svn)
                 else
                   XSRETURN_UV(r);
               }
-              _vcallsub("_generic_znprimroot");
+              _vcallsub_with_gmp("znprimroot");
               break;
     }
     return; /* skip implicit PUTBACK */
diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index bcd2488..af577b4 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -91,14 +91,10 @@ BEGIN {
     $_Config{'xs'} = 0;
     $_Config{'maxbits'} = MPU_MAXBITS;
 
-    # Load PP code now.  Nothing is exported.
-    require Math::Prime::Util::PP;  Math::Prime::Util::PP->import();
+    # Load PP front end code
+    require Math::Prime::Util::PPFE;
 
     *_validate_num = \&Math::Prime::Util::PP::_validate_num;
-    *is_prime      = \&Math::Prime::Util::PP::is_prime;
-    *is_prob_prime = \&Math::Prime::Util::PP::is_prob_prime;
-    *is_pseudoprime=\&Math::Prime::Util::PP::is_pseudoprime;
-    *is_strong_pseudoprime=\&Math::Prime::Util::PP::is_strong_pseudoprime;
     *is_lucas_pseudoprime=\&Math::Prime::Util::PP::is_lucas_pseudoprime;
     *is_strong_lucas_pseudoprime=\&Math::Prime::Util::PP::is_strong_lucas_pseudoprime;
     *is_extra_strong_lucas_pseudoprime=\&Math::Prime::Util::PP::is_extra_strong_lucas_pseudoprime;
@@ -108,24 +104,8 @@ BEGIN {
     *next_prime    = \&Math::Prime::Util::_generic_next_prime;
     *prev_prime    = \&Math::Prime::Util::_generic_prev_prime;
     *exp_mangoldt  = \&Math::Prime::Util::_generic_exp_mangoldt;
-    *euler_phi     = \&Math::Prime::Util::_generic_euler_phi;
-    *jordan_totient= \&Math::Prime::Util::PP::jordan_totient;
-    *moebius       = \&Math::Prime::Util::_generic_moebius;
-    *mertens       = \&Math::Prime::Util::_generic_mertens;
     *prime_count   = \&Math::Prime::Util::_generic_prime_count;
-    *nth_prime     = \&Math::Prime::Util::PP::nth_prime;
-    *nth_prime_upper=\&Math::Prime::Util::PP::nth_prime_upper;
-    *nth_prime_lower=\&Math::Prime::Util::PP::nth_prime_lower;
-    *nth_prime_approx=\&Math::Prime::Util::PP::nth_prime_approx;
-    *prime_count_upper=\&Math::Prime::Util::PP::prime_count_upper;
-    *prime_count_lower=\&Math::Prime::Util::PP::prime_count_lower;
-    *prime_count_approx=\&Math::Prime::Util::PP::prime_count_approx;
-    *carmichael_lambda = \&Math::Prime::Util::_generic_carmichael_lambda;
-    *kronecker     = \&Math::Prime::Util::_generic_kronecker;
     *divisor_sum   = \&Math::Prime::Util::_generic_divisor_sum;
-    *znorder       = \&Math::Prime::Util::PP::znorder;
-    *znprimroot    = \&Math::Prime::Util::_generic_znprimroot;
-    *znlog         = \&Math::Prime::Util::PP::znlog;
     *legendre_phi  = \&Math::Prime::Util::PP::legendre_phi;
     *gcd           = \&Math::Prime::Util::PP::gcd;
     *lcm           = \&Math::Prime::Util::PP::lcm;
@@ -286,12 +266,6 @@ sub _validate_positive_integer {
   1;
 }
 
-sub _upgrade_to_float {
-  do { require Math::BigFloat; Math::BigFloat->import(); }
-    if !defined $Math::BigFloat::VERSION;
-  return Math::BigFloat->new($_[0]);
-}
-
 
 #############################################################################
 
@@ -448,62 +422,6 @@ sub consecutive_integer_lcm {
   return Math::Prime::Util::PP::consecutive_integer_lcm($n);
 }
 
-# A008683 Moebius function mu(n)
-# A030059, A013929, A030229, A002321, A005117, A013929 all relate.
-sub _generic_moebius {
-  my($n, $nend) = @_;
-  return 0 if defined $n && $n < 0;
-  require Math::Prime::Util::PP;
-  _validate_num($n) || _validate_positive_integer($n);
-  return Math::Prime::Util::PP::moebius($n) if !defined $nend;
-  _validate_num($nend) || _validate_positive_integer($nend);
-  return Math::Prime::Util::PP::moebius_range($n, $nend);
-}
-
-# A002321 Mertens' function.  mertens(n) = sum(moebius(1,n))
-sub _generic_mertens {
-  my($n) = @_;
-  _validate_num($n) || _validate_positive_integer($n);
-  # This is the most basic Deléglise and Rivat algorithm.  u = n^1/2
-  # and no segmenting is done.  Their algorithm uses u = n^1/3, breaks
-  # the summation into two parts, and calculates those in segments.  Their
-  # computation time growth is half of this code.
-  return $n if $n <= 1;
-  my $u = int(sqrt($n));
-  my @mu = (0, moebius(1, $u));          # Hold values of mu for 0-u
-  my $musum = 0;
-  my @M = map { $musum += $_; } @mu;     # Hold values of M for 0-u
-  my $sum = $M[$u];
-  foreach my $m (1 .. $u) {
-    next if $mu[$m] == 0;
-    my $inner_sum = 0;
-    my $lower = int($u/$m) + 1;
-    my $last_nmk = int($n/($m*$lower));
-    my ($denom, $this_k, $next_k) = ($m, 0, int($n/($m*1)));
-    for my $nmk (1 .. $last_nmk) {
-      $denom += $m;
-      $this_k = int($n/$denom);
-      next if $this_k == $next_k;
-      ($this_k, $next_k) = ($next_k, $this_k);
-      $inner_sum += $M[$nmk] * ($this_k - $next_k);
-    }
-    $sum -= $mu[$m] * $inner_sum;
-  }
-  return $sum;
-}
-
-
-# A000010 Euler Phi, aka Euler Totient
-sub _generic_euler_phi {
-  my($n, $nend) = @_;
-  return 0 if defined $n && $n < 0;
-  require Math::Prime::Util::PP;
-  _validate_num($n) || _validate_positive_integer($n);
-  return Math::Prime::Util::PP::euler_phi($n) if !defined $nend;
-  _validate_num($nend) || _validate_positive_integer($nend);
-  return Math::Prime::Util::PP::euler_phi_range($n, $nend);
-}
-
 sub _generic_divisor_sum {
   my($n) = @_;
   _validate_num($n) || _validate_positive_integer($n);
@@ -649,63 +567,6 @@ sub chebyshev_psi {
   return $sum;
 }
 
-sub _generic_carmichael_lambda {
-  my($n) = @_;
-  _validate_num($n) || _validate_positive_integer($n);
-  # lambda(n) = phi(n) for n < 8
-  return euler_phi($n) if $n < 8;
-  # lambda(n) = phi(n)/2 for powers of two greater than 4
-  return euler_phi($n)/2 if ($n & ($n-1)) == 0;
-
-  my @pe = factor_exp($n);
-  $pe[0]->[1]-- if $pe[0]->[0] == 2 && $pe[0]->[1] > 2;
-
-  my $lcm = Math::BigInt::blcm(
-    map { $_->[0]->copy->bpow($_->[1]->copy->bdec)->bmul($_->[0]->copy->bdec) }
-    map { [ map { Math::BigInt->new("$_") } @$_ ] }
-    @pe
-  );
-  $lcm = _bigint_to_int($lcm) if $lcm->bacmp(''.~0) <= 0;
-  return $lcm;
-}
-
-sub _generic_znprimroot {
-  my($n) = @_;
-  $n = -$n if defined $n && $n =~ /^-\d+/;   # TODO: fix this for string bigints
-  _validate_num($n) || _validate_positive_integer($n);
-  if ($n <= 4) {
-    return if $n == 0;
-    return $n-1;
-  }
-  return if $n % 4 == 0;
-  my $a = 1;
-  my $phi = euler_phi($n);
-  # Check that a primitive root exists.
-  return if !is_prob_prime($n) && $phi != carmichael_lambda($n);
-  my @exp = map { Math::BigInt->new("$_") }
-            map { int($phi/$_->[0]) }
-            factor_exp($phi);
-  #print "phi: $phi  factors: ", join(",",factor($phi)), "\n";
-  #print "  exponents: ", join(",", @exp), "\n";
-  my $bign = (ref($n) eq 'Math::BigInt') ? $n : Math::BigInt->new("$n");
-  while (1) {
-    my $fail = 0;
-    do { $a++ } while kronecker($a,$n) == 0;
-    return if $a >= $n;
-    foreach my $f (@exp) {
-      if ( Math::BigInt->new($a)->bmodpow($f, $bign)->is_one ) {
-        $fail = 1;
-        last;
-      }
-    }
-    return $a if !$fail;
-  }
-}
-
-
-
-
-
 #############################################################################
 # Front ends to functions.
 #
@@ -737,20 +598,6 @@ sub _generic_prev_prime {
   return Math::Prime::Util::PP::prev_prime($_[0]);
 }
 
-sub _generic_kronecker {
-  my($a, $b) = @_;
-  croak "Parameter must be defined" if !defined $a;
-  croak "Parameter must be defined" if !defined $b;
-  croak "Parameter '$a' must be an integer" unless $a =~ /^[-+]?\d+/;
-  croak "Parameter '$b' must be an integer" unless $b =~ /^[-+]?\d+/;
-
-  return Math::BigInt->new(''.Math::Prime::Util::GMP::kronecker($a,$b))
-    if $_HAVE_GMP && defined &Math::Prime::Util::GMP::kronecker;
-
-  require Math::Prime::Util::PP;
-  return Math::Prime::Util::PP::kronecker(@_);
-}
-
 sub _generic_prime_count {
   my($low,$high) = @_;
   if (defined $high) {
diff --git a/lib/Math/Prime/Util/PP.pm b/lib/Math/Prime/Util/PP.pm
index c54d71e..0dfb83d 100644
--- a/lib/Math/Prime/Util/PP.pm
+++ b/lib/Math/Prime/Util/PP.pm
@@ -227,8 +227,6 @@ sub _is_prime7 {  # n must not be divisible by 2, 3, or 5
 
 sub is_prime {
   my($n) = @_;
-  return 0 if defined $n && int($n) < 0;
-  _validate_positive_integer($n);
 
   if (ref($n) eq 'Math::BigInt') {
     return 0 unless Math::BigInt::bgcd($n, B_PRIM235)->is_one;
@@ -567,11 +565,9 @@ sub consecutive_integer_lcm {
 
 sub jordan_totient {
   my($k, $n) = @_;
-  _validate_num($k) || _validate_positive_integer($k);
   return ($n == 1) ? 1 : 0  if $k == 0;
   return euler_phi($n)      if $k == 1;
-  return 0 if defined $n && $n < 0;  # Following SAGE's logic here.
-  _validate_num($n) || _validate_positive_integer($n);
+  return 0 if $n < 0;
   return ($n == 1) ? 1 : 0  if $n <= 1;
 
   my @pe = Math::Prime::Util::factor_exp($n);
@@ -589,6 +585,7 @@ sub jordan_totient {
 }
 
 sub euler_phi {
+  return euler_phi_range(@_) if scalar @_ > 1;
   my($n) = @_;
   return 0 if $n < 0;
   return $n if $n <= 1;
@@ -638,6 +635,7 @@ sub euler_phi_range {
 }
 
 sub moebius {
+  return moebius_range(@_) if scalar @_ > 1;
   my($n) = @_;
   return ($n == 1) ? 1 : 0  if $n <= 1;
   return 0 if ($n >= 49) && (!($n % 4) || !($n % 9) || !($n % 25) || !($n%49) );
@@ -685,6 +683,54 @@ sub moebius_range {
   return @mu;
 }
 
+sub mertens {
+  my($n) = @_;
+    # This is the most basic Deléglise and Rivat algorithm.  u = n^1/2
+  # and no segmenting is done.  Their algorithm uses u = n^1/3, breaks
+  # the summation into two parts, and calculates those in segments.  Their
+  # computation time growth is half of this code.
+  return $n if $n <= 1;
+  my $u = int(sqrt($n));
+  my @mu = (0, Math::Prime::Util::moebius(1, $u)); # Hold values of mu for 0-u
+  my $musum = 0;
+  my @M = map { $musum += $_; } @mu;     # Hold values of M for 0-u
+  my $sum = $M[$u];
+  foreach my $m (1 .. $u) {
+    next if $mu[$m] == 0;
+    my $inner_sum = 0;
+    my $lower = int($u/$m) + 1;
+    my $last_nmk = int($n/($m*$lower));
+    my ($denom, $this_k, $next_k) = ($m, 0, int($n/($m*1)));
+    for my $nmk (1 .. $last_nmk) {
+      $denom += $m;
+      $this_k = int($n/$denom);
+      next if $this_k == $next_k;
+      ($this_k, $next_k) = ($next_k, $this_k);
+      $inner_sum += $M[$nmk] * ($this_k - $next_k);
+    }
+    $sum -= $mu[$m] * $inner_sum;
+  }
+  return $sum;
+}
+
+sub carmichael_lambda {
+  my($n) = @_;
+  return euler_phi($n) if $n < 8;                # = phi(n) for n < 8
+  return euler_phi($n)/2 if ($n & ($n-1)) == 0;  # = phi(n)/2 for 2^k, k>2
+
+  my @pe = Math::Prime::Util::factor_exp($n);
+  $pe[0]->[1]-- if $pe[0]->[0] == 2 && $pe[0]->[1] > 2;
+
+  my $lcm = Math::BigInt::blcm(
+    map { $_->[0]->copy->bpow($_->[1]->copy->bdec)->bmul($_->[0]->copy->bdec) }
+    map { [ map { Math::BigInt->new("$_") } @$_ ] }
+    @pe
+  );
+  $lcm = _bigint_to_int($lcm) if $lcm->bacmp(''.~0) <= 0;
+  return $lcm;
+}
+
+
 my @_ds_overflow =  # We'll use BigInt math if the input is larger than this.
   (~0 > 4294967295)
    ? (124, 3000000000000000000, 3000000000, 2487240, 64260, 7026)
@@ -1349,9 +1395,7 @@ sub _is_perfect_power {
 
 sub is_pseudoprime {
   my($n, $base) = @_;
-  return 0 if defined $n && int($n) < 0;
-  _validate_positive_integer($n);
-  _validate_positive_integer($base);
+  return 0 if int($n) < 0;
 
   if ($n < 5) { return ($n == 2) || ($n == 3) ? 1 : 0; }
   croak "Base $base is invalid" if $base < 2;
@@ -1422,9 +1466,6 @@ sub _miller_rabin_2 {
 
 sub is_strong_pseudoprime {
   my($n, @bases) = @_;
-  return 0 if defined $n && int($n) < 0;
-  _validate_positive_integer($n);
-  croak "No bases given to miller_rabin" unless @bases;
 
   return 0+($n >= 2) if $n < 4;
   return 0 if ($n % 2) == 0;
@@ -1562,8 +1603,6 @@ sub _is_perfect_square {
 
 sub znorder {
   my($a, $n) = @_;
-  _validate_num($a) || _validate_positive_integer($a);
-  _validate_num($n) || _validate_positive_integer($n);
   return if $n <= 0;
   return (undef,1)[$a] if $a <= 1;
   return 1 if $n == 1;
@@ -1614,6 +1653,39 @@ sub znlog {
   return;
 }
 
+sub znprimroot {
+  my($n) = @_;
+  $n = -$n if $n < 0;
+  if ($n <= 4) {
+    return if $n == 0;
+    return $n-1;
+  }
+  return if $n % 4 == 0;
+  my $a = 1;
+  my $phi = euler_phi($n);
+  # Check that a primitive root exists.
+  return if !is_prob_prime($n) && $phi != Math::Prime::Util::carmichael_lambda($n);
+  my @exp = map { Math::BigInt->new("$_") }
+            map { int($phi/$_->[0]) }
+            Math::Prime::Util::factor_exp($phi);
+  #print "phi: $phi  factors: ", join(",",factor($phi)), "\n";
+  #print "  exponents: ", join(",", @exp), "\n";
+  my $bign = (ref($n) eq 'Math::BigInt') ? $n : Math::BigInt->new("$n");
+  while (1) {
+    my $fail = 0;
+    do { $a++ } while kronecker($a,$n) == 0;
+    return if $a >= $n;
+    foreach my $f (@exp) {
+      if ( Math::BigInt->new($a)->bmodpow($f, $bign)->is_one ) {
+        $fail = 1;
+        last;
+      }
+    }
+    return $a if !$fail;
+  }
+}
+
+
 # Find first D in sequence (5,-7,9,-11,13,-15,...) where (D|N) == -1
 sub _lucas_selfridge_params {
   my($n) = @_;
diff --git a/lib/Math/Prime/Util/PPFE.pm b/lib/Math/Prime/Util/PPFE.pm
new file mode 100644
index 0000000..bf0ea9a
--- /dev/null
+++ b/lib/Math/Prime/Util/PPFE.pm
@@ -0,0 +1,149 @@
+# The PP front end, only loaded if XS is not used.  It is intended to load
+# directly into the package namespace.
+
+use strict;
+use warnings;
+use Math::Prime::Util::PP;
+
+*_validate_num = \&Math::Prime::Util::PP::_validate_num;
+
+sub mertens {
+  my($n) = @_;
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::mertens(@_);
+}
+
+sub moebius {
+  if (scalar @_ <= 1) {
+    my($n) = @_;
+    return 0 if defined $n && $n < 0;
+    _validate_num($n) || _validate_positive_integer($n);
+    return Math::Prime::Util::PP::moebius($n);
+  }
+  my($lo, $hi) = @_;
+  _validate_num($lo) || _validate_positive_integer($lo);
+  _validate_num($hi) || _validate_positive_integer($hi);
+  return Math::Prime::Util::PP::moebius_range($lo, $hi);
+}
+
+sub euler_phi {
+  if (scalar @_ <= 1) {
+    my($n) = @_;
+    return 0 if defined $n && $n < 0;
+    _validate_num($n) || _validate_positive_integer($n);
+    return Math::Prime::Util::PP::euler_phi($n);
+  }
+  my($lo, $hi) = @_;
+  _validate_num($lo) || _validate_positive_integer($lo);
+  _validate_num($hi) || _validate_positive_integer($hi);
+  return Math::Prime::Util::PP::euler_phi_range($lo, $hi);
+}
+sub jordan_totient {
+  my($k, $n) = @_;
+  _validate_positive_integer($k);
+  return 0 if defined $n && $n < 0;
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::jordan_totient(@_);
+}
+sub carmichael_lambda {
+  my($n) = @_;
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::carmichael_lambda(@_);
+}
+
+sub nth_prime {
+  my($n) = @_;
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::nth_prime(@_);
+}
+sub nth_prime_lower {
+  my($n) = @_;
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::nth_prime_lower($n);
+}
+sub nth_prime_upper {
+  my($n) = @_;
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::nth_prime_upper($n);
+}
+sub nth_prime_approx {
+  my($n) = @_;
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::nth_prime_approx($n);
+}
+sub prime_count_lower {
+  my($n) = @_;
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::prime_count_lower($n);
+}
+sub prime_count_upper {
+  my($n) = @_;
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::prime_count_upper($n);
+}
+sub prime_count_approx {
+  my($n) = @_;
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::prime_count_approx($n);
+}
+  
+sub is_prime {
+  my($n) = @_;
+  return 0 if defined $n && int($n) < 0;
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::is_prime($n);
+}
+sub is_prob_prime {
+  my($n) = @_;
+  return 0 if defined $n && int($n) < 0;
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::is_prob_prime($n);
+}
+sub is_pseudoprime {
+  my($n, $base) = @_;
+  return 0 if defined $n && int($n) < 0;
+  _validate_positive_integer($n);
+  _validate_positive_integer($base);
+  return Math::Prime::Util::PP::is_pseudoprime($n, $base);
+}
+sub is_strong_pseudoprime {
+  my($n, @bases) = @_;
+  return 0 if defined $n && int($n) < 0;
+  _validate_positive_integer($n);
+  croak "No bases given to miller_rabin" unless @bases;
+  return Math::Prime::Util::PP::is_strong_pseudoprime($n, @bases);
+}
+
+sub kronecker {
+  my($a, $b) = @_;
+  my ($va, $vb) = ($a, $b);
+  $va = -$va if defined $va && $va < 0;
+  $vb = -$vb if defined $vb && $vb < 0;
+  _validate_positive_integer($va);
+  _validate_positive_integer($vb);
+  return Math::Prime::Util::PP::kronecker(@_);
+}
+
+sub znorder {
+  my($a, $n) = @_;
+  _validate_positive_integer($a);
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::znorder($a, $n);
+}
+
+sub znlog {
+  my($a, $g, $p) = @_;
+  _validate_positive_integer($a);
+  _validate_positive_integer($g);
+  _validate_positive_integer($p);
+  return Math::Prime::Util::PP::znlog($a, $g, $p);
+}
+
+sub znprimroot {
+  my($n) = @_;
+  $n = -$n if defined $n && $n =~ /^-\d+/;   # TODO: fix this for string bigints
+  _validate_positive_integer($n);
+  return Math::Prime::Util::PP::znprimroot($n);
+}
+
+1;
diff --git a/t/80-pp.t b/t/80-pp.t
index d88d550..627fdae 100644
--- a/t/80-pp.t
+++ b/t/80-pp.t
@@ -298,9 +298,9 @@ require_ok 'Math::Prime::Util::PrimalityProving';
 
     *factor         = \&Math::Prime::Util::PP::factor;
 
-    *moebius        = \&Math::Prime::Util::_generic_moebius;
-    *euler_phi      = \&Math::Prime::Util::_generic_euler_phi;
-    *mertens        = \&Math::Prime::Util::_generic_mertens;
+    *moebius        = \&Math::Prime::Util::PP::moebius;
+    *euler_phi      = \&Math::Prime::Util::PP::euler_phi;
+    *mertens        = \&Math::Prime::Util::PP::mertens;
     *exp_mangoldt   = \&Math::Prime::Util::_generic_exp_mangoldt;
 
     *RiemannR            = \&Math::Prime::Util::PP::RiemannR;

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