예제 #1
0
void _fmpq_poly_scalar_div_ui(fmpz * rpoly, fmpz_t rden, const fmpz * poly, 
                              const fmpz_t den, long len, ulong c)
{
    if (c == 1UL)
    {
        if (rpoly != poly)
            _fmpz_vec_set(rpoly, poly, len);
        fmpz_set(rden, den);
    }
    else
    {
        fmpz_t d, fc;
        ulong ud;
        fmpz_init(d);
        fmpz_init(fc);
        _fmpz_vec_content(d, poly, len);
        fmpz_set_ui(fc, c);
        fmpz_gcd(d, d, fc);
        ud = fmpz_get_ui(d);  /* gcd of d and c fits into a ulong */
        
        _fmpz_vec_scalar_divexact_ui(rpoly, poly, len, ud);
        fmpz_mul_ui(rden, den, c / ud);
        
        fmpz_clear(d);
        fmpz_clear(fc);
    }
}
예제 #2
0
void _fmpq_poly_canonicalise(fmpz * poly, fmpz_t den, slong len)
{
    if (*den == WORD(1))
        return;
    
    if (*den == WORD(-1))
    {
        _fmpz_vec_neg(poly, poly, len);
        fmpz_one(den);
    }
    else if (len == 0)
    {
        fmpz_one(den);
    }
    else
    {
        fmpz_t gcd;
        fmpz_init(gcd);
        _fmpz_vec_content(gcd, poly, len);
        if (*gcd != WORD(1))
            fmpz_gcd(gcd, gcd, den);
        if (fmpz_sgn(den) < 0)
            fmpz_neg(gcd, gcd);
        if (*gcd != WORD(1))
        {
            _fmpz_vec_scalar_divexact_fmpz(poly, poly, len, gcd);
            fmpz_divexact(den, den, gcd);
        }
        fmpz_clear(gcd);
    }
}
예제 #3
0
 void ARingZZ::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 (fmpz_cmp_ui(&b,1) == 0)
     {
       set_from_long(x, 1);
       negate(y, a);
       return;
     }
   if (fmpz_cmp_si(&b,-1) == 0)
     {
       set_from_long(x, 1);
       set(y, a);
       return;
     }
   ElementType g;
   init(g);
   fmpz_gcd(&g,&a,&b);
   divide(y,a,g);
   divide(x,b,g);
   if (fmpz_sgn(&x) > 0)
     negate(y,y);
   else
     negate(x,x);
   clear(g);
 }
