Ejemplo n.º 1
0
void
nmod_poly_cosh_series(nmod_poly_t g, const nmod_poly_t h, long n)
{
    mp_ptr g_coeffs, h_coeffs;
    nmod_poly_t t1;
    long h_len;
    
    h_len = h->length;

    if (h_len > 0 && h->coeffs[0] != 0UL)
    {
        printf("Exception: nmod_poly_cosh_series: constant term != 0\n");
        abort();
    }

    if (h_len == 1 || n < 2)
    {
        nmod_poly_zero(g);
        if (n > 0)
            nmod_poly_set_coeff_ui(g, 0, 1UL);
        return;
    }

    if (h_len < n)
    {
        h_coeffs = _nmod_vec_init(n);
        mpn_copyi(h_coeffs, h->coeffs, h_len);
        mpn_zero(h_coeffs + h_len, n - h_len);
    }
    else
        h_coeffs = h->coeffs;

    if (h == g && h_len >= n)
    {
        nmod_poly_init2(t1, h->mod.n, n);
        g_coeffs = t1->coeffs;
    }
    else
    {
        nmod_poly_fit_length(g, n);
        g_coeffs = g->coeffs;
    }

    _nmod_poly_cosh_series(g_coeffs, h_coeffs, n, h->mod);

    if (h == g && h_len >= n)
    {
        nmod_poly_swap(g, t1);
        nmod_poly_clear(t1);
    }
    
    g->length = n;

    if (h_len < n)
        _nmod_vec_free(h_coeffs);

    _nmod_poly_normalise(g);
}
Ejemplo n.º 2
0
void
nmod_poly_compose_series_horner(nmod_poly_t res, 
                    const nmod_poly_t poly1, const nmod_poly_t poly2, long n)
{
    long len1 = poly1->length;
    long len2 = poly2->length;
    long lenr;

    if (len2 != 0 && poly2->coeffs[0] != 0)
    {
        printf("exception: nmod_poly_compose_series_horner: inner polynomial "
                "must have zero constant term\n");
        abort();
    }

    if (len1 == 0 || n == 0)
    {
        nmod_poly_zero(res);
        return;
    }

    if (len2 == 0 || len1 == 1)
    {
        nmod_poly_fit_length(res, 1);
        res->coeffs[0] = poly1->coeffs[0];
        res->length = 1;
        _nmod_poly_normalise(res);
        return;
    }

    lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n);
    len1 = FLINT_MIN(len1, lenr);
    len2 = FLINT_MIN(len2, lenr);

    if ((res != poly1) && (res != poly2))
    {
        nmod_poly_fit_length(res, lenr);
        _nmod_poly_compose_series_horner(res->coeffs, poly1->coeffs, len1, 
                                        poly2->coeffs, len2, lenr, res->mod);
        res->length = lenr;
        _nmod_poly_normalise(res);
    }
    else
    {
        nmod_poly_t t;
        nmod_poly_init2_preinv(t, res->mod.n, res->mod.ninv, lenr);
        _nmod_poly_compose_series_horner(t->coeffs, poly1->coeffs, len1,
                                        poly2->coeffs, len2, lenr, res->mod);
        t->length = lenr;
        _nmod_poly_normalise(t);
        nmod_poly_swap(res, t);
        nmod_poly_clear(t);
    }
}
Ejemplo n.º 3
0
void
nmod_poly_div_basecase(nmod_poly_t Q, const nmod_poly_t A,
                          const nmod_poly_t B)
{
    mp_ptr Q_coeffs, W;
    nmod_poly_t t1;
    long Alen, Blen;

    Blen = B->length;

    if (Blen == 0)
    {
        printf("Exception: division by zero in nmod_poly_div_basecase\n");
        abort();
    }

    Alen = A->length;

    if (Alen < Blen)
    {
        nmod_poly_zero(Q);

        return;
    }

    if (Q == A || Q == B)
    {
        nmod_poly_init2_preinv(t1, B->mod.n, B->mod.ninv,
                               Alen - Blen + 1);
        Q_coeffs = t1->coeffs;
    }
    else
    {
        nmod_poly_fit_length(Q, Alen - Blen + 1);
        Q_coeffs = Q->coeffs;
    }

    W = _nmod_vec_init(NMOD_DIV_BC_ITCH(Alen, Blen, A->mod));
    
    _nmod_poly_div_basecase(Q_coeffs, W, A->coeffs, Alen,
                               B->coeffs, Blen, B->mod);

    if (Q == A || Q == B)
    {
        nmod_poly_swap(Q, t1);
        nmod_poly_clear(t1);
    }
    
    Q->length = Alen - Blen + 1;

    _nmod_vec_clear(W);
    _nmod_poly_normalise(Q);
}
Ejemplo n.º 4
0
void
nmod_poly_revert_series_lagrange(nmod_poly_t Qinv, 
                                 const nmod_poly_t Q, long n)
{
    mp_ptr Qinv_coeffs, Q_coeffs;
    nmod_poly_t t1;
    long Qlen;
    
    Qlen = Q->length;

    if (Qlen < 2 || Q->coeffs[0] != 0 || Q->coeffs[1] == 0)
    {
        printf("exception: nmod_poly_revert_series_lagrange: input must have "
            "zero constant and an invertible coefficient of x^1");
        abort();
    }

    if (Qlen < n)
    {
        Q_coeffs = _nmod_vec_init(n);
        mpn_copyi(Q_coeffs, Q->coeffs, Qlen);
        mpn_zero(Q_coeffs + Qlen, n - Qlen);
    }
    else
        Q_coeffs = Q->coeffs;

    if (Q == Qinv && Qlen >= n)
    {
        nmod_poly_init2(t1, Q->mod.n, n);
        Qinv_coeffs = t1->coeffs;
    }
    else
    {
        nmod_poly_fit_length(Qinv, n);
        Qinv_coeffs = Qinv->coeffs;
    }

    _nmod_poly_revert_series_lagrange(Qinv_coeffs, Q_coeffs, n, Q->mod);

    if (Q == Qinv && Qlen >= n)
    {
        nmod_poly_swap(Qinv, t1);
        nmod_poly_clear(t1);
    }
    
    Qinv->length = n;

    if (Qlen < n)
        _nmod_vec_clear(Q_coeffs);

    _nmod_poly_normalise(Qinv);
}
Ejemplo n.º 5
0
void
nmod_poly_inv_series_basecase(nmod_poly_t Qinv,
                              const nmod_poly_t Q, long n)
{
    mp_ptr Qinv_coeffs, Q_coeffs;
    nmod_poly_t t1;
    long Qlen;

    Qlen = Q->length;

    if (n == 0 || Q->length == 0 || Q->coeffs[0] == 0)
    {
        printf("Exception: division by zero in nmod_poly_inv_series_basecase\n");
        abort();
    }

    if (Qlen < n)
    {
        Q_coeffs = _nmod_vec_init(n);
        mpn_copyi(Q_coeffs, Q->coeffs, Qlen);
        mpn_zero(Q_coeffs + Qlen, n - Qlen);
    }
    else
        Q_coeffs = Q->coeffs;

    if (Q == Qinv && Qlen >= n)
    {
        nmod_poly_init2(t1, Q->mod.n, n);
        Qinv_coeffs = t1->coeffs;
    }
    else
    {
        nmod_poly_fit_length(Qinv, n);
        Qinv_coeffs = Qinv->coeffs;
    }

    _nmod_poly_inv_series_basecase(Qinv_coeffs, Q_coeffs, n, Q->mod);

    if (Q == Qinv && Qlen >= n)
    {
        nmod_poly_swap(Qinv, t1);
        nmod_poly_clear(t1);
    }

    Qinv->length = n;

    if (Qlen < n)
        _nmod_vec_free(Q_coeffs);

    _nmod_poly_normalise(Qinv);
}
Ejemplo n.º 6
0
void
nmod_poly_pow(nmod_poly_t res, const nmod_poly_t poly, ulong e)
{
    const slong len = poly->length;
    slong rlen;

    if ((len < 2) | (e < UWORD(3)))
    {
        if (len == 0)
            nmod_poly_zero(res);
        else if (len == 1)
        {
            nmod_poly_fit_length(res, 1);
            res->coeffs[0] = n_powmod2_ui_preinv(poly->coeffs[0], e,
                poly->mod.n, poly->mod.ninv);
            res->length = 1;
            _nmod_poly_normalise(res);
        }
        else if (e == UWORD(0))
        {
            nmod_poly_set_coeff_ui(res, 0, UWORD(1));
            res->length = 1;
            _nmod_poly_normalise(res);
        }
        else if (e == UWORD(1))
            nmod_poly_set(res, poly);
        else  /* e == UWORD(2) */
            nmod_poly_mul(res, poly, poly);

        return;
    }

    rlen = (slong) e * (len - 1) + 1;

    if (res != poly)
    {
        nmod_poly_fit_length(res, rlen);
        _nmod_poly_pow(res->coeffs, poly->coeffs, len, e, poly->mod);
    }
    else
    {
        nmod_poly_t t;
        nmod_poly_init2(t, poly->mod.n, rlen);
        _nmod_poly_pow(t->coeffs, poly->coeffs, len, e, poly->mod);
        nmod_poly_swap(res, t);
        nmod_poly_clear(t);
    }

    res->length = rlen;
    _nmod_poly_normalise(res);
}
Ejemplo n.º 7
0
void nmod_poly_mulhigh(nmod_poly_t res, 
                   const nmod_poly_t poly1, const nmod_poly_t poly2, long n)
{
    long len1, len2, len_out;
    
    len1 = poly1->length;
    len2 = poly2->length;

    len_out = poly1->length + poly2->length - 1;
    if (n > len_out)
        n = len_out;
    
    if (len1 == 0 || len2 == 0 || n == 0)
    {
        nmod_poly_zero(res);

        return;
    }

    if (res == poly1 || res == poly2)
    {
        nmod_poly_t temp;

        nmod_poly_init2(temp, poly1->mod.n, len_out);

        if (len1 >= len2)
            _nmod_poly_mulhigh(temp->coeffs, poly1->coeffs, len1,
                           poly2->coeffs, len2, n, poly1->mod);
        else
            _nmod_poly_mulhigh(temp->coeffs, poly2->coeffs, len2,
                           poly1->coeffs, len1, n, poly1->mod);
        
        nmod_poly_swap(temp, res);
        nmod_poly_clear(temp);
    } else
    {
        nmod_poly_fit_length(res, len_out);
        
        if (len1 >= len2)
            _nmod_poly_mulhigh(res->coeffs, poly1->coeffs, len1,
                           poly2->coeffs, len2, n, poly1->mod);
        else
            _nmod_poly_mulhigh(res->coeffs, poly2->coeffs, len2,
                           poly1->coeffs, len1, n, poly1->mod);
    }

    res->length = len_out;
    _nmod_poly_normalise(res);
}
Ejemplo n.º 8
0
void
nmod_poly_mullow_classical(nmod_poly_t res,
                           const nmod_poly_t poly1, const nmod_poly_t poly2,
                           slong trunc)
{
    slong len_out;

    if (poly1->length == 0 || poly2->length == 0 || trunc == 0)
    {
        nmod_poly_zero(res);
        return;
    }

    len_out = poly1->length + poly2->length - 1;
    if (trunc > len_out)
        trunc = len_out;

    if (res == poly1 || res == poly2)
    {
        nmod_poly_t temp;
        nmod_poly_init2_preinv(temp, poly1->mod.n, poly1->mod.ninv, trunc);
        if (poly1->length >= poly2->length)
            _nmod_poly_mullow_classical(temp->coeffs, poly1->coeffs,
                                        poly1->length, poly2->coeffs,
                                        poly2->length, trunc, poly1->mod);
        else
            _nmod_poly_mullow_classical(temp->coeffs, poly2->coeffs,
                                        poly2->length, poly1->coeffs,
                                        poly1->length, trunc, poly1->mod);
        nmod_poly_swap(res, temp);
        nmod_poly_clear(temp);
    }
    else
    {
        nmod_poly_fit_length(res, trunc);
        if (poly1->length >= poly2->length)
            _nmod_poly_mullow_classical(res->coeffs, poly1->coeffs,
                                        poly1->length, poly2->coeffs,
                                        poly2->length, trunc, poly1->mod);
        else
            _nmod_poly_mullow_classical(res->coeffs, poly2->coeffs,
                                        poly2->length, poly1->coeffs,
                                        poly1->length, trunc, poly1->mod);
    }

    res->length = trunc;
    _nmod_poly_normalise(res);
}
Ejemplo n.º 9
0
void
nmod_poly_mullow_KS(nmod_poly_t res,
                 const nmod_poly_t poly1, const nmod_poly_t poly2,
                 mp_bitcnt_t bits, long n)
{
    long len_out;

    if ((poly1->length == 0) || (poly2->length == 0))
    {
        nmod_poly_zero(res);
        return;
    }

    len_out = poly1->length + poly2->length - 1;
    if (n > len_out)
        n = len_out;

    if (res == poly1 || res == poly2)
    {
        nmod_poly_t temp;
        nmod_poly_init2_preinv(temp, poly1->mod.n, poly1->mod.ninv, len_out);
        if (poly1->length >= poly2->length)
            _nmod_poly_mullow_KS(temp->coeffs, poly1->coeffs, poly1->length,
                              poly2->coeffs, poly2->length, bits,
                              n, poly1->mod);
        else
            _nmod_poly_mullow_KS(temp->coeffs, poly2->coeffs, poly2->length,
                              poly1->coeffs, poly1->length, bits,
                              n, poly1->mod);
        nmod_poly_swap(res, temp);
        nmod_poly_clear(temp);
    }
    else
    {
        nmod_poly_fit_length(res, len_out);
        if (poly1->length >= poly2->length)
            _nmod_poly_mullow_KS(res->coeffs, poly1->coeffs, poly1->length,
                              poly2->coeffs, poly2->length, bits,
                              n, poly1->mod);
        else
            _nmod_poly_mullow_KS(res->coeffs, poly2->coeffs, poly2->length,
                              poly1->coeffs, poly1->length, bits,
                              n, poly1->mod);
    }

    res->length = n;
    _nmod_poly_normalise(res);
}
Ejemplo n.º 10
0
void
nmod_poly_div_divconquer(nmod_poly_t Q,
                            const nmod_poly_t A, const nmod_poly_t B)
{
    nmod_poly_t tQ;
    mp_ptr q;
    long Alen, Blen;

    Blen = B->length;

    if (Blen == 0)
    {
        printf("Exception: division by zero in nmod_poly_div_divconquer\n");
        abort();
    }

    Alen = A->length;

    if (Alen < Blen)
    {
        nmod_poly_zero(Q);
        return;
    }

    if (Q == A || Q == B)
    {
        nmod_poly_init2(tQ, A->mod.n, Alen - Blen + 1);
        q = tQ->coeffs;
    }
    else
    {
        nmod_poly_fit_length(Q, Alen - Blen + 1);
        q = Q->coeffs;
    }

    _nmod_poly_div_divconquer(q, A->coeffs, Alen,
                                       B->coeffs, Blen, A->mod);

    if (Q == A || Q == B)
    {
        nmod_poly_swap(tQ, Q);
        nmod_poly_clear(tQ);
    }
    
    Q->length = Alen - Blen + 1;
}
Ejemplo n.º 11
0
void 
nmod_poly_rem_basecase(nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B)
{
    const long lenA = A->length, lenB = B->length;
    mp_ptr r, W;
    nmod_poly_t t;

    if (lenB == 0)
    {
        printf("Exception: division by zero in nmod_poly_rem_basecase\n");
        abort();
    }
    if (lenA < lenB)
    {
        nmod_poly_set(R, A);
        return;
    }

    if (R == A || R == B)
    {
        nmod_poly_init2_preinv(t, B->mod.n, B->mod.ninv, lenB - 1);
        r = t->coeffs;
    }
    else
    {
        nmod_poly_fit_length(R, lenB - 1);
        r = R->coeffs;
    }

    W = _nmod_vec_init(NMOD_DIVREM_BC_ITCH(lenA, lenB, A->mod));

    _nmod_poly_rem_basecase(r, W, A->coeffs, lenA,
                                  B->coeffs, lenB, B->mod);

    if (R == A || R == B)
    {
        nmod_poly_swap(R, t);
        nmod_poly_clear(t);
    }
    R->length = lenB - 1;

    _nmod_vec_clear(W);
    _nmod_poly_normalise(R);
}
Ejemplo n.º 12
0
void
nmod_poly_compose_divconquer(nmod_poly_t res, 
                             const nmod_poly_t poly1, const nmod_poly_t poly2)
{
    const long len1 = poly1->length;
    const long len2 = poly2->length;
    long lenr;
    
    if (len1 == 0)
    {
        nmod_poly_zero(res);
        return;
    }
    if (len1 == 1 || len2 == 0)
    {
        nmod_poly_set_coeff_ui(res, 0, poly1->coeffs[0]);
        nmod_poly_truncate(res, 1);
        return;
    }
    
    lenr = (len1 - 1) * (len2 - 1) + 1;
    
    if (res != poly1 && res != poly2)
    {
        nmod_poly_fit_length(res, lenr);
        _nmod_poly_compose_divconquer(res->coeffs, poly1->coeffs, len1, 
                                                   poly2->coeffs, len2, poly1->mod);
    }
    else
    {
        nmod_poly_t t;
        nmod_poly_init2(t, poly1->mod.n, lenr);
        _nmod_poly_compose_divconquer(t->coeffs, poly1->coeffs, len1,
                                                 poly2->coeffs, len2, poly1->mod);
        nmod_poly_swap(res, t);
        nmod_poly_clear(t);
    }

    res->length = lenr;
    _nmod_poly_normalise(res);
}
Ejemplo n.º 13
0
void
nmod_poly_exp_series(nmod_poly_t f, const nmod_poly_t h, long n)
{
    mp_ptr f_coeffs, h_coeffs;
    nmod_poly_t t1;
    long hlen, k;

    nmod_poly_fit_length(f, n);
    hlen = h->length;

    if (hlen > 0 && h->coeffs[0] != 0UL)
    {
        printf("Exception: nmod_poly_exp_series: constant term != 0\n");
        abort();
    }

    if (n <= 1 || hlen == 0)
    {
        if (n == 0)
        {
            nmod_poly_zero(f);
        }
        else
        {
            f->coeffs[0] = 1UL;
            f->length = 1;
        }
        return;
    }

    /* Handle monomials */
    for (k = 0; h->coeffs[k] == 0UL && k < n - 1; k++);
    if (k == hlen - 1 || k == n - 1)
    {
        hlen = FLINT_MIN(hlen, n);
        _nmod_poly_exp_series_monomial_ui(f->coeffs,
            h->coeffs[hlen-1], hlen - 1, n, f->mod);
        f->length = n;
        _nmod_poly_normalise(f);
        return;
    }

    if (n < NMOD_NEWTON_EXP_CUTOFF2)
    {
        _nmod_poly_exp_series_basecase(f->coeffs, h->coeffs, hlen, n, f->mod);
        f->length = n;
        _nmod_poly_normalise(f);
        return;
    }

    if (hlen < n)
    {
        h_coeffs = _nmod_vec_init(n);
        mpn_copyi(h_coeffs, h->coeffs, hlen);
        mpn_zero(h_coeffs + hlen, n - hlen);
    }
    else
        h_coeffs = h->coeffs;

    if (h == f && hlen >= n)
    {
        nmod_poly_init2(t1, h->mod.n, n);
        f_coeffs = t1->coeffs;
    }
    else
    {
        nmod_poly_fit_length(f, n);
        f_coeffs = f->coeffs;
    }

    _nmod_poly_exp_series(f_coeffs, h_coeffs, n, f->mod);

    if (h == f && hlen >= n)
    {
        nmod_poly_swap(f, t1);
        nmod_poly_clear(t1);
    }
    
    f->length = n;

    if (hlen < n)
        _nmod_vec_free(h_coeffs);

    _nmod_poly_normalise(f);
}
Ejemplo n.º 14
0
Archivo: xgcd.c Proyecto: goens/flint2
void
nmod_poly_xgcd(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T,
                              const nmod_poly_t A, const nmod_poly_t B)
{
    const long lenA = A->length, lenB = B->length;
    mp_limb_t inv;

    if (lenA == 0)
    {
        if (lenB == 0) 
        {
            nmod_poly_zero(G);
            nmod_poly_zero(S);
            nmod_poly_zero(T);
        }
        else 
        {
            inv = n_invmod(B->coeffs[lenB - 1], B->mod.n);
            nmod_poly_scalar_mul_nmod(G, B, inv);
            nmod_poly_zero(S);
            nmod_poly_set_coeff_ui(T, 0, inv);
            T->length = 1;
        }
    } 
    else if (lenB == 0)
    {
        inv = n_invmod(A->coeffs[lenA - 1], A->mod.n);
        nmod_poly_scalar_mul_nmod(G, A, inv);
        nmod_poly_zero(T);
        nmod_poly_set_coeff_ui(S, 0, inv);
        S->length = 1;
    }
    else
    {
        nmod_poly_t tG, tS, tT;
        mp_ptr g, s, t;
        long lenG;

        if (G == A || G == B)
        {
            nmod_poly_init2(tG, A->mod.n, FLINT_MIN(lenA, lenB));
            g = tG->coeffs;
        }
        else
        {
            nmod_poly_fit_length(G, FLINT_MIN(lenA, lenB));
            g = G->coeffs;
        }
        if (S == A || S == B)
        {
            nmod_poly_init2(tS, A->mod.n, lenB - 1);
            s = tS->coeffs;
        }
        else
        {
            nmod_poly_fit_length(S, lenB - 1);
            s = S->coeffs;
        }
        if (T == A || T == B)
        {
            nmod_poly_init2(tT, A->mod.n, lenA - 1);
            t = tT->coeffs;
        }
        else
        {
            nmod_poly_fit_length(T, lenA - 1);
            t = T->coeffs;
        }

        if (lenA >= lenB)
            lenG = _nmod_poly_xgcd(g, s, t, A->coeffs, lenA,
                                            B->coeffs, lenB, A->mod);
        else
            lenG = _nmod_poly_xgcd(g, t, s, B->coeffs, lenB,
                                            A->coeffs, lenA, A->mod);

        if (G == A || G == B)
        {
            nmod_poly_swap(tG, G);
            nmod_poly_clear(tG);
        }
        if (S == A || S == B)
        {
            nmod_poly_swap(tS, S);
            nmod_poly_clear(tS);
        }
        if (T == A || T == B)
        {
            nmod_poly_swap(tT, T);
            nmod_poly_clear(tT);
        }
        
        G->length = lenG;
        S->length = lenB - lenG;
        T->length = lenA - lenG;
        MPN_NORM(S->coeffs, S->length);
        MPN_NORM(T->coeffs, T->length);

        if (G->coeffs[lenG - 1] != 1)
        {
            inv = n_invmod(G->coeffs[lenG - 1], A->mod.n);
            nmod_poly_scalar_mul_nmod(G, G, inv);
            nmod_poly_scalar_mul_nmod(S, S, inv);
            nmod_poly_scalar_mul_nmod(T, T, inv);
        }
    }
}
Ejemplo n.º 15
0
void
nmod_poly_compose_mod_horner(nmod_poly_t res, 
                    const nmod_poly_t poly1, const nmod_poly_t poly2,
                    const nmod_poly_t poly3)
{
    long len1 = poly1->length;
    long len2 = poly2->length;
    long len3 = poly3->length;
    long len = len3 - 1;

    mp_ptr ptr2;

    if (len3 == 0)
    {
        printf("exception: division by zero in nmod_poly_compose_mod_horner\n");
        abort();
    }

    if (len1 == 0 || len3 == 1)
    {
        nmod_poly_zero(res);
        return;
    }

    if (len1 == 1)
    {
        nmod_poly_set(res, poly1);
        return;
    }

    if (res == poly3 || res == poly1)
    {
        nmod_poly_t tmp;
        nmod_poly_init_preinv(tmp, res->mod.n, res->mod.ninv);
        nmod_poly_compose_mod_horner(tmp, poly1, poly2, poly3);
        nmod_poly_swap(tmp, res);
        nmod_poly_clear(tmp);
        return;
    }

    ptr2 = _nmod_vec_init(len);

    if (len2 <= len)
    {
        mpn_copyi(ptr2, poly2->coeffs, len2);
        mpn_zero(ptr2 + len2, len - len2);
    }
    else
    {
        _nmod_poly_rem(ptr2, poly2->coeffs, len2,
                             poly3->coeffs, len3, res->mod);
    }

    nmod_poly_fit_length(res, len);
    _nmod_poly_compose_mod_horner(res->coeffs,
        poly1->coeffs, len1, ptr2, poly3->coeffs, len3, res->mod);
    res->length = len;
    _nmod_poly_normalise(res);

    _nmod_vec_clear(ptr2);
}
Ejemplo n.º 16
0
void
nmod_poly_compose_mod_brent_kung(nmod_poly_t res, 
                    const nmod_poly_t poly1, const nmod_poly_t poly2,
                    const nmod_poly_t poly3)
{
    long len1 = poly1->length;
    long len2 = poly2->length;
    long len3 = poly3->length;
    long len = len3 - 1;

    mp_ptr ptr2;

    if (len3 == 0)
    {
        printf("exception: division by zero in "
                "nmod_poly_compose_mod_brent_kung\n");
        abort();
    }

    if (len1 >= len3)
    {
        printf("exception: nmod_poly_compose_brent_kung: the degree of the"
                " first polynomial must be smaller than that of the modulus\n");
        abort();
    }

    if (len1 == 0 || len3 == 1)
    {
        nmod_poly_zero(res);
        return;
    }

    if (len1 == 1)
    {
        nmod_poly_set(res, poly1);
        return;
    }

    if (res == poly3 || res == poly1)
    {
        nmod_poly_t tmp;
        nmod_poly_init_preinv(tmp, res->mod.n, res->mod.ninv);
        nmod_poly_compose_mod_brent_kung(tmp, poly1, poly2, poly3);
        nmod_poly_swap(tmp, res);
        nmod_poly_clear(tmp);
        return;
    }

    ptr2 = _nmod_vec_init(len);

    if (len2 <= len)
    {
        mpn_copyi(ptr2, poly2->coeffs, len2);
        mpn_zero(ptr2 + len2, len - len2);
    }
    else
    {
        _nmod_poly_rem(ptr2, poly2->coeffs, len2,
                             poly3->coeffs, len3, res->mod);
    }

    nmod_poly_fit_length(res, len);
    _nmod_poly_compose_mod_brent_kung(res->coeffs,
        poly1->coeffs, len1, ptr2, poly3->coeffs, len3, res->mod);
    res->length = len;
    _nmod_poly_normalise(res);

    _nmod_vec_clear(ptr2);
}
Ejemplo n.º 17
0
void
nmod_poly_divrem_basecase(nmod_poly_t Q, nmod_poly_t R, const nmod_poly_t A,
                          const nmod_poly_t B)
{
    const slong lenA = A->length, lenB = B->length;
    mp_ptr Q_coeffs, R_coeffs, W;
    nmod_poly_t t1, t2;
    TMP_INIT;

    if (lenB == 0)
    {
        flint_printf("Exception (nmod_poly_divrem). Division by zero.\n");
        abort();
    }

    if (lenA < lenB)
    {
        nmod_poly_set(R, A);
        nmod_poly_zero(Q);
        return;
    }

    if (Q == A || Q == B)
    {
        nmod_poly_init2_preinv(t1, B->mod.n, B->mod.ninv, lenA - lenB + 1);
        Q_coeffs = t1->coeffs;
    }
    else
    {
        nmod_poly_fit_length(Q, lenA - lenB + 1);
        Q_coeffs = Q->coeffs;
    }

    if (R == A || R == B)
    {
        nmod_poly_init2_preinv(t2, B->mod.n, B->mod.ninv, lenB - 1);
        R_coeffs = t2->coeffs;
    }
    else
    {
        nmod_poly_fit_length(R, lenB - 1);
        R_coeffs = R->coeffs;
    }

    TMP_START;
    W = TMP_ALLOC(NMOD_DIVREM_BC_ITCH(lenA, lenB, A->mod)*sizeof(mp_limb_t));
    
    _nmod_poly_divrem_basecase(Q_coeffs, R_coeffs, W, A->coeffs, lenA,
                               B->coeffs, lenB, B->mod);

    if (Q == A || Q == B)
    {
        nmod_poly_swap(Q, t1);
        nmod_poly_clear(t1);
    }
    if (R == A || R == B)
    {
        nmod_poly_swap(R, t2);
        nmod_poly_clear(t2);
    }
    Q->length = lenA - lenB + 1;
    R->length = lenB - 1;

    TMP_END;
    _nmod_poly_normalise(R);
}
Ejemplo n.º 18
0
int
nmod_poly_mat_inv(nmod_poly_mat_t Ainv, nmod_poly_t den,
                    const nmod_poly_mat_t A)
{
    slong n = nmod_poly_mat_nrows(A);

    if (n == 0)
    {
        nmod_poly_one(den);
        return 1;
    }
    else if (n == 1)
    {
        nmod_poly_set(den, E(A, 0, 0));
        nmod_poly_one(E(Ainv, 0, 0));
        return !nmod_poly_is_zero(den);
    }
    else if (n == 2)
    {
        nmod_poly_mat_det(den, A);

        if (nmod_poly_is_zero(den))
        {
            return 0;
        }
        else if (Ainv == A)
        {
            nmod_poly_swap(E(A, 0, 0), E(A, 1, 1));
            nmod_poly_neg(E(A, 0, 1), E(A, 0, 1));
            nmod_poly_neg(E(A, 1, 0), E(A, 1, 0));
            return 1;
        }
        else
        {
            nmod_poly_set(E(Ainv, 0, 0), E(A, 1, 1));
            nmod_poly_set(E(Ainv, 1, 1), E(A, 0, 0));
            nmod_poly_neg(E(Ainv, 0, 1), E(A, 0, 1));
            nmod_poly_neg(E(Ainv, 1, 0), E(A, 1, 0));
            return 1;
        }
    }
    else
    {
        nmod_poly_mat_t LU, I;
        slong * perm;
        int result;

        perm = _perm_init(n);
        nmod_poly_mat_init_set(LU, A);
        result = (nmod_poly_mat_fflu(LU, den, perm, LU, 1) == n);

        if (result)
        {
            nmod_poly_mat_init(I, n, n, nmod_poly_mat_modulus(A));
            nmod_poly_mat_one(I);
            nmod_poly_mat_solve_fflu_precomp(Ainv, perm, LU, I);
            nmod_poly_mat_clear(I);
        }
        else
            nmod_poly_zero(den);

        if (_perm_parity(perm, n))
        {
            nmod_poly_mat_neg(Ainv, Ainv);
            nmod_poly_neg(den, den);
        }

        _perm_clear(perm);
        nmod_poly_mat_clear(LU);
        return result;
    }
}