Exemple #1
0
void
_fmpz_poly_resultant(fmpz_t res, const fmpz * poly1, long len1, 
                                 const fmpz * poly2, long len2)
{
    if (len2 == 1)
    {
        fmpz_pow_ui(res, poly2, len1 - 1);
    }
    else
    {
        fmpz_t a, b, g, h, t;
        fmpz *A, *B, *W;
        const long alloc = len1 + len2;
        long sgn = 1;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(g);
        fmpz_init(h);
        fmpz_init(t);

        A = W = _fmpz_vec_init(alloc);
        B = W + len1;

        _fmpz_poly_content(a, poly1, len1);
        _fmpz_poly_content(b, poly2, len2);
        _fmpz_vec_scalar_divexact_fmpz(A, poly1, len1, a);
        _fmpz_vec_scalar_divexact_fmpz(B, poly2, len2, b);

        fmpz_set_ui(g, 1);
        fmpz_set_ui(h, 1);

        fmpz_pow_ui(a, a, len2 - 1);
        fmpz_pow_ui(b, b, len1 - 1);
        fmpz_mul(t, a, b);

        do
        {
            const long d = len1 - len2;

            if (!(len1 & 1L) & !(len2 & 1L))
                sgn = -sgn;

            _fmpz_poly_pseudo_rem_cohen(A, A, len1, B, len2);

            for (len1--; len1 >= 0 && !A[len1]; len1--) ;
            len1++;

            if (len1 == 0)
            {
                fmpz_zero(res);
                goto cleanup;
            }

            {
                fmpz * T;
                long len;
                T = A, A = B, B = T;
                len = len1, len1 = len2, len2 = len;
            }

            fmpz_pow_ui(a, h, d);
            fmpz_mul(b, g, a);
            _fmpz_vec_scalar_divexact_fmpz(B, B, len2, b);

            fmpz_pow_ui(g, A + (len1 - 1), d);
            fmpz_mul(b, h, g);
            fmpz_divexact(h, b, a);
            fmpz_set(g, A + (len1 - 1));

        } while (len2 > 1);

        fmpz_pow_ui(g, h, len1 - 1);
        fmpz_pow_ui(b, B + (len2 - 1), len1 - 1);
        fmpz_mul(a, h, b);
        fmpz_divexact(h, a, g);

        fmpz_mul(res, t, h);
        if (sgn < 0)
            fmpz_neg(res, res);

      cleanup:

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(g);
        fmpz_clear(h);
        fmpz_clear(t);

        _fmpz_vec_clear(W, alloc);
    }
}
Exemple #2
0
void _fmpz_poly_signature(long * r1, long * r2, fmpz * poly, long len)
{
    fmpz *A, *B, *f, *g, *h, *w;
    long lenA, lenB;
    int s, t;

    if (len <= 2)
    {
        *r1 = (len == 2);
        *r2 = 0;
        return;
    }

    w = _fmpz_vec_init(2 * len + 2);
    A = w;
    B = w + len;
    lenA = len;
    lenB = lenA - 1;
    f = w + 2 * len - 1;
    g = w + 2 * len;
    h = w + 2 * len + 1;

    _fmpz_poly_primitive_part(A, poly, lenA);
    _fmpz_poly_derivative(B, A, lenA);
    _fmpz_poly_primitive_part(B, B, lenB);

    fmpz_one(g);
    fmpz_one(h);

    s = 1;
    t = (lenA & 1L) ? -s : s;
    *r1 = 1;

    while (1)
    {
        long delta = lenA - lenB;
        int sgnA;

        _fmpz_poly_pseudo_rem_cohen(A, A, lenA, B, lenB);

        lenA = lenB;
        FMPZ_VEC_NORM(A, lenA);

        if (lenA == 0)
        {
            printf("Exception: non-squarefree polynomial detected in fmpz_poly_signature\n");
            _fmpz_vec_clear(w, 2 * len + 2);
            abort();
        }

        if ((fmpz_sgn(B + (lenB - 1)) > 0) || (delta & 1L))
            _fmpz_vec_neg(A, A, lenA);

        sgnA = fmpz_sgn(A + (lenA - 1));
        if (sgnA != s)
        {
            s = -s;
            (*r1)--;
        }
        if (sgnA != ((lenA & 1L) ? t : -t))
        {
            t = -t;
            (*r1)++;
        }

        if (lenA == 1)
        {
            *r2 = ((len - 1) - *r1) / 2;

            _fmpz_vec_clear(w, 2 * len + 2);
            return;
        }
        else
        {
            {
                fmpz * temp = A;
                A = B;
                B = temp;
            }
            {
                long temp = lenA;
                lenA = lenB;
                lenB = temp;
            }

            if (delta == 1)
            {
                fmpz_mul(f, g, h);
                _fmpz_vec_scalar_divexact_fmpz(B, B, lenB, f);
                fmpz_set(g, A + (lenA - 1));
                fmpz_set(h, g);
            }
            else
            {
                fmpz_pow_ui(f, h, delta);
                fmpz_mul(f, f, g);
                _fmpz_vec_scalar_divexact_fmpz(B, B, lenB, f);
                fmpz_pow_ui(f, h, delta - 1);
                fmpz_pow_ui(g, A + (lenA - 1), delta);
                fmpz_divexact(h, g, f);
                fmpz_set(g, A + (lenA - 1));
            }
        }
    }
}