Beispiel #1
0
  void mult(const DMat<RT>& A, 
            const DMat<RT>& B, 
            DMat<RT>& result_product)
  {
    //printf("entering dmat mult\n");
    typedef typename RT::ElementType ElementType;
    typedef typename DMat<RT>::ConstIterator ConstIterator;
    
    M2_ASSERT(A.numColumns() == B.numRows());
    M2_ASSERT(A.numRows() == result_product.numRows());
    M2_ASSERT(B.numColumns() == result_product.numColumns());

    ElementType* result = result_product.array();

    ElementType tmp;
    A.ring().init(tmp);
    // WARNING: this routine expects the result matrix to be in ROW MAJOR ORDER
    for (size_t i = 0; i<A.numRows(); i++)
      for (size_t j = 0; j<B.numColumns(); j++)
        {
          ConstIterator i1 = A.rowBegin(i);
          ConstIterator iend = A.rowEnd(i);
          ConstIterator j1 = B.columnBegin(j);
          
          while (i1 != iend)
            {
              A.ring().mult(tmp, *i1, *j1);
              A.ring().add(*result, *result, tmp);
              ++i1;
              ++j1;
            }
          result++;
        }
    A.ring().clear(tmp);
  }
Beispiel #2
0
  bool inverse(const DMatZZpFFPACK& mat, 
               DMatZZpFFPACK& result_inv)
  {
    M2_ASSERT(mat.numRows() == mat.numColumns());
    result_inv.resize(mat.numRows(), mat.numRows());

    M2_ASSERT(result_inv.numRows() == mat.numRows());
    M2_ASSERT(result_inv.numColumns() == mat.numRows());

    if (mat.numRows() == 0)
      {
        // 26 April 2014: this branch is needed as FFPACK gives answer of 0 in this case.
        return true;
      }

    DMatZZpFFPACK N(mat);
    size_t n = mat.numRows();
    int nullspacedim;
    FFPACK::Invert2(mat.ring().field(), 
                    n, 
                    N.array(), 
                    n, 
                    result_inv.array(), 
                    n, 
                    nullspacedim);
    return (nullspacedim == 0);
  }
Beispiel #3
0
SchreyerOrder *SchreyerOrder::exterior(int pp) const
     // p th exterior power
{
  // This routine is only called from FreeModule::exterior.
  // Therefore: p is in the range 0 < p <= rk.
  SchreyerOrder *result = new SchreyerOrder(M);
  int rk = rank();

  M2_ASSERT(pp > 0);
  M2_ASSERT(pp <= rk);
  size_t p = static_cast<size_t>(pp);

  Subset a(p, 0);
  for (size_t i=0; i<p; i++) a[i] = i;
  
  int *base = M->make_one();
  int next = 0;
  do
    {
      M->one(base);
      for (size_t r=0; r<p; r++)
        M->mult(base, base_monom(a[r]), base);

      result->append(next++, base);
    }
  while (Subsets::increment(rk, a));

  M->remove(base);
  return result;
}
Beispiel #4
0
  void subtractMultipleTo(DMat<RT>& C, 
                          const DMat<RT>& A, 
                          const DMat<RT>& B)
  // C = C - A*B
  {
    typedef typename RT::ElementType ElementType;
    typedef typename DMat<RT>::ConstIterator ConstIterator;
    
    M2_ASSERT(A.numColumns() == B.numRows());
    M2_ASSERT(A.numRows() == C.numRows());
    M2_ASSERT(B.numColumns() == C.numColumns());

    ElementType* result = C.array();

    ElementType tmp;
    A.ring().init(tmp);
    // WARNING: this routine expects the result matrix to be in ROW MAJOR ORDER
    for (size_t i = 0; i<A.numRows(); i++)
      for (size_t j = 0; j<B.numColumns(); j++)
        {
          ConstIterator i1 = A.rowBegin(i);
          ConstIterator iend = A.rowEnd(i);
          ConstIterator j1 = B.columnBegin(j);
          
          while (i1 != iend)
            {
              A.ring().mult(tmp, *i1, *j1);
              A.ring().subtract(*result, *result, tmp);
              ++i1;
              ++j1;
            }
          result++;
        }
    A.ring().clear(tmp);
  }
