Ejemplo n.º 1
0
void fmpq_poly_scalar_div_mpq(fmpq_poly_t rop, const fmpq_poly_t op, const mpq_t c)
{
    fmpz_t r, s;

    if (mpq_sgn(c) == 0)
    {
        printf("Exception: division by zero in fmpq_poly_scalar_div_mpq\n");
        abort();
    }
    
    if (fmpq_poly_is_zero(op))
    {
        fmpq_poly_zero(rop);
        return;
    }
    
    fmpq_poly_fit_length(rop, op->length);
    _fmpq_poly_set_length(rop, op->length);
    
    fmpz_init(r);
    fmpz_init(s);
    fmpz_set_mpz(r, mpq_numref(c));
    fmpz_set_mpz(s, mpq_denref(c));
    
    _fmpq_poly_scalar_div_mpq(rop->coeffs, rop->den, 
                              op->coeffs, op->den, op->length, r, s);
    
    fmpz_clear(r);
    fmpz_clear(s);
}
Ejemplo n.º 2
0
void dgsl_rot_mp_clear(dgsl_rot_mp_t *self) {
  if (!self)
    return;
  fmpz_poly_clear(self->c_z);
  fmpq_poly_clear(self->c);

  if (!fmpz_poly_is_zero(self->B))
     fmpz_poly_clear(self->B);
  if (!fmpq_poly_is_zero(self->B_inv))
     fmpq_poly_clear(self->B_inv);

  if(self->call == dgsl_rot_mp_call_identity) {
    if(self->D) {
      dgs_disc_gauss_mp_clear(self->D[0]);
      free(self->D);
    }
  }
  if(self->call == dgsl_rot_mp_call_gpv_inlattice) {

  }
  if(self->call == dgsl_rot_mp_call_inlattice) {
    mpfr_clear(self->r_f);
    fmpq_poly_clear(self->sigma_sqrt);
  }
  mpfr_clear(self->sigma);
  free(self);
}
Ejemplo n.º 3
0
void fmpq_poly_scalar_mul_fmpz(fmpq_poly_t rop, const fmpq_poly_t op, const fmpz_t c)
{
    if (fmpz_is_zero(c) || fmpq_poly_is_zero(op))
    {
        fmpq_poly_zero(rop);
        return;
    }
    
    fmpq_poly_fit_length(rop, op->length);
    _fmpq_poly_set_length(rop, op->length);
    
    _fmpq_poly_scalar_mul_fmpz(rop->coeffs, rop->den, 
                               op->coeffs, op->den, op->length, c);
}
Ejemplo n.º 4
0
void fmpq_poly_scalar_mul_ui(fmpq_poly_t rop, const fmpq_poly_t op, ulong c)
{
    if (c == 0 || fmpq_poly_is_zero(op))
    {
        fmpq_poly_zero(rop);
        return;
    }
    
    fmpq_poly_fit_length(rop, op->length);
    _fmpq_poly_set_length(rop, op->length);
    
    _fmpq_poly_scalar_mul_ui(rop->coeffs, rop->den, 
                             op->coeffs, op->den, op->length, c);
}
Ejemplo n.º 5
0
void fmpq_poly_scalar_div_ui(fmpq_poly_t rop, const fmpq_poly_t op, ulong c)
{
    if (c == 0UL)
    {
        printf("Exception: division by zero in fmpq_poly_scalar_div_ui\n");
        abort();
    }
    
    if (fmpq_poly_is_zero(op))
    {
        fmpq_poly_zero(rop);
        return;
    }
    
    fmpq_poly_fit_length(rop, op->length);
    _fmpq_poly_set_length(rop, op->length);
    
    _fmpq_poly_scalar_div_ui(rop->coeffs, rop->den, 
                             op->coeffs, op->den, op->length, c);
}
Ejemplo n.º 6
0
Archivo: div.c Proyecto: goens/flint2
void fmpq_poly_div(fmpq_poly_t Q, 
                      const fmpq_poly_t poly1, const fmpq_poly_t poly2)
{
    long lenA, lenB, lenQ;

    if (fmpq_poly_is_zero(poly2))
    {
        printf("Exception: division by zero in fmpq_poly_div\n");
        abort();
    }

    if (poly1->length < poly2->length)
    {
        fmpq_poly_zero(Q);
        return;
    }
 
    /* Deal with aliasing */
    if (Q == poly1 || Q == poly2)
    {
        fmpq_poly_t tempQ;
        fmpq_poly_init(tempQ);
        fmpq_poly_div(tempQ, poly1, poly2);
        fmpq_poly_swap(Q, tempQ);
        fmpq_poly_clear(tempQ);
        return;
    }
    
    
    lenA = poly1->length;
    lenB = poly2->length;
    lenQ = lenA - lenB + 1;
    
    fmpq_poly_fit_length(Q, lenQ);
    
    _fmpq_poly_div(Q->coeffs, Q->den, 
                   poly1->coeffs, poly1->den, poly1->length, 
                   poly2->coeffs, poly2->den, poly2->length);
    
    _fmpq_poly_set_length(Q, lenQ);
}
Ejemplo n.º 7
0
void fmpq_poly_scalar_div_fmpq(fmpq_poly_t rop, const fmpq_poly_t op, const fmpq_t c)
{
    if (fmpq_is_zero(c))
    {
        flint_printf("Exception (fmpq_poly_scalar_div_fmpq). Division by zero.\n");
        abort();
    }

    if (fmpq_poly_is_zero(op))
    {
        fmpq_poly_zero(rop);
    }
    else
    {
        fmpq_poly_fit_length(rop, op->length);
        _fmpq_poly_set_length(rop, op->length);
        
        _fmpq_poly_scalar_div_fmpq(rop->coeffs, rop->den, 
                                   op->coeffs, op->den, op->length, 
                                   fmpq_numref(c), fmpq_denref(c));
    }
}
Ejemplo n.º 8
0
Archivo: t-lcm.c Proyecto: goens/flint2
int
main(void)
{
    int cflags = 0, i, result;
    flint_rand_t state;
    
    printf("lcm....");
    fflush(stdout);

    flint_randinit(state);

    /* Check aliasing of a and c */
    for (i = 0; i < 1000; i++)
    {
        fmpq_poly_t a, b, c;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(c);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 100);

        fmpq_poly_lcm(c, a, b);
        fmpq_poly_lcm(a, a, b);

        cflags |= fmpq_poly_is_canonical(a) ? 0 : 1;
        cflags |= fmpq_poly_is_canonical(c) ? 0 : 2;
        result = (fmpq_poly_equal(a, c) && !cflags);
        if (!result)
        {
            printf("FAIL:\n");
            fmpq_poly_debug(a), printf("\n\n");
            fmpq_poly_debug(b), printf("\n\n");
            fmpq_poly_debug(c), printf("\n\n");
            printf("cflags = %d\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(c);
    }

    /* Check aliasing of b and c */
    for (i = 0; i < 1000; i++)
    {
        fmpq_poly_t a, b, c;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(c);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 100);

        fmpq_poly_lcm(c, a, b);
        fmpq_poly_lcm(b, a, b);

        cflags |= fmpq_poly_is_canonical(b) ? 0 : 1;
        cflags |= fmpq_poly_is_canonical(c) ? 0 : 2;
        result = (fmpq_poly_equal(b, c) && !cflags);
        if (!result)
        {
            printf("FAIL:\n");
            fmpq_poly_debug(a), printf("\n\n");
            fmpq_poly_debug(b), printf("\n\n");
            fmpq_poly_debug(c), printf("\n\n");
            printf("cflags = %d\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(c);
    }

    /* Generic case when a, b are most likely co-prime ***********************/

    /* Verify commutativity and that c is monic */
    for (i = 0; i < 1000; i++)
    {
        fmpq_poly_t a, b, c;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(c);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 100);

        fmpq_poly_lcm(c, a, b);
        fmpq_poly_lcm(a, b, a);

        cflags |= fmpq_poly_is_canonical(a) ? 0 : 1;
        cflags |= fmpq_poly_is_canonical(c) ? 0 : 2;
        result = (fmpq_poly_equal(a, c) && !cflags 
                  && (fmpq_poly_is_zero(c) || fmpq_poly_is_monic(c)));
        if (!result)
        {
            printf("FAIL:\n");
            fmpq_poly_debug(a), printf("\n\n");
            fmpq_poly_debug(b), printf("\n\n");
            fmpq_poly_debug(c), printf("\n\n");
            printf("cflags = %d\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(c);
    }

    /* Verify that LCM(a, b) GCD(a, b) == a b */
    for (i = 0; i < 1000; i++)
    {
        fmpq_poly_t a, b, lcm, gcd;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(lcm);
        fmpq_poly_init(gcd);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 100);

        fmpq_poly_lcm(lcm, a, b);
        fmpq_poly_gcd(gcd, a, b);
        fmpq_poly_mul(lcm, lcm, gcd);
        fmpq_poly_mul(a, a, b);
        fmpq_poly_make_monic(a, a);

        result = fmpq_poly_equal(lcm, a);
        if (!result)
        {
            printf("FAIL:\n");
            fmpq_poly_debug(a), printf("\n\n");
            fmpq_poly_debug(b), printf("\n\n");
            fmpq_poly_debug(lcm), printf("\n\n");
            fmpq_poly_debug(gcd), printf("\n\n");
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(lcm);
        fmpq_poly_clear(gcd);
    }

    /* Case when a, b are not co-prime ***************************************/

    /* Verify commutativity and that c is monic */
    for (i = 0; i < 1000; i++)
    {
        fmpq_poly_t a, b, c, t;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(c);
        fmpq_poly_init(t);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(t, state, n_randint(state, 50), 20);
        fmpq_poly_mul(a, a, t);
        fmpq_poly_mul(b, b, t);

        fmpq_poly_lcm(c, a, b);
        fmpq_poly_lcm(a, b, a);

        cflags |= fmpq_poly_is_canonical(a) ? 0 : 1;
        cflags |= fmpq_poly_is_canonical(c) ? 0 : 2;
        result = (fmpq_poly_equal(a, c) && !cflags 
                  && (fmpq_poly_is_zero(c) || fmpq_poly_is_monic(c)));
        if (!result)
        {
            printf("FAIL:\n");
            fmpq_poly_debug(a), printf("\n\n");
            fmpq_poly_debug(b), printf("\n\n");
            fmpq_poly_debug(c), printf("\n\n");
            printf("cflags = %d\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(c);
        fmpq_poly_clear(t);
    }

    /* Verify that LCM(a, b) GCD(a, b) == a b */
    for (i = 0; i < 1000; i++)
    {
        fmpq_poly_t a, b, lcm, gcd, t;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(lcm);
        fmpq_poly_init(gcd);
        fmpq_poly_init(t);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(t, state, n_randint(state, 50), 20);
        fmpq_poly_mul(a, a, t);
        fmpq_poly_mul(b, b, t);

        fmpq_poly_lcm(lcm, a, b);
        fmpq_poly_gcd(gcd, a, b);
        fmpq_poly_mul(lcm, lcm, gcd);
        fmpq_poly_mul(a, a, b);
        fmpq_poly_make_monic(a, a);

        result = fmpq_poly_equal(lcm, a);
        if (!result)
        {
            printf("FAIL:\n");
            fmpq_poly_debug(a), printf("\n\n");
            fmpq_poly_debug(b), printf("\n\n");
            fmpq_poly_debug(lcm), printf("\n\n");
            fmpq_poly_debug(gcd), printf("\n\n");
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(lcm);
        fmpq_poly_clear(gcd);
        fmpq_poly_clear(t);
    }

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}
Ejemplo n.º 9
0
dgsl_rot_mp_t *dgsl_rot_mp_init(const long n, const fmpz_poly_t B, mpfr_t sigma, fmpq_poly_t c, const dgsl_alg_t algorithm, const oz_flag_t flags) {
  assert(mpfr_cmp_ui(sigma, 0) > 0);

  dgsl_rot_mp_t *self = (dgsl_rot_mp_t*)calloc(1, sizeof(dgsl_rot_mp_t));
  if(!self) dgs_die("out of memory");

  dgsl_alg_t alg = algorithm;

  self->n = n;

  self->prec = mpfr_get_prec(sigma);

  fmpz_poly_init(self->B);
  fmpz_poly_set(self->B, B);
  if(fmpz_poly_length(self->B) > n)
    dgs_die("polynomial is longer than length n");
  else
    fmpz_poly_realloc(self->B, n);


  fmpz_poly_init(self->c_z);
  fmpq_poly_init(self->c);

  mpfr_init2(self->sigma, self->prec);
  mpfr_set(self->sigma, sigma, MPFR_RNDN);

  if (alg == DGSL_DETECT) {
    if (fmpz_poly_is_one(self->B) && (c && fmpq_poly_is_zero(c))) {
      alg = DGSL_IDENTITY;
    } else if (c && fmpq_poly_is_zero(c))
      alg = DGSL_INLATTICE;
    else
      alg = DGSL_COSET; //TODO: we could test for lattice membership here
  }

  size_t tau = 3;
  if (2*ceil(sqrt(log2((double)n))) > tau)
    tau = 2*ceil(sqrt(log2((double)n)));

  switch(alg) {
  case DGSL_IDENTITY: {
    self->D = (dgs_disc_gauss_mp_t**)calloc(1, sizeof(dgs_disc_gauss_mp_t*));
    mpfr_t c_;
    mpfr_init2(c_, self->prec);
    mpfr_set_d(c_, 0.0, MPFR_RNDN);
    self->D[0] = dgs_disc_gauss_mp_init(self->sigma, c_, tau, DGS_DISC_GAUSS_DEFAULT);
    self->call = dgsl_rot_mp_call_identity;
    mpfr_clear(c_);
    break;
  }
  case DGSL_GPV_INLATTICE: {
    self->D = (dgs_disc_gauss_mp_t**)calloc(n, sizeof(dgs_disc_gauss_mp_t*));

    if (c && !fmpq_poly_is_zero(c)) {
      fmpq_t c_i;
      fmpq_init(c_i);
      for(int i=0; i<n; i++) {
        fmpq_poly_get_coeff_fmpq(c_i, c, i);
        fmpz_poly_set_coeff_fmpz(self->c_z, i, fmpq_numref(c_i));
      }
      fmpq_clear(c_i);
    }
    mpfr_mat_t G;
    mpfr_mat_init(G, n, n, self->prec);
    mpfr_mat_set_fmpz_poly(G, B);
    mpfr_mat_gso(G, MPFR_RNDN);

    mpfr_t sigma_;
    mpfr_init2(sigma_, self->prec);

    mpfr_t norm;
    mpfr_init2(norm, self->prec);

    mpfr_t c_;
    mpfr_init2(c_, self->prec);
    mpfr_set_d(c_, 0.0, MPFR_RNDN);

    for(long i=0; i<n; i++) {
      _mpfr_vec_2norm(norm, G->rows[i], n, MPFR_RNDN);
      assert(mpfr_cmp_d(norm, 0.0) > 0);
      mpfr_div(sigma_, self->sigma, norm, MPFR_RNDN);
      assert(mpfr_cmp_d(sigma_, 0.0) > 0);
      self->D[i] = dgs_disc_gauss_mp_init(sigma_, c_, tau, DGS_DISC_GAUSS_DEFAULT);
    }

    mpfr_clear(sigma_);
    mpfr_clear(norm);
    mpfr_clear(c_);
    mpfr_mat_clear(G);

    self->call = dgsl_rot_mp_call_gpv_inlattice;
    break;
  }
  case DGSL_INLATTICE: {
    fmpq_poly_init(self->sigma_sqrt);
    long r= 2*ceil(sqrt(log(n)));

    fmpq_poly_t Bq;    fmpq_poly_init(Bq);
    fmpq_poly_set_fmpz_poly(Bq, self->B);
    fmpq_poly_oz_invert_approx(self->B_inv, Bq, n, self->prec, flags);
    fmpq_poly_clear(Bq);

    _dgsl_rot_mp_sqrt_sigma_2(self->sigma_sqrt, self->B, sigma, r, n, self->prec, flags);

    mpfr_init2(self->r_f, self->prec);
    mpfr_set_ui(self->r_f, r, MPFR_RNDN);

    self->call = dgsl_rot_mp_call_inlattice;
    break;
  }
  case DGSL_COSET:
    dgs_die("not implemented");

  default:
    dgs_die("not implemented");
  }


  return self;
}
Ejemplo n.º 10
0
int
main(void)
{
    int i, result;
    ulong cflags = UWORD(0);

    FLINT_TEST_INIT(state);

    flint_printf("derivative....");
    fflush(stdout);    

    /* Check aliasing */
    for (i = 0; i < 1000 * flint_test_multiplier(); i++)
    {
        fmpq_poly_t a, b;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 200);

        fmpq_poly_derivative(b, a);
        fmpq_poly_derivative(a, a);

        cflags |= fmpq_poly_is_canonical(a) ? 0 : 1;
        cflags |= fmpq_poly_is_canonical(b) ? 0 : 2;
        result = (fmpq_poly_equal(a, b) && !cflags);
        if (!result)
        {
            flint_printf("FAIL:\n");
            fmpq_poly_debug(a), flint_printf("\n\n");
            fmpq_poly_debug(b), flint_printf("\n\n");
            flint_printf("cflags = %wu\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
    }

    /* Check constants have derivative zero */
    for (i = 0; i < 1000 * flint_test_multiplier(); i++)
    {
        fmpq_poly_t a, b;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_randtest(a, state, n_randint(state, 2), 200);

        fmpq_poly_derivative(b, a);

        cflags |= fmpq_poly_is_canonical(b) ? 0 : 1;
        result = fmpq_poly_is_zero(b) && !cflags;
        if (!result)
        {
            flint_printf("FAIL:\n");
            fmpq_poly_debug(a), flint_printf("\n\n");
            fmpq_poly_debug(b), flint_printf("\n\n");
            flint_printf("cflags = %wu\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
    }

    /* Check (f g)' = f' g + f g' */
    for (i = 0; i < 1000 * flint_test_multiplier(); i++)
    {
        fmpq_poly_t a, b, c, d, lhs, rhs;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(c);
        fmpq_poly_init(d);
        fmpq_poly_init(lhs);
        fmpq_poly_init(rhs);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 200);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 200);

        fmpq_poly_mul(lhs, a, b);
        fmpq_poly_derivative(lhs, lhs);
        fmpq_poly_derivative(c, a);
        fmpq_poly_derivative(d, b);
        fmpq_poly_mul(c, c, b);
        fmpq_poly_mul(d, a, d);
        fmpq_poly_add(rhs, c, d);

        cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1;
        cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2;
        result = fmpq_poly_equal(lhs, rhs) && !cflags;
        if (!result)
        {
            flint_printf("FAIL:\n");
            fmpq_poly_debug(a), flint_printf("\n\n");
            fmpq_poly_debug(b), flint_printf("\n\n");
            flint_printf("cflags = %wu\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(c);
        fmpq_poly_clear(d);
        fmpq_poly_clear(lhs);
        fmpq_poly_clear(rhs);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}
Ejemplo n.º 11
0
void fmpq_poly_divrem(fmpq_poly_t Q, fmpq_poly_t R, 
                      const fmpq_poly_t poly1, const fmpq_poly_t poly2)
{
    slong lenA, lenB, lenQ, lenR;

    if (fmpq_poly_is_zero(poly2))
    {
        flint_printf("Exception (fmpq_poly_divrem). Division by zero.\n");
        abort();
    }
    if (Q == R)
    {
        flint_printf("Exception (fmpq_poly_divrem). Output arguments aliased.\n");
        abort();
    }
    
    /* Deal with the various other cases of aliasing. */
    if (R == poly1 || R == poly2)
    {
        if (Q == poly1 || Q == poly2)
        {
            fmpq_poly_t tempQ, tempR;
            fmpq_poly_init(tempQ);
            fmpq_poly_init(tempR);
            fmpq_poly_divrem(tempQ, tempR, poly1, poly2);
            fmpq_poly_swap(Q, tempQ);
            fmpq_poly_swap(R, tempR);
            fmpq_poly_clear(tempQ);
            fmpq_poly_clear(tempR);
            return;
        }
        else
        {
            fmpq_poly_t tempR;
            fmpq_poly_init(tempR);
            fmpq_poly_divrem(Q, tempR, poly1, poly2);
            fmpq_poly_swap(R, tempR);
            fmpq_poly_clear(tempR);
            return;
        }
    }
    else
    {
        if (Q == poly1 || Q == poly2)
        {
            fmpq_poly_t tempQ;
            fmpq_poly_init(tempQ);
            fmpq_poly_divrem(tempQ, R, poly1, poly2);
            fmpq_poly_swap(Q, tempQ);
            fmpq_poly_clear(tempQ);
            return;
        }
    }
    
    if (poly1->length < poly2->length)
    {
        fmpq_poly_set(R, poly1);
        fmpq_poly_zero(Q);
        return;
    }
    
    lenA = poly1->length;
    lenB = poly2->length;
    lenQ = lenA - lenB + 1;
    lenR = lenB - 1;
    
    fmpq_poly_fit_length(Q, lenQ);
    fmpq_poly_fit_length(R, lenA);  /* XXX: Need at least that much space */
    
    _fmpq_poly_divrem(Q->coeffs, Q->den, R->coeffs, R->den, 
                      poly1->coeffs, poly1->den, poly1->length, 
                      poly2->coeffs, poly2->den, poly2->length, NULL);
    
    _fmpq_poly_set_length(Q, lenQ);
    _fmpq_poly_set_length(R, lenR);
    _fmpq_poly_normalise(R);
}
Ejemplo n.º 12
0
Archivo: t-gcd.c Proyecto: goens/flint2
int
main(void)
{
    int cflags = 0, i, result;
    flint_rand_t state;
    
    printf("gcd....");
    fflush(stdout);

    flint_randinit(state);

    /* Check aliasing of a and c */
    for (i = 0; i < 1000; i++)
    {
        fmpq_poly_t a, b, c;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(c);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 100);

        fmpq_poly_gcd(c, a, b);
        fmpq_poly_gcd(a, a, b);

        cflags |= fmpq_poly_is_canonical(a) ? 0 : 1;
        cflags |= fmpq_poly_is_canonical(c) ? 0 : 2;
        result = (fmpq_poly_equal(a, c) && !cflags);
        if (!result)
        {
            printf("FAIL (aliasing a, c):\n");
            fmpq_poly_debug(a), printf("\n\n");
            fmpq_poly_debug(b), printf("\n\n");
            fmpq_poly_debug(c), printf("\n\n");
            printf("cflags = %d\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(c);
    }

    /* Check aliasing of b and c */
    for (i = 0; i < 1000; i++)
    {
        fmpq_poly_t a, b, c;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(c);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 100);

        fmpq_poly_gcd(c, a, b);
        fmpq_poly_gcd(b, a, b);

        cflags |= fmpq_poly_is_canonical(b) ? 0 : 1;
        cflags |= fmpq_poly_is_canonical(c) ? 0 : 2;
        result = (fmpq_poly_equal(b, c) && !cflags);
        if (!result)
        {
            printf("FAIL (aliasing b, c):\n");
            fmpq_poly_debug(a), printf("\n\n");
            fmpq_poly_debug(b), printf("\n\n");
            fmpq_poly_debug(c), printf("\n\n");
            printf("cflags = %d\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(c);
    }

    /* Generic case when a, b are most likely co-prime ***********************/

    /* Verify commutativity and that c is monic */
    for (i = 0; i < 1000; i++)
    {
        fmpq_poly_t a, b, c;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(c);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 100);

        fmpq_poly_gcd(c, a, b);
        fmpq_poly_gcd(a, b, a);

        cflags |= fmpq_poly_is_canonical(a) ? 0 : 1;
        cflags |= fmpq_poly_is_canonical(c) ? 0 : 2;
        result = (fmpq_poly_equal(a, c) && !cflags 
                  && (fmpq_poly_is_zero(c) || fmpq_poly_is_monic(c)));
        if (!result)
        {
            printf("FAIL (commutativity #1):\n");
            fmpq_poly_debug(a), printf("\n\n");
            fmpq_poly_debug(b), printf("\n\n");
            fmpq_poly_debug(c), printf("\n\n");
            printf("cflags = %d\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(c);
    }

    /* Verify that GCD(a, b) divides a, b */
    for (i = 0; i < 1000; i++)
    {
        fmpq_poly_t a, b, c, r1, r2;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(c);
        fmpq_poly_init(r1);
        fmpq_poly_init(r2);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 100);

        fmpq_poly_gcd(c, a, b);
        if (!fmpq_poly_is_zero(c))
        {
            fmpq_poly_rem(r1, a, c);
            fmpq_poly_rem(r2, b, c);
        }

        result = fmpq_poly_is_zero(r1) && fmpq_poly_is_zero(r2);
        if (!result)
        {
            printf("FAIL (division #1):\n");
            fmpq_poly_debug(a), printf("\n\n");
            fmpq_poly_debug(b), printf("\n\n");
            fmpq_poly_debug(c), printf("\n\n");
            printf("cflags = %d\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(c);
        fmpq_poly_clear(r1);
        fmpq_poly_clear(r2);
    }

    /* Case when a, b are not co-prime ***************************************/

    /* Verify commutativity and that c is monic */
    for (i = 0; i < 1000; i++)
    {
        fmpq_poly_t a, b, c, t;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(c);
        fmpq_poly_init(t);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(t, state, n_randint(state, 50), 20);
        fmpq_poly_mul(a, a, t);
        fmpq_poly_mul(b, b, t);

        fmpq_poly_gcd(c, a, b);
        fmpq_poly_gcd(a, b, a);

        cflags |= fmpq_poly_is_canonical(a) ? 0 : 1;
        cflags |= fmpq_poly_is_canonical(c) ? 0 : 2;
        result = (fmpq_poly_equal(a, c) && !cflags 
                  && (fmpq_poly_is_zero(c) || fmpq_poly_is_monic(c)));
        if (!result)
        {
            printf("FAIL (commutativity #2):\n");
            fmpq_poly_debug(a), printf("\n\n");
            fmpq_poly_debug(b), printf("\n\n");
            fmpq_poly_debug(c), printf("\n\n");
            printf("cflags = %d\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(c);
        fmpq_poly_clear(t);
    }

    /* Verify that GCD(a, b) divides a, b */
    for (i = 0; i < 1000; i++)
    {
        fmpq_poly_t a, b, c, r1, r2, t;

        fmpq_poly_init(a);
        fmpq_poly_init(b);
        fmpq_poly_init(c);
        fmpq_poly_init(r1);
        fmpq_poly_init(r2);
        fmpq_poly_init(t);
        fmpq_poly_randtest(a, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(b, state, n_randint(state, 100), 100);
        fmpq_poly_randtest(t, state, n_randint(state, 50), 20);
        fmpq_poly_mul(a, a, t);
        fmpq_poly_mul(b, b, t);

        fmpq_poly_gcd(c, a, b);
        if (!fmpq_poly_is_zero(c))
        {
            fmpq_poly_rem(r1, a, c);
            fmpq_poly_rem(r2, b, c);
        }

        result = fmpq_poly_is_zero(r1) && fmpq_poly_is_zero(r2);
        if (!result)
        {
            printf("FAIL (division #2):\n");
            fmpq_poly_debug(a), printf("\n\n");
            fmpq_poly_debug(b), printf("\n\n");
            fmpq_poly_debug(c), printf("\n\n");
            printf("cflags = %d\n\n", cflags);
            abort();
        }

        fmpq_poly_clear(a);
        fmpq_poly_clear(b);
        fmpq_poly_clear(c);
        fmpq_poly_clear(r1);
        fmpq_poly_clear(r2);
        fmpq_poly_clear(t);
    }

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}