示例#1
0
void fmpz_poly_q_canonicalise(fmpz_poly_q_t rop)
{
    fmpz_poly_t gcd;

    if (fmpz_poly_is_zero(rop->den))
    {
        flint_printf("Exception (fmpz_poly_q_canonicalise). Denominator is zero.\n");
        abort();
    }

    if (fmpz_poly_is_one(rop->den))
        return;

    fmpz_poly_init(gcd);
    fmpz_poly_gcd(gcd, rop->num, rop->den);
    if (!fmpz_poly_is_unit(gcd))
    {
        fmpz_poly_div(rop->num, rop->num, gcd);
        fmpz_poly_div(rop->den, rop->den, gcd);
    }
    fmpz_poly_clear(gcd);

    if (fmpz_sgn(fmpz_poly_lead(rop->den)) < 0)
    {
        fmpz_poly_neg(rop->num, rop->num);
        fmpz_poly_neg(rop->den, rop->den);
    }
}
示例#2
0
文件: bit_pack.c 项目: goens/flint2
void
fmpz_poly_bit_pack(fmpz_t f, const fmpz_poly_t poly,
                   mp_bitcnt_t bit_size)
{
    long len;
    __mpz_struct * mpz;
    long i, d;
    int negate;

    len = fmpz_poly_length(poly);

    if (len == 0 || bit_size == 0)
    {
        fmpz_zero(f);
        return;
    }

    mpz = _fmpz_promote(f);
    mpz_realloc2(mpz, len * bit_size);
    d = mpz->_mp_alloc;

    mpn_zero(mpz->_mp_d, d);

    if (fmpz_sgn(fmpz_poly_lead(poly)) < 0)
        negate = -1;
    else
        negate = 0;

    _fmpz_poly_bit_pack(mpz->_mp_d, poly->coeffs, len, bit_size, negate);

    for (i = d - 1; i >= 0; i--)
    {
        if (mpz->_mp_d[i] != 0)
            break;
    }
    d = i + 1;

    mpz->_mp_size = d;
    _fmpz_demote_val(f);

    if (negate)
        fmpz_neg(f, f);
}
示例#3
0
void fmpz_mod_poly_divrem_f(fmpz_t f, fmpz_mod_poly_t Q, fmpz_mod_poly_t R, 
                            const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
{
    const slong lenA = A->length;
    const slong lenB = B->length;
    const slong lenQ = lenA - lenB + 1;

    fmpz *q, *r;
    fmpz_t invB;

    fmpz_init(invB);
    fmpz_gcdinv(f, invB, fmpz_poly_lead(B), &(B->p));

    if (!fmpz_is_one(f))
    {
        fmpz_clear(invB);
        return;
    }

    if (lenA < lenB)
    {
        fmpz_mod_poly_set(R, A);
        fmpz_mod_poly_zero(Q);
        fmpz_clear(invB);
        return;
    }

    if (Q == A || Q == B)
    {
        q = _fmpz_vec_init(lenQ);
    }
    else
    {
        fmpz_mod_poly_fit_length(Q, lenQ);
        q = Q->coeffs;
    }

    if (R == A || R == B)
    {
        r = _fmpz_vec_init(lenA);
    }
    else
    {
        fmpz_mod_poly_fit_length(R, lenA);
        r = R->coeffs;
    }

    _fmpz_mod_poly_divrem_divconquer(q, r, A->coeffs, lenA, 
                                           B->coeffs, lenB, invB, &(B->p));

    if (Q == A || Q == B)
    {
        _fmpz_vec_clear(Q->coeffs, Q->alloc);
        Q->coeffs = q;
        Q->alloc  = lenQ;
        Q->length = lenQ;
    }
    else
    {
        _fmpz_mod_poly_set_length(Q, lenQ);
    }

    if (R == A || R == B)
    {
        _fmpz_vec_clear(R->coeffs, R->alloc);
        R->coeffs = r;
        R->alloc  = lenA;
        R->length = lenA;
    }
    _fmpz_mod_poly_set_length(R, lenB - 1);
    _fmpz_mod_poly_normalise(R);

    fmpz_clear(invB);
}
示例#4
0
long _fmpz_poly_hensel_start_lift(fmpz_poly_factor_t lifted_fac, long *link, 
    fmpz_poly_t *v, fmpz_poly_t *w, const fmpz_poly_t f, 
    const nmod_poly_factor_t local_fac, long N)
{
    const long r = local_fac->num;

    long i, preve;
    fmpz_t p, P;
    fmpz_poly_t monic_f;

    fmpz_init(p);
    fmpz_init(P);
    fmpz_poly_init(monic_f);

    fmpz_set_ui(p, (local_fac->p + 0)->mod.n);
    fmpz_pow_ui(P, p, N);

    if (fmpz_is_one(fmpz_poly_lead(f)))
    {
        fmpz_poly_set(monic_f, f);
    }
    else if (fmpz_cmp_si(fmpz_poly_lead(f), -1) == 0)
    {
        fmpz_poly_neg(monic_f, f);
    }
    else
    {
        fmpz_t t;

        fmpz_init(t);
        fmpz_mod(t, fmpz_poly_lead(f), P);

        if (fmpz_invmod(t, t, P) == 0)
        {
            printf("Exception in fmpz_poly_start_hensel_lift.\n");
            abort();
        }

        fmpz_poly_scalar_mul_fmpz(monic_f, f, t);
        fmpz_poly_scalar_mod_fmpz(monic_f, monic_f, P);
        fmpz_clear(t);
    }

    fmpz_poly_hensel_build_tree(link, v, w, local_fac);

    {
        long *e, n = FLINT_CLOG2(N) + 1;

        e = flint_malloc(n * sizeof(long));
        for (e[i = 0] = N; e[i] > 1; i++)
            e[i + 1] = (e[i] + 1) / 2;

        for (i--; i > 0; i--)
        {
            fmpz_poly_hensel_lift_tree(link, v, w, monic_f, r, 
                p, e[i+1], e[i], 1);
        }
        if (N > 1)
        {
            fmpz_poly_hensel_lift_tree(link, v, w, monic_f, r, 
                p, e[i+1], e[i], 0);
        }

        preve = e[i+1];

        flint_free(e);
    }

    /*
        Now everything is lifted to p^N, we just need to 
        insert the factors into their correct places in lifted_fac.
     */
    fmpz_poly_factor_fit_length(lifted_fac, r);

    for (i = 0; i < 2*r - 2; i++)
    { 
        if (link[i] < 0)
        {
            fmpz_poly_scalar_smod_fmpz(lifted_fac->p + (- link[i] - 1), v[i], P);
            lifted_fac->exp[- link[i] - 1] = 1L; 
        }
    }
    lifted_fac->num = r;

    fmpz_clear(p);
    fmpz_clear(P);
    fmpz_poly_clear(monic_f);

    return preve;
}
int
main(void)
{
    int i, result;
    flint_rand_t state;

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

    flint_randinit(state);

    /* We check that lifting local factors of F yields factors */
    for (i = 0; i < 1000; i++)
    {
        fmpz_poly_t F, G, H, R;
        nmod_poly_factor_t f_fac;
        fmpz_poly_factor_t F_fac;
        long bits, nbits, n, exp, j, part_exp;

        long r;
        fmpz_poly_t *v, *w;
        long *link;
        long prev_exp;

        bits = n_randint(state, 200) + 1;
        nbits = n_randint(state, FLINT_BITS - 6) + 6;

        fmpz_poly_init(F);
        fmpz_poly_init(G);
        fmpz_poly_init(H);
        fmpz_poly_init(R);
        nmod_poly_factor_init(f_fac);
        fmpz_poly_factor_init(F_fac);

        n = n_randprime(state, nbits, 0); 
        exp = bits / (FLINT_BIT_COUNT(n) - 1) + 1;
        part_exp = n_randint(state, exp);

        /* Produce F as the product of random G and H */
        {
            nmod_poly_t f;

            nmod_poly_init(f, n);

            do {
                do {
                    fmpz_poly_randtest(G, state, n_randint(state, 200) + 2, bits);
                } while (G->length < 2);

                fmpz_randtest_not_zero(G->coeffs, state, bits);
                fmpz_one(fmpz_poly_lead(G));

                do {
                    fmpz_poly_randtest(H, state, n_randint(state, 200) + 2, bits);
                } while (H->length < 2);

                fmpz_randtest_not_zero(H->coeffs, state, bits);
                fmpz_one(fmpz_poly_lead(H));

                fmpz_poly_mul(F, G, H);

                fmpz_poly_get_nmod_poly(f, F);
            } while (!nmod_poly_is_squarefree(f));

            fmpz_poly_get_nmod_poly(f, G);
            nmod_poly_factor_insert(f_fac, f, 1);
            fmpz_poly_get_nmod_poly(f, H);
            nmod_poly_factor_insert(f_fac, f, 1);
            nmod_poly_clear(f);
        }

        r = f_fac->num;
        v = flint_malloc((2*r - 2)*sizeof(fmpz_poly_t));
        w = flint_malloc((2*r - 2)*sizeof(fmpz_poly_t));
        link = flint_malloc((2*r - 2)*sizeof(long));

        for (j = 0; j < 2*r - 2; j++)
        {
            fmpz_poly_init(v[j]);
            fmpz_poly_init(w[j]);
        }

        if (part_exp < 1)
        {
            _fmpz_poly_hensel_start_lift(F_fac, link, v, w, F, f_fac, exp);
        }
        else
        {
            fmpz_t nn;

            fmpz_init_set_ui(nn, n);

            prev_exp = _fmpz_poly_hensel_start_lift(F_fac, link, v, w, 
                F, f_fac, part_exp);
            _fmpz_poly_hensel_continue_lift(F_fac, link, v, w, 
                F, prev_exp, part_exp, exp, nn);

            fmpz_clear(nn);
        }

        result = 1;
        for (j = 0; j < F_fac->num; j++)
        {
            fmpz_poly_rem(R, F, F_fac->p + j);
            result &= (R->length == 0);
        }

        for (j = 0; j < 2*r - 2; j++)
        {
            fmpz_poly_clear(v[j]);
            fmpz_poly_clear(w[j]);
        }

        flint_free(link);
        flint_free(v);
        flint_free(w);

        if (!result) 
        {
            printf("FAIL:\n");
            printf("bits = %ld, n = %ld, exp = %ld\n", bits, n, exp);
            fmpz_poly_print(F); printf("\n\n");
            fmpz_poly_print(G); printf("\n\n");
            fmpz_poly_print(H); printf("\n\n");
            fmpz_poly_factor_print(F_fac); printf("\n\n");
            abort();
        } 

        nmod_poly_factor_clear(f_fac);
        fmpz_poly_factor_clear(F_fac);

        fmpz_poly_clear(F);
        fmpz_poly_clear(H);
        fmpz_poly_clear(G);
        fmpz_poly_clear(R);
    }

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