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); }
void set_var(ElementType& result, int v) const { if (v != 0) set_from_long(result, 1); std::vector<long> poly = {0, 1}; fromSmallIntegerCoefficients(result, poly); // printf("variable is %lu\n", result.value); }
void power(ElementType &result, const ElementType& a, int n) const { ElementType curr_pow; init(curr_pow); set_from_long(result,1); if (n == 0) {} else if (n < 0) { n = -n; invert(curr_pow, a); } else { set(curr_pow,a); } while (n > 0) { if (n%2) { mult(result, result, curr_pow); } n = n/2; mult(curr_pow, curr_pow, curr_pow); } clear(curr_pow); }
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_long(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 } }
void power_mpz(ElementType &result, const ElementType& a, mpz_ptr n) const { if (mpz_fits_slong_p(n)) { int n1 = static_cast<int>(mpz_get_si(n)); power(result,a,n1); } else { ERROR("exponent too large"); set_from_long(result, 1); } }
void ARingGFM2::fromSmallIntegerCoefficients(ElementType& result, const std::vector<long>& poly) const { result = 0; ElementType a,b; for (long i=0; i<poly.size(); i++) if (poly[i] != 0) { set_from_long(a, poly[i]); power(b, mGF.generatorExponent(), i); mult(a,a,b); add(result,result,a); } }
void syzygy(const ElementType& a, const ElementType& b, ElementType& x, ElementType& y) const // returns x,y s.y. x*a + y*b == 0. // if possible, x is set to 1. // no need to consider the case a==0 or b==0. { assert(not is_zero(a)); assert(not is_zero(b)); set_from_long(x, 1); divide(y, a, b); negate(y, y); }
void ARingGFFlint::getGenerator(ElementType& result_gen) const { if (not mGeneratorComputed) { fq_zech_init(&mCachedGenerator, mContext); if (mCharacteristic == 2 and mDimension == 1) // This is currently a bug in flint... set_from_long(mCachedGenerator, 1); else fq_zech_gen(&mCachedGenerator, mContext); mGeneratorComputed = true; } copy(result_gen, mCachedGenerator); }
ARingZZpFFPACK::ElementType ARingZZpFFPACK::computeGenerator() const { for (UTT currIntElem=2; currIntElem < mCharac; currIntElem++) { ElementType currElem; set_from_long(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); }
void set_from_mpz(ElementType& result, mpz_srcptr a) const { int b = static_cast<int>(mpz_fdiv_ui(a, characteristic())); set_from_long(result, b); }
void set_var(ElementType &result, int v) const { set_from_long(result, 1); }