Beispiel #5
0
  void addInPlace(SMat<RT>&A, const SMat<RT>& B) 
  {
    M2_ASSERT(&B.ring() == &A.ring());
    M2_ASSERT(B.numRows() == A.numRows());
    M2_ASSERT(B.numColumns() == A.numColumns());

    A.addInPlace(B);
  }
Beispiel #6
0
  void subtractInPlace(SMat<RT>& A, const SMat<RT>& B)
  // A -= B
  {
    M2_ASSERT(&B.ring() == &A.ring());
    M2_ASSERT(B.numRows() == A.numRows());
    M2_ASSERT(B.numColumns() == A.numColumns());

    A.subtractInPlace(B);
  }
Beispiel #7
0
 void transpose(const SMat<RT>& A, SMat<RT>& result)
 {
   // result should be the 0 matrix of the correct size.
   M2_ASSERT(&A != &result);  // these cannot be aliased!
   M2_ASSERT(result.numRows() == A.numColumns());
   M2_ASSERT(result.numColumns() == A.numRows());
   throw exc::engine_error("'transpose' not writtten for sparse mutable matrices");
   //TODO: MES: write this!!
 }
Beispiel #8
0
 void subtractInPlace(DMat<RT>& A, const DMat<RT>& B)
 // A -= B
 {
   M2_ASSERT(&B.ring() == &A.ring());
   M2_ASSERT(B.numRows() == A.numRows());
   M2_ASSERT(B.numColumns() == A.numColumns());
   
   size_t len = A.numRows() * A.numColumns();
   for (size_t i=0; i<len; i++)
     {
       A.ring().subtract(A.array()[i], A.array()[i], B.array()[i]);
     }
 }
Beispiel #9
0
 void transpose(const DMat<RT>& A, DMat<RT>& result)
 {
   M2_ASSERT(&A != &result);  // these cannot be aliased!
   M2_ASSERT(result.numRows() == A.numColumns());
   M2_ASSERT(result.numColumns() == A.numRows());
   for (size_t c = 0; c < A.numColumns(); ++c)
     {
       auto i = A.columnBegin(c);
       auto j = result.rowBegin(c);
       auto end = A.columnEnd(c);
       for ( ; i != end; ++i, ++j)
         A.ring().set(*j, *i);
     }
 }
Beispiel #10
0
void binomial_ring::intvector_to_binomial(vec f, binomial &result) const
  // result should be a preallocated binomial
{
  for (int i=0; i<nslots; i++)
    {
      result.lead[i] = 0;
      result.tail[i] = 0;
    }

  for ( ; f != NULL; f = f->next)
    {
      std::pair<bool,long> res = globalZZ->coerceToLongInteger(f->coeff);
      M2_ASSERT(res.first);
      int e = static_cast<int>(res.second);

      if (e > 0)
        result.lead[f->comp] = e;
      else if (e < 0)
        result.tail[f->comp] = -e;
    }

  set_weights(result.lead);
  set_weights(result.tail);
  normalize(result);
}
Beispiel #11
0
  void ARingZZpFFPACK::power(ElementType &result, const ElementType a, STT n) const
  {
    if (is_zero(a))
      {
        if (n < 0) 
          ERROR("division by zero");
        set(result, a);
        return;
      }
    ElementType base;
    set(base, a);
    if (n < 0)
      {
        invert(base,base);
        n = -n;
      }
    n = n % (mCharac-1);
    set_from_int(result, 1);
    if (n == 0)
      return;

    // Now use doubling algorithm
    M2_ASSERT(n > 0);
    for (;;)
      {
        if ((n % 2) != 0)
          mFfpackField.mulin(result,base); // result *= base
        n >>= 1;
        if (n == 0)
          return;
        else
          mFfpackField.mulin(base, base); // base = base^2
      }
  }
