[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