示例#1
0
void
_fmpz_poly_revert_series_lagrange(fmpz * Qinv, const fmpz * Q, slong n)
{
    slong i;
    fmpz *R, *S, *T, *tmp;

    if (n <= 2)
    {
        _fmpz_vec_set(Qinv, Q, n);
        return;
    }

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

    fmpz_zero(Qinv);
    fmpz_set(Qinv + 1, Q + 1);

    _fmpz_poly_inv_series(R, Q + 1, n - 1);
    _fmpz_vec_set(S, R, n - 1);

    for (i = 2; i < n; i++)
    {
        _fmpz_poly_mullow(T, S, n - 1, R, n - 1, n - 1);
        fmpz_divexact_ui(Qinv + i, T + i - 1, i);
        tmp = S; S = T; T = tmp;
    }

    _fmpz_vec_clear(R, n - 1);
    _fmpz_vec_clear(S, n - 1);
    _fmpz_vec_clear(T, n - 1);
}
示例#2
0
int
fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den,
                            const fmpz_mat_t A, const fmpz_mat_t B)
{
    long i, dim = fmpz_mat_nrows(A);

    if (dim == 0)
    {
        fmpz_one(den);
        return 1;
    }
    else if (dim == 1)
    {
        fmpz_set(den, fmpz_mat_entry(A, 0, 0));

        if (fmpz_is_zero(den))
            return 0;

        if (!fmpz_mat_is_empty(B))
            _fmpz_vec_set(X->rows[0], B->rows[0], fmpz_mat_ncols(B));
        return 1;
    }
    else if (dim == 2)
    {
        fmpz_t t, u;

        _fmpz_mat_det_cofactor_2x2(den, A->rows);

        if (fmpz_is_zero(den))
            return 0;

        fmpz_init(t);
        fmpz_init(u);

        for (i = 0; i < fmpz_mat_ncols(B); i++)
        {
            fmpz_mul   (t, fmpz_mat_entry(A, 1, 1), fmpz_mat_entry(B, 0, i));
            fmpz_submul(t, fmpz_mat_entry(A, 0, 1), fmpz_mat_entry(B, 1, i));
            fmpz_mul   (u, fmpz_mat_entry(A, 0, 0), fmpz_mat_entry(B, 1, i));
            fmpz_submul(u, fmpz_mat_entry(A, 1, 0), fmpz_mat_entry(B, 0, i));

            fmpz_swap(fmpz_mat_entry(X, 0, i), t);
            fmpz_swap(fmpz_mat_entry(X, 1, i), u);
        }

        fmpz_clear(t);
        fmpz_clear(u);

        return 1;
    }
    else if (dim == 3)
    {
        return _fmpz_mat_solve_cramer_3x3(X, den, A, B);
    }
    else
    {
        printf("Exception: fmpz_mat_solve_cramer: dim > 3 not implemented");
        abort();
    }
}
示例#3
0
文件: get_slice.c 项目: goens/flint2
void fmpq_poly_get_slice(fmpq_poly_t rop, const fmpq_poly_t op, long i, long j)
{
    i = FLINT_MAX(i, 0);
    j = FLINT_MIN(j, op->length);

    if (i < j)
    {
        long k;

        if (rop == op)
        {
            for (k = 0; k < i; k++)
                fmpz_zero(rop->coeffs + k);
            for (k = j; k < rop->length; k++)
                fmpz_zero(rop->coeffs + k);
            fmpq_poly_canonicalise(rop);
        }
        else
        {
            fmpq_poly_fit_length(rop, j);
            _fmpq_poly_set_length(rop, j);

            _fmpz_vec_set(rop->coeffs + i, op->coeffs + i, j - i);
            fmpz_set(rop->den, op->den);
            fmpq_poly_canonicalise(rop);
        }
    }
    else
    {
        fmpq_poly_zero(rop);
    }
}
示例#4
0
文件: radix.c 项目: goens/flint2
void _fmpz_mod_poly_radix(fmpz **B, const fmpz *F, fmpz **Rpow, fmpz **Rinv, 
                          long degR, long k, long i, fmpz *W, const fmpz_t p)
{
    if (i == -1)
    {
        _fmpz_vec_set(B[k], F, degR);
    }
    else
    {
        const long lenQ = (1L << i) * degR;

        fmpz *Frev = W;
        fmpz *Q    = W + lenQ;
        fmpz *S    = W;

        _fmpz_poly_reverse(Frev, F + lenQ, lenQ, lenQ);
        _fmpz_mod_poly_mullow(Q, Frev, lenQ, Rinv[i], lenQ, p, lenQ);
        _fmpz_poly_reverse(Q, Q, lenQ, lenQ);

        _fmpz_mod_poly_radix(B, Q, Rpow, Rinv, degR, k + (1L << i), i-1, W, p);

        _fmpz_mod_poly_mullow(S, Rpow[i], lenQ, Q, lenQ, p, lenQ);
        _fmpz_mod_poly_sub(S, F, lenQ, S, lenQ, p);

        _fmpz_mod_poly_radix(B, S, Rpow, Rinv, degR, k, i-1, W + lenQ, p);
    }
}
示例#5
0
static
void _fmpz_poly_compose_pow(fmpz *rop, const fmpz *op, long len, long k)
{
    if (k == 1)
    {
        if (rop != op)
        {
            _fmpz_vec_set(rop, op, len);
        }
    }
    else if (len == 1)
    {
        fmpz_set(rop, op);
    }
    else
    {
        long i, j, h;

        for (i = len - 1, j = (len - 1) * k ; i >= 0; i--, j -= k)
        {
            fmpz_set(rop + j, op + i);
            if (i != 0)
                for (h = 1; h < k; h++)
                    fmpz_zero(rop + (j - h));
        }
    }
}
示例#6
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;
}
示例#7
0
void _fmpq_poly_scalar_div_ui(fmpz * rpoly, fmpz_t rden, const fmpz * poly, 
                              const fmpz_t den, long len, ulong c)
{
    if (c == 1UL)
    {
        if (rpoly != poly)
            _fmpz_vec_set(rpoly, poly, len);
        fmpz_set(rden, den);
    }
    else
    {
        fmpz_t d, fc;
        ulong ud;
        fmpz_init(d);
        fmpz_init(fc);
        _fmpz_vec_content(d, poly, len);
        fmpz_set_ui(fc, c);
        fmpz_gcd(d, d, fc);
        ud = fmpz_get_ui(d);  /* gcd of d and c fits into a ulong */
        
        _fmpz_vec_scalar_divexact_ui(rpoly, poly, len, ud);
        fmpz_mul_ui(rden, den, c / ud);
        
        fmpz_clear(d);
        fmpz_clear(fc);
    }
}
示例#8
0
void
_fmpz_poly_pseudo_divrem_cohen(fmpz * Q, fmpz * R, const fmpz * A, 
                               long lenA, const fmpz * B, long lenB)
{
    const fmpz * leadB = B + (lenB - 1);
    long e, lenQ;
    fmpz_t pow;
    
    if (lenB == 1)
    {
        fmpz_init(pow);
        fmpz_pow_ui(pow, leadB, lenA - 1);
        _fmpz_vec_scalar_mul_fmpz(Q, A, lenA, pow);
        _fmpz_vec_zero(R, lenA);
        fmpz_clear(pow);
        return;
    }

    lenQ = lenA - lenB + 1;
    _fmpz_vec_zero(Q, lenQ);
    if (R != A)
        _fmpz_vec_set(R, A, lenA);
    e = lenA - lenB;
    
    /* Unroll the first run of the while loop */
    {
        fmpz_set(Q + (lenQ - 1), R + (lenA - 1));

        _fmpz_vec_scalar_mul_fmpz(R, R, lenA - 1, leadB);
        _fmpz_vec_scalar_submul_fmpz(R + (lenA - lenB), B, lenB - 1, R + (lenA - 1));
        fmpz_zero(R + (lenA - 1));

        for (lenA -= 2; (lenA >= 0) && (R[lenA] == 0L); lenA--) ;
        lenA++;
    }
    while (lenA >= lenB)
    {
        _fmpz_vec_scalar_mul_fmpz(Q, Q, lenQ, leadB);
        fmpz_add(Q + (lenA - lenB), Q + (lenA - lenB), R + (lenA - 1));

        _fmpz_vec_scalar_mul_fmpz(R, R, lenA - 1, leadB);
        _fmpz_vec_scalar_submul_fmpz(R + lenA - lenB, B, lenB - 1, R + (lenA - 1));
        fmpz_zero(R + (lenA - 1));

        for (lenA -= 2; (lenA >= 0) && (R[lenA] == 0L); lenA--) ;
        lenA++;

        e--;
    }

    fmpz_init(pow);
    fmpz_pow_ui(pow, leadB, e);
    _fmpz_vec_scalar_mul_fmpz(Q, Q, lenQ, pow);
    _fmpz_vec_scalar_mul_fmpz(R, R, lenA, pow);
    fmpz_clear(pow);
}
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);

    flint_printf("scalar_submul_si_2exp....");
    fflush(stdout);

    

    /* Compare with alternative method of computation */
    for (i = 0; i < 1000 * flint_test_multiplier(); i++)
    {
        fmpz *a, *b, *c, *d;
        slong len = n_randint(state, 100), x;
        mp_bitcnt_t exp;

        a = _fmpz_vec_init(len);
        b = _fmpz_vec_init(len);
        c = _fmpz_vec_init(len);
        d = _fmpz_vec_init(len);

        _fmpz_vec_randtest(a, state, len, 200);
        _fmpz_vec_randtest(b, state, len, 200);
        _fmpz_vec_set(c, b, len);

        x = z_randtest(state);
        exp = n_randint(state, 200);

        _fmpz_vec_scalar_submul_si_2exp(b, a, len, x, exp);
        _fmpz_vec_scalar_mul_2exp(d, a, len, exp);
        _fmpz_vec_scalar_submul_si(c, d, len, x);

        result = (_fmpz_vec_equal(b, c, len));
        if (!result)
        {
            flint_printf("FAIL:\n");
            flint_printf("x = %wd, exp = %wu\n", x, exp);
            _fmpz_vec_print(b, len), flint_printf("\n\n");
            _fmpz_vec_print(c, len), flint_printf("\n\n");
            abort();
        }

        _fmpz_vec_clear(a, len);
        _fmpz_vec_clear(b, len);
        _fmpz_vec_clear(c, len);
        _fmpz_vec_clear(d, len);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}
