예제 #1
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);
}
예제 #2
0
void
_nmod_poly_revert_series_lagrange(mp_ptr Qinv, mp_srcptr Q, long n, nmod_t mod)
{
    long i;
    mp_ptr R, S, T, tmp;

    if (n >= 1) Qinv[0] = 0UL;
    if (n >= 2) Qinv[1] = n_invmod(Q[1], mod.n);
    if (n <= 2)
        return;

    R = _nmod_vec_init(n - 1);
    S = _nmod_vec_init(n - 1);
    T = _nmod_vec_init(n - 1);

    _nmod_poly_inv_series(R, Q + 1, n - 1, mod);
    _nmod_vec_set(S, R, n - 1);

    for (i = 2; i < n; i++)
    {
        _nmod_poly_mullow(T, S, n - 1, R, n - 1, n - 1, mod);
        Qinv[i] = nmod_div(T[i - 1], i, mod);
        tmp = S; S = T; T = tmp;
    }

    _nmod_vec_clear(R);
    _nmod_vec_clear(S);
    _nmod_vec_clear(T);
}