Beispiel #12
0
 void ARingZZGMP::syzygy(const ElementType& a, const ElementType& b,
                      ElementType& x, ElementType& y) const
 {
   M2_ASSERT(!is_zero(b));
   // First check the special cases a = 0, b = 1, -1.  Other cases: use gcd.
   if (is_zero(a))
     {
       set_from_long(x, 1);
       set_zero(y);
       return;
     }
   if (mpz_cmp_ui(&b,1) == 0)
     {
       set_from_long(x, 1);
       negate(y, a);
       return;
     }
   if (mpz_cmp_si(&b,-1) == 0)
     {
       set_from_long(x, 1);
       set(y, a);
       return;
     }
   elem g;
   init(g);
   mpz_gcd(&g,&a,&b);
   divide(y,a,g);
   divide(x,b,g);
   if (mpz_sgn(&x) > 0)
     negate(y,y);
   else
     negate(x,x);
   clear(g);
 }
Beispiel #13
0
ring_elem GF::from_rational(mpq_ptr q) const
{
  // a should be an element of ZZ/p
  ring_elem a = _originalR->getCoefficients()->from_rational(q);
  std::pair<bool,long> b = _originalR->getCoefficients()->coerceToLongInteger(a);
  M2_ASSERT(b.first);
  return GF::from_long(b.second);
}
Beispiel #14
0
 ARingZZpFFPACK::ARingZZpFFPACK(UTT charact)  :   
   mFfpackField          (FieldType(static_cast<double>(charact))),
   mFfpackRandomIterator (mFfpackField),
   mCharac               (charact),
   mDimension            (1),
   mGeneratorComputed    (false)
 {
   M2_ASSERT( FieldType::getMaxModulus()>=mCharac );
 }
Beispiel #15
0
 void set(DMat<RT>& A, MatrixWindow wA, const DMat<RT>& B, MatrixWindow wB)
 {
   M2_ASSERT(wA.sameSize(wB));
   long rA = wA.begin_row;
   long rB = wB.begin_row;
   for ( ; rA < wA.end_row; ++rA, ++rB)
     {
       long cA = wA.begin_column;
       long cB = wB.begin_column;
       for ( ; cA < wA.end_column; ++cA, ++cB)
         A.ring().set(A.entry(rA,cA), B.entry(rB,cB));
     }
 }
Beispiel #16
0
 bool isEqual(const DMat<RT>& A, const DMat<RT>& B)
 {
   M2_ASSERT(&A.ring() == &B.ring());
   if (B.numRows() != A.numRows()) return false;
   if (B.numColumns() != A.numColumns()) return false;
   size_t top = A.numRows() * A.numColumns();
   auto elemsA = A.array();
   auto elemsB = B.array();
   for (size_t i = 0; i < top; i++)
     if (!A.ring().is_equal(*elemsA++, *elemsB++))
       return false;
   return true;
 }
Beispiel #17
0
   void scalarMultInPlace(DMat<RT>& A, MatrixWindow wA, const typename RT::ElementType& c)
 {
   M2_ASSERT(wA.sameSize(wB));
   long rA = wA.begin_row;
   for ( ; rA < wA.end_row; ++rA)
     {
       long cA = wA.begin_column;
       for ( ; cA < wA.end_column; ++cA)
         {
           auto& a = A.entry(rA,cA);
           A.ring().mult(a, a, c);
         }
     }
 }
Beispiel #18
0
 void operator=(SubMatrix<MatType> src)
 {
   M2_ASSERT(sameSize(src));
   long rA = begin_row;
   long rB = src.begin_row;
   for ( ; rA < end_row; ++rA, ++rB)
     {
       long cA = begin_column;
       long cB = src.begin_column;
       for ( ; cA < end_column; ++cA, ++cB)
         matrix.ring().set(matrix.entry(rA,cA), src.matrix.entry(rB,cB));
     }
   
 }
