예제 #1
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);
}
예제 #2
0
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;
}
예제 #3
0
파일: LLL.cpp 프로젝트: ChristineJost/M2
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);
}
예제 #4
0
ring_elem RingZZ::remainderAndQuotient(const ring_elem f, const ring_elem g,
                                  ring_elem &quot) 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);
}
예제 #5
0
파일: QQ.cpp 프로젝트: ChristineJost/M2
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);
}
예제 #6
0
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;
}
예제 #7
0
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);
}
예제 #8
0
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);
}
예제 #9
0
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);
}
예제 #10
0
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);
}
예제 #11
0
파일: ZZ.cpp 프로젝트: DanGrayson/M2
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);
}
예제 #12
0
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);
}
예제 #13
0
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);
}
예제 #14
0
파일: LLL.cpp 프로젝트: ChristineJost/M2
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;
}
예제 #15
0
파일: QQ.cpp 프로젝트: ChristineJost/M2
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;
}
예제 #16
0
파일: ZZp.cpp 프로젝트: AlessandroOneto/M2
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;
}
예제 #17
0
파일: aring-qq-gmp.hpp 프로젝트: pzinn/M2
 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;
 }
예제 #18
0
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);
}
예제 #19
0
 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;
 }
예제 #20
0
void RingZZ::internal_add_to(ring_elem &f, ring_elem &g) const
{
  mpz_add(f.get_mpz(), f.get_mpz(), g.get_mpz());
  remove(g);
}
예제 #21
0
int RingZZ::coerce_to_int(ring_elem a) const
{
  return static_cast<int>(mpz_get_si(a.get_mpz()));
}
예제 #22
0
ring_elem RingZZ::eval(const RingMap *map, const ring_elem f,int) const
{
  return map->get_ring()->from_int(f.get_mpz());
}
예제 #23
0
int RingZZ::is_positive(const ring_elem f) const
{
  mpz_ptr a = f.get_mpz();
  return mpz_sgn(a) > 0;
}
예제 #24
0
void RingZZ::internal_negate_to(ring_elem &f) const
{
  mpz_sub(f.get_mpz(), _zero_elem, f.get_mpz());
}
예제 #25
0
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);
}
예제 #26
0
void RingZZ::internal_subtract_to(ring_elem &f, ring_elem &g) const
{
  mpz_sub(f.get_mpz(), f.get_mpz(), g.get_mpz());
  remove(g);
}
예제 #27
0
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);
}
예제 #28
0
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);
}
예제 #29
0
ring_elem RingZZ::subtract(const ring_elem f, const ring_elem g) const
{
  mpz_ptr result = new_elem();
  mpz_sub(result, f.get_mpz(), g.get_mpz());
  return ring_elem(result);
}
예제 #30
0
ring_elem RingZZ::negate(const ring_elem f) const
{
  mpz_ptr result = new_elem();
  mpz_sub(result, _zero_elem, f.get_mpz());
  return ring_elem(result);
}