[mathicgb] 381/393: Made Poly use PolyRing::Field and other slight cleanup.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:37 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 f42b685402b70b49f807b5ebb0bfbe7d927423d6
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date: Mon Sep 23 12:49:25 2013 +0200
Made Poly use PolyRing::Field and other slight cleanup.
---
src/mathicgb/F4MatrixBuilder.cpp | 10 ++++-----
src/mathicgb/F4MatrixBuilder.hpp | 5 ++++-
src/mathicgb/F4MatrixBuilder2.cpp | 11 ++++++----
src/mathicgb/F4MatrixBuilder2.hpp | 5 ++++-
src/mathicgb/MathicIO.hpp | 2 +-
src/mathicgb/Poly.cpp | 41 +++++++++-------------------------
src/mathicgb/Poly.hpp | 39 ++++++++++++++++-----------------
src/mathicgb/PolyRing.hpp | 10 ++++++---
src/mathicgb/PrimeField.hpp | 46 +++++++++++++++++++++++++++++++++++----
src/mathicgb/Scanner.hpp | 3 ++-
src/mathicgb/SigPolyBasis.cpp | 2 +-
src/mathicgb/SigPolyBasis.hpp | 3 +++
12 files changed, 105 insertions(+), 72 deletions(-)
diff --git a/src/mathicgb/F4MatrixBuilder.cpp b/src/mathicgb/F4MatrixBuilder.cpp
index 7f932d7..b970be8 100755
--- a/src/mathicgb/F4MatrixBuilder.cpp
+++ b/src/mathicgb/F4MatrixBuilder.cpp
@@ -296,9 +296,9 @@ updateReader:
}
const auto origScalar = it.coef();
- MATHICGB_ASSERT(origScalar != 0);
+ MATHICGB_ASSERT(!ring().field().isZero(origScalar));
const auto maybeNegated =
- negate ? ring().coefficientNegateNonZero(origScalar) : origScalar;
+ negate ? field().negativeNonZero(origScalar) : origScalar;
MATHICGB_ASSERT(maybeNegated < std::numeric_limits<Scalar>::max());
builder.appendEntryBottom(*col.first, static_cast<Scalar>(maybeNegated));
}
@@ -330,14 +330,14 @@ updateReader:
ColReader colMap(mMap);
while (it != end) {
MATHICGB_ASSERT(it.coef() < std::numeric_limits<Scalar>::max());
- MATHICGB_ASSERT(it.coef() != 0);
+ MATHICGB_ASSERT(!field().isZero(it.coef()));
const auto scalar1 = static_cast<Scalar>(it.coef());
const auto mono1 = it.mono();
auto it2 = it;
++it2;
MATHICGB_ASSERT(it2.coef() < std::numeric_limits<Scalar>::max());
- MATHICGB_ASSERT(it2.coef() != 0);
+ MATHICGB_ASSERT(!field().isZero(it2.coef()));
const auto scalar2 = static_cast<Scalar>(it2.coef());
const auto mono2 = it2.mono();
@@ -410,7 +410,7 @@ void F4MatrixBuilder::appendRowBottom(
++itB;
}
MATHICGB_ASSERT(coeff < std::numeric_limits<Scalar>::max());
- if (coeff != 0)
+ if (!field().isZero(coeff))
builder.appendEntryBottom(col, static_cast<Scalar>(coeff));
}
}
diff --git a/src/mathicgb/F4MatrixBuilder.hpp b/src/mathicgb/F4MatrixBuilder.hpp
index 0d4d384..f43c658 100755
--- a/src/mathicgb/F4MatrixBuilder.hpp
+++ b/src/mathicgb/F4MatrixBuilder.hpp
@@ -29,6 +29,8 @@ private:
typedef QuadMatrixBuilder::Monomials Monomials;
public:
+ typedef PolyRing::Field Field;
+
typedef PolyRing::Monoid Monoid;
typedef Monoid::Mono Mono;
typedef Monoid::MonoRef MonoRef;
@@ -78,7 +80,8 @@ public:
void buildMatrixAndClear(QuadMatrix& matrix);
const PolyRing& ring() const {return mBuilder.ring();}
- const Monoid& monoid() const {return mBuilder.ring().monoid();}
+ const Monoid& monoid() const {return ring().monoid();}
+ const Field& field() const {return ring().field();}
private:
typedef const MonomialMap<LeftRightColIndex>::Reader ColReader;
diff --git a/src/mathicgb/F4MatrixBuilder2.cpp b/src/mathicgb/F4MatrixBuilder2.cpp
index 87e9bad..b475de9 100755
--- a/src/mathicgb/F4MatrixBuilder2.cpp
+++ b/src/mathicgb/F4MatrixBuilder2.cpp
@@ -20,6 +20,8 @@ MATHICGB_NAMESPACE_BEGIN
class F4MatrixBuilder2::Builder {
public:
+ typedef PolyRing::Field Field;
+
typedef PolyRing::Monoid Monoid;
typedef Monoid::Mono Mono;
typedef Monoid::MonoRef MonoRef;
@@ -264,7 +266,8 @@ public:
}
const PolyRing& ring() const {return mBasis.ring();}
- const Monoid& monoid() const {return mBasis.ring().monoid();}
+ const Monoid& monoid() const {return ring().monoid();}
+ const Field& field() const {return ring().field();}
Builder(const PolyBasis& basis, const size_t memoryQuantum):
mMemoryQuantum(memoryQuantum),
@@ -358,7 +361,7 @@ public:
const auto col = findOrCreateColumn
(it.mono(), multiple, reader, feeder);
MATHICGB_ASSERT(it.coef() < std::numeric_limits<Scalar>::max());
- MATHICGB_ASSERT(it.coef() != 0);
+ MATHICGB_ASSERT(!field().isZero(it.coef()));
*indices = col.first;
++indices;
++it;
@@ -367,14 +370,14 @@ public:
ColReader colMap(mMap);
while (it != end) {
MATHICGB_ASSERT(it.coef() < std::numeric_limits<Scalar>::max());
- MATHICGB_ASSERT(it.coef() != 0);
+ MATHICGB_ASSERT(!field().isZero(it.coef()));
const auto scalar1 = static_cast<Scalar>(it.coef());
const auto mono1 = it.mono();
auto it2 = it;
++it2;
MATHICGB_ASSERT(it2.coef() < std::numeric_limits<Scalar>::max());
- MATHICGB_ASSERT(it2.coef() != 0);
+ MATHICGB_ASSERT(!field().isZero(it2.coef()));
const auto scalar2 = static_cast<Scalar>(it2.coef());
const auto mono2 = it2.mono();
diff --git a/src/mathicgb/F4MatrixBuilder2.hpp b/src/mathicgb/F4MatrixBuilder2.hpp
index 06ac20b..46c3c71 100755
--- a/src/mathicgb/F4MatrixBuilder2.hpp
+++ b/src/mathicgb/F4MatrixBuilder2.hpp
@@ -22,6 +22,8 @@ MATHICGB_NAMESPACE_BEGIN
/// functionality, so add one of those before fixing this.
class F4MatrixBuilder2 {
public:
+ typedef PolyRing::Field Field;
+
typedef PolyRing::Monoid Monoid;
typedef Monoid::Mono Mono;
typedef Monoid::MonoRef MonoRef;
@@ -72,7 +74,8 @@ public:
void buildMatrixAndClear(QuadMatrix& matrix);
const PolyRing& ring() const {return mBasis.ring();}
- const Monoid& monoid() const {return mBasis.ring().monoid();}
+ const Monoid& monoid() const {return ring().monoid();}
+ const Field& field() const {return ring().field();}
private:
/// Represents the task of adding a row to the matrix. If sPairPoly is null
diff --git a/src/mathicgb/MathicIO.hpp b/src/mathicgb/MathicIO.hpp
index 1ec1709..998a8fd 100755
--- a/src/mathicgb/MathicIO.hpp
+++ b/src/mathicgb/MathicIO.hpp
@@ -421,7 +421,7 @@ void MathicIO<M, BF>::writePoly(
writeTerm(
poly.ring(),
writeComponent,
- poly.ring().field().toElement(it.coef()),
+ it.coef(),
it.mono(),
it != poly.begin(),
out
diff --git a/src/mathicgb/Poly.cpp b/src/mathicgb/Poly.cpp
index 6a6f097..fe84c9a 100755
--- a/src/mathicgb/Poly.cpp
+++ b/src/mathicgb/Poly.cpp
@@ -14,6 +14,11 @@ Poly Poly::polyWithTermsDescending() {
// it is not clear that that would be any faster, since swapping around
// monomials in-place is slow. Swapping terms is faster, since terms
// just refer to the monomials. This way is also easier to implement.
+ //
+ /// @todo: make a separate TermSorter object that allows the terms vector
+ /// to be reused between sorts. This should matter for sorting input
+ /// ideals where there might be a lot of polynomials to go through.
+ /// That way terms would not need to be allocated anew for each polynomial.
auto greaterOrEqual = [&](const NewConstTerm& a, const NewConstTerm& b) {
return monoid().lessThan(*b.mono, *a.mono);
};
@@ -22,36 +27,11 @@ Poly Poly::polyWithTermsDescending() {
// *** Make a new polynomial with terms in that order
Poly poly(ring());
- poly.append(terms, termCount());
+ poly.reserve(termCount());
+ poly.append(terms);
MATHICGB_ASSERT(poly.termsAreInDescendingOrder());
-
- // This return statements causes no copy. The return value optimization
- // will be used at the option of the compiler. If a crappy compiler gets
- // that wrong, poly will be treated as an r-value, which is to say that
- // this code becomes equivalent to return std::move(poly). That happens
- // because poly is a local variable being returned, so the standard
- // allows movement out of poly in this particular situation - that is
- // safe/reasonable because the very next thing that will happen to poly is
- // that it will get destructed, so anyone in a position to know that the
- // contents of poly had been moved out would then also be using
- // a pointer to the now-invalid poly object, which invokes undefined
- // behavior anyway.
- //
- // Capturing the returned Poly into another poly also will not cause a copy.
- // Consider the code
- //
- // Poly p1(q.polyWithTermsDescending());
- // Poly p2(ring);
- // p2 = q.polyWithTermsDescending();
- //
- // The return value is an unnamed temporary that is constructed/assigned
- // into p1/p2. Unnamed temporaries are r-values, so the guts of those
- // temporary objects will be moved into p1/p2. There will be no copy.
- //
- // (Of course there is the one copy that we are doing further up into poly
- // to avoid doing an in-place sort. The point is that there are no further
- // copies than that one.)
+ MATHICGB_ASSERT(poly.termCount() == termCount());
return poly;
}
@@ -59,10 +39,9 @@ void Poly::makeMonic() {
MATHICGB_ASSERT(!isZero());
if (isMonic())
return;
- auto multiply = leadCoef();
- ring().coefficientReciprocalTo(multiply);
+ auto multiplier = field().inverse(leadCoef());
for (auto& coef : mCoefs)
- ring().coefficientMultTo(coef, multiply);
+ coef = field().product(coef, multiplier);
MATHICGB_ASSERT(isMonic());
}
diff --git a/src/mathicgb/Poly.hpp b/src/mathicgb/Poly.hpp
index 1a2400f..2b19cb5 100755
--- a/src/mathicgb/Poly.hpp
+++ b/src/mathicgb/Poly.hpp
@@ -15,6 +15,10 @@ MATHICGB_NAMESPACE_BEGIN
class Poly {
public:
+ typedef PolyRing::Field Field;
+ typedef Field::Element Coef;
+ typedef Field::ConstElementRef ConstCoefRef;
+
typedef PolyRing::Monoid Monoid;
typedef Monoid::Mono Mono;
typedef Monoid::MonoRef MonoRef;
@@ -37,6 +41,8 @@ public:
const PolyRing& ring() const {return mRing;}
const Monoid& monoid() const {return ring().monoid();}
+ const Field& field() const {return ring().field();}
+
bool isZero() const {return mCoefs.empty();}
size_t termCount() const {return mCoefs.size();}
size_t getMemoryUse() const;
@@ -56,6 +62,11 @@ public:
/// Appends the given term as the last term in the polynomial.
void append(const NewConstTerm& term) {
MATHICGB_ASSERT(term.mono != nullptr);
+ typedef Field::RawElement C;
+ typedef Field::Element E;
+ C c = term.coef;
+ E e = c;
+
append(term.coef, *term.mono);
}
@@ -67,17 +78,6 @@ public:
append(term);
}
- /// As append(r), but possibly with better performance. The number of
- /// elements in the range r must equal rangeTermCount.
- template<class Range>
- void append(const Range& r, size_t rangeTermCount) {
- MATHICGB_ASSERT
- (std::distance(std::begin(r), std::end(r)) == rangeTermCount);
- reserve(termCount() + rangeTermCount);
- for (const auto& term : r)
- append(term);
- }
-
/// As append(range(termsBegin, termsEnd))
template<class ForwardIterator>
void append(
@@ -87,8 +87,7 @@ public:
append(range(termsBegin, termsEnd));
}
-
- void append(coefficient coef, ConstMonoRef mono);
+ void append(ConstCoefRef coef, ConstMonoRef mono);
/// Hint that space for the give number of terms is going to be needed.
/// This serves the same purpose as std::vector<>::reserve.
@@ -117,13 +116,13 @@ public:
// *** Accessing the coefficients of the terms in the polynomial.
/// Returns the coefficient of the given term.
- coefficient coef(size_t index) const {
+ const Coef& coef(size_t index) const {
MATHICGB_ASSERT(index < termCount());
return mCoefs[index];
}
/// Returns the coefficient of the leading term.
- coefficient leadCoef() const {
+ const Coef& leadCoef() const {
MATHICGB_ASSERT(!isZero());
return mCoefs.front();
}
@@ -135,10 +134,10 @@ public:
/// polynomial is monic - you'll get an assert to help pinpoint the error.
bool isMonic() const {
MATHICGB_ASSERT(!isZero());
- return ring().coefficientIsOne(leadCoef());
+ return field().isOne(leadCoef());
}
- typedef std::vector<coefficient>::const_iterator ConstCoefIterator;
+ typedef std::vector<Coef>::const_iterator ConstCoefIterator;
typedef Range<ConstCoefIterator> ConstCoefIteratorRange;
ConstCoefIterator coefBegin() const {return mCoefs.begin();}
@@ -246,7 +245,7 @@ public:
bool operator==(const ConstTermIterator& it) const {return mIt == it.mIt;}
bool operator!=(const ConstTermIterator& it) const {return mIt != it.mIt;}
- coefficient coef() const {return (*mIt).first;}
+ const Coef& coef() const {return (*mIt).first;}
ConstMonoRef mono() const {return (*mIt).second;}
private:
@@ -272,14 +271,14 @@ private:
friend bool operator==(const Poly &a, const Poly &b);
const PolyRing& mRing;
- std::vector<coefficient> mCoefs;
+ std::vector<Coef> mCoefs;
std::vector<exponent> mMonos;
};
bool operator==(const Poly& a, const Poly& b);
// This is inline since it is performance-critical.
-inline void Poly::append(coefficient a, ConstMonoRef m) {
+inline void Poly::append(ConstCoefRef a, ConstMonoRef m) {
mCoefs.push_back(a);
const auto offset = mMonos.size();
diff --git a/src/mathicgb/PolyRing.hpp b/src/mathicgb/PolyRing.hpp
index 54e6907..97140cc 100755
--- a/src/mathicgb/PolyRing.hpp
+++ b/src/mathicgb/PolyRing.hpp
@@ -91,7 +91,9 @@ typedef int32 exponent ;
typedef uint32 HashValue;
typedef long coefficient;
typedef MonoMonoid<exponent> Monoid;
-typedef PrimeField<unsigned long> Field;
+
+/// This typedef should really be for an unsigned type.
+typedef PrimeField<coefficient> Field;
typedef exponent* vecmonomial; // includes a component
@@ -231,7 +233,9 @@ struct term {
class PolyRing {
public:
typedef MonoMonoid<exponent> Monoid;
- typedef PrimeField<unsigned long> Field;
+
+ /// This typedef should really be for an unsigned type.
+ typedef PrimeField<coefficient> Field;
/// @todo: make this dependent on the monoid and field once all code
/// has been migrated from ::term to PolyRing::Term.
@@ -499,7 +503,7 @@ public:
///////////////////////////////////////////
const Monoid& monoid() const {return mMonoid;}
- const Field field() const {return mField;}
+ const Field& field() const {return mField;}
private:
Field mField;
diff --git a/src/mathicgb/PrimeField.hpp b/src/mathicgb/PrimeField.hpp
index 03fd228..a486752 100755
--- a/src/mathicgb/PrimeField.hpp
+++ b/src/mathicgb/PrimeField.hpp
@@ -19,9 +19,31 @@ public:
class Element {
public:
- static_assert(!std::numeric_limits<T>::is_signed, "");
+ // Re-instate this assert once all code has moved to using PrimeField
+ // properly so that coefficients are no longer signed.
+ //static_assert(!std::numeric_limits<T>::is_signed, "");
static_assert(std::numeric_limits<T>::is_integer, "");
+ /// This constructor/conversion needs to go away as soon as all code
+ /// has been converted to using PrimeField properly. Kill it with fire!
+ Element(const RawElement& e): mValue(e) {}
+
+ /// This conversion needs to go away as soon as all code
+ /// has been converted to using PrimeField properly. Kill it with fire!
+ operator RawElement&() {return mValue;}
+
+ /// This conversion needs to go away as soon as all code
+ /// has been converted to using PrimeField properly. Kill it with fire!
+ operator const RawElement&() const {return mValue;}
+
+ /// This method needs to go away as soon as all code
+ /// has been converted to using PrimeField properly. Kill it with fire!
+ bool operator==(const RawElement e) const {return value() == e.value();}
+
+ /// This method needs to go away as soon as all code
+ /// has been converted to using PrimeField properly. Kill it with fire!
+ bool operator!=(const RawElement e) const {return !(*this == e);}
+
Element(const Element& e): mValue(e.value()) {}
Element& operator=(const Element& e) {
@@ -31,16 +53,23 @@ public:
bool operator==(const Element e) const {return value() == e.value();}
bool operator!=(const Element e) const {return !(*this == e);}
+
T value() const {return mValue;}
private:
friend class PrimeField;
- Element(const T value): mValue(value) {}
+ // Uncomment this constructor once the public one is gone.
+ //Element(const T value): mValue(value) {}
friend class PrimeFile;
T mValue;
};
+ typedef Element& ElementRef;
+ typedef const Element& ConstElementRef;
+ typedef Element* ElementPtr;
+ typedef const Element* ConstElementPtr;
+
PrimeField(const T primeCharacteristic): mCharac(primeCharacteristic) {}
Element zero() const {return Element(0);}
@@ -67,7 +96,10 @@ public:
MATHICGB_ASSERT(0 <= i);
typedef typename std::make_unsigned<NoRefInteger>::type Unsigned;
- MATHICGB_ASSERT(static_cast<Unsigned>(i) < charac());
+ //replace the below assert with this uncommented one once we get rid
+ //of signed element types.
+ //MATHICGB_ASSERT(static_cast<Unsigned>(i) < charac());
+ MATHICGB_ASSERT(i < charac());
return Element(i);
}
@@ -167,11 +199,17 @@ namespace PrimeFieldInternal {
template<> struct ModularProdType<uint16> {typedef uint32 type;};
template<> struct ModularProdType<uint32> {typedef uint64 type;};
+ template<> struct ModularProdType<int8> {typedef int16 type;};
+ template<> struct ModularProdType<int16> {typedef int32 type;};
+ template<> struct ModularProdType<int32> {typedef int64 type;};
+
// @todo: Remove this typedef when possible. 64 bits is not enough
// to store a 64 bit product. We need it right now because
// coefficients are handled as 64 bit in the legacy PolyRing.
template<> struct ModularProdType<uint64> {typedef uint64 type;};
template<> struct ModularProdType<long unsigned int> {typedef uint64 type;};
+ template<> struct ModularProdType<int64> {typedef uint64 type;};
+ template<> struct ModularProdType<long int> {typedef uint64 type;};
}
template<class T>
@@ -215,7 +253,7 @@ auto PrimeField<T>::inverse(const Element elementA) const -> Element {
// second turn
if (b == 1) {
- MATHICGB_ASSERT(minusLastX != 0);
+ MATHICGB_ASSERT(!isZero(minusLastX));
MATHICGB_ASSERT(minusLastX < charac());
x = charac() - minusLastX;
break;
diff --git a/src/mathicgb/Scanner.hpp b/src/mathicgb/Scanner.hpp
index 4c1af9d..b608832 100755
--- a/src/mathicgb/Scanner.hpp
+++ b/src/mathicgb/Scanner.hpp
@@ -255,7 +255,8 @@ typename PrimeField<T>::Element Scanner::readModular(
// Otherwise we need to consider that the most negative value's
// negative cannot be represented as a positive number when reading.
- static_assert(!std::is_signed<T>::value, "");
+ // todo: reinstate this assert once we get rid of signed coefficients.
+ //static_assert(!std::is_signed<T>::value, "");
eatWhite();
const bool minus = !match('+') && match('-');
diff --git a/src/mathicgb/SigPolyBasis.cpp b/src/mathicgb/SigPolyBasis.cpp
index 90a96c2..fcef4bb 100755
--- a/src/mathicgb/SigPolyBasis.cpp
+++ b/src/mathicgb/SigPolyBasis.cpp
@@ -57,7 +57,7 @@ void SigPolyBasis::addComponent() {
void SigPolyBasis::insert(Mono ownedSig, std::unique_ptr<Poly> f) {
MATHICGB_ASSERT(f.get() != nullptr);
MATHICGB_ASSERT(!f->isZero());
- MATHICGB_ASSERT(f->leadCoef() != 0);
+ MATHICGB_ASSERT(!field().isZero(f->leadCoef()));
MATHICGB_ASSERT(!ownedSig.isNull());
MATHICGB_ASSERT(monoid().fromPool(*ownedSig));
diff --git a/src/mathicgb/SigPolyBasis.hpp b/src/mathicgb/SigPolyBasis.hpp
index 46d48ef..afbd7c6 100755
--- a/src/mathicgb/SigPolyBasis.hpp
+++ b/src/mathicgb/SigPolyBasis.hpp
@@ -21,6 +21,8 @@ MATHICGB_NAMESPACE_BEGIN
/// use in signature Groebner basis algorithms.
class SigPolyBasis {
public:
+ typedef PolyRing::Field Field;
+
typedef PolyRing::Monoid Monoid;
typedef Monoid::Mono Mono;
typedef Monoid::MonoRef MonoRef;
@@ -40,6 +42,7 @@ public:
const PolyRing& ring() const {return mBasis.ring();}
const Monoid& monoid() const {return ring().monoid();}
+ const Field& field() const {return ring().field();}
const Poly& poly(size_t index) const {return mBasis.poly(index);}
size_t size() const {return mBasis.size();}
--
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