Пример #1
0
// X_i^p = X_i
void nmod_multi_poly_mod_fermat(mp_ptr f_bar, const mp_ptr f, slong p, slong d, slong m, const slong* P) {

	if(p < d) {

		slong i, cpt, *pos, coord_p;
		
		_nmod_vec_zero(f_bar,n_pow(p,m));

		pos = (slong*)calloc(sizeof(slong),m);
		coord_p;
		cpt = 0;

		while(pos[m-1] != d) {

			coord_p = Coord_mod(P,p,pos,m);

			f_bar[coord_p] = n_addmod(f_bar[coord_p],f[cpt],p);

			pos[0]++;
			cpt++;
			i = 0;
			while( (pos[i] == d) && (i != (m-1)) ) {
				pos[i] = 0;
				// Le i est incrémenté avant pos++
				pos[++i]++;
			}
		}

		free(pos);

	}


}
Пример #2
0
void partition_function_nmod_vec(mp_ptr res, long len, nmod_t mod)
{
    mp_ptr tmp;
    mp_limb_t r;
    long k, n;

    r = mod.n - 1UL;

    if (len < 1)
        return;

    tmp = _nmod_vec_init(len);
    _nmod_vec_zero(tmp, len);

    tmp[0] = 1UL;

    for (n = k = 1; n + 4*k + 2 < len; k += 2)
    {
        tmp[n] = r;
        tmp[n + k] = r;
        tmp[n + 3*k + 1] = 1UL;
        tmp[n + 4*k + 2] = 1UL;
        n += 6*k + 5;
    }

    if (n < len) tmp[n] = r;
    if (n + k < len) tmp[n + k] = r;
    if (n + 3*k + 1 < len) tmp[n + 3*k + 1] = 1L;

    _nmod_poly_inv_series(res, tmp, len, mod);

    _nmod_vec_free(tmp);
}
Пример #3
0
void
nmod_poly_randtest_pentomial(nmod_poly_t poly, flint_rand_t state, slong len)
{
    nmod_poly_fit_length(poly, len);
    _nmod_vec_zero(poly->coeffs, len);
    poly->coeffs[0] = n_randtest(state) % poly->mod.n;
    poly->coeffs[1] = n_randtest(state) % poly->mod.n;
    poly->coeffs[2] = n_randtest(state) % poly->mod.n;
    poly->coeffs[3] = n_randtest(state) % poly->mod.n;
    poly->coeffs[len - 1] = 1;
    _nmod_poly_set_length(poly, len);
}
Пример #4
0
void
nmod_poly_randtest_trinomial(nmod_poly_t poly, flint_rand_t state, slong len)
{
    ulong k;
    nmod_poly_fit_length(poly, len);
    _nmod_vec_zero(poly->coeffs, len);
    poly->coeffs[0] = n_randtest(state) % poly->mod.n;
    poly->coeffs[len - 1] = 1;
    k = (n_randtest(state) % (len - 2)) + 1;
    poly->coeffs[k] = n_randtest(state) % poly->mod.n;
    _nmod_poly_set_length(poly, len);
}
Пример #5
0
void
__nmod_poly_exp_series_prealloc(mp_ptr f, mp_ptr g, mp_srcptr h,
    mp_srcptr hprime, mp_ptr T, mp_ptr U, long n, nmod_t mod, int extend)
{
    long m, m2, l;

    if (n < NMOD_NEWTON_EXP_CUTOFF)
    {
        _nmod_poly_exp_series_basecase(f, h, n, n, mod);
        _nmod_poly_inv_series_basecase(g, f, extend ? n : (n + 1) / 2, mod);
        return;
    }

    m = (n + 1) / 2;
    m2 = (m + 1) / 2;
    l = m - 1;  /* shifted for derivative */

    /* f := exp(h) + O(x^m),  g := exp(-h) + O(x^m2) */
    __nmod_poly_exp_series_prealloc(f, g, h, hprime, T, U, m, mod, 0);

    /* g := exp(-h) + O(x^m) */
    _nmod_poly_mullow(T, f, m, g, m2, m, mod);
    _nmod_poly_mullow(g + m2, g, m2, T + m2, m - m2, m - m2, mod);
    _nmod_vec_neg(g + m2, g + m2, m - m2, mod);

    /* U := h' + g (f' - f h') + O(x^(n-1))
       Note: should replace h' by h' mod x^(m-1) */
    _nmod_vec_zero(f + m, n - m);
    _nmod_poly_mullow(T, f, n, hprime, n, n, mod);  /* should be mulmid */
    _nmod_poly_derivative(U, f, n, mod);            /* should skip low terms */
    _nmod_vec_sub(U + l, U + l, T + l, n - l, mod);
    _nmod_poly_mullow(T + l, g, n - m, U + l, n - m, n - m, mod);
    _nmod_vec_add(U + l, hprime + l, T + l, n - m, mod);

    /* f := f + f * (h - int U) + O(x^n) = exp(h) + O(x^n) */
    _nmod_poly_integral(U, U, n, mod);  /* should skip low terms */
    _nmod_vec_sub(U + m, h + m, U + m, n - m, mod);
    _nmod_poly_mullow(f + m, f, n - m, U + m, n - m, n - m, mod);

    /* g := exp(-h) + O(x^n) */
    if (extend)
    {
        _nmod_poly_mullow(T, f, n, g, m, n, mod);
        _nmod_poly_mullow(g + m, g, m, T + m, n - m, n - m, mod);
        _nmod_vec_neg(g + m, g + m, n - m, mod);
    }
}
Пример #6
0
void _fq_nmod_trace(fmpz_t rop2, const mp_limb_t *op, slong len, 
                    const fq_nmod_ctx_t ctx)
{
    const slong d = fq_nmod_ctx_degree(ctx);

    ulong i, l;
    mp_limb_t *t, rop;

    t = _nmod_vec_init(d);
    _nmod_vec_zero(t, d);

    t[0] = n_mod2_preinv(d, ctx->mod.n, ctx->mod.ninv);

    for (i = 1; i < d; i++)
    {
        for (l = ctx->len - 2; l >= 0 && ctx->j[l] >= d - (i - 1); l--)
        {
            t[i] = n_addmod(t[i],
                            n_mulmod2_preinv(t[ctx->j[l] + i - d], ctx->a[l], ctx->mod.n, ctx->mod.ninv), 
                            ctx->mod.n);
        }

        if (l >= 0 && ctx->j[l] == d - i)
        {
            t[i] = n_addmod(t[i],
                            n_mulmod2_preinv(ctx->a[l], i, ctx->mod.n, ctx->mod.ninv),
                            ctx->mod.n);
        }

        t[i] = n_negmod(t[i], ctx->mod.n);
    }

    
    rop = WORD(0);
    for (i = 0; i < d; i++)
    {
        rop = n_addmod(rop,
                       n_mulmod2_preinv(op[i], t[i], ctx->mod.n, ctx->mod.ninv),
                       ctx->mod.n);
    }

    _nmod_vec_clear(t);

    fmpz_set_ui(rop2, rop);
}
Пример #7
0
void
_nmod_poly_exp_series_monomial_ui(mp_ptr res, mp_limb_t coeff, ulong power,
                                        slong n, nmod_t mod)
{
    slong k, r;
    mp_limb_t rfac;
    mp_limb_t a;

    r = (n - 1) / power;
    rfac = n_factorial_mod2_preinv(r, mod.n, mod.ninv);
    rfac = n_invmod(rfac, mod.n);

    if (power > 1)
        _nmod_vec_zero(res, n);

    res[0] = UWORD(1);

    if (coeff == UWORD(1))
    {
        a = rfac;
        for (k = r; k >= 1; k--)
        {
            res[k * power] = a;
            a = n_mulmod2_preinv(a, k, mod.n, mod.ninv);
        }
    }
    else
    {
        a = coeff;
        for (k = power; k < n; k += power)
        {
            res[k] = a;
            a = n_mulmod2_preinv(a, coeff, mod.n, mod.ninv);
        }

        a = rfac;
        for (k = r; k >= 1; k--)
        {
            res[k * power] = n_mulmod2_preinv(res[k * power],
                a, mod.n, mod.ninv);
            a = n_mulmod2_preinv(a, k, mod.n, mod.ninv);
        }
    }
}
void
_nmod_poly_interpolate_nmod_vec_barycentric(mp_ptr poly,
                            mp_srcptr xs, mp_srcptr ys, slong n, nmod_t mod)
{
    mp_ptr P, Q, w;
    slong i, j;

    if (n == 1)
    {
        poly[0] = ys[0];
        return;
    }

    P = _nmod_vec_init(n + 1);
    Q = _nmod_vec_init(n);
    w = _nmod_vec_init(n);

    _nmod_poly_product_roots_nmod_vec(P, xs, n, mod);

    for (i = 0; i < n; i++)
    {
        w[i] = UWORD(1);
        for (j = 0; j < n; j++)
        {
            if (i != j)
                w[i] = nmod_mul(w[i], nmod_sub(xs[i], xs[j], mod), mod);
        }
        w[i] = n_invmod(w[i], mod.n);
    }

    _nmod_vec_zero(poly, n);

    for (i = 0; i < n; i++)
    {
        _nmod_poly_div_root(Q, P, n + 1, xs[i], mod);
        _nmod_vec_scalar_addmul_nmod(poly, Q, n,
            nmod_mul(w[i], ys[i], mod), mod);
    }

    _nmod_vec_clear(P);
    _nmod_vec_clear(Q);
    _nmod_vec_clear(w);
}
Пример #9
0
void
_nmod_poly_compose_series_horner(mp_ptr res, mp_srcptr poly1, long len1, 
                            mp_srcptr poly2, long len2, long n, nmod_t mod)
{
    if (n == 1)
    {
        res[0] = poly1[0];
    }
    else
    {
        long i = len1 - 1;
        long lenr;

        mp_ptr t = _nmod_vec_init(n);

        lenr = len2;
        _nmod_vec_scalar_mul_nmod(res, poly2, len2, poly1[i], mod);
        i--;
        res[0] = nmod_add(res[0], poly1[i], mod);

        while (i > 0)
        {
            i--;
            if (lenr + len2 - 1 < n)
            {
                _nmod_poly_mul(t, res, lenr, poly2, len2, mod);
                lenr = lenr + len2 - 1;
            }
            else
            {
                _nmod_poly_mullow(t, res, lenr, poly2, len2, n, mod);
                lenr = n;
            }
            _nmod_poly_add(res, t, lenr, poly1 + i, 1, mod);
        }

        _nmod_vec_zero(res + lenr, n - lenr);
        _nmod_vec_clear(t);
    }
}
Пример #10
0
void _fq_nmod_pow(mp_limb_t *rop, const mp_limb_t *op, slong len, const fmpz_t e, 
                  const fq_nmod_ctx_t ctx)
{
    const slong d = fq_nmod_ctx_degree(ctx);

    if (fmpz_is_zero(e))
    {
        rop[0] = WORD(1);
        _nmod_vec_zero(rop + 1, 2 * d - 1 - 1);
    }
    else if (fmpz_is_one(e))
    {
        _nmod_vec_set(rop, op, len);
        _nmod_vec_zero(rop + len, 2 * d - 1 - len);
    }
    else
    {
        ulong bit;
        mp_limb_t *v = _nmod_vec_init(2 * d - 1);
        mp_limb_t *R, *S, *T;

        _nmod_vec_zero(v, 2 * d - 1);
        _nmod_vec_zero(rop, 2 * d - 1);

        /*
           Set bits to the bitmask with a 1 one place lower than the msb of e
         */

        bit = fmpz_bits(e) - 2;

        /*
           Trial run without any polynomial arithmetic to determine the parity 
           of the number of swaps;  then set R and S accordingly
         */
        
        {
            unsigned int swaps = 0U;
            ulong bit2 = bit;
            if (fmpz_tstbit(e, bit2))
                swaps = ~swaps;
            while (bit2--)
                if (!fmpz_tstbit(e, bit2))
                    swaps = ~swaps;
            
            if (swaps == 0U)
            {
                R = rop;
                S = v;
            }
            else
            {
                R = v;
                S = rop;
            }
        }
        
        /*
           We unroll the first step of the loop, referring to {op, len}
         */

        _nmod_poly_mul(R, op, len, op, len, ctx->mod);
        _fq_nmod_reduce(R, 2 * len - 1, ctx);

        if (fmpz_tstbit(e, bit))
        {
            _nmod_poly_mul(S, R, d, op, len, ctx->mod);
            _fq_nmod_reduce(S, d + len - 1, ctx);
            T = R;
            R = S;
            S = T;
        }

        while (bit--)
        {
            if (fmpz_tstbit(e, bit))
            {
                _nmod_poly_mul(S, R, d, R, d, ctx->mod);
                _fq_nmod_reduce(S, 2 * d - 1, ctx);
                _nmod_poly_mul(R, S, d, op, len, ctx->mod);
                _fq_nmod_reduce(R, d + len - 1, ctx);
            }
            else
            {
                _nmod_poly_mul(S, R, d, R, d, ctx->mod);
                _fq_nmod_reduce(S, 2 * d - 1, ctx);
                T = R;
                R = S;
                S = T;
            }
        }

        _nmod_vec_clear(v);
    }
}