[mathicgb] 112/393: Small changes that allow for exponent to be a char/int8. That was a problem with IO code since >>char is different from >>int in that the former reads a single character while the latter reads a possibly multi-character integer.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:58:43 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 b04df39a0b072b20247d980ce07a42f84520f03e
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date: Thu Nov 15 19:47:48 2012 +0100
Small changes that allow for exponent to be a char/int8. That was a problem with IO code since >>char is different from >>int in that the former reads a single character while the latter reads a possibly multi-character integer.
---
src/mathicgb/F4MatrixBuilder.cpp | 6 +++--
src/mathicgb/PolyRing.cpp | 53 ++++++++++++++++++++--------------------
src/mathicgb/PolyRing.hpp | 42 ++++++++++++++++++++++++-------
src/test/poly-test.cpp | 2 +-
4 files changed, 65 insertions(+), 38 deletions(-)
diff --git a/src/mathicgb/F4MatrixBuilder.cpp b/src/mathicgb/F4MatrixBuilder.cpp
index ec4cca5..6647d33 100755
--- a/src/mathicgb/F4MatrixBuilder.cpp
+++ b/src/mathicgb/F4MatrixBuilder.cpp
@@ -244,6 +244,8 @@ F4MatrixBuilder::createColumn(
// The column really does not exist, so we need to create it
ring().monomialMult(monoA, monoB, mTmp);
+ if (!ring().monomialHasAmpleCapacity(mTmp))
+ mathic::reportError("Monomial exponent overflow in F4MatrixBuilder.");
MATHICGB_ASSERT(ring().hashValid(mTmp));
// look for a reducer of mTmp
@@ -251,12 +253,12 @@ F4MatrixBuilder::createColumn(
const bool insertLeft = (reducerIndex != static_cast<size_t>(-1));
// Create the new left or right column
- const auto colCount = insertLeft ? mLeftColCount : mRightColCount;
+ auto& colCount = insertLeft ? mLeftColCount : mRightColCount;
if (colCount == std::numeric_limits<ColIndex>::max())
throw std::overflow_error("Too many columns in QuadMatrix");
const auto inserted = mMap.insert
(std::make_pair(mTmp, LeftRightColIndex(colCount, insertLeft)));
- insertLeft ? ++mLeftColCount : ++mRightColCount;
+ ++colCount;
MATHICGB_ASSERT(inserted.second);
MATHICGB_ASSERT(inserted.first.first != 0);
diff --git a/src/mathicgb/PolyRing.cpp b/src/mathicgb/PolyRing.cpp
index ad22a52..2602c02 100755
--- a/src/mathicgb/PolyRing.cpp
+++ b/src/mathicgb/PolyRing.cpp
@@ -225,7 +225,7 @@ void PolyRing::monomialParse(std::istream &i,
// first initialize result:
for (size_t j=0; j<mMaxMonomialSize; j++) result[j] = 0;
- exponent e;
+ uint64 e;
int v, x;
// now look at the next char
for (;;)
@@ -243,9 +243,7 @@ void PolyRing::monomialParse(std::istream &i,
next = i.peek();
e = 1;
if (isdigit(next))
- {
- i >> e;
- }
+ i >> e;
result[v+1] = e;
}
else if (next == '<')
@@ -273,19 +271,19 @@ void PolyRing::monomialDisplay(std::ostream &o,
// print_one: only is consulted in print_comp is false.
bool printed_any = false;
- for (size_t i=0; i<mNumVars; i++)
- if (a[i+1] != 0)
- {
- printed_any = true;
- if (i <= 25)
- o << static_cast<unsigned char>('a' + i);
- else
- o << static_cast<unsigned char>('A' + (i - 26));
- if (a[i+1] != 1)
- o << a[i+1];
- }
+ for (size_t i=0; i<mNumVars; i++) {
+ if (a[i+1] != 0) {
+ printed_any = true;
+ if (i <= 25)
+ o << static_cast<unsigned char>('a' + i);
+ else
+ o << static_cast<unsigned char>('A' + (i - 26));
+ if (a[i+1] != 1)
+ o << static_cast<int64>(a[i+1]);
+ }
+ }
if (print_comp)
- o << '<' << *a.mValue << '>';
+ o << '<' << static_cast<int64>(*a.mValue) << '>';
else if (!printed_any && print_one)
o << "1";
}
@@ -655,24 +653,27 @@ void PolyRing::printMonomialFrobbyM2Format(std::ostream& out, const_monomial m)
PolyRing *PolyRing::read(std::istream &i)
{
+ int64 characInt;
coefficient charac;
int mNumVars, mNumWeights;
- i >> charac;
+ i >> characInt;
+ charac = characInt;
i >> mNumVars;
i >> mNumWeights;
- PolyRing *R = new PolyRing(charac, mNumVars, mNumWeights);
+ PolyRing* R = new PolyRing(charac, mNumVars, mNumWeights);
int wtlen = mNumVars * mNumWeights;
R->mWeights.resize(wtlen);
R->mTotalDegreeGradedOnly = (mNumWeights == 1);
- for (int j=0; j <mNumVars * mNumWeights; j++)
- {
- exponent a;
- i >> a;
- R->mWeights[j] = -a;
- if (R->mWeights[j] != -1)
- R->mTotalDegreeGradedOnly = false;
- }
+ for (int j=0; j <mNumVars * mNumWeights; j++) {
+ exponent a;
+ int64 aInt;
+ i >> aInt;
+ a = aInt;
+ R->mWeights[j] = -a;
+ if (R->mWeights[j] != -1)
+ R->mTotalDegreeGradedOnly = false;
+ }
return R;
}
diff --git a/src/mathicgb/PolyRing.hpp b/src/mathicgb/PolyRing.hpp
index c875612..90bd347 100755
--- a/src/mathicgb/PolyRing.hpp
+++ b/src/mathicgb/PolyRing.hpp
@@ -360,14 +360,18 @@ public:
bool weightsCorrect(ConstMonomial a) const;
+ // returns LT, EQ, or GT, depending on sig ? (m2 * sig2).
int monomialCompare(ConstMonomial a,
ConstMonomial b) const;
// returns LT, EQ or GT
-
int monomialCompare(ConstMonomial sig,
ConstMonomial m2,
ConstMonomial sig2) const;
- // returns LT, EQ, or GT, depending on sig ? (m2 * sig2).
+
+ // If this method returns true for monomials a and b then it is guaranteed
+ // the multiplying a and b together will not overflow the underlying
+ // exponent integer. Does not work for negative exponents.
+ bool monomialHasAmpleCapacity(ConstMonomial mono) const;
bool monomialLT(ConstMonomial a, ConstMonomial b) const {
for (size_t i = mTopIndex; i != static_cast<size_t>(-1); --i)
@@ -435,8 +439,9 @@ public:
/// Returns the hash of the product of a and b.
HashValue monomialHashOfProduct(ConstMonomial a, ConstMonomial b) const {
- return static_cast<HashValue>(a[mHashIndex]) +
- static_cast<HashValue>(b[mHashIndex]);
+ return static_cast<exponent>(
+ static_cast<HashValue>(a[mHashIndex]) +
+ static_cast<HashValue>(b[mHashIndex]));
}
void monomialCopy(ConstMonomial a, Monomial &result) const;
@@ -667,6 +672,9 @@ inline bool PolyRing::monomialIsProductOfHintTrue(
// for unaligned access. Performance seems to be no worse than for using
// 32 bit integers directly.
+ if (sizeof(exponent) < 4)
+ return monomialIsProductOf(a, b, ab);
+
uint64 orOfXor = 0;
for (size_t i = mNumVars / 2; i != static_cast<size_t>(-1); --i) {
uint64 A, B, AB;
@@ -691,6 +699,10 @@ MATHICGB_INLINE bool PolyRing::monomialIsTwoProductsOfHintTrue(
const ConstMonomial a1b,
const ConstMonomial a2b
) const {
+ if (sizeof(exponent) < 4)
+ return (monomialIsProductOf(a1, b, a1b) &&
+ monomialIsProductOf(a2, b, a2b));
+
uint64 orOfXor = 0;
for (size_t i = mNumVars / 2; i != static_cast<size_t>(-1); --i) {
uint64 A1, A2, B, A1B, A2B;
@@ -725,7 +737,7 @@ inline void PolyRing::monomialMult(ConstMonomial a,
for (size_t i = mHashIndex; i != static_cast<size_t>(-1); --i)
result[i] = a[i] + b[i];
MATHICGB_ASSERT(computeHashValue(result) ==
- computeHashValue(a) + computeHashValue(b));
+ static_cast<exponent>(computeHashValue(a) + computeHashValue(b)));
#if 0
// testing different things to see if we can speed it up further.
@@ -761,7 +773,10 @@ inline HashValue PolyRing::computeHashValue(const_monomial a1) const {
a++;
for (size_t i = 0; i < mNumVars; ++i)
hash += static_cast<HashValue>(a[i]) * mHashVals[i];
- return hash;
+ // cast to potentially discard precision that will also be lost
+ // when storing a hash value as an exponent. Otherwise the hash
+ // value that is computed will not match the stored hash value.
+ return static_cast<exponent>(hash);
}
inline void PolyRing::setHashOnly(Monomial& a1) const
@@ -842,10 +857,11 @@ inline void PolyRing::monomialDivideToNegative(ConstMonomial a,
{
for (size_t i = 0; i <= mHashIndex; ++i)
result[i] = a[i] - b[i];
- MATHICGB_ASSERT(monomialHashValue(result) == monomialHashValue(a) - monomialHashValue(b));
+ MATHICGB_ASSERT(monomialHashValue(result) ==
+ static_cast<exponent>(monomialHashValue(a) - monomialHashValue(b)));
MATHICGB_ASSERT(!hashValid(a) || !hashValid(b) || hashValid(result));
- MATHICGB_ASSERT(computeHashValue(result) ==
- computeHashValue(a) - computeHashValue(b));
+ MATHICGB_ASSERT(computeHashValue(result) == static_cast<exponent>
+ (computeHashValue(a) - computeHashValue(b)));
}
inline bool PolyRing::monomialRelativelyPrime(ConstMonomial a,
@@ -1125,6 +1141,14 @@ inline void PolyRing::coefficientMult(coefficient a, coefficient b, coefficient
result = c % mCharac;
}
+inline bool PolyRing::monomialHasAmpleCapacity(ConstMonomial mono) const {
+ const auto halfMax = std::numeric_limits<exponent>::max() / 2;
+ for (size_t i = mTopIndex; i != 0; --i)
+ if (mono[i] > halfMax)
+ return false;
+ return true;
+}
+
#endif
// Local Variables:
diff --git a/src/test/poly-test.cpp b/src/test/poly-test.cpp
index bbb6e88..f92fc3c 100755
--- a/src/test/poly-test.cpp
+++ b/src/test/poly-test.cpp
@@ -282,7 +282,7 @@ TEST(Monomial, ops)
testMonomialOps(R.get(), "<0>", "<0>");
testMonomialOps(R.get(), "a<0>", "a<0>");
testMonomialOps(R.get(), "a<0>", "b<0>");
- testMonomialOps(R.get(), "a1000b1000c1000d1000e1000f1000<0>", "b2f5<0>");
+ testMonomialOps(R.get(), "a10b10c10d10e10f10<0>", "b2f5<0>");
}
TEST(Monomial, ei)
--
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