예제 #1
0
void fmpz_poly_hensel_lift_without_inverse(fmpz_poly_t Gout, fmpz_poly_t Hout, 
	const fmpz_poly_t f, const fmpz_poly_t g, const fmpz_poly_t h, 
    const fmpz_poly_t a, const fmpz_poly_t b, 
    const fmpz_t p, const fmpz_t p1)
{
    fmpz_poly_fit_length(Gout, g->length);
    fmpz_poly_fit_length(Hout, h->length);
    _fmpz_poly_set_length(Gout, g->length);
    _fmpz_poly_set_length(Hout, h->length);

    _fmpz_poly_hensel_lift_without_inverse(Gout->coeffs, Hout->coeffs, 
        f->coeffs, f->length, g->coeffs, g->length, h->coeffs, h->length, 
        a->coeffs, a->length, b->coeffs, b->length, p, p1);
}
예제 #2
0
void
fmpz_poly_bit_unpack_unsigned(fmpz_poly_t poly, const fmpz_t f,
                                        mp_bitcnt_t bit_size)
{
    slong len;
    mpz_t tmp;

    if (fmpz_sgn(f) < 0)
    {
        flint_printf("Exception (fmpz_poly_bit_unpack_unsigned). Expected an unsigned value.\n");
        abort();
    }

    if (bit_size == 0 || fmpz_is_zero(f))
    {
        fmpz_poly_zero(poly);
        return;
    }

    len = (fmpz_bits(f) + bit_size - 1) / bit_size;

    mpz_init2(tmp, bit_size*len);
    flint_mpn_zero(tmp->_mp_d, tmp->_mp_alloc);
    fmpz_get_mpz(tmp, f);

    fmpz_poly_fit_length(poly, len);

    _fmpz_poly_bit_unpack_unsigned(poly->coeffs, len, tmp->_mp_d, bit_size);
    _fmpz_poly_set_length(poly, len);
    _fmpz_poly_normalise(poly);

    mpz_clear(tmp);
}
예제 #3
0
void
fmpz_poly_mulmid_classical(fmpz_poly_t res,
                           const fmpz_poly_t poly1, const fmpz_poly_t poly2)
{
    slong len_out;

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

    len_out = poly1->length - poly2->length + 1;

    if (res == poly1 || res == poly2)
    {
        fmpz_poly_t temp;
        fmpz_poly_init2(temp, len_out);
        _fmpz_poly_mulmid_classical(temp->coeffs, poly1->coeffs, poly1->length,
                                    poly2->coeffs, poly2->length);
        fmpz_poly_swap(res, temp);
        fmpz_poly_clear(temp);
    }
    else
    {
        fmpz_poly_fit_length(res, len_out);
        _fmpz_poly_mulmid_classical(res->coeffs, poly1->coeffs, poly1->length,
                                    poly2->coeffs, poly2->length);
    }

    _fmpz_poly_set_length(res, len_out);
    _fmpz_poly_normalise(res);
}
예제 #4
0
int padic_poly_get_fmpz_poly(fmpz_poly_t rop, const padic_poly_t op, 
                             const padic_ctx_t ctx)
{
    const slong len = op->length;

    if (op->val < 0)
    {
        return 0;
    }

    if (padic_poly_is_zero(op))
    {
        fmpz_poly_zero(rop);
        return 1;
    }

    fmpz_poly_fit_length(rop, len);
    _fmpz_poly_set_length(rop, len);

    if (op->val == 0)
    {
        _fmpz_vec_set(rop->coeffs, op->coeffs, len);
    }
    else  /* op->val > 0 */
    {
        fmpz_t pow;

        fmpz_init(pow);
        fmpz_pow_ui(pow, ctx->p, op->val);
        _fmpz_vec_scalar_mul_fmpz(rop->coeffs, op->coeffs, len, pow);
        fmpz_clear(pow);
    }

    return 1;
}
예제 #5
0
int
fmpz_poly_sqrt_classical(fmpz_poly_t b, const fmpz_poly_t a)
{
    long blen, len = a->length;
    int result;

    if (len % 2 == 0)
    {
        fmpz_poly_zero(b);
        return len == 0;
    }

    if (b == a)
    {
        fmpz_poly_t tmp;
        fmpz_poly_init(tmp);
        result = fmpz_poly_sqrt(tmp, a);
        fmpz_poly_swap(b, tmp);
        fmpz_poly_clear(tmp);
        return result;
    }

    blen = len / 2 + 1;
    fmpz_poly_fit_length(b, blen);
    _fmpz_poly_set_length(b, blen);
    result = _fmpz_poly_sqrt_classical(b->coeffs, a->coeffs, len);
    if (!result)
        _fmpz_poly_set_length(b, 0);
    return result;
}
예제 #6
0
void
fmpz_poly_mul_karatsuba(fmpz_poly_t res,
                        const fmpz_poly_t poly1, const fmpz_poly_t poly2)
{
    long len_out;

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

    len_out = poly1->length + poly2->length - 1;

    fmpz_poly_fit_length(res, len_out);

    if (poly1->length >= poly2->length)
        _fmpz_poly_mul_karatsuba(res->coeffs, poly1->coeffs, poly1->length,
                                 poly2->coeffs, poly2->length);
    else
        _fmpz_poly_mul_karatsuba(res->coeffs, poly2->coeffs, poly2->length,
                                 poly1->coeffs, poly1->length);

    _fmpz_poly_set_length(res, len_out);
}
예제 #7
0
/* x^n+1 */
void
pol_xn1(fmpz_poly_t poly, ulong n)
{
    fmpz_poly_fit_length(poly, n + 1);
    fmpz_poly_set_coeff_si(poly, 0, 1);
    fmpz_poly_set_coeff_si(poly, n, 1);
}
예제 #8
0
파일: sqrlow.c 프로젝트: goens/flint2
void fmpz_poly_sqrlow(fmpz_poly_t res, const fmpz_poly_t poly, long n)
{
    const long len = poly->length;

    if (len == 0 || n == 0)
    {
        fmpz_poly_zero(res);
        return;
    }

    if (res == poly)
    {
        fmpz_poly_t t;
        fmpz_poly_init2(t, n);
        fmpz_poly_sqrlow(t, poly, n);
        fmpz_poly_swap(res, t);
        fmpz_poly_clear(t);
        return;
    }

    n = FLINT_MIN(2 * len - 1, n);

    fmpz_poly_fit_length(res, n);
    _fmpz_poly_sqrlow(res->coeffs, poly->coeffs, len, n);
    _fmpz_poly_set_length(res, n);
    _fmpz_poly_normalise(res);
}
예제 #9
0
파일: mullow_KS.c 프로젝트: goens/flint2
void
fmpz_poly_mullow_KS(fmpz_poly_t res,
                    const fmpz_poly_t poly1, const fmpz_poly_t poly2, long n)
{
    const long len1 = poly1->length;
    const long len2 = poly2->length;

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

    if (res == poly1 || res == poly2)
    {
        fmpz_poly_t t;
        fmpz_poly_init2(t, n);
        fmpz_poly_mullow_KS(t, poly1, poly2, n);
        fmpz_poly_swap(res, t);
        fmpz_poly_clear(t);
        return;
    }

    fmpz_poly_fit_length(res, n);

    if (len1 >= len2)
        _fmpz_poly_mullow_KS(res->coeffs, poly1->coeffs, len1,
                                          poly2->coeffs, len2, n);
    else
        _fmpz_poly_mullow_KS(res->coeffs, poly2->coeffs, len2,
                                          poly1->coeffs, len1, n);

    _fmpz_poly_set_length(res, n);
    _fmpz_poly_normalise(res);
}
예제 #10
0
void
fmpz_poly_scalar_mul_ui(fmpz_poly_t poly1, const fmpz_poly_t poly2, ulong x)
{
    long i;

    /* Either scalar or input poly is zero */
    if ((x == 0) || (poly2->length == 0))
    {
        fmpz_poly_zero(poly1);
        return;
    }

    /* Special case, multiply by 1 */
    if (x == 1)
    {
        fmpz_poly_set(poly1, poly2);
        return;
    }

    fmpz_poly_fit_length(poly1, poly2->length);

    for (i = 0; i < poly2->length; i++)
        fmpz_mul_ui(poly1->coeffs + i, poly2->coeffs + i, x);

    _fmpz_poly_set_length(poly1, poly2->length);
}
예제 #11
0
void fmpz_poly_sqr_classical(fmpz_poly_t rop, const fmpz_poly_t op)
{
    long len;

    if (op->length == 0)
    {
        fmpz_poly_zero(rop);
        return;
    }

    len = 2 * op->length - 1;

    if (rop == op)
    {
        fmpz_poly_t t;
        fmpz_poly_init2(t, len);
        _fmpz_poly_sqr_classical(t->coeffs, op->coeffs, op->length);
        fmpz_poly_swap(rop, t);
        fmpz_poly_clear(t);
    }
    else
    {
        fmpz_poly_fit_length(rop, len);
        _fmpz_poly_sqr_classical(rop->coeffs, op->coeffs, op->length);
    }

    _fmpz_poly_set_length(rop, len);
}
예제 #12
0
void
fmpz_poly_mulhigh_classical(fmpz_poly_t res,
                            const fmpz_poly_t poly1, const fmpz_poly_t poly2,
                            long start)
{
    long len_out = poly1->length + poly2->length - 1;

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

    if (res == poly1 || res == poly2)
    {
        fmpz_poly_t temp;
        fmpz_poly_init2(temp, len_out);
        _fmpz_poly_mulhigh_classical(temp->coeffs, poly1->coeffs,
                                     poly1->length, poly2->coeffs,
                                     poly2->length, start);
        fmpz_poly_swap(res, temp);
        fmpz_poly_clear(temp);
    }
    else
    {
        fmpz_poly_fit_length(res, len_out);
        _fmpz_poly_mulhigh_classical(res->coeffs, poly1->coeffs, poly1->length,
                                     poly2->coeffs, poly2->length, start);
    }

    _fmpz_poly_set_length(res, len_out);
}
예제 #13
0
void
fmpz_poly_mullow_classical(fmpz_poly_t res, const fmpz_poly_t poly1, 
                                            const fmpz_poly_t poly2, long n)
{
    long len_out;

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

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

    if (res == poly1 || res == poly2)
    {
        fmpz_poly_t t;
        fmpz_poly_init2(t, n);
        _fmpz_poly_mullow_classical(t->coeffs, poly1->coeffs, poly1->length,
                                    poly2->coeffs, poly2->length, n);
        fmpz_poly_swap(res, t);
        fmpz_poly_clear(t);
    }
    else
    {
        fmpz_poly_fit_length(res, n);
        _fmpz_poly_mullow_classical(res->coeffs, poly1->coeffs, poly1->length,
                                    poly2->coeffs, poly2->length, n);
    }

    _fmpz_poly_set_length(res, n);
    _fmpz_poly_normalise(res);
}
예제 #14
0
void
fmpz_poly_pow_multinomial(fmpz_poly_t res, const fmpz_poly_t poly, ulong e)
{
    const long len = poly->length;
    long rlen;

    if ((len < 2) | (e < 3UL))
    {
        if (e == 0UL)
            fmpz_poly_set_ui(res, 1);
        else if (len == 0)
            fmpz_poly_zero(res);
        else if (len == 1)
        {
            fmpz_poly_fit_length(res, 1);
            fmpz_pow_ui(res->coeffs, poly->coeffs, e);
            _fmpz_poly_set_length(res, 1);
        }
        else if (e == 1UL)
            fmpz_poly_set(res, poly);
        else  /* e == 2UL */
            fmpz_poly_sqr(res, poly);
        return;
    }
    
    rlen = (long) e * (len - 1) + 1;

    if (res != poly)
    {
        fmpz_poly_fit_length(res, rlen);
        _fmpz_poly_pow_multinomial(res->coeffs, poly->coeffs, len, e);
        _fmpz_poly_set_length(res, rlen);
    }
    else
    {
        fmpz_poly_t t;
        fmpz_poly_init2(t, rlen);
        _fmpz_poly_pow_multinomial(t->coeffs, poly->coeffs, len, e);
        _fmpz_poly_set_length(t, rlen);
        fmpz_poly_swap(res, t);
        fmpz_poly_clear(t);
    }
}
예제 #15
0
파일: set_ui.c 프로젝트: clear731/lattice
void
fmpz_poly_set_ui(fmpz_poly_t poly, ulong c)
{
    if (c == UWORD(0))
        fmpz_poly_zero(poly);
    else
    {
        fmpz_poly_fit_length(poly, 1);
        fmpz_set_ui(poly->coeffs, c);
        _fmpz_poly_set_length(poly, 1);
    }
}
예제 #16
0
/*
    Applies the operator $\sigma^e$ to all elements in the matrix \code{op},
    setting the corresponding elements in \code{rop} to the results.
 */