Beispiel #19
0
  void addMultipleTo(DMatZZpFFPACK& C,
                     const DMatZZpFFPACK::ElementType& a,
                     const DMatZZpFFPACK& A, 
                     const DMatZZpFFPACK& B)
  {
    // Compute C := C + a*A*B
    // Both DMat, and FFPACK store dense matrices in row major order.
    // Note that the leading dimension in gemm arguments is #columns, 
    // as the matrix is in row-major order
    
    FFLAS::FFLAS_TRANSPOSE tA = FFLAS::FflasNoTrans;
    FFLAS::FFLAS_TRANSPOSE tB = FFLAS::FflasNoTrans;

    size_t m = A.numRows();
    size_t k = A.numColumns();
    M2_ASSERT(A.numColumns() == B.numRows());
    size_t n = B.numColumns();
    
    M2_ASSERT(C.numRows() == m);
    M2_ASSERT(C.numColumns() == n);

    DMatZZpFFPACK::ElementType b;
    C.ring().init(b);
    C.ring().set_from_long(b, 1);
    FFLAS::fgemm( C.ring().field(),
                  tB, tA,
                  m,n,k,
                  a,
                  A.array(),
                  A.numColumns(),
                  B.array(),
                  B.numColumns(),
                  b,
                  C.array(),
                  C.numColumns()
                  );
  }
Beispiel #20
0
   void scalarMult(DMat<RT>& A, MatrixWindow wA, const typename RT::ElementType& c, const DMat<RT>& B, MatrixWindow wB)
 {
   M2_ASSERT(wA.sameSize(wB));
   long rA = wA.begin_row;
   long rB = wB.begin_row;
   for ( ; rA < wA.end_row; ++rA, ++rB)
     {
       long cA = wA.begin_column;
       long cB = wB.begin_column;
       for ( ; cA < wA.end_column; ++cA, ++cB)
         {
           A.ring().mult(A.entry(rA,cA), c, B.entry(rB,cB));
         }
     }
 }
Beispiel #21
0
 void addMultipleTo(ElementType& c, SubMatrix<MatType> src)
 {
   M2_ASSERT(sameSize(src));
   long rA = begin_row;
   long rB = src.begin_row;
   for ( ; rA < end_row; ++rA, ++rB)
     {
       long cA = begin_column;
       long cB = src.begin_column;
       for ( ; cA < end_column; ++cA, ++cB)
         matrix.ring().addMultipleTo(matrix.entry(rA,cA),
                                     c,
                                     src.matrix.entry(rB,cB));
     }
 }
Beispiel #22
0
   void addMultipleTo(DMat<RT>& A, MatrixWindow wA, const typename RT::ElementType& c, const DMat<RT>& B, MatrixWindow wB)
 {
   M2_ASSERT(wA.sameSize(wB));
   typename RT::ElementType tmp;
   A.ring().init(tmp);
   long rA = wA.begin_row;
   long rB = wB.begin_row;
   for ( ; rA < wA.end_row; ++rA, ++rB)
     {
       long cA = wA.begin_column;
       long cB = wB.begin_column;
       for ( ; cA < wA.end_column; ++cA, ++cB)
         {
           A.ring().mult(tmp, c, B.entry(rB,cB));
           auto& a = A.entry(rA,cA);
           A.ring().add(a, a, tmp);
         }
     }
   A.ring().clear(tmp);
 }
Beispiel #23
0
 ARingZZpFFPACK::ElementType ARingZZpFFPACK::computeGenerator() const
 {
   for (UTT currIntElem=2; currIntElem < mCharac; currIntElem++)
     {
       ElementType currElem;
       set_from_int(currElem, currIntElem);
       bool found = true;
       ElementType tmpElem = currElem;
       for (UTT count=0;count < mCharac-2; count++)
         {
           mult(tmpElem, tmpElem, currElem);
           if (is_equal(currElem, tmpElem))
             found = false;
         }
       if (found) 
         {
           std::cerr << "generator = " << currElem << std::endl;
           return currElem;
         }
     }
   M2_ASSERT(false); // we should not get here, if the program logic is OK
   return ElementType(1);    
 }