예제 #4
0
void _fmpq_poly_scalar_mul_fmpz(fmpz * rpoly, fmpz_t rden, 
                                const fmpz * poly, const fmpz_t den, long len,
                                const fmpz_t c)
{
    fmpz_t gcd;  /* GCD( den, c ) */

    if (fmpz_is_zero(c))
    {
        _fmpz_vec_zero(rpoly, len);
        fmpz_one(rden);
        return;
    }

    fmpz_init(gcd);
    fmpz_one(gcd);
    if (*c != 1L)
        fmpz_gcd(gcd, c, den);
    if (*gcd == 1L)
    {
        _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, c);
        fmpz_set(rden, den);
    }
    else
    {
        fmpz_t c2;
        fmpz_init(c2);
        fmpz_divexact(c2, c, gcd);
        _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, c2);
        fmpz_divexact(rden, den, gcd);
        fmpz_clear(c2);
    }
    fmpz_clear(gcd);
}
예제 #5
0
void _fmpq_poly_scalar_mul_ui(fmpz * rpoly, fmpz_t rden, 
                              const fmpz * poly, const fmpz_t den, slong len, 
                              ulong c)
{
    fmpz_t gcd;  /* GCD( den, c ) */

    if (c == 0)
    {
        _fmpz_vec_zero(rpoly, len);
        fmpz_one(rden);
        return;
    }

    fmpz_init(gcd);
    fmpz_set_ui(gcd, c);
    fmpz_gcd(gcd, gcd, den);
    if (*gcd == WORD(1))
    {
        _fmpz_vec_scalar_mul_ui(rpoly, poly, len, c);
        fmpz_set(rden, den);
    }
    else
    {
        ulong gcd2 = fmpz_get_ui(gcd);
        ulong c2 = c / gcd2;
        _fmpz_vec_scalar_mul_ui(rpoly, poly, len, c2);
        fmpz_fdiv_q_ui(rden, den, gcd2);
    }
    fmpz_clear(gcd);
}
예제 #6
0
파일: compose.c 프로젝트: goens/flint2
void
fmpq_poly_compose(fmpq_poly_t res, 
                              const fmpq_poly_t poly1, const fmpq_poly_t poly2)
{
    const long len1 = poly1->length;
    const long len2 = poly2->length;
    long lenr;
    
    if (len1 == 0L)
    {
        fmpq_poly_zero(res);
        return;
    }
    if (len1 == 1L || len2 == 0L)
    {
        fmpq_poly_fit_length(res, 1);
        fmpz_set(res->coeffs, poly1->coeffs);
        fmpz_set(res->den, poly1->den);
        {
            fmpz_t d;
            fmpz_init(d);
            fmpz_gcd(d, res->coeffs, res->den);
            if (*d != 1L)
            {
                fmpz_divexact(res->coeffs, res->coeffs, d);
                fmpz_divexact(res->den, res->den, d);
            }
            fmpz_clear(d);
        }
        _fmpq_poly_set_length(res, 1);
        _fmpq_poly_normalise(res);
        return;
    }
    
    lenr = (len1 - 1L) * (len2 - 1L) + 1L;
    
    if ((res != poly1) && (res != poly2))
    {
        fmpq_poly_fit_length(res, lenr);
        _fmpq_poly_compose(res->coeffs, res->den, 
                           poly1->coeffs, poly1->den, len1, 
                           poly2->coeffs, poly2->den, len2);
        _fmpq_poly_set_length(res, lenr);
        _fmpq_poly_normalise(res);
    }
    else
    {
        fmpq_poly_t t;
        fmpq_poly_init2(t, lenr);
        _fmpq_poly_compose(t->coeffs, t->den, 
                           poly1->coeffs, poly1->den, len1,
                           poly2->coeffs, poly2->den, len2);
        _fmpq_poly_set_length(t, lenr);
        _fmpq_poly_normalise(t);
        fmpq_poly_swap(res, t);
        fmpq_poly_clear(t);
    }
}
예제 #7
0
void fmpz_poly_q_scalar_mul_si(fmpz_poly_q_t rop, const fmpz_poly_q_t op, long x)
{
    fmpz_t cont, fx, gcd;

    if (fmpz_poly_q_is_zero(op) || (x == 0))
    {
        fmpz_poly_q_zero(rop);
        return;
    }

    if (x == 1)
    {
        fmpz_poly_q_set(rop, op);
        return;
    }

    fmpz_init(cont);
    fmpz_poly_content(cont, op->den);

    if (fmpz_is_one(cont))
    {
        fmpz_poly_scalar_mul_si(rop->num, op->num, x);
        fmpz_poly_set(rop->den, op->den);
        fmpz_clear(cont);
        return;
    }

    fmpz_init(fx);
    fmpz_init(gcd);

    fmpz_set_si(fx, x);
    fmpz_gcd(gcd, cont, fx);

    if (fmpz_is_one(gcd))
    {
        fmpz_poly_scalar_mul_si(rop->num, op->num, x);
        fmpz_poly_set(rop->den, op->den);
    }
    else
    {
        fmpz_divexact(fx, fx, gcd);
        fmpz_poly_scalar_mul_fmpz(rop->num, op->num, fx);
        fmpz_poly_scalar_divexact_fmpz(rop->den, op->den, gcd);
    }

    fmpz_clear(cont);
    fmpz_clear(fx);
    fmpz_clear(gcd);
}
예제 #8
0
void _fmpq_poly_scalar_div_si(fmpz * rpoly, fmpz_t rden, const fmpz * poly,
                              const fmpz_t den, long len, long c)
{
    if (c == 1)
    {
        if (rpoly != poly)
        {
            _fmpz_vec_set(rpoly, poly, len);
            fmpz_set(rden, den);
        }
    }
    else if (c == -1)
    {
        _fmpz_vec_neg(rpoly, poly, len);
        fmpz_set(rden, den);
    }
    else
    {
        fmpz_t d, f;

        fmpz_init(d);
        fmpz_init(f);
        
        fmpz_set_si(f, c);
        _fmpz_vec_content(d, poly, len);
        fmpz_gcd(d, d, f);

        if (c > 0)
        {
            _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d);
            fmpz_mul_si(rden, den, c / fmpz_get_si(d));
        }
        else
        {
            ulong q = (- (ulong) c) / fmpz_get_ui(d);

            fmpz_neg(d, d);
            _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d);
            fmpz_mul_ui(rden, den, q);
        }

        fmpz_clear(d);
        fmpz_clear(f);
    }
}
예제 #9
0
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);

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

    

    /* Check q*b + r = a when gcd(lead(B),p) = 1, no aliasing */
    for (i = 0; i < 5000; i++)
    {
        fmpz_t f, p;
        fmpz_mod_poly_t a, b, q, r, t;

        fmpz_init(f);
        fmpz_init(p);
        fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS);
        fmpz_add_ui(p, p, 2);

        fmpz_mod_poly_init(a, p);
        fmpz_mod_poly_init(b, p);
        fmpz_mod_poly_init(q, p);
        fmpz_mod_poly_init(r, p);
        fmpz_mod_poly_init(t, p);
        fmpz_mod_poly_randtest(a, state, n_randint(state, 100));
        fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1);

        {
            fmpz_t d;
            fmpz *leadB = fmpz_mod_poly_lead(b);

            fmpz_init(d);
            fmpz_gcd(d, p, leadB);
            while (!fmpz_is_one(d))
            {
                fmpz_divexact(leadB, leadB, d);
                fmpz_gcd(d, p, leadB);
            }
            fmpz_clear(d);
        }

        fmpz_mod_poly_divrem_f(f, q, r, a, b);
        fmpz_mod_poly_mul(t, q, b);
        fmpz_mod_poly_add(t, t, r);

        result = (fmpz_is_one(f) && fmpz_mod_poly_equal(a, t));
        if (!result)
        {
            flint_printf("FAIL (divrem):\n");
            flint_printf("p = "), fmpz_print(p), flint_printf("\n\n");
            flint_printf("f = "), fmpz_print(f), flint_printf("\n\n");
            flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n");
            flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n");
            flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n");
            flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n");
            flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n");
            abort();
        }

        fmpz_mod_poly_clear(a);
        fmpz_mod_poly_clear(b);
        fmpz_mod_poly_clear(q);
        fmpz_mod_poly_clear(r);
        fmpz_mod_poly_clear(t);
        fmpz_clear(f);
        fmpz_clear(p);
    }

    /* Check f | p when gcd(lead(B),p) > 1 */
    for (i = 0; i < 5000; i++)
    {
        fmpz_t f, p, q1, q2;
        fmpz_mod_poly_t a, b, q, r, t;

        fmpz_init(f);
        fmpz_init(p);
        fmpz_init(q1);
        fmpz_init(q2);
        fmpz_randtest_unsigned(q1, state, 2 * FLINT_BITS);
        fmpz_randtest_unsigned(q2, state, 2 * FLINT_BITS);
        fmpz_add_ui(q1, q1, 2);
        fmpz_add_ui(q2, q2, 2);
        fmpz_mul(p, q1, q2);

        fmpz_mod_poly_init(a, p);
        fmpz_mod_poly_init(b, p);
        fmpz_mod_poly_init(q, p);
        fmpz_mod_poly_init(r, p);
        fmpz_mod_poly_init(t, p);
        fmpz_mod_poly_randtest(a, state, n_randint(state, 100));
        fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1);

        {
            fmpz_t d;
            fmpz *leadB = fmpz_mod_poly_lead(b);

            fmpz_init(d);
            fmpz_gcd(d, p, leadB);
            if (fmpz_is_one(d))
                fmpz_set(leadB, q1);
            fmpz_clear(d);
        }

        fmpz_mod_poly_divrem_f(f, q, r, a, b);
        fmpz_mod_poly_mul(t, q, b);
        fmpz_mod_poly_add(t, t, r);

        result = (fmpz_cmp_ui(f, 1) > 0 && fmpz_cmp(f, p) < 0 && fmpz_divisible(p, f));
        if (!result)
        {
            flint_printf("FAIL (factor):\n");
            flint_printf("p = "), fmpz_print(p), flint_printf("\n\n");
            flint_printf("f = "), fmpz_print(f), flint_printf("\n\n");
            flint_printf("q1 = "), fmpz_print(q1), flint_printf("\n\n");
            flint_printf("q2 = "), fmpz_print(q2), flint_printf("\n\n");
            flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n");
            flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n");
            flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n");
            flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n");
            flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n");
            abort();
        }

        fmpz_mod_poly_clear(a);
        fmpz_mod_poly_clear(b);
        fmpz_mod_poly_clear(q);
        fmpz_mod_poly_clear(r);
        fmpz_mod_poly_clear(t);
        fmpz_clear(f);
        fmpz_clear(p);
        fmpz_clear(q1);
        fmpz_clear(q2);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}