static
void fmpz_poly_mat_frobenius(fmpz_poly_mat_t B,
                             const fmpz_poly_mat_t A, long e,
                             const fmpz_t p, long N, const qadic_ctx_t ctx)
{
    const long d = qadic_ctx_degree(ctx);

    e = e % d;
    if (e < 0)
        e += d;

    if (e == 0)
    {
        fmpz_t pN;

        fmpz_init(pN);
        fmpz_pow_ui(pN, p, N);

        fmpz_poly_mat_scalar_mod_fmpz(B, A, pN);

        fmpz_clear(pN);
    }
    else
    {
        long i, j;
        fmpz *t = _fmpz_vec_init(2 * d - 1);

        for (i = 0; i < B->r; i++)
            for (j = 0; j < B->c; j++)
            {
                const fmpz_poly_struct *a = fmpz_poly_mat_entry(A,  i, j);
                fmpz_poly_struct *b       = fmpz_poly_mat_entry(B, i, j);

                if (a->length == 0)
                {
                    fmpz_poly_zero(b);
                }
                else
                {
                    _qadic_frobenius(t, a->coeffs, a->length, e,
                                     ctx->a, ctx->j, ctx->len, p, N);

                    fmpz_poly_fit_length(b, d);
                    _fmpz_vec_set(b->coeffs, t, d);
                    _fmpz_poly_set_length(b, d);
                    _fmpz_poly_normalise(b);
                }
            }

        _fmpz_vec_clear(t, 2 * d - 1);
    }
}
예제 #17
0
파일: randtest.c 프로젝트: goens/flint2
void
fmpz_poly_randtest_unsigned(fmpz_poly_t f, flint_rand_t state, 
                            long len, mp_bitcnt_t bits)
{
    long i;
    fmpz_poly_fit_length(f, len);

    for (i = 0; i < len; i++)
        fmpz_randtest_unsigned(f->coeffs + i, state, bits);

    _fmpz_poly_set_length(f, len);
    _fmpz_poly_normalise(f);
}
예제 #18
0
void
fmpz_poly_compose_series(fmpz_poly_t res, 
                    const fmpz_poly_t poly1, const fmpz_poly_t poly2, long n)
{
    long len1 = poly1->length;
    long len2 = poly2->length;
    long lenr;

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

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

    if (len2 == 0 || len1 == 1)
    {
        fmpz_poly_set_fmpz(res, poly1->coeffs);
        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))
    {
        fmpz_poly_fit_length(res, lenr);
        _fmpz_poly_compose_series(res->coeffs, poly1->coeffs, len1, 
                                               poly2->coeffs, len2, lenr);
        _fmpz_poly_set_length(res, lenr);
        _fmpz_poly_normalise(res);
    }
    else
    {
        fmpz_poly_t t;
        fmpz_poly_init2(t, lenr);
        _fmpz_poly_compose_series(t->coeffs, poly1->coeffs, len1,
                                             poly2->coeffs, len2, lenr);
        _fmpz_poly_set_length(t, lenr);
        _fmpz_poly_normalise(t);
        fmpz_poly_swap(res, t);
        fmpz_poly_clear(t);
    }
}
예제 #19
0
void
fmpz_poly_revert_series_lagrange(fmpz_poly_t Qinv,
                                        const fmpz_poly_t Q, slong n)
{
    fmpz *Qcopy;
    int Qalloc;
    slong Qlen = Q->length;

    if (Qlen < 2 || !fmpz_is_zero(Q->coeffs) || !fmpz_is_pm1(Q->coeffs + 1))
    {
        flint_printf("Exception (fmpz_poly_revert_series_lagrange). Input must have \n"
               "zero constant term and +1 or -1 as coefficient of x^1.\n");
        abort();
    }

    if (Qlen >= n)
    {
        Qcopy = Q->coeffs;
        Qalloc = 0;
    }
    else
    {
        slong i;
        Qcopy = (fmpz *) flint_malloc(n * sizeof(fmpz));
        for (i = 0; i < Qlen; i++)
            Qcopy[i] = Q->coeffs[i];
        for ( ; i < n; i++)
            Qcopy[i] = 0;
        Qalloc = 1;
    }

    if (Qinv != Q)
    {
        fmpz_poly_fit_length(Qinv, n);
        _fmpz_poly_revert_series_lagrange(Qinv->coeffs, Qcopy, n);
    }
    else
    {
        fmpz_poly_t t;
        fmpz_poly_init2(t, n);
        _fmpz_poly_revert_series_lagrange(t->coeffs, Qcopy, n);
        fmpz_poly_swap(Qinv, t);
        fmpz_poly_clear(t);
    }
    
    _fmpz_poly_set_length(Qinv, n);
    _fmpz_poly_normalise(Qinv);

    if (Qalloc)
        flint_free(Qcopy);
}
예제 #20
0
파일: sub.c 프로젝트: clear731/lattice
void
fmpz_poly_sub(fmpz_poly_t res, const fmpz_poly_t poly1,
              const fmpz_poly_t poly2)
{
    slong max = FLINT_MAX(poly1->length, poly2->length);

    fmpz_poly_fit_length(res, max);

    _fmpz_poly_sub(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs,
                   poly2->length);

    _fmpz_poly_set_length(res, max);
    _fmpz_poly_normalise(res);  /* there may have been cancellation */
}
예제 #21
0
void
fmpz_poly_scalar_mul_2exp(fmpz_poly_t poly1, const fmpz_poly_t poly2,
                        ulong exp)
{
    if (poly2->length == 0)
    {
        fmpz_poly_zero(poly1);
        return;
    }

    fmpz_poly_fit_length(poly1, poly2->length);
    _fmpz_vec_scalar_mul_2exp(poly1->coeffs, poly2->coeffs, poly2->length, exp);
    _fmpz_poly_set_length(poly1, poly2->length);
}
예제 #22
0
파일: sub.c 프로젝트: clear731/lattice
void
fq_sub(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx)
{
    slong max = FLINT_MAX(op1->length, op2->length);

    fmpz_poly_fit_length(rop, max);

    _fmpz_mod_poly_sub(rop->coeffs,
                       op1->coeffs, op1->length, op2->coeffs, op2->length,
                       fq_ctx_prime(ctx));

    _fmpz_poly_set_length(rop, max);
    _fmpz_poly_normalise(rop);
}
예제 #23
0
파일: set_coeff_si.c 프로젝트: goens/flint2
void
fmpz_poly_set_coeff_si(fmpz_poly_t poly, long n, long x)
{
    fmpz_poly_fit_length(poly, n + 1);

    if (n + 1 > poly->length)   /* insert zeroes between end of poly and new coeff if needed */
    {
        mpn_zero((mp_ptr) (poly->coeffs + poly->length), n - poly->length);
        poly->length = n + 1;
    }

    fmpz_set_si(poly->coeffs + n, x);
    _fmpz_poly_normalise(poly); /* we may have set leading coefficient to zero */
}
예제 #24
0
void
fmpz_poly_scalar_mul_fmpz(fmpz_poly_t poly1, const fmpz_poly_t poly2,
                          const fmpz_t x)
{
    /* Either scalar or input poly is zero */
    if ((*x == 0) || (poly2->length == 0))
    {
        fmpz_poly_zero(poly1);
        return;
    }

    fmpz_poly_fit_length(poly1, poly2->length);
    _fmpz_vec_scalar_mul_fmpz(poly1->coeffs, poly2->coeffs, poly2->length, x);
    _fmpz_poly_set_length(poly1, poly2->length);
}
예제 #25
0
void
arith_cos_minpoly(fmpz_poly_t poly, ulong n)
{
    if (n == 0)
    {
        fmpz_poly_set_ui(poly, UWORD(1));
    }
    else
    {
        slong d = (n <= 2) ? 1 : n_euler_phi(n) / 2;

        fmpz_poly_fit_length(poly, d + 1);
        _arith_cos_minpoly(poly->coeffs, d, n);
        _fmpz_poly_set_length(poly, d + 1);
    }
}
예제 #26
0
static
void fmpz_poly_compose_pow(fmpz_poly_t rop, const fmpz_poly_t op, long k)
{
    const long len  = op->length;
    const long lenr = (len - 1) * k + 1;

    if (len == 0)
    {
        fmpz_poly_zero(rop);
    }
    else
    {
        fmpz_poly_fit_length(rop, lenr);
        _fmpz_poly_compose_pow(rop->coeffs, op->coeffs, len, k);
        _fmpz_poly_set_length(rop, lenr);
    }
}
예제 #27
0
void
fmpz_poly_scalar_divexact_fmpz(fmpz_poly_t poly1, const fmpz_poly_t poly2,
                               const fmpz_t x)
{
    if (fmpz_is_zero(x))
    {
        printf("Exception: division by zero in fmpz_poly_scalar_divexact_fmpz\n");
        abort();
    }

    if (poly2->length == 0)
    {
        fmpz_poly_zero(poly1);
        return;
    }

    fmpz_poly_fit_length(poly1, poly2->length);
    _fmpz_vec_scalar_divexact_fmpz(poly1->coeffs, poly2->coeffs, poly2->length, x);
    _fmpz_poly_set_length(poly1, poly2->length);
}
예제 #28
0
void
fmpz_poly_scalar_fdiv_ui(fmpz_poly_t poly1, const fmpz_poly_t poly2,
                         ulong x)
{
    if (x == 0)
    {
        flint_printf("Exception (fmpz_poly_scalar_fdiv_ui). Division by zero.\n");
        abort();
    }

    if (poly2->length == 0)
    {
        fmpz_poly_zero(poly1);
        return;
    }

    fmpz_poly_fit_length(poly1, poly2->length);
    _fmpz_vec_scalar_fdiv_q_ui(poly1->coeffs, poly2->coeffs, poly2->length, x);
    _fmpz_poly_set_length(poly1, poly2->length);
}
예제 #29
0
파일: pow_binomial.c 프로젝트: goens/flint2
void
fmpz_poly_pow_binomial(fmpz_poly_t res, const fmpz_poly_t poly, ulong e)
{
    const long len = poly->length;
    long rlen;

    if (len != 2)
    {
        printf("Exception: poly->length not equal to 2 in fmpz_poly_pow_binomial\n");
        abort();
    }

    if (e < 3UL)
    {
        if (e == 0UL)
            fmpz_poly_set_ui(res, 1UL);
        else if (e == 1UL)
            fmpz_poly_set(res, poly);
        else  /* e == 2UL */
            fmpz_poly_sqr(res, poly);
        return;
    }
    
    rlen = (long) e + 1;

    if (res != poly)
    {
        fmpz_poly_fit_length(res, rlen);
        _fmpz_poly_set_length(res, rlen);
        _fmpz_poly_pow_binomial(res->coeffs, poly->coeffs, e);
    }
    else
    {
        fmpz_poly_t t;
        fmpz_poly_init2(t, rlen);
        _fmpz_poly_set_length(t, rlen);
        _fmpz_poly_pow_binomial(t->coeffs, poly->coeffs, e);
        fmpz_poly_swap(res, t);
        fmpz_poly_clear(t);
    }
}
예제 #30
0
void
fmpz_poly_compose_divconquer(fmpz_poly_t res, 
                             const fmpz_poly_t poly1, const fmpz_poly_t poly2)
{
    const long len1 = poly1->length;
    const long len2 = poly2->length;
    long lenr;
    
    if (len1 == 0)
    {
        fmpz_poly_zero(res);
        return;
    }
    if (len1 == 1 || len2 == 0)
    {
        fmpz_poly_set_fmpz(res, poly1->coeffs);
        return;
    }
    
    lenr = (len1 - 1) * (len2 - 1) + 1;
    
    if (res != poly1 && res != poly2)
    {
        fmpz_poly_fit_length(res, lenr);
        _fmpz_poly_compose_divconquer(res->coeffs, poly1->coeffs, len1, 
                                                   poly2->coeffs, len2);
        _fmpz_poly_set_length(res, lenr);
        _fmpz_poly_normalise(res);
    }
    else
    {
        fmpz_poly_t t;
        fmpz_poly_init2(t, lenr);
        _fmpz_poly_compose_divconquer(t->coeffs, poly1->coeffs, len1,
                                                 poly2->coeffs, len2);
        _fmpz_poly_set_length(t, lenr);
        _fmpz_poly_normalise(t);
        fmpz_poly_swap(res, t);
        fmpz_poly_clear(t);
    }
}