Exemplo n.º 1
0
int
fmpz_invmod_ui(fmpz_t f, const fmpz_t g, const uint32_t mod)
{
	fmpz_t modulus;

	fmpz_init_set_ui(modulus, mod);

	return fmpz_invmod(f, g, modulus);
}
Exemplo n.º 2
0
void fmpz_mod_poly_div_basecase(fmpz_mod_poly_t Q, 
    const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
{
    const long lenA = A->length, lenB = B->length, lenQ = lenA - lenB + 1;
    fmpz *q;
    fmpz_t invB;

    if (lenA < lenB)
    {
        fmpz_mod_poly_zero(Q);
        return;
    }

    fmpz_init(invB);
    fmpz_invmod(invB, B->coeffs + (lenB - 1), &(B->p));

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

    _fmpz_mod_poly_div_basecase(q, NULL, 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);
    }

    fmpz_clear(invB);
}
Exemplo n.º 3
0
Arquivo: radix.c Projeto: goens/flint2
void fmpz_mod_poly_radix_init(fmpz_mod_poly_radix_t D, 
                              const fmpz_mod_poly_t R, long degF)
{
    const long degR = R->length - 1;

    if (degF < degR)
    {
        D->k = 0;
    }
    else
    {
        const long N = degF / degR;
        const long k = FLINT_BIT_COUNT(N);     /* k := ceil{log{N+1}} */
        const long lenV = degR * ((1L << k) - 1) + k;
        const long lenW = degR * ((1L << k) - 1);

        long i;

        D->V = _fmpz_vec_init(lenV + lenW);
        D->W = D->V + lenV;

        D->Rpow = flint_malloc(k * sizeof(fmpz *));
        D->Rinv = flint_malloc(k * sizeof(fmpz *));

        for (i = 0; i < k; i++)
        {
            D->Rpow[i] = D->V + (degR * ((1L << i) - 1) + i);
            D->Rinv[i] = D->W + (degR * ((1L << i) - 1));
        }

        fmpz_init(&(D->invL));
        fmpz_invmod(&(D->invL), R->coeffs + degR, &(R->p));

        _fmpz_mod_poly_radix_init(D->Rpow, D->Rinv, R->coeffs, degR + 1, 
                                  k, &(D->invL), &(R->p));

        D->k = k;
        D->degR = degR;
    }
}
Exemplo n.º 4
0
void fmpz_mod_poly_make_monic(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly)
{
    const slong len = poly->length;
    fmpz_t inv;

    if (len == 0)
    {
        fmpz_mod_poly_zero(res);
        return;
    }

    fmpz_init(inv);
    fmpz_invmod(inv, fmpz_mod_poly_lead(poly), &(poly->p));

    fmpz_mod_poly_fit_length(res, len);
    _fmpz_mod_poly_set_length(res, len);

    _fmpz_mod_poly_scalar_mul_fmpz(res->coeffs, 
                                   poly->coeffs, len, inv, &(poly->p));

    fmpz_clear(inv);
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
void precompute_muex(fmpz **mu, long M, 
                     const long **C, const long *lenC, 
                     const fmpz *a, long n, long p, long N)
{
    const long ve = (p == 2) ? M / 4 + 1 : M / (p * (p - 1)) + 1;

    fmpz_t P, pNe, pe;
    fmpz_t apow, f, g, h;

    fmpz *nu;
    long *v;

    long i, j;

    fmpz_init_set_ui(P, p);
    fmpz_init(pNe);
    fmpz_init(pe);
    fmpz_pow_ui(pNe, P, N + ve);
    fmpz_pow_ui(pe, P, ve);

    fmpz_init(apow);
    fmpz_init(f);
    fmpz_init(g);
    fmpz_init(h);

    /* Precompute $(l!)^{-1}$ */
    nu = _fmpz_vec_init(M + 1);
    v  = malloc((M + 1) * sizeof(long));

    {
        long *D, lenD = 0, k = 0;

        for (i = 0; i <= n; i++)
            lenD += lenC[i];

        D = malloc(lenD * sizeof(long));

        for (i = 0; i <= n; i++)
            for (j = 0; j < lenC[i]; j++)
                D[k++] = C[i][j];

        _remove_duplicates(D, &lenD);
        _sort(D, lenD);

        precompute_nu(nu, v, M, D, lenD, p, N + ve);

        free(D);
    }

    for (i = 0; i <= n; i++)
    {
        long m = -1, quo, idx, w;
        fmpz *z;

        /* Set apow = a[i]^{-(p-1)} mod p^N */
        fmpz_invmod(apow, a + i, pNe);
        fmpz_powm_ui(apow, apow, p - 1, pNe);

        /*
            Run over all relevant m in [0, M]. 
            Note that lenC[i] > 0 for all i.
         */
        for (quo = 0; m <= M; quo++)
        {
            for (idx = 0; idx < lenC[i]; idx++)
            {
                m = quo * p + C[i][idx];

                if (m > M)
                    break;

                /*
                    Note that $\mu_m$ is equal to 
                    $\sum_{k=0}^{\floor{m/p}} p^{\floor{m/p}-k}\nu_{m-pk}\nu_k$
                    where $\nu_i$ denotes the number with unit part nu[i] 
                    and valuation v[i].
                 */
                w = (p == 2) ? (3 * m) / 4 - (m == 3 || m == 7) : m / p;
                z = mu[i] + lenC[i] * quo + idx;
                fmpz_zero(z);
                fmpz_one(h);
                for (j = 0; j <= m / p; j++)
                {
                    fmpz_pow_ui(f, P, ve + w - j + v[m - p*j] + v[j]);
                    fmpz_mul(g, nu + (m - p*j), nu + j);

                    fmpz_mul(f, f, g);
                    fmpz_mul(f, f, h);

                    fmpz_add(z, z, f);
                    fmpz_mod(z, z, pNe);

                    /* Set h = a[i]^{- (j+1)(p-1)} mod p^{N+e} */
                    fmpz_mul(h, h, apow);
                    fmpz_mod(h, h, pNe);
                }
                fmpz_divexact(z, z, pe);
            }
        }
    }

    fmpz_clear(P);
    fmpz_clear(pNe);
    fmpz_clear(pe);

    fmpz_clear(apow);
    fmpz_clear(f);
    fmpz_clear(g);
    fmpz_clear(h);

    _fmpz_vec_clear(nu, M + 1);
    free(v);
}