예제 #10
0
void
fmpq_poly_compose_series_horner(fmpq_poly_t res, 
                    const fmpq_poly_t poly1, const fmpq_poly_t poly2, long n)
{
    long len1 = poly1->length;
    long len2 = poly2->length;
    long lenr;

    if (len2 != 0 && !fmpz_is_zero(poly2->coeffs))
    {
        printf("exception: fmpq_poly_compose_series_horner: inner polynomial "
                "must have zero constant term\n");
        abort();
    }

    if (len1 == 0 || n == 0)
    {
        fmpq_poly_zero(res);
        return;
    }

    if (len2 == 0 || len1 == 1)
    {
        fmpq_poly_fit_length(res, 1);
        fmpz_set(res->coeffs, poly1->coeffs);
        fmpz_set(res->den, poly1->den);
        {
            fmpz_t d;
            fmpz_init(d);
            fmpz_gcd(d, res->coeffs, res->den);
            if (!fmpz_is_one(d))
            {
                fmpz_divexact(res->coeffs, res->coeffs, d);
                fmpz_divexact(res->den, res->den, d);
            }
            fmpz_clear(d);
        }
        _fmpq_poly_set_length(res, 1);
        _fmpq_poly_normalise(res);
        return;
    }

    lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n);
    len1 = FLINT_MIN(len1, lenr);
    len2 = FLINT_MIN(len2, lenr);

    if ((res != poly1) && (res != poly2))
    {
        fmpq_poly_fit_length(res, lenr);
        _fmpq_poly_compose_series_horner(res->coeffs, res->den, 
                           poly1->coeffs, poly1->den, len1, 
                           poly2->coeffs, poly2->den, len2, lenr);
        _fmpq_poly_set_length(res, lenr);
        _fmpq_poly_normalise(res);
    }
    else
    {
        fmpq_poly_t t;
        fmpq_poly_init2(t, lenr);
        _fmpq_poly_compose_series_horner(t->coeffs, t->den, 
                           poly1->coeffs, poly1->den, len1,
                           poly2->coeffs, poly2->den, len2, lenr);
        _fmpq_poly_set_length(t, lenr);
        _fmpq_poly_normalise(t);
        fmpq_poly_swap(res, t);
        fmpq_poly_clear(t);
    }
}
예제 #11
0
int
main(void)
{
    int i, result;
    flint_rand_t state;

    printf("div_basecase....");
    fflush(stdout);

    flint_randinit(state);

    /* Compare to divrem_basecase */
    for (i = 0; i < 5000; i++)
    {
        fmpz_t p;
        fmpz_mod_poly_t a, b, q, q2, r2;

        fmpz_init(p);
        fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS);
        fmpz_add_ui(p, p, 2);

        fmpz_mod_poly_init(a, p);
        fmpz_mod_poly_init(b, p);
        fmpz_mod_poly_init(q, p);
        fmpz_mod_poly_init(q2, p);
        fmpz_mod_poly_init(r2, p);
        fmpz_mod_poly_randtest(a, state, n_randint(state, 100));
        fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1);

        {
            fmpz_t d;
            fmpz *leadB = fmpz_mod_poly_lead(b);

            fmpz_init(d);
            fmpz_gcd(d, p, leadB);
            while (!fmpz_is_one(d))
            {
                fmpz_divexact(leadB, leadB, d);
                fmpz_gcd(d, p, leadB);
            }
            fmpz_clear(d);
        }

        fmpz_mod_poly_div_basecase(q, a, b);
        fmpz_mod_poly_divrem_basecase(q2, r2, a, b);

        result = (fmpz_mod_poly_equal(q, q2));
        if (!result)
        {
            printf("FAIL:\n");
            printf("p = "), fmpz_print(p), printf("\n\n");
            printf("a = "), fmpz_mod_poly_print(a), printf("\n\n");
            printf("b = "), fmpz_mod_poly_print(b), printf("\n\n");
            printf("q = "), fmpz_mod_poly_print(q), printf("\n\n");
            printf("q2 = "), fmpz_mod_poly_print(q2), printf("\n\n");
            printf("r2 = "), fmpz_mod_poly_print(r2), printf("\n\n");
            abort();
        }

        fmpz_mod_poly_clear(a);
        fmpz_mod_poly_clear(b);
        fmpz_mod_poly_clear(q);
        fmpz_mod_poly_clear(q2);
        fmpz_mod_poly_clear(r2);
        fmpz_clear(p);
    }

    /* Alias a and q */
    for (i = 0; i < 500; i++)
    {
        fmpz_t p;
        fmpz_mod_poly_t a, b, q;

        fmpz_init(p);
        fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS);
        fmpz_add_ui(p, p, 2);

        fmpz_mod_poly_init(a, p);
        fmpz_mod_poly_init(b, p);
        fmpz_mod_poly_init(q, p);
        fmpz_mod_poly_randtest(a, state, n_randint(state, 100));
        fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1);

        {
            fmpz_t d;
            fmpz *leadB = fmpz_mod_poly_lead(b);

            fmpz_init(d);
            fmpz_gcd(d, p, leadB);
            while (!fmpz_is_one(d))
            {
                fmpz_divexact(leadB, leadB, d);
                fmpz_gcd(d, p, leadB);
            }
            fmpz_clear(d);
        }

        fmpz_mod_poly_div_basecase(q, a, b);
        fmpz_mod_poly_div_basecase(a, a, b);

        result = (fmpz_mod_poly_equal(q, a));
        if (!result)
        {
            printf("FAIL:\n");
            printf("p = "), fmpz_print(p), printf("\n\n");
            printf("a = "), fmpz_mod_poly_print(a), printf("\n\n");
            printf("b = "), fmpz_mod_poly_print(b), printf("\n\n");
            printf("q = "), fmpz_mod_poly_print(q), printf("\n\n");
            abort();
        }

        fmpz_mod_poly_clear(a);
        fmpz_mod_poly_clear(b);
        fmpz_mod_poly_clear(q);
        fmpz_clear(p);
    }

    /* Alias b and q */
    for (i = 0; i < 500; i++)
    {
        fmpz_t p;
        fmpz_mod_poly_t a, b, q;

        fmpz_init(p);
        fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS);
        fmpz_add_ui(p, p, 2);

        fmpz_mod_poly_init(a, p);
        fmpz_mod_poly_init(b, p);
        fmpz_mod_poly_init(q, p);
        fmpz_mod_poly_randtest(a, state, n_randint(state, 100));
        fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1);

        {
            fmpz_t d;
            fmpz *leadB = fmpz_mod_poly_lead(b);

            fmpz_init(d);
            fmpz_gcd(d, p, leadB);
            while (!fmpz_is_one(d))
            {
                fmpz_divexact(leadB, leadB, d);
                fmpz_gcd(d, p, leadB);
            }
            fmpz_clear(d);
        }

        fmpz_mod_poly_div_basecase(q, a, b);
        fmpz_mod_poly_div_basecase(b, a, b);

        result = (fmpz_mod_poly_equal(q, b));
        if (!result)
        {
            printf("FAIL:\n");
            printf("p = "), fmpz_print(p), printf("\n\n");
            printf("a = "), fmpz_mod_poly_print(a), printf("\n\n");
            printf("b = "), fmpz_mod_poly_print(b), printf("\n\n");
            printf("q = "), fmpz_mod_poly_print(q), printf("\n\n");
            abort();
        }

        fmpz_mod_poly_clear(a);
        fmpz_mod_poly_clear(b);
        fmpz_mod_poly_clear(q);
        fmpz_clear(p);
    }

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}
예제 #12
0
파일: sub.c 프로젝트: goens/flint2
void
_fmpq_sub(fmpz_t rnum, fmpz_t rden, const fmpz_t p, const fmpz_t q,
            const fmpz_t r, const fmpz_t s)
{
    fmpz_t g, a, b, t, u;

    /* Same denominator */
    if (fmpz_equal(q, s))
    {
        fmpz_sub(rnum, p, r);

        /* Both are integers */
        if (fmpz_is_one(q))
        {
            fmpz_set(rden, q);
        }
        else
        {
            fmpz_init(g);
            fmpz_gcd(g, rnum, q);

            if (fmpz_is_one(g))
            {
                fmpz_set(rden, q);
            }
            else
            {
                fmpz_divexact(rnum, rnum, g);
                fmpz_divexact(rden, q, g);
            }
            fmpz_clear(g);
        }
        return;
    }

    /* p/q is an integer */
    if (fmpz_is_one(q))
    {
        fmpz_init(t);
        fmpz_mul(t, p, s);
        fmpz_sub(rnum, t, r);
        fmpz_set(rden, s);
        fmpz_clear(t);
        return;
    }

    /* r/s is an integer */
    if (fmpz_is_one(s))
    {
        fmpz_init(t);
        fmpz_mul(t, r, q);
        fmpz_sub(rnum, p, t);
        fmpz_set(rden, q);
        fmpz_clear(t);
        return;
    }

    fmpz_init(g);
    fmpz_gcd(g, q, s);

    if (fmpz_is_one(g))
    {
        fmpz_init(t);
        fmpz_init(u);

        fmpz_mul(t, p, s);
        fmpz_mul(u, q, r);
        fmpz_sub(rnum, t, u);
        fmpz_mul(rden, q, s);

        fmpz_clear(t);
        fmpz_clear(u);
    }
    else
    {
        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(t);
        fmpz_init(u);

        fmpz_divexact(a, q, g);
        fmpz_divexact(b, s, g);

        fmpz_mul(t, p, b);
        fmpz_mul(u, r, a);
        fmpz_sub(rnum, t, u);

        fmpz_gcd(t, rnum, g);

        if (fmpz_is_one(t))
        {
            fmpz_mul(rden, q, b);
        }
        else
        {
            fmpz_divexact(rnum, rnum, t);
            fmpz_divexact(g, q, t);
            fmpz_mul(rden, g, b);
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(t);
        fmpz_clear(u);
    }

    fmpz_clear(g);
}
예제 #13
0
파일: sub.c 프로젝트: videlec/e-antic
void _nf_elem_sub_qf(nf_elem_t a, const nf_elem_t b, 
                                   const nf_elem_t c, const nf_t nf, int can)
{
   fmpz_t d;

   const fmpz * const bnum = QNF_ELEM_NUMREF(b);
   const fmpz * const bden = QNF_ELEM_DENREF(b);
   
   const fmpz * const cnum = QNF_ELEM_NUMREF(c);
   const fmpz * const cden = QNF_ELEM_DENREF(c);
   
   fmpz * const anum = QNF_ELEM_NUMREF(a);
   fmpz * const aden = QNF_ELEM_DENREF(a);

   fmpz_init(d);
   fmpz_one(d);

   if (fmpz_equal(bden, cden))
   {
      fmpz_sub(anum, bnum, cnum);
      fmpz_sub(anum + 1, bnum + 1, cnum + 1);
      fmpz_sub(anum + 2, bnum + 2, cnum + 2);
      fmpz_set(aden, bden);

      if (can && !fmpz_is_one(aden))
      {
         fmpz_gcd(d, anum, anum + 1);
         fmpz_gcd(d, d, anum + 2);
         if (!fmpz_is_one(d))
         {
            fmpz_gcd(d, d, aden);

            if (!fmpz_is_one(d))
            {
               fmpz_divexact(anum, anum, d);
               fmpz_divexact(anum + 1, anum + 1, d);
               fmpz_divexact(anum + 2, anum + 2, d);
               fmpz_divexact(aden, aden, d);
            }
         }
      }

      fmpz_clear(d);

      return;
   }

   if (!fmpz_is_one(bden) && !fmpz_is_one(cden))
      fmpz_gcd(d, bden, cden);

   if (fmpz_is_one(d))
   {
      fmpz_mul(anum, bnum, cden);
      fmpz_mul(anum + 1, bnum + 1, cden);
      fmpz_mul(anum + 2, bnum + 2, cden);
      fmpz_submul(anum, cnum, bden);
      fmpz_submul(anum + 1, cnum + 1, bden);
      fmpz_submul(anum + 2, cnum + 2, bden);
      fmpz_mul(aden, bden, cden);
   } else
   {
      fmpz_t bden1;
      fmpz_t cden1;
      
      fmpz_init(bden1);
      fmpz_init(cden1);
      
      fmpz_divexact(bden1, bden, d);
      fmpz_divexact(cden1, cden, d);
        
      fmpz_mul(anum, bnum, cden1);
      fmpz_mul(anum + 1, bnum + 1, cden1);
      fmpz_mul(anum + 2, bnum + 2, cden1);
      fmpz_submul(anum, cnum, bden1);
      fmpz_submul(anum + 1, cnum + 1, bden1);
      fmpz_submul(anum + 2, cnum + 2, bden1);
      
      if (fmpz_is_zero(anum) && fmpz_is_zero(anum + 1) && fmpz_is_zero(anum + 2))
         fmpz_one(aden);
      else
      {
         if (can)
         {
            fmpz_t e;
            
            fmpz_init(e);
              
            fmpz_gcd(e, anum, anum + 1);
            fmpz_gcd(e, e, anum + 2);
            if (!fmpz_is_one(e))
               fmpz_gcd(e, e, d);
            
            if (fmpz_is_one(e))
               fmpz_mul(aden, bden, cden1);
            else
            {
                fmpz_divexact(anum, anum, e);
                fmpz_divexact(anum + 1, anum + 1, e);
                fmpz_divexact(anum + 2, anum + 2, e);
                fmpz_divexact(bden1, bden, e);
                fmpz_mul(aden, bden1, cden1);
            }
            
            fmpz_clear(e);
         } else
            fmpz_mul(aden, bden, cden1);
      }

      fmpz_clear(bden1);
      fmpz_clear(cden1);
   }

   fmpz_clear(d);
}
예제 #14
0
파일: qseive.c 프로젝트: alexjbest/bw
void
_qseive(const mp_limb_t n, const mp_limb_t B)
{
    nmod_sparse_mat_t M;
    mp_limb_t quad, *quads, *xs, x, i = 0, j, piB = n_prime_pi(B);
    const mp_limb_t * ps = n_primes_arr_readonly(piB + 2);
    const double * pinvs = n_prime_inverses_arr_readonly(piB + 2);
    mzd_t *K;

    /* init */
    quads = (mp_limb_t *)malloc((piB + 1)*sizeof(mp_limb_t *));
    xs = (mp_limb_t *)malloc((piB + 1)*sizeof(mp_limb_t *));
    K = mzd_init(piB + 1, 1);
    nmod_sparse_mat_init(M, piB + 1, piB + 1, 2);

    printf("init done\n");
    printf("using %ld primes\n", piB);
    /* seive */

    for (x = n_sqrt(n), i = 0; i <= piB; x++)
    {
        quad = x*x - n;
        if (quad == 0)
            continue;
        for (j = 0; j < piB; j++)
            n_remove2_precomp(&quad, ps[j], pinvs[j]);
        if (quad == 1) /* was B-smooth */
        {
            quads[i] = x*x - n;
            quad = x*x - n;
            for (j = 0; j < piB; j++)
            {
                if (n_remove2_precomp(&quad, ps[j], pinvs[j]) % 2)
                    _nmod_sparse_mat_set_entry(M, j, i, M->row_supports[j], 1);
            }
            xs[i] = x;
            i++;
        }
    }
    printf("data collection done\n");

    n_cleanup_primes();

    _bw(K, M, 1, 2, 7, 7);

    printf("procesing complete\n");
    mzd_print(K);

    int done = 0;
    for (j = 0; !done; j++)
    {
        fmpz_t a, b, diff, N;
        fmpz_init_set_ui(a, 1);
        fmpz_init_set_ui(b, 1);
        fmpz_init_set_ui(N, n);
        fmpz_init(diff);
        for (i = 0; i < piB; i++)
        {
            if (mzd_read_bit(K, i, j))
            {
                fmpz_mul_ui(a, a, xs[i]);
                fmpz_mul_ui(b, b, quads[i]);
            }
        }
        assert(fmpz_is_square(b));
        fmpz_sqrt(b, b);
        if (fmpz_mod_ui(a, a, n) != fmpz_mod_ui(b, b, n) && fmpz_mod_ui(a, a, n) != n - fmpz_mod_ui(b, b, n))
        {
            done = 1;

            fmpz_print(a);
            printf("\n");
            fmpz_print(b);
            printf("\n");
            fmpz_sub(diff, a, b);
            fmpz_gcd(a, diff, N);
            fmpz_divexact(b, N, a);
            fmpz_print(a);
            printf("\n");
            fmpz_print(b);
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(N);
        fmpz_clear(diff);
    }
    /* cleanup */
    free(quads);
    free(xs);

    mzd_free(K);

    nmod_sparse_mat_clear(M);

    return;
}
예제 #15
0
void _fmpq_poly_scalar_div_mpq(fmpz * rpoly, fmpz_t rden, 
                               const fmpz * poly, const fmpz_t den, long len, 
                               const fmpz_t r, const fmpz_t s)
{
    fmpz_t gcd1;  /* GCD( poly, r ) */
    fmpz_t gcd2;  /* GCD( s, den )  */
    fmpz_init(gcd1);
    fmpz_init(gcd2);
    fmpz_set_ui(gcd1, 1);
    fmpz_set_ui(gcd2, 1);
    if (*r != 1L)
    {
        _fmpz_vec_content(gcd1, poly, len);
        if (*gcd1 != 1L)
            fmpz_gcd(gcd1, gcd1, r);
    }
    if (*den != 1L && *s != 1L)
        fmpz_gcd(gcd2, s, den);
    
    if (*gcd1 == 1L)
    {
        if (*gcd2 == 1L)
        {
            _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, s);
            fmpz_mul(rden, den, r);
        }
        else
        {
            fmpz_t s2;
            fmpz_init(s2);
            fmpz_divexact(s2, s, gcd2);
            _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, s2);
            fmpz_divexact(rden, den, gcd2);
            fmpz_mul(rden, rden, r);
            fmpz_clear(s2);
        }
    }
    else
    {
        fmpz_t r2;
        fmpz_init(r2);
        fmpz_divexact(r2, r, gcd1);
        if (*gcd2 == 1L)
        {
            _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, gcd1);
            _fmpz_vec_scalar_mul_fmpz(rpoly, rpoly, len, s);
            fmpz_mul(rden, den, r2);
        }
        else
        {
            fmpz_t s2;
            fmpz_init(s2);
            fmpz_divexact(s2, s, gcd2);
            _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, gcd1);
            _fmpz_vec_scalar_mul_fmpz(rpoly, rpoly, len, s2);
            fmpz_divexact(rden, den, gcd2);
            fmpz_mul(rden, rden, r2);
            fmpz_clear(s2);
        }
        fmpz_clear(r2);
    }
    
    if (_fmpz_vec_is_zero(rpoly, len))
        fmpz_set_ui(rden, 1);
    if (fmpz_sgn(rden) < 0)
    {
        _fmpz_vec_neg(rpoly, rpoly, len);
        fmpz_neg(rden, rden);
    }
    
    fmpz_clear(gcd1);
    fmpz_clear(gcd2);
}
예제 #16
0
파일: mul.c 프로젝트: clear731/lattice
void
_fmpq_mul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, const fmpz_t op1den,
            const fmpz_t op2num, const fmpz_t op2den)
{
    /* Common special cases: squaring, same denominator (e.g. both integers) */
    if (((op1num == op2num) && (op1den == op2den)) ||
         fmpz_equal(op1den, op2den))
    {
        fmpz_mul(rnum, op1num, op2num);
        fmpz_mul(rden, op1den, op2den);
    }
    /* Exactly one argument is an integer */
    else if (fmpz_is_one(op1den))
    {
        fmpz_t t, x;
        fmpz_init(t);
        fmpz_init(x);

        fmpz_gcd(t, op1num, op2den);
        fmpz_divexact(x, op1num, t);
        fmpz_mul(rnum, x, op2num);
        fmpz_divexact(t, op2den, t);
        fmpz_mul(rden, op1den, t);

        fmpz_clear(t);
        fmpz_clear(x);
    }
    else if (fmpz_is_one(op2den))
    {
        fmpz_t t, x;
        fmpz_init(t);
        fmpz_init(x);

        fmpz_gcd(t, op2num, op1den);
        fmpz_divexact(x, op2num, t);
        fmpz_mul(rnum, x, op1num);
        fmpz_divexact(t, op1den, t);
        fmpz_mul(rden, op2den, t);

        fmpz_clear(t);
        fmpz_clear(x);
    }
    else
    {
        fmpz_t t, u, x, y;

        fmpz_init(t);
        fmpz_init(u);
        fmpz_init(x);
        fmpz_init(y);

        fmpz_gcd(t, op1num, op2den);
        fmpz_gcd(u, op1den, op2num);

        fmpz_divexact(x, op1num, t);
        fmpz_divexact(y, op2num, u);

        fmpz_mul(rnum, x, y);

        fmpz_divexact(x, op1den, u);
        fmpz_divexact(y, op2den, t);

        fmpz_mul(rden, x, y);

        fmpz_clear(t);
        fmpz_clear(u);
        fmpz_clear(x);
        fmpz_clear(y);
    }
}
예제 #17
0
/* Assumes len1 != 0 != len2 */
int
_fmpz_poly_gcd_heuristic(fmpz * res, const fmpz * poly1, long len1, 
                                        const fmpz * poly2, long len2)
{
	ulong bits1, bits2, max_bits, pack_bits, bound_bits, bits_G, bits_Q;
   ulong limbs1, limbs2, limbsg, pack_limbs, qlimbs;
   ulong log_glen, log_length;
   long sign1, sign2, glen, qlen;
	fmpz_t ac, bc, d, gc;
   fmpz * A, * B, * G, * Q, * t;
   mp_ptr array1, array2, arrayg, q, temp;
   int divides;

   fmpz_init(ac);
   fmpz_init(bc);
   fmpz_init(d);
   
	/* compute gcd of content of poly1 and poly2 */
   _fmpz_poly_content(ac, poly1, len1);
   _fmpz_poly_content(bc, poly2, len2);
   fmpz_gcd(d, ac, bc);

   /* special case, one of the polys is a constant */
   if (len2 == 1) /* if len1 == 1 then so does len2 */
   {
      fmpz_set(res, d);

      fmpz_clear(ac);
      fmpz_clear(bc);
	   fmpz_clear(d);

      return 1;
   }
   
   /* divide poly1 and poly2 by their content */
   A = _fmpz_vec_init(len1);
   B = _fmpz_vec_init(len2);
   _fmpz_vec_scalar_divexact_fmpz(A, poly1, len1, ac);
   _fmpz_vec_scalar_divexact_fmpz(B, poly2, len2, bc);
   fmpz_clear(ac);
   fmpz_clear(bc);
	   
	/* special case, one of the polys is length 2 */
   if (len2 == 2) /* if len1 == 2 then so does len2 */
	{
		Q = _fmpz_vec_init(len1 - len2 + 1);
		if (_fmpz_poly_divides(Q, A, len1, B, 2))
      {
		   _fmpz_vec_scalar_mul_fmpz(res, B, 2, d);
         if (fmpz_sgn(res + 1) < 0)
            _fmpz_vec_neg(res, res, 2);
      }
		else  
      {
			fmpz_set(res, d);
         fmpz_zero(res + 1);
      }

		fmpz_clear(d);
		_fmpz_vec_clear(A, len1);
      _fmpz_vec_clear(B, len2);
      _fmpz_vec_clear(Q, len1 - len2 + 1);
      
      return 1;
	}
	
   /* 
      Determine how many bits (pack_bits) to pack into. The bound 
      bound_bits ensures that if G | A and G | B with G primitive 
      then G is the gcd of A and B. The bound is taken from 
      http://arxiv.org/abs/cs/0206032v1
   */
   bits1 = FLINT_ABS(_fmpz_vec_max_bits(A, len1));
	bits2 = FLINT_ABS(_fmpz_vec_max_bits(B, len2));
	max_bits = FLINT_MAX(bits1, bits2);
   			
	bound_bits = FLINT_MIN(bits1, bits2) + 6; 
	pack_bits = FLINT_MAX(bound_bits, max_bits); /* need to pack original polys */
   pack_limbs = (pack_bits - 1)/FLINT_BITS + 1;
   
	if (pack_bits >= 32) /* pack into multiples of limbs if >= 32 bits */
      pack_bits = FLINT_BITS*pack_limbs;
		
   /* allocate space to pack into */
   limbs1 = (pack_bits*len1 - 1)/FLINT_BITS + 1;
   limbs2 = (pack_bits*len2 - 1)/FLINT_BITS + 1;
	array1 = flint_calloc(limbs1, sizeof(mp_limb_t));
   array2 = flint_calloc(limbs2, sizeof(mp_limb_t));
   arrayg = flint_calloc(limbs2, sizeof(mp_limb_t));
   
   /* pack first poly and normalise */
   sign1 = (long) fmpz_sgn(A + len1 - 1);
	_fmpz_poly_bit_pack(array1, A, len1, pack_bits, sign1);
	while (array1[limbs1 - 1] == 0) limbs1--;

   /* pack second poly and normalise */
   sign2 = (long) fmpz_sgn(B + len2 - 1);
   _fmpz_poly_bit_pack(array2, B, len2, pack_bits, sign2);
	while (array2[limbs2 - 1] == 0) limbs2--;
	
	/* compute integer GCD */
   limbsg = mpn_gcd_full(arrayg, array1, limbs1, array2, limbs2);
	
   /* 
      Make space for unpacked gcd. May have one extra coeff due to 
      1 0 -x being packed as 0 -1 -x. 
   */
   glen = FLINT_MIN((limbsg*FLINT_BITS)/pack_bits + 1, len2); 
   G = _fmpz_vec_init(glen);
   
   /* unpack gcd */
   _fmpz_poly_bit_unpack(G, glen, arrayg, pack_bits, 0);
   while (G[glen - 1] == 0) glen--;
   
	/* divide by any content */
   fmpz_init(gc);
	_fmpz_poly_content(gc, G, glen);

   if (!fmpz_is_one(gc)) 
      limbsg = mpn_tdiv_q_fmpz_inplace(arrayg, limbsg, gc);

   /* make space for quotient and remainder of first poly by gcd */
   qlimbs = limbs1 - limbsg + 1;
   qlen = FLINT_MIN(len1, (qlimbs*FLINT_BITS)/pack_bits + 1);
   qlimbs = (qlen*pack_bits - 1)/FLINT_BITS + 1;
   q = flint_calloc(qlimbs, sizeof(mp_limb_t));
   temp = flint_malloc(limbsg*sizeof(mp_limb_t));
   
	divides = 0;

   if (mpn_divides(q, array1, limbs1, arrayg, limbsg, temp)) 
	{
      /* unpack quotient of first poly by gcd */
      Q = _fmpz_vec_init(len1); 
      t = _fmpz_vec_init(len1 + glen);
      _fmpz_poly_bit_unpack(Q, qlen, q, pack_bits, 0);
      while (Q[qlen - 1] == 0) qlen--;
      
      /* divide by content */
      _fmpz_vec_scalar_divexact_fmpz(G, G, glen, gc);
		
      /* check if we really need to multiply out to check for exact quotient */
      bits_G = FLINT_ABS(_fmpz_vec_max_bits(G, glen));
		bits_Q = FLINT_ABS(_fmpz_vec_max_bits(Q, qlen));
		log_glen = FLINT_BIT_COUNT(glen);
		log_length = FLINT_MIN(log_glen, FLINT_BIT_COUNT(qlen));
       
	   divides = (bits_G + bits_Q + log_length < pack_bits);
     
      if (!divides) /* need to multiply out to check exact quotient */
         divides = multiplies_out(A, len1, Q, qlen, G, glen, sign1, t);

		if (divides) /* quotient really was exact */
		{
         mpn_zero(q, qlimbs);
          
         if (mpn_divides(q, array2, limbs2, arrayg, limbsg, temp)) 
	      {
            /* unpack quotient of second poly by gcd */
            qlimbs = limbs2 - limbsg + 1;
            qlen = FLINT_MIN(len2, (qlimbs*FLINT_BITS - 1)/pack_bits + 1);
            _fmpz_poly_bit_unpack(Q, qlen, q, pack_bits, 0);
            while (Q[qlen - 1] == 0) qlen--;
            
            /* check if we really need to multiply out to check for exact quotient */
            bits_Q = FLINT_ABS(_fmpz_vec_max_bits(Q, qlen));
				log_length = FLINT_MIN(log_glen, FLINT_BIT_COUNT(qlen));

				divides = (bits_G + bits_Q + log_length < pack_bits);
		      
            if (!divides) /* we need to multiply out */
               divides = multiplies_out(B, len2, Q, qlen, G, glen, sign1, t);
			} 
		} 

      _fmpz_vec_clear(t, len1 + glen);
      _fmpz_vec_clear(Q, len1);
	}

   flint_free(q); 
	flint_free(temp); 
	flint_free(arrayg); 
	flint_free(array1); 
	flint_free(array2); 
	fmpz_clear(gc); 
	
	_fmpz_vec_clear(A, len1);
	_fmpz_vec_clear(B, len2);
	
   /* we found the gcd, so multiply by content */
   if (divides)
   {
	   _fmpz_vec_zero(res + glen, len2 - glen);
      _fmpz_vec_scalar_mul_fmpz(res, G, glen, d);
   }
		
   fmpz_clear(d);
   _fmpz_vec_clear(G, glen);
		
   return divides;
}