Пример #1
0
void
fmpq_poly_compose(fmpq_poly_t res, 
                              const fmpq_poly_t poly1, const fmpq_poly_t poly2)
{
    const long len1 = poly1->length;
    const long len2 = poly2->length;
    long lenr;
    
    if (len1 == 0L)
    {
        fmpq_poly_zero(res);
        return;
    }
    if (len1 == 1L || len2 == 0L)
    {
        fmpq_poly_fit_length(res, 1);
        fmpz_set(res->coeffs, poly1->coeffs);
        fmpz_set(res->den, poly1->den);
        {
            fmpz_t d;
            fmpz_init(d);
            fmpz_gcd(d, res->coeffs, res->den);
            if (*d != 1L)
            {
                fmpz_divexact(res->coeffs, res->coeffs, d);
                fmpz_divexact(res->den, res->den, d);
            }
            fmpz_clear(d);
        }
        _fmpq_poly_set_length(res, 1);
        _fmpq_poly_normalise(res);
        return;
    }
    
    lenr = (len1 - 1L) * (len2 - 1L) + 1L;
    
    if ((res != poly1) && (res != poly2))
    {
        fmpq_poly_fit_length(res, lenr);
        _fmpq_poly_compose(res->coeffs, res->den, 
                           poly1->coeffs, poly1->den, len1, 
                           poly2->coeffs, poly2->den, len2);
        _fmpq_poly_set_length(res, lenr);
        _fmpq_poly_normalise(res);
    }
    else
    {
        fmpq_poly_t t;
        fmpq_poly_init2(t, lenr);
        _fmpq_poly_compose(t->coeffs, t->den, 
                           poly1->coeffs, poly1->den, len1,
                           poly2->coeffs, poly2->den, len2);
        _fmpq_poly_set_length(t, lenr);
        _fmpq_poly_normalise(t);
        fmpq_poly_swap(res, t);
        fmpq_poly_clear(t);
    }
}
Пример #2
0
int
fmpq_poly_set_str(fmpq_poly_t poly, const char * str)
{
    int ans;
    long len;

    len = atol(str);
    if (len < 0)
        return -1;
    if (len == 0)
    {
        fmpq_poly_zero(poly);
        return 0;
    }

    fmpq_poly_fit_length(poly, len);
    
    ans = _fmpq_poly_set_str(poly->coeffs, poly->den, str);
    
    if (ans == 0)
    {
        _fmpq_poly_set_length(poly, len);
        _fmpq_poly_normalise(poly);
    }
    else
    {
        _fmpz_vec_zero(poly->coeffs, len);
        fmpz_set_ui(poly->den, 1);
        _fmpq_poly_set_length(poly, 0);
    }
    
    return ans;
}
Пример #3
0
void fmpq_poly_set_coeff_mpz(fmpq_poly_t poly, long n, const mpz_t x)
{
    long len = poly->length;
    const int replace = (n < len && !fmpz_is_zero(poly->coeffs + n));
    
    if (!replace && mpz_sgn(x) == 0)
        return;
    
    if (n + 1 > len)
    {
        fmpq_poly_fit_length(poly, n + 1);
        _fmpq_poly_set_length(poly, n + 1);
        mpn_zero((mp_ptr) poly->coeffs + len, (n + 1) - len);
    }
    
    if (*poly->den == 1L)
    {
        fmpz_set_mpz(poly->coeffs + n, x);
        if (replace)
            _fmpq_poly_normalise(poly);
    }
    else
    {
        fmpz_set_mpz(poly->coeffs + n, x);
        fmpz_mul(poly->coeffs + n, poly->coeffs + n, poly->den);
        if (replace)
            fmpq_poly_canonicalise(poly);
    }
}
Пример #4
0
void fmpq_poly_exp_series(fmpq_poly_t res, const fmpq_poly_t poly, long n)
{
    fmpz *copy;
    int alloc;

    if (poly->length == 0)
    {
        fmpq_poly_set_ui(res, 1UL);
        return;
    }

    if (!fmpz_is_zero(poly->coeffs))
    {
        printf("Exception: fmpq_poly_exp_series: constant term != 0");
        abort();
    }

    if (n < 2)
    {
        if (n == 0) fmpq_poly_zero(res);
        if (n == 1) fmpq_poly_set_ui(res, 1UL);
        return;
    }

    if (poly->length >= n)
    {
        copy = poly->coeffs;
        alloc = 0;
    }
    else
    {
        long i;
        copy = (fmpz *) flint_malloc(n * sizeof(fmpz));
        for (i = 0; i < poly->length; i++)
            copy[i] = poly->coeffs[i];
        for ( ; i < n; i++)
            copy[i] = 0;
        alloc = 1;
    }

    if (res != poly)
    {
        fmpq_poly_fit_length(res, n);
        _fmpq_poly_exp_series(res->coeffs, res->den, copy, poly->den, n);
    }
    else
    {
        fmpq_poly_t t;
        fmpq_poly_init2(t, n);
        _fmpq_poly_exp_series(t->coeffs, t->den, copy, poly->den, n);
        fmpq_poly_swap(res, t);
        fmpq_poly_clear(t);
    }

    _fmpq_poly_set_length(res, n);
    _fmpq_poly_normalise(res);

    if (alloc)
        flint_free(copy);
}
Пример #5
0
void
fmpq_poly_revert_series(fmpq_poly_t res,
            const fmpq_poly_t poly, long n)
{
    fmpz *copy;
    int alloc;

    if (poly->length < 2 || !fmpz_is_zero(poly->coeffs)
                         || fmpz_is_zero(poly->coeffs + 1))
    {
        printf("exception: fmpq_poly_revert_series: input must have "
            "zero constant term and nonzero coefficient of x^1");
        abort();
    }

    if (n < 2)
    {
        fmpq_poly_zero(res);
        return;
    }

    if (poly->length >= n)
    {
        copy = poly->coeffs;
        alloc = 0;
    }
    else
    {
        long i;
        copy = (fmpz *) flint_malloc(n * sizeof(fmpz));
        for (i = 0; i < poly->length; i++)
            copy[i] = poly->coeffs[i];
        for ( ; i < n; i++)
            copy[i] = 0;
        alloc = 1;
    }

    if (res != poly)
    {
        fmpq_poly_fit_length(res, n);
        _fmpq_poly_revert_series(res->coeffs,
                res->den, copy, poly->den, n);
    }
    else
    {
        fmpq_poly_t t;
        fmpq_poly_init2(t, n);
        _fmpq_poly_revert_series(t->coeffs,
                t->den, copy, poly->den, n);
        fmpq_poly_swap(res, t);
        fmpq_poly_clear(t);
    }

    _fmpq_poly_set_length(res, n);
    _fmpq_poly_normalise(res);

    if (alloc)
        flint_free(copy);
}
Пример #6
0
void fmpq_poly_set_ui(fmpq_poly_t poly, ulong x)
{
    fmpq_poly_fit_length(poly, 1);
    fmpz_set_ui(poly->coeffs, x);
    fmpz_one(poly->den);
    _fmpq_poly_set_length(poly, 1);
    _fmpq_poly_normalise(poly);
}
Пример #7
0
/* hack: avoid overflow since exp currently uses mpfr */
void
fmpq_poly_randtest_small(fmpq_poly_t A, flint_rand_t state, long len, long bits)
{
    fmpq_poly_randtest(A, state, len, bits);
    if (A->length > 0)
    {
        bits = _fmpz_vec_max_bits(A->coeffs, A->length);
        bits = FLINT_ABS(bits);
        fmpz_mul_2exp(A->den, A->den, bits);
        _fmpq_poly_normalise(A);
    }
}
Пример #8
0
void fmpq_poly_set_array_mpq(fmpq_poly_t poly, const mpq_t * a, long n)
{
    if (n == 0)
        fmpq_poly_zero(poly);
    else
    {
        fmpq_poly_fit_length(poly, n);
        _fmpq_poly_set_array_mpq(poly->coeffs, poly->den, a, n);
        _fmpq_poly_set_length(poly, n);
        _fmpq_poly_normalise(poly);
    }
}
Пример #9
0
void random_fmpq_poly(fmpq_poly_t pol, flint_rand_t state, slong length)
{
   fmpz * arr;
   slong i;

   fmpq_poly_fit_length(pol, length);

   arr = fmpq_poly_numref(pol);

   for (i = 0; i < length; i++)
      fmpz_randbits(arr + i, state, BITS);

   fmpz_randbits(fmpq_poly_denref(pol), state, BITS);

   _fmpq_poly_set_length(pol, length);
   _fmpq_poly_normalise(pol);
   fmpq_poly_canonicalise(pol);
}
Пример #10
0
void
fmpq_poly_log_series(fmpq_poly_t res, const fmpq_poly_t f, long n)
{
    fmpz * f_coeffs;
    long flen = f->length;

    if (flen < 1 || !fmpz_equal(f->coeffs, f->den))
    {
        printf("Exception: fmpq_poly_log_series: constant term != 1\n");
        abort();
    }

    if (flen == 1 || n < 2)
    {
        fmpq_poly_zero(res);
        return;
    }

    fmpq_poly_fit_length(res, n);

    if (flen < n)
    {
        f_coeffs = _fmpz_vec_init(n);
        _fmpz_vec_set(f_coeffs, f->coeffs, flen);
    }
    else
    {
        f_coeffs = f->coeffs;
    }

    _fmpq_poly_log_series(res->coeffs, res->den, f_coeffs, f->den, n);

    if (flen < n)
    {
        _fmpz_vec_clear(f_coeffs, n);
    }

    _fmpq_poly_set_length(res, n);
    _fmpq_poly_normalise(res);
}
Пример #11
0
void fmpq_poly_randtest_unsigned(fmpq_poly_t poly, flint_rand_t state,
                                 long len, mp_bitcnt_t bits)
{
    ulong m;

    m = n_randlimb(NULL);

    fmpq_poly_fit_length(poly, len);
    _fmpq_poly_set_length(poly, len);

    if (m & 1UL)
    {
        _fmpz_vec_randtest_unsigned(poly->coeffs, state, len, bits);
    }
    else
    {
        fmpz_t x;

        fmpz_init(x);
        fmpz_randtest_unsigned(x, state, bits / 2);
        _fmpz_vec_randtest_unsigned(poly->coeffs, state, len, (bits + 1) / 2);
        _fmpz_vec_scalar_mul_fmpz(poly->coeffs, poly->coeffs, len, x);
        fmpz_clear(x);
    }

    if (m & 2UL)
    {
        fmpz_randtest_not_zero(poly->den, state, FLINT_MAX(bits, 1));
        fmpz_abs(poly->den, poly->den);
        fmpq_poly_canonicalise(poly);
    }
    else
    {
        fmpz_set_ui(poly->den, 1);
        _fmpq_poly_normalise(poly);
    }
}
Пример #12
0
void
fmpq_poly_compose_series_horner(fmpq_poly_t res, 
                    const fmpq_poly_t poly1, const fmpq_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: fmpq_poly_compose_series_horner: inner polynomial "
                "must have zero constant term\n");
        abort();
    }

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

    if (len2 == 0 || len1 == 1)
    {
        fmpq_poly_fit_length(res, 1);
        fmpz_set(res->coeffs, poly1->coeffs);
        fmpz_set(res->den, poly1->den);
        {
            fmpz_t d;
            fmpz_init(d);
            fmpz_gcd(d, res->coeffs, res->den);
            if (!fmpz_is_one(d))
            {
                fmpz_divexact(res->coeffs, res->coeffs, d);
                fmpz_divexact(res->den, res->den, d);
            }
            fmpz_clear(d);
        }
        _fmpq_poly_set_length(res, 1);
        _fmpq_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))
    {
        fmpq_poly_fit_length(res, lenr);
        _fmpq_poly_compose_series_horner(res->coeffs, res->den, 
                           poly1->coeffs, poly1->den, len1, 
                           poly2->coeffs, poly2->den, len2, lenr);
        _fmpq_poly_set_length(res, lenr);
        _fmpq_poly_normalise(res);
    }
    else
    {
        fmpq_poly_t t;
        fmpq_poly_init2(t, lenr);
        _fmpq_poly_compose_series_horner(t->coeffs, t->den, 
                           poly1->coeffs, poly1->den, len1,
                           poly2->coeffs, poly2->den, len2, lenr);
        _fmpq_poly_set_length(t, lenr);
        _fmpq_poly_normalise(t);
        fmpq_poly_swap(res, t);
        fmpq_poly_clear(t);
    }
}
Пример #13
0
void fmpq_poly_canonicalise(fmpq_poly_t poly)
{
    _fmpq_poly_normalise(poly);
    _fmpq_poly_canonicalise(poly->coeffs, poly->den, poly->length);
}
Пример #14
0
void fmpq_poly_divrem(fmpq_poly_t Q, fmpq_poly_t R, 
                      const fmpq_poly_t poly1, const fmpq_poly_t poly2)
{
    slong lenA, lenB, lenQ, lenR;

    if (fmpq_poly_is_zero(poly2))
    {
        flint_printf("Exception (fmpq_poly_divrem). Division by zero.\n");
        abort();
    }
    if (Q == R)
    {
        flint_printf("Exception (fmpq_poly_divrem). Output arguments aliased.\n");
        abort();
    }
    
    /* Deal with the various other cases of aliasing. */
    if (R == poly1 || R == poly2)
    {
        if (Q == poly1 || Q == poly2)
        {
            fmpq_poly_t tempQ, tempR;
            fmpq_poly_init(tempQ);
            fmpq_poly_init(tempR);
            fmpq_poly_divrem(tempQ, tempR, poly1, poly2);
            fmpq_poly_swap(Q, tempQ);
            fmpq_poly_swap(R, tempR);
            fmpq_poly_clear(tempQ);
            fmpq_poly_clear(tempR);
            return;
        }
        else
        {
            fmpq_poly_t tempR;
            fmpq_poly_init(tempR);
            fmpq_poly_divrem(Q, tempR, poly1, poly2);
            fmpq_poly_swap(R, tempR);
            fmpq_poly_clear(tempR);
            return;
        }
    }
    else
    {
        if (Q == poly1 || Q == poly2)
        {
            fmpq_poly_t tempQ;
            fmpq_poly_init(tempQ);
            fmpq_poly_divrem(tempQ, R, poly1, poly2);
            fmpq_poly_swap(Q, tempQ);
            fmpq_poly_clear(tempQ);
            return;
        }
    }
    
    if (poly1->length < poly2->length)
    {
        fmpq_poly_set(R, poly1);
        fmpq_poly_zero(Q);
        return;
    }
    
    lenA = poly1->length;
    lenB = poly2->length;
    lenQ = lenA - lenB + 1;
    lenR = lenB - 1;
    
    fmpq_poly_fit_length(Q, lenQ);
    fmpq_poly_fit_length(R, lenA);  /* XXX: Need at least that much space */
    
    _fmpq_poly_divrem(Q->coeffs, Q->den, R->coeffs, R->den, 
                      poly1->coeffs, poly1->den, poly1->length, 
                      poly2->coeffs, poly2->den, poly2->length, NULL);
    
    _fmpq_poly_set_length(Q, lenQ);
    _fmpq_poly_set_length(R, lenR);
    _fmpq_poly_normalise(R);
}