[libmath-prime-util-perl] 23/33: znlog update

Partha P. Mukherjee ppm-guest at moszumanska.debian.org
Thu May 21 18:51:43 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 71a3bd117cfaa9adf335777a2b04e0dc848fbea6
Author: Dana Jacobsen <dana at acm.org>
Date:   Fri Jan 24 12:36:25 2014 -0800

    znlog update
---
 Changes                   |  2 ++
 TODO                      |  2 +-
 XS.xs                     |  4 ++--
 factor.c                  |  8 ++++----
 lib/Math/Prime/Util.pm    |  7 +++++--
 lib/Math/Prime/Util/PP.pm |  8 ++++----
 t/81-bignum.t             |  5 ++++-
 util.c                    | 11 +++++------
 8 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/Changes b/Changes
index 1513dee..677bc6c 100644
--- a/Changes
+++ b/Changes
@@ -28,6 +28,8 @@ Revision history for Perl module Math::Prime::Util
     - nth_prime_{lower,upper,approx} and prime_count_{lower,upper,approx}
       moved to XS->PP.  This helps us slim down and cut startup overhead.
 
+    - Fix doc for znlog:   znlog(a,g,p) finds k s.t. a = g^k mod p
+
 
 0.36  2014-01-13
 
diff --git a/TODO b/TODO
index 04f4d03..904b6ca 100644
--- a/TODO
+++ b/TODO
@@ -73,4 +73,4 @@
 
 - Ensure a fast path for Math::GMP from MPU -> MPU:GMP -> GMP, and back.
 
-- znlog bignum tests, znlog better implementation
+- znlog better implementation
diff --git a/XS.xs b/XS.xs
index a7ccee5..e17bf86 100644
--- a/XS.xs
+++ b/XS.xs
@@ -739,7 +739,7 @@ znorder(IN SV* sva, IN SV* svn)
     }
     overflow:
     switch (ix) {
-      case 0:  _vcallsub_with_pp("znorder");  break;
+      case 0:  _vcallsub_with_gmp("znorder");  break;
       case 1:  _vcallsub_with_pp("jordan_totient");  break;
       case 2:
       default: _vcallsub_with_pp("legendre_phi"); break;
@@ -760,7 +760,7 @@ znlog(IN SV* sva, IN SV* svg, IN SV* svp)
       if (ret == 0 && a > 1) XSRETURN_UNDEF;
       XSRETURN_UV(ret);
     }
-    _vcallsub_with_pp("znlog");
+    _vcallsub_with_gmp("znlog");
     return; /* skip implicit PUTBACK */
 
 void
