bool LLLoperations::Lovasz(MutableMatrix *lambda, int k, ring_elem alphaTop, ring_elem alphaBottom) { // Test:alphaBottom * (D#(k-2) * D#k + lambda#(k,k-1)^2) < // alphaTop * D#(k-1)^2 ring_elem D2,D1,D,L; mpz_t a,b; lambda->get_entry(k-1,k-1,D1); lambda->get_entry(k,k,D); bool Lnotzero = lambda->get_entry(k-1,k,L); if (k == 1) mpz_init_set(a,D.get_mpz()); else { mpz_init(a); lambda->get_entry(k-2,k-2,D2); mpz_mul(a,D2.get_mpz(),D.get_mpz()); } mpz_init(b); if (Lnotzero) { mpz_mul(b,L.get_mpz(),L.get_mpz()); mpz_add(a,a,b); } mpz_mul(a,a,alphaBottom.get_mpz()); // This is the LHS. mpz_mul(b,D1.get_mpz(),D1.get_mpz()); mpz_mul(b,alphaTop.get_mpz(),b); // RHS int cmp = mpz_cmp(a,b); mpz_clear(a); mpz_clear(b); return (cmp < 0); }
void RingZZ::syzygy(const ring_elem a, const ring_elem b, ring_elem &x, ring_elem &y) const { // First check the special cases a = 0, b = 1, -1. Other cases: use gcd. if (RingZZ::is_zero(a)) { x = RingZZ::from_int(1); y = RingZZ::from_int(0); return; } mpz_ptr bb = b.get_mpz(); if (mpz_cmp_ui(bb,1) == 0) { x = RingZZ::from_int(1); y = RingZZ::negate(a); return; } if (mask_mpz_cmp_si(bb,-1) == 0) { x = RingZZ::from_int(1); y = RingZZ::copy(a); return; } ring_elem g = RingZZ::gcd(a,b); y = RingZZ::divide(a,g); x = RingZZ::divide(b,g); RingZZ::remove(g); if (mpz_sgn(x.get_mpz()) > 0) RingZZ::internal_negate_to(y); else RingZZ::internal_negate_to(x); }
bool RingZZ::is_equal(const ring_elem f, const ring_elem g) const { mpz_ptr a = f.get_mpz(); mpz_ptr b = g.get_mpz(); return mpz_cmp(a, b) == 0; }
int GF::compare_elems(const ring_elem f, const ring_elem g) const { int cmp = f.get_int() - g.get_int(); if (cmp < 0) return -1; if (cmp == 0) return 0; return 1; }
ring_elem RingZZ::remainderAndQuotient(const ring_elem f, const ring_elem g, ring_elem ") const { mpz_ptr q = new_elem(); mpz_ptr r = new_elem(); int gsign = mpz_sgn(g.get_mpz()); mpz_t gg, ghalf; mpz_init(gg); mpz_init(ghalf); mpz_abs(gg,g.get_mpz()); mpz_fdiv_qr(q, r, f.get_mpz(), gg); mpz_tdiv_q_2exp(ghalf, gg, 1); if (mpz_cmp(r,ghalf) > 0) // r > ghalf { mpz_sub(r,r,gg); mpz_add_ui(q,q,1); } if (gsign < 0) mpz_neg(q,q); mpz_clear(gg); mpz_clear(ghalf); quot = ring_elem(q); return ring_elem(r); }
ring_elem QQ::fraction(ring_elem top, ring_elem bottom) const { gmp_QQ result = QQ::new_elem(); mpz_set(mpq_numref(result),top.get_mpz()); mpz_set(mpq_denref(result),bottom.get_mpz()); mpq_canonicalize(result); return MPQ_RINGELEM(result); }
int RingZZ::compare_elems(const ring_elem f, const ring_elem g) const { mpz_ptr a = f.get_mpz(); mpz_ptr b = g.get_mpz(); int cmp = mpz_cmp(a,b); if (cmp > 0) return 1; if (cmp == 0) return 0; return -1; }
ring_elem RingZZ::gcd_extended(const ring_elem f, const ring_elem g, ring_elem &u, ring_elem &v) const { mpz_ptr result = new_elem(); mpz_ptr u1 = new_elem(); mpz_ptr v1 = new_elem(); mpz_gcdext(result, u1, v1, f.get_mpz(), g.get_mpz()); u = ring_elem(u1); v = ring_elem(v1); return ring_elem(result); }
void RingZZ::elem_text_out(buffer &o, const ring_elem ap, bool p_one, bool p_plus, bool p_parens) const { mpz_ptr a = ap.get_mpz(); #warning "possible overflow in large int situations" char s[1000]; char *str; bool is_neg = (mask_mpz_cmp_si(a, 0) == -1); bool is_one = (mask_mpz_cmp_si(a, 1) == 0 || mask_mpz_cmp_si(a, -1) == 0); int size = static_cast<int>(mpz_sizeinbase(a, 10)) + 2; char *allocstr = (size > 1000 ? newarray_atomic(char,size) : s); if (!is_neg && p_plus) o << '+'; if (is_one) { if (is_neg) o << '-'; if (p_one) o << '1'; } else { str = mpz_get_str(allocstr, 10, a); o << str; } if (size > 1000) deletearray(allocstr); }
void RingZZ::lower_content(ring_elem &c, ring_elem g) const // c is a content elem, g is in ring { if (is_zero(c)) { c = g; return; } gmp_ZZ result = RingZZ::new_elem(); mpz_srcptr a = c.get_mpz(); mpz_srcptr b = g.get_mpz(); mpz_gcd(result, a, b); if(mpz_sgn(a) == -1) mpz_neg(result, result); c = ring_elem(result); }
void RingZZ::lower_content(ring_elem &c, ring_elem g) const // c is a content elem, g is in ring { // if f is 0, do f=sign(g), else f=sign(f) // return whether f is zero if (is_zero(c)) { c = g; return; } gmp_ZZ result = RingZZ::new_elem(); mpz_ptr a = c.get_mpz(); mpz_ptr b = g.get_mpz(); mpz_gcd(result,a,b); c = ring_elem(result); }
bool RingZZ::lower_associate_divisor(ring_elem &f, const ring_elem g) const { // This sets f to either 0, 1 or -1. // if f is 0, do f=sign(g), else f=sign(f) // return whether f is zero gmp_ZZ result = RingZZ::new_elem(); mpz_ptr a = f.get_mpz(); mpz_ptr b = g.get_mpz(); int sa = mpz_sgn(a); int sb = mpz_sgn(b); int s = (sa == 0 ? sb : sa); mpz_set_si(result,s); f = ring_elem(result); return !RingZZ::is_zero(f); }
ring_elem RingZZ::preferred_associate(ring_elem f) const { mpz_ptr a = f.get_mpz(); if (mpz_sgn(a) >= 0) return from_int(1); return from_int(-1); }
ring_elem RingZZ::copy(const ring_elem f) const { mpz_ptr a = f.get_mpz(); mpz_ptr result = new_elem(); mpz_set(result, a); return ring_elem(result); }
bool LLLoperations::checkThreshold(ring_elem num, ring_elem den) { // Makes sure that 1/4 < num/den <= 1 // Assumed: num, den are elements of ZZ. mpz_ptr a = num.get_mpz(); mpz_ptr b = den.get_mpz(); if (mpz_sgn(a) < 0) return false; if (mpz_sgn(b) < 0) return false; if (mpz_cmp(a,b) > 0) return false; // return false if a>b. mpz_t c; mpz_init(c); mpz_mul_2exp(c,a,2); // c = 4*a int cmp = mpz_cmp(b,c); mpz_clear(c); if (cmp >= 0) return false; return true; }
bool QQ::promote(const Ring *Rf, const ring_elem f, ring_elem &result) const { // Rf = ZZ ---> QQ if (Rf->is_ZZ()) { result = QQ::from_int(f.get_mpz()); return true; } return false; }
bool Z_mod::promote(const Ring *Rf, const ring_elem f, ring_elem &result) const { // Rf = Z ---> Z/p if (Rf == globalZZ) { result = from_int(f.get_mpz()); return true; } return false; }
ring_elem RingZZ::power(const ring_elem f, mpz_t n) const { mpz_ptr result = new_elem(); int n1; if (!get_si(n1, n)) { ERROR("exponent too large"); } else mpz_pow_ui(result, f.get_mpz(), n1); return ring_elem(result); }
bool promote(const Ring *Rf, const ring_elem f, ElementType& result) const { printf("ARingQQGMP::calling promote\n"); // Rf = ZZ ---> QQ if (Rf->is_ZZ()) { set_from_mpz(result, f.get_mpz()); return true; } return false; }
void GF::elem_text_out(buffer &o, const ring_elem a, bool p_one, bool p_plus, bool p_parens) const { if (a.get_int() == _ZERO) { o << "0"; return; } ring_elem h = _originalR->power(_primitive_element->get_value(), a.int_val); _originalR->elem_text_out(o, h, p_one, p_plus, p_parens); _originalR->remove(h); }
bool ConcreteRing<RingType>::promote(const Ring *R, const ring_elem fR, ring_elem &resultS) const { const Ring *S = this; fprintf(stderr, "calling promote\n"); typedef RingPromoter RP; if (R == globalZZ) { resultS = S->from_int(fR.get_mpz()); return true; } if (R == S) { resultS = copy(fR); return true; } switch (R->ringID()) { case M2::ring_ZZp: switch (S->ringID()) { case M2::ring_ZZp: return false; case M2::ring_GF: return RP::promoter<ARingZZp,ARingGF>(R,S,fR,resultS); case M2::ring_FFPACK: return RP::promoter<ARingZZp,ARingZZpFFPACK>(R,S,fR,resultS); default: return false; } break; case M2::ring_GF: switch (S->ringID()) { case M2::ring_ZZp: return RP::promoter<ARingGF,ARingZZp>(R,S,fR,resultS); case M2::ring_GF: return RP::promoter<ARingGF,ARingGF>(R,S,fR,resultS); case M2::ring_FFPACK: return RP::promoter<ARingGF,ARingZZpFFPACK>(R,S,fR,resultS); default: return false; } case M2::ring_FFPACK: switch (S->ringID()) { case M2::ring_ZZp: return RP::promoter<ARingZZpFFPACK,ARingZZp>(R,S,fR,resultS); case M2::ring_GF: return RP::promoter<ARingZZpFFPACK,ARingGF>(R,S,fR,resultS); case M2::ring_FFPACK: return RP::promoter<ARingZZpFFPACK,ARingZZpFFPACK>(R,S,fR,resultS); default: return false; } default: break; }; return false; }
bool GF::is_equal(const ring_elem f, const ring_elem g) const { return f.get_int() == g.get_int(); }
bool GF::is_zero(const ring_elem f) const { return (f.get_int() == _ZERO); }
bool GF::is_unit(const ring_elem f) const { return (f.get_int() != _ZERO); }
int RingZZ::coerce_to_int(ring_elem a) const { return static_cast<int>(mpz_get_si(a.get_mpz())); }
ring_elem RingZZ::eval(const RingMap *map, const ring_elem f,int) const { return map->get_ring()->from_int(f.get_mpz()); }
ring_elem RingZZ::power(const ring_elem f, int n) const { mpz_ptr result = new_elem(); mpz_pow_ui(result, f.get_mpz(), n); return ring_elem(result); }
ring_elem RingZZ::gcd(const ring_elem f, const ring_elem g) const { mpz_ptr result = new_elem(); mpz_gcd(result, f.get_mpz(), g.get_mpz()); return ring_elem(result); }
void GF::internal_negate_to(ring_elem &f) const { if (f.get_int() != _ZERO) f = modulus_add(f.get_int(), _MINUS_ONE, Q1_); }
ring_elem RingZZ::divide(const ring_elem f, const ring_elem g) const { mpz_ptr result = new_elem(); mpz_fdiv_q(result, f.get_mpz(), g.get_mpz()); return ring_elem(result); }