Beispiel #24
0
bool GF::promote(const Ring *Rf, const ring_elem f, ring_elem &result) const
{
  // Rf = Z/p[x]/F(x) ---> GF(p,n)
  // promotion: need to be able to know the value of 'x'.
  // lift: need to compute (primite_element)^e

  if (Rf != _originalR) return false;

  result = from_long(0);
  int exp[1];
  for (Nterm *t = f; t != NULL; t = t->next)
    {
      std::pair<bool,long> b = _originalR->getCoefficients()->coerceToLongInteger(t->coeff);
      M2_ASSERT(b.first);
      ring_elem coef = from_long(b.second);
      _originalR->getMonoid()->to_expvector(t->monom, exp);
      // exp[0] is the variable we want.  Notice that since the ring is a quotient,
      // this degree is < n (where Q_ = P^n).
      ring_elem g = power(_x_exponent, exp[0]);
      g = mult(g, coef);
      internal_add_to(result, g);
    }
  return true;
}
Beispiel #25
0
 void power(ElementType& result, const ElementType& a, long n) const {
   M2_ASSERT(n >= 0);
   return fmpq_pow_si(&result,&a,n);
 }
Beispiel #26
0
int LLLoperations::doLLL(MutableMatrix *A,
                         MutableMatrix *Achange,
                         MutableMatrix *LLLstate,
                         int nsteps)
{
    size_t n = A->n_cols();
    if (n == 0) return COMP_DONE;

    // Extract the state from LLLstate:
    int k, kmax;
    ring_elem a, alphaTop, alphaBottom;
    buffer o;

    if (LLLstate->get_entry(0,n,a))
    {
        std::pair<bool,long> res = globalZZ->coerceToLongInteger(a);
        M2_ASSERT(res.first);
        k = static_cast<int>(res.second);
    }
    else
        k = 0;

    if (LLLstate->get_entry(0,n+1,a))
    {
        std::pair<bool,long> res = globalZZ->coerceToLongInteger(a);
        M2_ASSERT(res.first);
        kmax = static_cast<int>(res.second);
    }
    else
        kmax = 0;

    LLLstate->get_entry(0,n+2,alphaTop);  // Don't free alphaTop!
    LLLstate->get_entry(0,n+3,alphaBottom);

    while (k < n && nsteps != 0 && !system_interrupted())
    {
        if (M2_gbTrace >= 1)
        {
            o.reset();
            o << ".";
            if (M2_gbTrace >= 2)
                o << k;
            if (nsteps % 20 == 0)
                o << newline;
            emit(o.str());
        }
        nsteps--;

        if (k > kmax)
        {
            if (M2_gbTrace == 1)
            {
                o.reset();
                o << "." << k;
                if (nsteps % 20 == 0)
                    o << newline;
                emit(o.str());
            }

            kmax = k;
            for (int j=0; j<=k; j++)
            {
                ring_elem u;
                A->dot_product(k,j,u);
                for (int i=0; i<=j-1; i++)
                {
                    // u = (D#i * u - lambda#(k,i) * lambda#(j,i)) // D#(i-1)
                    ring_elem Di, mki, mji, Di1;
                    LLLstate->get_entry(i,i,Di);
                    globalZZ->mult_to(u, Di);
                    if (LLLstate->get_entry(i,k,mki) &&  LLLstate->get_entry(i,j,mji))
                    {
                        ring_elem t1 = globalZZ->mult(mki,mji);
                        globalZZ->subtract_to(u,t1);
                    }
                    if (i > 0)
                    {
                        LLLstate->get_entry(i-1,i-1,Di1);  // Cannot be zero!!
                        ring_elem t1 = globalZZ->divide(u,Di1);
                        globalZZ->remove(u);
                        u = t1;
                    }
                }
                // At this point we have our element:
                LLLstate->set_entry(j,k,u);
                if (j == k && globalZZ->is_zero(u))
                {
                    ERROR("LLL vectors not independent");
                    return COMP_ERROR;
                }
            }
        } // end of the k>kmax initialization
        REDI(k,k-1,A,Achange,LLLstate);
        if (Lovasz(LLLstate,k,alphaTop,alphaBottom))
        {
            SWAPI(k,kmax,A,Achange,LLLstate);
            k--;
            if (k == 0) k = 1;
        }
        else
        {
            for (int ell=k-2; ell>=0; ell--)
                REDI(k,ell,A,Achange,LLLstate);
            k++;
        }
    }

    // Before returning, reset k,kmax:
    LLLstate->set_entry(0,n,globalZZ->from_long(k));
    LLLstate->set_entry(0,n+1,globalZZ->from_long(kmax));

    if (k >= n) return COMP_DONE;
    if (nsteps == 0) return COMP_DONE_STEPS;
    return COMP_INTERRUPTED;
}
Beispiel #27
0
 void ARingZZpFFPACK::unsafeInvert(ElementType &result, const ElementType a) const
 {
   M2_ASSERT(not is_zero(a));
   mFfpackField.inv(result, a);
 }
 void power(ElementType& result, const ElementType& a, long n) const {
   M2_ASSERT(n >= 0);
   mpz_pow_ui(mpq_numref(&result),mpq_numref(&a),n);
   mpz_pow_ui(mpq_denref(&result),mpq_denref(&a),n);
 }