diff --git a/factor.c b/factor.c
index 9ae66b1..752ab51 100644
--- a/factor.c
+++ b/factor.c
@@ -908,12 +908,12 @@ int squfof_factor(UV n, UV *factors, UV rounds)
 }
 
 UV dlp_trial(UV a, UV g, UV p, UV maxrounds) {
-  UV t, n = 1;
+  UV t, k = 1;
   if (maxrounds > p) maxrounds = p;
-  for (n = 1; n < maxrounds; n++) {
-    t = powmod(g, n, p);
+  for (k = 1; k < maxrounds; k++) {
+    t = powmod(g, k, p);
     if (t == a)
-      return n;
+      return k;
   }
   return 0;
 }
diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index 1f3fb63..6e96795 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -499,6 +499,9 @@ sub prime_iterator {
   $start = 0 unless defined $start;
   _validate_num($start) || _validate_positive_integer($start);
   my $p = ($start > 0) ? $start-1 : 0;
+  # This works fine:
+  #   return sub { $p = next_prime($p); return $p; };
+  # but we can optimize a little
   if (ref($p) ne 'Math::BigInt' && $p <= $_XS_MAXVAL) {
     return sub { $p = next_prime($p); return $p; };
   } elsif ($_HAVE_GMP) {
@@ -2079,9 +2082,9 @@ produces.
 
 =head2 znlog
 
-  $k = znlog($b, $g, $p)
+  $k = znlog($a, $g, $p)
 
-Returns the integer C<k> that solves the equation C<b^k = g mod p>, or
+Returns the integer C<k> that solves the equation C<a = g^k mod p>, or
 undef if no solution is found.  This is the discrete logarithm problem.
 The implementation in this version is not very useful, but may be improved.
 
diff --git a/lib/Math/Prime/Util/PP.pm b/lib/Math/Prime/Util/PP.pm
index 461e767..e1601df 100644
--- a/lib/Math/Prime/Util/PP.pm
+++ b/lib/Math/Prime/Util/PP.pm
@@ -1695,11 +1695,11 @@ sub znorder {
 sub znlog {
   my ($a,$g,$p) =
     map { ref($_) eq 'Math::BigInt' ? $_ : Math::BigInt->new("$_") } @_;
-  for (my $n = BONE->copy; $n < $p; $n->binc) {
-    my $t = $g->copy->bmodpow($n, $p);
+  for (my $k = BONE->copy; $k < $p; $k->binc) {
+    my $t = $g->copy->bmodpow($k, $p);
     if ($t == $a) {
-      $n = _bigint_to_int($n) if $n->bacmp(''.~0) <= 0;
-      return $n;
+      $k = _bigint_to_int($k) if $k->bacmp(''.~0) <= 0;
+      return $k;
     }
   }
   return;
diff --git a/t/81-bignum.t b/t/81-bignum.t
index 0e064cf..e27564b 100644
--- a/t/81-bignum.t
+++ b/t/81-bignum.t
@@ -76,7 +76,7 @@ plan tests =>  0
              + 6*2*$extra # more PC tests
              + 2*scalar(keys %factors)
              + scalar(keys %allfactors)
-             + 13+3*$extra  # moebius, euler_phi, jordan totient, divsum, etc.
+             + 14+3*$extra  # moebius, euler_phi, jordan totient, divsum, etc.
              + 2   # liouville
              + 3   # gcd
              + 3   # lcm
@@ -108,6 +108,7 @@ use Math::Prime::Util qw/
   divisor_sum
   znorder
   znprimroot
+  znlog
   liouville
   gcd
   lcm
@@ -267,6 +268,8 @@ SKIP: {
 
   is( znprimroot(333822190384002421914469856494764513809), 3, "znprimroot(333822190384002421914469856494764513809)" );
 
+  is( znlog(232752345212475230211680, 23847293847923847239847098123812075234, 804842536444911030681947), 13, "znlog(b,g,p): find k where b^k = g mod p" );
+
 }
 
 ###############################################################################
diff --git a/util.c b/util.c
index 870581f..2dbae67 100644
--- a/util.c
+++ b/util.c
@@ -1220,9 +1220,9 @@ UV divmod(UV a, UV b, UV n) {   /* a / b  mod n */
   return mulmod(a, binv, n);
 }
 
-/* Find smallest n where a = g^n mod p
+/* Find smallest k where a = g^k mod p
  * This implementation is just a stupid placeholder.
- * When prho or bsgs gets working well, lower the trial limit
+ * When prho or bsgs starts working well, lower the trial limit
  */
 #define DLP_TRIAL_NUM  1000000
 UV znlog(UV a, UV g, UV p) {
@@ -1399,10 +1399,9 @@ long double _XS_LogarithmicIntegral(long double x) {
 
 /* Thanks to Kim Walisch for this idea */
 UV _XS_Inverse_Li(UV x) {
-  double n = x;
-  double logn = log(n);
-  UV lo = (UV) (n*logn);
-  UV hi = (UV) (n*logn * 2 + 2);
+  double nlogn = (double)x * log((double)x);
+  UV lo = (UV) (nlogn);
+  UV hi = (UV) (nlogn * 2 + 2);
 
   if (x == 0)  return 0;
   if (hi <= lo) hi = UV_MAX;

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