[SCM] polybori: Polynomials over Boolean Rings branch, upstream-hg, updated. b4a5cffaa908c53e1d958a42110f8c4dad853aa3

Alexander Dreyer adreyer at gmx.de
Fri Mar 23 08:01:22 UTC 2012


The following commit has been merged in the upstream-hg branch:
commit 48d758174035c0776038b1ff52a8dcbdf8b64254
Author: Alexander Dreyer <adreyer at gmx.de>
Date:   Thu Feb 23 13:56:52 2012 +0100

    CHA: simplified use of pseudo-long-longs

diff --git a/groebner/include/polybori/groebner/linear_algebra_step.h b/groebner/include/polybori/groebner/linear_algebra_step.h
index 52929c4..500014a 100644
--- a/groebner/include/polybori/groebner/linear_algebra_step.h
+++ b/groebner/include/polybori/groebner/linear_algebra_step.h
@@ -249,57 +249,138 @@ class BitMask;
 template <>
 class BitMask<0> {
 public:
+  static const unsigned nbits = 0;
   static const unsigned long mask = 0;
+
+  unsigned long low(const unsigned long& value) const { return 0; }
+  const unsigned long& high(const unsigned long& value) const { return value; }
+  const unsigned long& shift(const unsigned long& value) const { return value; }
 };
 
 template <unsigned NBits>
 class BitMask {
 public:
-  static const unsigned long mask = (BitMask<NBits-1>::mask << 1) + 1;
+  static const unsigned nbits = NBits;
+  static const unsigned long mask = (BitMask<nbits-1>::mask << 1) + 1;
+
+  unsigned long low(const unsigned long& value) const {
+    return value & mask;
+  }
+  unsigned long high(const unsigned long& value) const {
+    return value >> NBits;
+  }
+  unsigned long shift(const unsigned long& value) const {
+    return value << NBits;
+  }
 };
 
-template <unsigned NBits, unsigned long MaxHigh>
-inline bool
-number_check(const unsigned long& number, 
-	     unsigned long& high, unsigned long& low) {
-  const unsigned long mask = BitMask<NBits>::mask; 
 
-  high += (number >> NBits);
-  if (high > MaxHigh)
-    return true;
-  low += (number & mask);
+class DelayedLongLong:
+  protected std::pair<unsigned long, unsigned long>,
+  protected BitMask<sizeof(unsigned long)*4> {
 
-  high += (low >> NBits);
-  if (high > MaxHigh)
-    return true;
-  low  &= mask;
+public:
+  typedef unsigned long long_type;
 
-  return false;
-}
-template <unsigned NBits, unsigned long MaxHigh, unsigned long MaxLow>
-inline bool
-number_check_low(const unsigned long& number, 
-		 unsigned long& high, unsigned long& low) {
-
-  return number_check<NBits, MaxHigh>(number >> NBits, high, low) ||
-    ((high == MaxHigh) && ( ((low << NBits) + 
-			     (number & BitMask<NBits-1>::mask)) > MaxLow) );
-}
+protected:
+  typedef std::pair<long_type, long_type> base;
+
+public:
+  DelayedLongLong(const long_type& high, const long_type& low):
+    base(high, low) {}
+
+#ifdef PBORI_HAVE_LONG_LONG
+  operator unsigned long long() const {
+    return (unsigned long long(first) << (sizeof(long_type)*8)) + second;
+  }
+#endif
+};
 
-/// This checks cols*rows > MaxHigh*2^(2*NBits) + MaxLow
-template <unsigned NBits, 
-	  unsigned long MaxHigh, unsigned long MaxLow>
-inline bool
-matrix_size_exceeded(wlen_type cols, wlen_type rows) {
+template <DelayedLongLong::long_type High,
+          DelayedLongLong::long_type Low>
+class LongLongConstant {
+public:
+  typedef typename DelayedLongLong::long_type long_type;
+  static const long_type first = High;
+  static const long_type second = Low;
+
+#ifdef PBORI_HAVE_LONG_LONG
+  operator DelayedLongLong() const {
+    return DelayedLongLong(first, second);
+  }
+  operator unsigned long long() const {
+    return operator DelayedLongLong();
+  }
+#endif
+};
+
+
+
+template <DelayedLongLong::long_type MaxHigh,
+          DelayedLongLong::long_type MaxLow>
+class LongProductLess:
+  private DelayedLongLong {
+  typedef DelayedLongLong base;
+
+public:
+  LongProductLess():
+    base(0, 0) {}
 
-  const unsigned long mask = BitMask<NBits-1>::mask;
-  unsigned long high = (cols >> NBits)*(rows >> NBits), low = 0;
+  bool operator()(const long_type& higher, const long_type & lower) {
+
+    return most(high(higher) * high(lower)) || 
+      mid(high(higher)*low(lower)) || mid(low(higher)*high(lower)) ||
+      least(low(higher)*low(lower));
+  }
+
+protected:
+  bool most(const long_type& number) {
+    first = number;
+    second = 0;
+    return (first > MaxHigh);
+  }
+
+  bool mid(const long_type& number) {
+    first += high(number);
+
+    if (first > MaxHigh)
+      return true;
+    second += low(number);
+
+    first += high(second);
+
+    if (first > MaxHigh)
+      return true;
+
+    second = low(second);
+    return false;
+  }
+
+  bool least(const long_type& number) {
+    return mid(high(number)) ||
+      ((first == MaxHigh) && ( (shift(second) + low(number)) > MaxLow));
+  }
+
+
+};
+
+class DelayedLongProduct:
+  private DelayedLongLong {
+
+  typedef DelayedLongLong base;
+public:
+  DelayedLongProduct(const long_type& high, const long_type & low):
+    base(high, low) {}
+
+  template <long_type MaxHigh, long_type MaxLow>
+  bool less(const LongLongConstant<MaxHigh, MaxLow>&) const {
+    return LongProductLess<MaxHigh, MaxLow>()(first, second);
+  }
+};
 
-  return (high > MaxHigh) || 
-    number_check<NBits, MaxHigh>((cols >> NBits)*(rows & mask), high, low)  || 
-    number_check<NBits, MaxHigh>((cols & mask)*(rows >> NBits), high, low) ||
-    number_check_low<NBits, MaxHigh, MaxLow>((cols & mask)*(rows & mask),
-					     high, low);
+template <class RhsType>
+bool operator> (DelayedLongProduct lhs, const RhsType& rhs) {
+   return lhs.less(rhs);
 }
 
 inline void 
@@ -321,8 +402,8 @@ linalg_step_modified(std::vector < Polynomial > &polys, MonomialSet terms, Monom
     int unmodified_cols=terms.size();
 
     /// This checks cols*rows > 20000000000ll = 4*2^32 + 2820130816
-    if (PBORI_UNLIKELY((matrix_size_exceeded<16,4,2820130816>(unmodified_cols,
-						          unmodified_rows)))){
+    if (PBORI_UNLIKELY( (DelayedLongProduct(unmodified_cols, unmodified_rows) >
+                         LongLongConstant<4,2820130816>()) )){
       PBoRiError error(CTypes::matrix_size_exceeded);
       throw error;
     }

-- 
polybori: Polynomials over Boolean Rings



More information about the debian-science-commits mailing list