示例#10
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);
    }
}
示例#11
0
void _fmpz_poly_divrem_divconquer(fmpz *Q, fmpz *R, 
                                  const fmpz *A, long lenA, 
                                  const fmpz *B, long lenB)
{
    if (lenA <= 2 * lenB - 1)
    {
        __fmpz_poly_divrem_divconquer(Q, R, A, lenA, B, lenB);
    }
    else  /* lenA > 2 * lenB - 1 */
    {
        fmpz *S, *T;

        S = _fmpz_vec_init(2 * lenA + 2 * (2 * lenB - 1));
        T = S + lenA;
        _fmpz_vec_set(S, A, lenA);

        __fmpz_poly_divrem_divconquer(Q, T, S, lenA, B, lenB);

        _fmpz_vec_set(R, T, lenA);
        _fmpz_vec_clear(S, 2 * lenA + 2 * (2 * lenB - 1));
    }
}
示例#12
0
void _fmpq_poly_scalar_div_si(fmpz * rpoly, fmpz_t rden, const fmpz * poly,
                              const fmpz_t den, long len, long c)
{
    if (c == 1)
    {
        if (rpoly != poly)
        {
            _fmpz_vec_set(rpoly, poly, len);
            fmpz_set(rden, den);
        }
    }
    else if (c == -1)
    {
        _fmpz_vec_neg(rpoly, poly, len);
        fmpz_set(rden, den);
    }
    else
    {
        fmpz_t d, f;

        fmpz_init(d);
        fmpz_init(f);
        
        fmpz_set_si(f, c);
        _fmpz_vec_content(d, poly, len);
        fmpz_gcd(d, d, f);

        if (c > 0)
        {
            _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d);
            fmpz_mul_si(rden, den, c / fmpz_get_si(d));
        }
        else
        {
            ulong q = (- (ulong) c) / fmpz_get_ui(d);

            fmpz_neg(d, d);
            _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d);
            fmpz_mul_ui(rden, den, q);
        }

        fmpz_clear(d);
        fmpz_clear(f);
    }
}
示例#13
0
slong renf_set_embeddings_fmpz_poly(renf * nf, fmpz_poly_t pol, slong lim, slong prec)
{
    slong i, n, n_exact, n_interval;
    fmpq_poly_t p2;
    arb_t a;
    fmpz * c;
    slong * k;

    n = fmpz_poly_num_real_roots_upper_bound(pol);
    c = _fmpz_vec_init(n);
    k = (slong *) flint_malloc(n * sizeof(slong));

    fmpz_poly_isolate_real_roots(NULL, &n_exact, c, k, &n_interval, pol);

    if (n_exact)
    {
        fprintf(stderr, "ERROR (fmpz_poly_real_embeddings): rational roots\n");
        abort();
    }

    arb_init(a);
    fmpq_poly_init(p2);
    fmpz_one(fmpq_poly_denref(p2));
    fmpq_poly_fit_length(p2, pol->length);
    _fmpz_vec_set(p2->coeffs, pol->coeffs, pol->length);
    p2->length = pol->length;
    for (i = 0; i < FLINT_MIN(lim, n_interval); i++)
    {
        arb_set_fmpz(a, c + i);
        arb_mul_2exp_si(a, a, 1);
        arb_add_si(a, a, 1, prec);
        mag_one(arb_radref(a));
        arb_mul_2exp_si(a, a, k[i] - 1);

        renf_init(nf + i, p2, a, prec);

    }

    arb_clear(a);
    fmpq_poly_clear(p2);
    _fmpz_vec_clear(c, n);
    flint_free(k);

    return n_interval;
}
示例#14
0
void
_fmpz_poly_revert_series_newton(fmpz * Qinv, const fmpz * Q, long n)
{
    if (n <= 2)
    {
        _fmpz_vec_set(Qinv, Q, n);
        return;
    }
    else
    {
        long *a, i, k;
        fmpz *T, *U, *V;

        T = _fmpz_vec_init(n);
        U = _fmpz_vec_init(n);
        V = _fmpz_vec_init(n);

        k = n;
        for (i = 1; (1L << i) < k; i++);
        a = (long *) flint_malloc(i * sizeof(long));
        a[i = 0] = k;
        while (k >= FLINT_REVERSE_NEWTON_CUTOFF)
            a[++i] = (k = (k + 1) / 2);

        _fmpz_poly_revert_series_lagrange(Qinv, Q, k);
        _fmpz_vec_zero(Qinv + k, n - k);

        for (i--; i >= 0; i--)
        {
            k = a[i];
            _fmpz_poly_compose_series(T, Q, k, Qinv, k, k);
            _fmpz_poly_derivative(U, T, k); fmpz_zero(U + k - 1);
            fmpz_zero(T + 1);
            _fmpz_poly_div_series(V, T, U, k);
            _fmpz_poly_derivative(T, Qinv, k);
            _fmpz_poly_mullow(U, V, k, T, k, k);
            _fmpz_vec_sub(Qinv, Qinv, U, k);
        }

        flint_free(a);
        _fmpz_vec_clear(T, n);
        _fmpz_vec_clear(U, n);
        _fmpz_vec_clear(V, n);
    }
}
示例#15
0
文件: radix.c 项目: goens/flint2
void _fmpz_mod_poly_radix_init(fmpz **Rpow, fmpz **Rinv, 
                    const fmpz *R, long lenR, long k, 
                    const fmpz_t invL, const fmpz_t p)
{
    const long degR = lenR - 1;
    long i;
    fmpz_t invLP;
    fmpz *W;

    fmpz_init_set(invLP, invL);
    W = flint_malloc((1L << (k - 1)) * degR * sizeof(fmpz));

    _fmpz_vec_set(Rpow[0], R, lenR);
    for (i = 1; i < k; i++)
    {
        _fmpz_mod_poly_sqr(Rpow[i], Rpow[i - 1], degR * (1L << (i - 1)) + 1, p);
    }

    for (i = 0; i < k; i++)
    {
        const long lenQ = (1L << i) * degR;
        long j;

        /* W := rev{Rpow[i], lenQ} */
        for (j = 0; j < lenQ; j++)
        {
            W[j] = Rpow[i][lenQ - j];
        }

        _fmpz_mod_poly_inv_series_newton(Rinv[i], W, lenQ, invLP, p);

        /* invLP := inv{lead{R^{2^i}}} */
        if (i != k - 1)
        {
            fmpz_mul(invLP, invLP, invLP);
            fmpz_mod(invLP, invLP, p);
        }
    }

    fmpz_clear(invLP);
    flint_free(W);
}
示例#16
0
文件: log_series.c 项目: goens/flint2
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);
}
示例#17
0
void _fmpz_mod_poly_div_basecase(fmpz *Q, fmpz *R, 
    const fmpz *A, long lenA, const fmpz *B, long lenB, 
    const fmpz_t invB, const fmpz_t p)
{
    const long alloc = (R == NULL) ? lenA : 0;
    long lenR = lenB - 1, iQ;

    if (alloc)
        R = _fmpz_vec_init(alloc);
    if (R != A)
        _fmpz_vec_set(R + lenR, A + lenR, lenA - lenR);

    for (iQ = lenA - lenB; iQ >= 0; iQ--)
    {
        if (fmpz_is_zero(R + lenA - 1))
        {
            fmpz_zero(Q + iQ);
        }
        else
        {
            fmpz_mul(Q + iQ, R + lenA - 1, invB);
            fmpz_mod(Q + iQ, Q + iQ, p);

            _fmpz_vec_scalar_submul_fmpz(R + lenA - lenR - 1, B, lenR, Q + iQ);
            _fmpz_vec_scalar_mod_fmpz(R + lenA - lenR - 1, R + lenA - lenR - 1, lenR, p);
        }

        if (lenR - 1 >= iQ)
        {
            B++;
            lenR--;
        }

        lenA--;
    }

    if (alloc)
        _fmpz_vec_clear(R, alloc);
}
示例#18
0
void
_fmpz_poly_pseudo_divrem_basecase(fmpz * Q, fmpz * R, ulong * d,
                                  const fmpz * A, long lenA, const fmpz * B,
                                  long lenB)
{
    const fmpz * leadB = B + (lenB - 1);
    long iQ = lenA - lenB, iR = lenA - 1;
    fmpz_t rem;

    fmpz_init(rem);

    *d = 0;
    _fmpz_vec_zero(Q, lenA - lenB + 1);
    if (R != A)
        _fmpz_vec_set(R, A, lenA);

    while (iR >= lenB - 1)
    {
        fmpz_fdiv_qr(Q + iQ, rem, R + iR, leadB);
        if (!fmpz_is_zero(rem))
        {
            _fmpz_vec_scalar_mul_fmpz(Q, Q, lenA - lenB + 1, leadB);
            fmpz_set(Q + iQ, R + iR);
            _fmpz_vec_scalar_mul_fmpz(R, R, lenA, leadB);
            (*d)++;
        }

        if (lenB > 1)
            _fmpz_vec_scalar_submul_fmpz(R + (iR - lenB + 1), B, lenB - 1, Q + iQ);

        fmpz_zero(R + iR);

        iR--;
        iQ--;
    }

    fmpz_clear(rem);
}
示例#19
0
void
_fmpz_poly_compose_divconquer(fmpz * res, const fmpz * poly1, long len1, 
                                          const fmpz * poly2, long len2)
{
    long i, j, k, n;
    long *hlen, alloc, powlen;
    fmpz *v, **h, *pow, *temp;
    
    if (len1 == 1)
    {
        fmpz_set(res, poly1);
        return;
    }
    if (len2 == 1)
    {
        _fmpz_poly_evaluate_fmpz(res, poly1, len1, poly2);
        return;
    }
    if (len1 == 2)
    {
        _fmpz_poly_compose_horner(res, poly1, len1, poly2, len2);
        return;
    }

    /* Initialisation */
    
    hlen = (long *) malloc(((len1 + 1) / 2) * sizeof(long));
    
    for (k = 1; (2 << k) < len1; k++) ;
    
    hlen[0] = hlen[1] = ((1 << k) - 1) * (len2 - 1) + 1;
    for (i = k - 1; i > 0; i--)
    {
        long hi = (len1 + (1 << i) - 1) / (1 << i);
        for (n = (hi + 1) / 2; n < hi; n++)
            hlen[n] = ((1 << i) - 1) * (len2 - 1) + 1;
    }
    powlen = (1 << k) * (len2 - 1) + 1;
    
    alloc = 0;
    for (i = 0; i < (len1 + 1) / 2; i++)
        alloc += hlen[i];

    v = _fmpz_vec_init(alloc +  2 * powlen);
    h = (fmpz **) malloc(((len1 + 1) / 2) * sizeof(fmpz *));
    h[0] = v;
    for (i = 0; i < (len1 - 1) / 2; i++)
    {
        h[i + 1] = h[i] + hlen[i];
        hlen[i]  = 0;
    }
    hlen[(len1 - 1) / 2] = 0;
    pow  = v + alloc;
    temp = pow + powlen;
    
    /* Let's start the actual work */
    
    for (i = 0, j = 0; i < len1 / 2; i++, j += 2)
    {
        if (poly1[j + 1] != 0L)
        {
            _fmpz_vec_scalar_mul_fmpz(h[i], poly2, len2, poly1 + j + 1);
            fmpz_add(h[i], h[i], poly1 + j);
            hlen[i] = len2;
        }
        else if (poly1[j] != 0L)
        {
            fmpz_set(h[i], poly1 + j);
            hlen[i] = 1;
        }
    }
    if ((len1 & 1L))
    {
        if (poly1[j] != 0L)
        {
            fmpz_set(h[i], poly1 + j);
            hlen[i] = 1;
        }
    }
    
    _fmpz_poly_mul(pow, poly2, len2, poly2, len2);
    powlen = 2 * len2 - 1;
    
    for (n = (len1 + 1) / 2; n > 2; n = (n + 1) / 2)
    {
        if (hlen[1] > 0)
        {
            long templen = powlen + hlen[1] - 1;
            _fmpz_poly_mul(temp, pow, powlen, h[1], hlen[1]);
            _fmpz_poly_add(h[0], temp, templen, h[0], hlen[0]);
            hlen[0] = FLINT_MAX(hlen[0], templen);
        }
        
        for (i = 1; i < n / 2; i++)
        {
            if (hlen[2*i + 1] > 0)
            {
                _fmpz_poly_mul(h[i], pow, powlen, h[2*i + 1], hlen[2*i + 1]);
                hlen[i] = hlen[2*i + 1] + powlen - 1;
            } else
                hlen[i] = 0;
            _fmpz_poly_add(h[i], h[i], hlen[i], h[2*i], hlen[2*i]);
            hlen[i] = FLINT_MAX(hlen[i], hlen[2*i]);
        }
        if ((n & 1L))
        {
            _fmpz_vec_set(h[i], h[2*i], hlen[2*i]);
            hlen[i] = hlen[2*i];
        }
        
        _fmpz_poly_mul(temp, pow, powlen, pow, powlen);
        powlen += powlen - 1;
        {
            fmpz * t = pow;
            pow      = temp;
            temp     = t;
        }
    }

    _fmpz_poly_mul(res, pow, powlen, h[1], hlen[1]);
    _fmpz_vec_add(res, res, h[0], hlen[0]);
    
    _fmpz_vec_clear(v, alloc + 2 * powlen);
    free(h);
    free(hlen);
}
void
_fmpq_poly_revert_series_lagrange_fast(fmpz * Qinv, fmpz_t den,
                                    const fmpz * Q, const fmpz_t Qden, slong n)
{
    slong i, j, k, m;
    fmpz *R, *Rden, *S, *T, *dens, *tmp;
    fmpz_t Sden, Tden, t;

    if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1))
    {
        _fmpz_poly_revert_series(Qinv, Q, n);
        fmpz_one(den);
        return;
    }

    if (n <= 2)
    {
        fmpz_zero(Qinv);
        if (n == 2)
        {
            fmpz_set(Qinv + 1, Qden);
            fmpz_set(den, Q + 1);
            _fmpq_poly_canonicalise(Qinv, den, 2);
        }
        return;
    }

    m = n_sqrt(n);

    fmpz_init(t);
    dens = _fmpz_vec_init(n);
    R = _fmpz_vec_init((n - 1) * m);
    S = _fmpz_vec_init(n - 1);
    T = _fmpz_vec_init(n - 1);
    Rden = _fmpz_vec_init(m);
    fmpz_init(Sden);
    fmpz_init(Tden);

    fmpz_zero(Qinv);
    fmpz_one(dens);

    _fmpq_poly_inv_series(Ri(1), Rdeni(1), Q + 1, Qden, n - 1);
    _fmpq_poly_canonicalise(Ri(1), Rdeni(1), n - 1);

    for (i = 2; i <= m; i++)
    {
        _fmpq_poly_mullow(Ri(i), Rdeni(i), Ri(i-1), Rdeni(i-1), n - 1,
                Ri(1), Rdeni(1), n - 1, n - 1);
        _fmpq_poly_canonicalise(Ri(i), Rdeni(i), n - 1);
    }

    for (i = 1; i < m; i++)
    {
        fmpz_set(Qinv + i, Ri(i) + i - 1);
        fmpz_mul_ui(dens + i, Rdeni(i), i);
    }

    _fmpz_vec_set(S, Ri(m), n - 1);
    fmpz_set(Sden, Rdeni(m));

    for (i = m; i < n; i += m)
    {
        fmpz_set(Qinv + i, S + i - 1);
        fmpz_mul_ui(dens + i, Sden, i);

        for (j = 1; j < m && i + j < n; j++)
        {
            fmpz_mul(t, S + 0, Ri(j) + i + j - 1);

            for (k = 1; k <= i + j - 1; k++)
                fmpz_addmul(t, S + k, Ri(j) + i + j - 1 - k);

            fmpz_set(Qinv + i + j, t);
            fmpz_mul(dens + i + j, Sden, Rdeni(j));
            fmpz_mul_ui(dens + i + j, dens + i + j, i + j);
        }

        if (i + 1 < n)
        {
            _fmpq_poly_mullow(T, Tden, S, Sden, n - 1,
                Ri(m), Rdeni(m), n - 1, n - 1);
            _fmpq_poly_canonicalise(T, Tden, n - 1);
            fmpz_swap(Tden, Sden);
            tmp = S; S = T; T = tmp;
        }
    }

    _set_vec(Qinv, den, Qinv, dens, n);
    _fmpq_poly_canonicalise(Qinv, den, n);

    fmpz_clear(t);
    _fmpz_vec_clear(dens, n);
    _fmpz_vec_clear(R, (n - 1) * m);
    _fmpz_vec_clear(S, n - 1);
    _fmpz_vec_clear(T, n - 1);
    _fmpz_vec_clear(Rden, m);
    fmpz_clear(Sden);
    fmpz_clear(Tden);
}
示例#21
0
void
_fmpq_poly_revert_series_lagrange(fmpz * Qinv, fmpz_t den,
                            const fmpz * Q, const fmpz_t Qden, long n)
{
    long i;
    fmpz *R, *S, *T, *dens, *tmp;
    fmpz_t Rden, Sden, Tden;

    if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1))
    {
        _fmpz_poly_revert_series(Qinv, Q, n);
        fmpz_one(den);
    }
    else if (n <= 2)
    {
        fmpz_zero(Qinv);
        if (n == 2)
        {
            fmpz_set(Qinv + 1, Qden);
            fmpz_set(den, Q + 1);
            _fmpq_poly_canonicalise(Qinv, den, 2);
        }
    }
    else
    {
        dens = _fmpz_vec_init(n);
        R = _fmpz_vec_init(n - 1);
        S = _fmpz_vec_init(n - 1);
        T = _fmpz_vec_init(n - 1);
        fmpz_init(Rden);
        fmpz_init(Sden);
        fmpz_init(Tden);

        fmpz_zero(Qinv);
        fmpz_one(dens);
        fmpz_set(Qinv + 1, Qden);
        fmpz_set(dens + 1, Q + 1);

        _fmpq_poly_inv_series(R, Rden, Q + 1, Qden, n - 1);
        _fmpq_poly_canonicalise(R, Rden, n - 1);

        _fmpz_vec_set(S, R, n - 1);
        fmpz_set(Sden, Rden);

        for (i = 2; i < n; i++)
        {
            _fmpq_poly_mullow(T, Tden, S, Sden, n - 1, R, Rden, n - 1, n - 1);
            _fmpq_poly_canonicalise(T, Tden, n - 1);
            fmpz_set(Qinv + i, T + i - 1);
            fmpz_mul_ui(dens + i, Tden, i);
            tmp = S; S = T; T = tmp;
            fmpz_swap(Sden, Tden);
        }

        _set_vec(Qinv, den, Qinv, dens, n);
        _fmpq_poly_canonicalise(Qinv, den, n);

        _fmpz_vec_clear(R, n - 1);
        _fmpz_vec_clear(S, n - 1);
        _fmpz_vec_clear(T, n - 1);
        _fmpz_vec_clear(dens, n);
        fmpz_clear(Rden);
        fmpz_clear(Sden);
        fmpz_clear(Tden);
    }
}
示例#22
0
int fmpq_poly_check_unique_real_root(const fmpq_poly_t pol, const arb_t a, slong prec)
{
    if (pol->length < 2)
        return 0;
    else if (pol->length == 2)
    {
        /* linear polynomial */
        fmpq_t root;
        int ans;

        fmpq_init(root);
        fmpq_set_fmpz_frac(root, fmpq_poly_numref(pol), fmpq_poly_numref(pol) + 1);
        fmpq_neg(root, root);
        ans = arb_contains_fmpq(a, root);
        fmpq_clear(root);
        return ans;
    }
    else
    {
        arb_t b, c;
        arf_t l, r;

        fmpz * der;
        int lsign, rsign;
        fmpz_poly_t pol2;
        slong n;

        /* 1 - cheap test:                    */
        /*   - sign(left) * sign(right) = -1  */
        /*   - no zero of the derivative      */
        arb_init(b);
        arb_init(c);
        arf_init(l);
        arf_init(r);
        arb_get_interval_arf(l, r, a, prec);
        arb_set_arf(b, l);
        _fmpz_poly_evaluate_arb(c, pol->coeffs, pol->length, b, 2*prec);
        lsign = arb_sgn2(c);

        arb_set_arf(b, r);
        _fmpz_poly_evaluate_arb(c, pol->coeffs, pol->length, b, 2*prec);
        rsign = arb_sgn2(c);

        arb_clear(c);
        if (lsign * rsign == -1)
        {
            der = _fmpz_vec_init(pol->length - 1);
            _fmpz_poly_derivative(der, pol->coeffs, pol->length);
            _fmpz_poly_evaluate_arb(b, der, pol->length - 1, a, prec);
            _fmpz_vec_clear(der, pol->length - 1);

            if (!arb_contains_zero(b))
            {
                arf_clear(l);
                arf_clear(r);
                arb_clear(b);
                return 1;
            }
        }
        else
            return 0;
        arb_clear(b);

        /* 2 - expensive testing                                        */
        fmpq_t ql, qr;

        fmpq_init(ql);
        fmpq_init(qr);
        arf_get_fmpq(ql, l);
        arf_get_fmpq(qr, r);

        fmpz_poly_init(pol2);
        fmpz_poly_fit_length(pol2, pol->length);
        _fmpz_vec_set(pol2->coeffs, pol->coeffs, pol->length);
        pol2->length = pol->length;
        _fmpz_poly_scale_0_1_fmpq(pol2->coeffs, pol2->length, ql, qr);

        n = fmpz_poly_num_real_roots_0_1(pol2);

        fmpz_poly_clear(pol2);
        fmpq_clear(ql);
        fmpq_clear(qr);

        return (n == 1);
    }
}
示例#23
0
int
_fmpz_poly_sqrt_classical(fmpz * res, const fmpz * poly, long len)
{
    long i, m;
    int result;

    /* the degree must be even */
    if (len % 2 == 0)
        return 0;

    /* valuation must be even, and then can be reduced to 0 */
    while (fmpz_is_zero(poly))
    {
        if (!fmpz_is_zero(poly + 1))
            return 0;

        fmpz_zero(res);
        poly += 2;
        len -= 2;
        res++;
    }

    /* check whether a square root exists modulo 2 */
    for (i = 1; i < len; i += 2)
        if (!fmpz_is_even(poly + i))
            return 0;

    /* check endpoints */
    if (!fmpz_is_square(poly) || (len > 1 && !fmpz_is_square(poly + len - 1)))
        return 0;

    /* square root of leading coefficient */
    m = (len + 1) / 2;
    fmpz_sqrt(res + m - 1, poly + len - 1);
    result = 1;

    /* do long divison style 'square root with remainder' from top to bottom */
    if (len > 1)
    {
        fmpz_t t, u;
        fmpz * r;

        fmpz_init(t);
        fmpz_init(u);
        r = _fmpz_vec_init(len);
        _fmpz_vec_set(r, poly, len);
        fmpz_mul_ui(u, res + m - 1, 2);

        for (i = 1; i < m; i++)
        {
            fmpz_fdiv_qr(res + m - i - 1, t, r + len - i - 1, u);
            if (!fmpz_is_zero(t))
            {
                result = 0;
                break;
            }

            fmpz_mul_si(t, res + m - i - 1, -2);
            _fmpz_vec_scalar_addmul_fmpz(r + len - 2*i, res + m - i, i - 1, t);
            fmpz_submul(r + len - 2*i - 1, res + m - i - 1, res + m - i - 1);
        }

        for (i = m; i < len && result; i++)
            if (!fmpz_is_zero(r + len - 1 - i))
                result = 0;

        _fmpz_vec_clear(r, len);
        fmpz_clear(t);
        fmpz_clear(u);
    }

    return result;
}
示例#24
0
static void 
_qadic_exp_bsplit_series(fmpz *P, fmpz_t Q, fmpz *T, 
                         const fmpz *x, slong len, slong lo, slong hi, 
                         const fmpz *a, const slong *j, slong lena)
{
    const slong d = j[lena - 1];

    if (hi - lo == 1)
    {
        _fmpz_vec_set(P, x, len);
        _fmpz_vec_zero(P + len, 2*d - 1 - len);

        fmpz_set_si(Q, lo);

        _fmpz_vec_set(T, P, 2*d - 1);
    }
    else if (hi - lo == 2)
    {
        _fmpz_poly_sqr(P, x, len);
        _fmpz_vec_zero(P + (2*len - 1), d - (2*len - 1));
        _fmpz_poly_reduce(P, 2*len - 1, a, j, lena);

        fmpz_set_si(Q, lo);
        fmpz_mul_si(Q, Q, lo + 1);

        _fmpz_vec_scalar_mul_si(T, x, len, lo + 1);
        _fmpz_vec_zero(T + len, d - len);
        _fmpz_vec_add(T, T, P, d);
    }
    else
    {
        const slong m = (lo + hi) / 2;

        fmpz *PR, *TR, *W;
        fmpz_t QR;

        PR = _fmpz_vec_init(2*d - 1);
        TR = _fmpz_vec_init(2*d - 1);
        W  = _fmpz_vec_init(2*d - 1);
        fmpz_init(QR);

        _qadic_exp_bsplit_series(P, Q, T, x, len, lo, m, a, j, lena);

        _qadic_exp_bsplit_series(PR, QR, TR, x, len, m, hi, a, j, lena);

        _fmpz_poly_mul(W, TR, d, P, d);
        _fmpz_poly_reduce(W, 2*d - 1, a, j, lena);

        _fmpz_vec_scalar_mul_fmpz(T, T, d, QR);
        _fmpz_vec_add(T, T, W, d);

        _fmpz_poly_mul(W, P, d, PR, d);
        _fmpz_poly_reduce(W, 2*d - 1, a, j, lena);
        _fmpz_vec_swap(P, W, d);

        fmpz_mul(Q, Q, QR);

        _fmpz_vec_clear(PR, 2*d - 1);
        _fmpz_vec_clear(TR, 2*d - 1);
        _fmpz_vec_clear(W,  2*d - 1);
        fmpz_clear(QR);
    }
}
示例#25
0
int
main(void)
{
    int i, result;
    flint_rand_t state;

    printf("scalar_submul_fmpz....");
    fflush(stdout);

    flint_randinit(state);

    /* Compare with fmpz_vec_scalar_submul_si */
    for (i = 0; i < 10000; i++)
    {
        fmpz *a, *b, *c;
        long len, n;
        fmpz_t n1;
        len = n_randint(state, 100);
        n = (long) n_randbits(state, FLINT_BITS - 1);
        if (n_randint(state, 2))
            n = -n;
        fmpz_init(n1);
        fmpz_set_si(n1, n);

        a = _fmpz_vec_init(len);
        b = _fmpz_vec_init(len);
        c = _fmpz_vec_init(len);
        _fmpz_vec_randtest(a, state, len, 200);
        _fmpz_vec_randtest(b, state, len, 200);
        _fmpz_vec_set(c, b, len);

        _fmpz_vec_scalar_submul_fmpz(b, a, len, n1);
        _fmpz_vec_scalar_submul_si(c, a, len, n);

        result = (_fmpz_vec_equal(c, b, len));
        if (!result)
        {
            printf("FAIL:\n");
            _fmpz_vec_print(c, len), printf("\n\n");
            _fmpz_vec_print(b, len), printf("\n\n");
            abort();
        }

        fmpz_clear(n1);
        _fmpz_vec_clear(a, len);
        _fmpz_vec_clear(b, len);
        _fmpz_vec_clear(c, len);
    }

    /* Compute a different way */
    for (i = 0; i < 10000; i++)
    {
        fmpz *a, *b, *c, *d;
        long len = n_randint(state, 100);
        fmpz_t n1;
        fmpz_init(n1);
        fmpz_randtest(n1, state, 200);

        a = _fmpz_vec_init(len);
        b = _fmpz_vec_init(len);
        c = _fmpz_vec_init(len);
        d = _fmpz_vec_init(len);
        _fmpz_vec_randtest(a, state, len, 200);
        _fmpz_vec_randtest(b, state, len, 200);
        _fmpz_vec_set(c, b, len);

        _fmpz_vec_scalar_submul_fmpz(b, a, len, n1);
        _fmpz_vec_scalar_mul_fmpz(d, a, len, n1);
        _fmpz_vec_sub(c, c, d, len);

        result = (_fmpz_vec_equal(c, b, len));
        if (!result)
        {
            printf("FAIL:\n");
            _fmpz_vec_print(c, len), printf("\n\n");
            _fmpz_vec_print(b, len), printf("\n\n");
            abort();
        }

        fmpz_clear(n1);
        _fmpz_vec_clear(a, len);
        _fmpz_vec_clear(b, len);
        _fmpz_vec_clear(c, len);
        _fmpz_vec_clear(d, len);
    }

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}
示例#26
0
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);

    flint_printf("scalar_fdiv_q_fmpz....");
    fflush(stdout);

    

    for (i = 0; i < 1000 * flint_test_multiplier(); i++)
    {
        fmpz *a, *b, *c;
        fmpz_t n;
        mpz_t d, e, f, m;
        slong i;
        slong len = n_randint(state, 100);

        fmpz_init(n);
        fmpz_randtest_not_zero(n, state, 100);
        if (n_randint(state, 2))
            fmpz_neg(n, n);

        a = _fmpz_vec_init(len);
        b = _fmpz_vec_init(len);
        c = _fmpz_vec_init(len);

        _fmpz_vec_randtest(a, state, len, 200);

        _fmpz_vec_set(b, a, len);

        _fmpz_vec_scalar_fdiv_q_fmpz(c, a, len, n);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(m);

        for (i = 0; i < len; i++)
        {
            fmpz_get_mpz(m, n);
            fmpz_get_mpz(d, b + i);

            mpz_fdiv_q(e, d, m);

            fmpz_get_mpz(f, c + i);

            result = (mpz_cmp(f, e) == 0);
            if (!result)
            {
                flint_printf("FAIL:\n");
                gmp_printf("d = %Zd, m = %Zd, e = %Zd, f = %Zd\n", d, m, e, f);
                abort();
            }
        }

        _fmpz_vec_clear(a, len);
        _fmpz_vec_clear(b, len);
        _fmpz_vec_clear(c, len);

        fmpz_clear(n);
        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(m);
    }    

    /* Test aliasing of a and c */
    for (i = 0; i < 1000 * flint_test_multiplier(); i++)
    {
        fmpz *a, *b;
        fmpz_t n;
        mpz_t d, e, f, m;
        slong i;
        slong len = n_randint(state, 100);

        fmpz_init(n);
        fmpz_randtest_not_zero(n, state, 100);
        if (n_randint(state, 2))
            fmpz_neg(n, n);

        a = _fmpz_vec_init(len);
        b = _fmpz_vec_init(len);

        _fmpz_vec_randtest(a, state, len, 200);

        _fmpz_vec_set(b, a, len);

        _fmpz_vec_scalar_fdiv_q_fmpz(a, a, len, n);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(m);

        for (i = 0; i < len; i++)
        {
            fmpz_get_mpz(m, n);
            fmpz_get_mpz(d, b + i);

            mpz_fdiv_q(e, d, m);

            fmpz_get_mpz(f, a + i);

            result = (mpz_cmp(f, e) == 0);
            if (!result)
            {
                flint_printf("FAIL:\n");
                gmp_printf("d = %Zd, m = %Zd, e = %Zd, f = %Zd\n", d, m, e, f);
                abort();
            }
        }

        _fmpz_vec_clear(a, len);
        _fmpz_vec_clear(b, len);

        fmpz_clear(n);
        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(m);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}
