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 } }
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); }
bool ARingGF::promote(const Ring *Rf, const ring_elem f, ElementType &result) const { if (mOriginalRing != Rf) return false; result = givaroField.zero; int exp[1]; ElementType genRep; givaroField.generator(genRep); std::cerr << "genRep " << genRep << std::endl; for (Nterm *t = f; t != NULL; t = t->next) { elem a, b; int coeff = mOriginalRing->getCoefficientRing()->coerce_to_int(t->coeff); set_from_int(a, coeff); mOriginalRing->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). power(b, genRep, exp[0]); mult(a, a, b); add(result, result, a); } return true; }