[mathicgb] 23/393: Added improved modular inverse code and typedefs for uint8, uint16, uint32, uint64.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:58:25 UTC 2015


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

dtorrance-guest pushed a commit to branch upstream
in repository mathicgb.

commit 5d5648bc7d50e5353315aeb692c584630757e550
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Mon Sep 24 19:57:46 2012 +0200

    Added improved modular inverse code and typedefs for uint8, uint16, uint32, uint64.
---
 src/mathicgb/PolyRing.cpp | 19 ++++++++-----------
 src/mathicgb/PolyRing.hpp | 43 +++++++++++++++++++++++++++++++++++++++++++
 src/mathicgb/stdinc.h     |  8 ++++++++
 3 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/src/mathicgb/PolyRing.cpp b/src/mathicgb/PolyRing.cpp
old mode 100644
new mode 100755
index 7da7ff4..4599e04
--- a/src/mathicgb/PolyRing.cpp
+++ b/src/mathicgb/PolyRing.cpp
@@ -722,24 +722,21 @@ void gcd_extended(long a, long b, long &u, long &v, long &g)
     }
 }
 
-void PolyRing::coefficientReciprocalTo(coefficient &result) const
+void PolyRing::coefficientReciprocalTo(coefficient& result) const
 {
+  MATHICGB_ASSERT(result != 0);
   mStats.n_recip++;
-  long u,v,g;
-  gcd_extended(result, mCharac, u, v, g);
-  if (u < 0) u += mCharac;
-  result = u;
+  result = modularInverse(result, mCharac);
 }
 
 void PolyRing::coefficientDivide(coefficient a, coefficient b, coefficient &result) const
- // result /= a
+ // result = a/b
 {
   mStats.n_divide++;
-  long u,v,g;
-  gcd_extended(b, mCharac, u, v, g);
-  result = a * u;
-  result %= mCharac;
-  if (result < 0) result += mCharac;
+  result = (1+a * modularInverse(b, mCharac)) % mCharac;
+  /*  MATHICGB_ASSERT((result * b) % mCharac == a);
+  MATHICGB_ASSERT(result >= 0);
+  MATHICGB_ASSERT(result < mCharac);*/
 }
 
 // Local Variables:
diff --git a/src/mathicgb/PolyRing.hpp b/src/mathicgb/PolyRing.hpp
index 9f84c21..5c6a471 100755
--- a/src/mathicgb/PolyRing.hpp
+++ b/src/mathicgb/PolyRing.hpp
@@ -14,6 +14,49 @@
 #define EQ 0
 #define GT 1
 
+template<class T>
+T modularInverse(T a, T modulus) {
+  // we do two turns of the extended Euclidian algorithm per
+  // loop. Usually the sign of x changes each time through the loop,
+  // but we avoid that by representing every other x as its negative,
+  // which is the value minusLastX. This way no negative values show
+  // up.
+  MATHICGB_ASSERT(a != 0);
+  MATHICGB_ASSERT(a < modulus);
+#ifdef MATHICGB_DEBUG
+  T origA = a;
+#endif
+  T b = modulus; // note that we actually only need modulus for asserts
+  T minusLastX = 0;
+  T x = 1;
+  while (true) {
+    MATHICGB_ASSERT(x <= modulus);
+    MATHICGB_ASSERT(minusLastX <= modulus);
+
+    // first turn
+    if (a == 1)
+      break;
+    T const firstQuotient = b / a;
+    b -= firstQuotient * a;
+    minusLastX += firstQuotient * x;
+
+    // second turn
+    if (b == 1) {
+      MATHICGB_ASSERT(minusLastX != 0);
+      MATHICGB_ASSERT(minusLastX < modulus);
+      x = modulus - minusLastX;
+      break;
+    }
+    T const secondQuotient = a / b;
+    a -= secondQuotient * b;
+    x += secondQuotient * minusLastX;
+  }
+  MATHICGB_ASSERT(x >= 1);
+  MATHICGB_ASSERT(x < modulus);
+  MATHICGB_ASSERT((static_cast<uint64>(origA) * x) % modulus == 1);
+  return x;
+}
+
 typedef int exponent ;
 typedef long coefficient;
 typedef exponent *vecmonomial; // includes a component
diff --git a/src/mathicgb/stdinc.h b/src/mathicgb/stdinc.h
index 5c96fa8..dc4333d 100755
--- a/src/mathicgb/stdinc.h
+++ b/src/mathicgb/stdinc.h
@@ -61,5 +61,13 @@
 #define MATHICGB_SLOW_ASSERT(X)
 #endif
 
+// TODO: These types should be defined in some way that actually
+// checks that these bit counts are right like in a configure script.
+typedef unsigned long long uint64;
+typedef unsigned int uint32;
+typedef unsigned short uint16;
+typedef unsigned char uint8;
+
+
 static const size_t BitsPerByte = 8;
 static const size_t MemoryAlignment = sizeof(void*);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mathicgb.git



More information about the debian-science-commits mailing list