Beispiel #29
0
  GaloisFieldTable::GaloisFieldTable(const PolynomialRing& R,
                                     const ring_elem prim):
    mCharac(static_cast<int>(R.characteristic())),
    mOriginalRing(R),
    mPrimitiveElement(prim)
  {
    M2_ASSERT(mOriginalRing.n_quotients() == 1);

    mGenerator = RingElement::make_raw(&R, R.copy(prim));
    ring_elem f = mOriginalRing.quotient_element(0);
    Nterm *t = f;
    mDimension = mOriginalRing.getMonoid()->primary_degree(t->monom);
    mOrder = mCharac;
    for (int i=1; i<mDimension; i++) mOrder *= mCharac;
    mOne = mOrder - 1; // representation for the number 1: p^n - 1.
    mOrderMinusOne = mOne; // p^n - 1
    mMinusOne = (mCharac == 2 ? mOne : mOne/2);
    
    // Get ready to create mOneTable.
    std::vector<ring_elem> polys;
    polys.push_back(mOriginalRing.from_long(0));
    polys.push_back(mOriginalRing.copy(mPrimitiveElement));
    
    ring_elem oneR = mOriginalRing.from_long(1);
    
    mGeneratorExponent = static_cast<GFElement>(-1);
    ring_elem x = mOriginalRing.var(0);
    if (mOriginalRing.is_equal(mPrimitiveElement, x))
      mGeneratorExponent = 1;
    for (GFElement i=2; i<=mOne; i++)
      {
	ring_elem g = mOriginalRing.mult(polys[i-1], mPrimitiveElement);
	polys.push_back(g);
	if (mOriginalRing.is_equal(g, oneR)) break;
	if (mOriginalRing.is_equal(g, x))
	  mGeneratorExponent = i;
      }

#if 0
    for (size_t i = 0; i < polys.size(); i++)
      {
        std::cerr << i << "  ";
        dringelem(&R, polys[i]);
        std::cerr << "\n";
      }
#endif
    M2_ASSERT(polys.size() == mOrder);
    M2_ASSERT(mGeneratorExponent != static_cast<GFElement>(-1));
    
    // Set 'one_table'.
    mOneTable = newarray_atomic(GFElement,mOrder);
    mOneTable[0] = mOrderMinusOne;

    for (GFElement i=1; i<=mOrderMinusOne; i++)
      {
          if (system_interrupted()) 
          {
            // first clean up?
            return;
          }
	ring_elem f1 = mOriginalRing.add(polys[i], oneR);
    GFElement j;
	for (j=0; j<=mOrderMinusOne; j++)
          if (mOriginalRing.is_equal(f1, polys[j]))
            break;
        if (j > mOrderMinusOne)
          {
            std::cout << "oops: didn't find element " << i << " !!" << std::endl;
          }
        mOneTable[i] = j;
      }
    
    // Create the ZZ/P ---> GF(Q) inclusion map
    mFromIntTable = newarray_atomic(GFElement,mCharac);
    GFElement a = mOne;;
    mFromIntTable[0] = 0;
    for (GFElement i=1; i<mCharac; i++)
      {
        mFromIntTable[i] = a;
        a = mOneTable[a];
      }
  }
Beispiel #30
0
 const ElementType& entry(size_t row, size_t column) const { 
   M2_ASSERT(row < numRows());
   M2_ASSERT(column < numColumns());
   return * fmpq_mat_entry(mArray, row, column); 
 }