示例#27
0
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);

    flint_printf("scalar_divexact_ui....");
    fflush(stdout);

    

    /* Check aliasing of a and b */
    for (i = 0; i < 1000 * flint_test_multiplier(); i++)
    {
        fmpz *a, *b;
        ulong n = n_randtest_not_zero(state);
        slong len = n_randint(state, 100);

        a = _fmpz_vec_init(len);
        b = _fmpz_vec_init(len);
        _fmpz_vec_randtest(a, state, len, 200);

        _fmpz_vec_scalar_mul_ui(a, a, len, n);
        _fmpz_vec_scalar_divexact_ui(b, a, len, n);
        _fmpz_vec_scalar_divexact_ui(a, a, len, n);

        result = (_fmpz_vec_equal(a, b, len));
        if (!result)
        {
            flint_printf("FAIL:\n");
            _fmpz_vec_print(a, len), flint_printf("\n\n");
            _fmpz_vec_print(b, len), flint_printf("\n\n");
            abort();
        }

        _fmpz_vec_clear(a, len);
        _fmpz_vec_clear(b, len);
    }

    /* Check that a * n / n == a */
    for (i = 0; i < 1000 * flint_test_multiplier(); i++)
    {
        fmpz *a, *b;
        ulong n = n_randtest_not_zero(state);
        slong len = n_randint(state, 100);

        a = _fmpz_vec_init(len);
        b = _fmpz_vec_init(len);
        _fmpz_vec_randtest(a, state, len, 200);

        _fmpz_vec_set(b, a, len);
        _fmpz_vec_scalar_mul_ui(a, a, len, n);
        _fmpz_vec_scalar_divexact_ui(a, a, len, n);

        result = (_fmpz_vec_equal(a, b, len));
        if (!result)
        {
            flint_printf("FAIL:\n");
            _fmpz_vec_print(a, len), flint_printf("\n\n");
            _fmpz_vec_print(b, len), flint_printf("\n\n");
            abort();
        }

        _fmpz_vec_clear(a, len);
        _fmpz_vec_clear(b, len);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}