예제 #1
0
static 
void _fmpz_mod_mat_det(fmpz_t rop, const fmpz *M, slong n, const fmpz_t pN)
{
    fmpz *F;
    fmpz *a;
    fmpz *A;
    fmpz_t s;
    slong t, i, j, p, k;

    F = _fmpz_vec_init(n);
    a = _fmpz_vec_init((n-1) * n);
    A = _fmpz_vec_init(n);

    fmpz_init(s);

    fmpz_neg(F + 0, M + 0*n + 0);

    for (t = 1; t < n; t++)
    {
        for (i = 0; i <= t; i++)
            fmpz_set(a + 0*n + i, M + i*n + t);

        fmpz_set(A + 0, M + t*n + t);

        for (p = 1; p < t; p++)
        {
            for (i = 0; i <= t; i++)
            {
                fmpz_zero(s);
                for (j = 0; j <= t; j++)
                    fmpz_addmul(s, M + i*n + j, a + (p-1)*n + j);
                fmpz_mod(a + p*n + i, s, pN);
            }

            fmpz_set(A + p, a + p*n + t);
        }

        fmpz_zero(s);
        for (j = 0; j <= t; j++)
            fmpz_addmul(s, M + t*n + j, a + (t-1)*n + j);
        fmpz_mod(A + t, s, pN);

        for (p = 0; p <= t; p++)
        {
            fmpz_sub(F + p, F + p, A + p);
            for (k = 0; k < p; k++)
                fmpz_submul(F + p, A + k, F + (p-k-1));
            fmpz_mod(F + p, F + p, pN);
        }
    }

    /*
        Now [F{n-1}, F{n-2}, ..., F{0}, 1] is the 
        characteristic polynomial of the matrix M.
     */

    if (n % WORD(2) == 0)
    {
        fmpz_set(rop, F + (n-1));
    }
    else
    {
        fmpz_neg(rop, F + (n-1));
        fmpz_mod(rop, rop, pN);
    }

    _fmpz_vec_clear(F, n);
    _fmpz_vec_clear(a, (n-1)*n);
    _fmpz_vec_clear(A, n);
    fmpz_clear(s);
}
예제 #2
0
int main()
{
    fmpz * num1;
    fmpz * den1;
    fmpz_t num2;
    fmpz_t den2;
    long n, N;

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

    N = 4000;

    num1 = _fmpz_vec_init(N);
    den1 = _fmpz_vec_init(N);
    fmpz_init(num2);
    fmpz_init(den2);

    _bernoulli_number_vec_multi_mod(num1, den1, N);

    for (n = 0; n < N; n++)
    {
        _bernoulli_number(num2, den2, n);

        if (!fmpz_equal(num1 + n, num2))
        {
            printf("FAIL: n = %ld, numerator\n", n);
            printf("vec:    "); fmpz_print(num1 + n); printf("\n");
            printf("single: "); fmpz_print(num2); printf("\n");
            abort();
        }

        if (!fmpz_equal(den1 + n, den2))
        {
            printf("FAIL: n = %ld, denominator\n", n);
            printf("vec:    "); fmpz_print(den1 + n); printf("\n");
            printf("single: "); fmpz_print(den2); printf("\n");
            abort();
        }
    }

    /* Check non underscore versions */
    do
    {
        long N = 100;
        fmpq * x;
        fmpq_t t;

        fmpq_init(t);
        x = flint_malloc(sizeof(fmpq) * N);

        for (n = 0; n < N; n++)
            fmpq_init(x + n);

        bernoulli_number_vec(x, N);
        for (n = 0; n < N; n++)
        {
            bernoulli_number(t, n);
            if (!fmpq_equal(x + n, t))
            {
                printf("FAIL!: n = %ld\n", n);
                abort();
            }
        }

        for (n = 0; n < N; n++)
            fmpq_clear(x + n);
        flint_free(x);
        fmpq_clear(t);

    } while (0);

    _fmpz_vec_clear(num1, N);
    _fmpz_vec_clear(den1, N);
    fmpz_clear(num2);
    fmpz_clear(den2);

    mpfr_free_cache();
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}
예제 #3
0
int
main(void)
{
    int i, result;
    flint_rand_t state;

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

    flint_randinit(state);

    /* Check aliasing of a and b */
    for (i = 0; i < 10000; i++)
    {
        fmpz *a, *b;
        long len = n_randint(state, 100);
        ulong exp = n_randint(state, 200);

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

        _fmpz_vec_scalar_mul_2exp(b, a, len, exp);
        _fmpz_vec_scalar_mul_2exp(a, a, len, exp);

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

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

    /* Check aliasing of (a*2^e1)*2^e2 equals a*2^(e1+e2) */
    for (i = 0; i < 10000; i++)
    {
        fmpz *a, *b;
        long len = n_randint(state, 100);
        ulong e1 = n_randint(state, 200);
        ulong e2 = n_randint(state, 200);

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

        _fmpz_vec_scalar_mul_2exp(b, a, len, e1);
        _fmpz_vec_scalar_mul_2exp(b, b, len, e2);
        _fmpz_vec_scalar_mul_2exp(a, a, len, e1 + e2);

        result = (_fmpz_vec_equal(a, b, len));
        if (!result)
        {
            printf("FAIL:\n");
            printf("e1 = %lu, e2 = %lu\n", e1, e2);
            _fmpz_vec_print(a, len), printf("\n\n");
            _fmpz_vec_print(b, len), printf("\n\n");
            abort();
        }

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

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}
예제 #4
0
파일: t-rising2_ui.c 프로젝트: jdemeyer/arb
int main()
{
    long iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 1000; iter++)
    {
        arb_t a, u, v, u2, v2;
        fmpz *f;
        arb_ptr g;
        ulong n;
        long i, prec;

        arb_init(a);
        arb_init(u);
        arb_init(v);
        arb_init(u2);
        arb_init(v2);

        arb_randtest(a, state, 1 + n_randint(state, 4000), 10);
        arb_randtest(u, state, 1 + n_randint(state, 4000), 10);
        arb_randtest(v, state, 1 + n_randint(state, 4000), 10);
        n = n_randint(state, 120);

        f = _fmpz_vec_init(n + 1);
        g = _arb_vec_init(n + 1);

        prec = 2 + n_randint(state, 4000);
        arb_rising2_ui(u, v, a, n, prec);

        arith_stirling_number_1u_vec(f, n, n + 1);
        for (i = 0; i <= n; i++)
            arb_set_fmpz(g + i, f + i);
        _arb_poly_evaluate(u2, g, n + 1, a, prec);

        _arb_poly_derivative(g, g, n + 1, prec);
        _arb_poly_evaluate(v2, g, n, a, prec);

        if (!arb_overlaps(u, u2) || !arb_overlaps(v, v2))
        {
            printf("FAIL: overlap\n\n");
            printf("n = %lu\n", n);
            printf("a = ");
            arb_printd(a, 15);
            printf("\n\n");
            printf("u = ");
            arb_printd(u, 15);
            printf("\n\n");
            printf("u2 = ");
            arb_printd(u2, 15);
            printf("\n\n");
            printf("v = ");
            arb_printd(v, 15);
            printf("\n\n");
            printf("v2 = ");
            arb_printd(v2, 15);
            printf("\n\n");
            abort();
        }

        arb_set(u2, a);
        arb_rising2_ui(u2, v, u2, n, prec);

        if (!arb_equal(u2, u))
        {
            printf("FAIL: aliasing 1\n\n");
            printf("a = ");
            arb_printd(a, 15);
            printf("\n\n");
            printf("u = ");
            arb_printd(u, 15);
            printf("\n\n");
            printf("u2 = ");
            arb_printd(u2, 15);
            printf("\n\n");
            printf("n = %lu\n", n);
            abort();
        }

        arb_set(v2, a);
        arb_rising2_ui(u, v2, v2, n, prec);

        if (!arb_equal(v2, v))
        {
            printf("FAIL: aliasing 2\n\n");
            printf("a = ");
            arb_printd(a, 15);
            printf("\n\n");
            printf("v = ");
            arb_printd(v, 15);
            printf("\n\n");
            printf("v2 = ");
            arb_printd(v2, 15);
            printf("\n\n");
            printf("n = %lu\n", n);
            abort();
        }

        arb_clear(a);
        arb_clear(u);
        arb_clear(v);
        arb_clear(u2);
        arb_clear(v2);
        _fmpz_vec_clear(f, n + 1);
        _arb_vec_clear(g, n + 1);
    }

    flint_randclear(state);
    flint_cleanup();
    printf("PASS\n");
    return EXIT_SUCCESS;
}
예제 #5
0
static void 
__fmpz_poly_divrem_divconquer(fmpz * Q, fmpz * R, 
                              const fmpz * A, long lenA, 
                              const fmpz * B, long lenB)
{
    if (lenA < 2 * lenB - 1)
    {
        /*
           Convert unbalanced division into a 2 n1 - 1 by n1 division
         */

        const long n1 = lenA - lenB + 1;
        const long n2 = lenB - n1;

        const fmpz * p1 = A + n2;
        const fmpz * d1 = B + n2;
        const fmpz * d2 = B;

        fmpz * W = _fmpz_vec_init((2 * n1 - 1) + lenB - 1);

        fmpz * d1q1 = R + n2;
        fmpz * d2q1 = W + (2 * n1 - 1);

        _fmpz_poly_divrem_divconquer_recursive(Q, d1q1, W, p1, d1, n1);

        /*
           Compute d2q1 = Q d2, of length lenB - 1
         */

        if (n1 >= n2)
            _fmpz_poly_mul(d2q1, Q, n1, d2, n2);
        else
            _fmpz_poly_mul(d2q1, d2, n2, Q, n1);

        /*
           Compute BQ = d1q1 * x^n1 + d2q1, of length lenB - 1; 
           then compute R = A - BQ
         */

        _fmpz_vec_swap(R, d2q1, n2);
        _fmpz_vec_add(R + n2, R + n2, d2q1 + n2, n1 - 1);
        _fmpz_vec_sub(R, A, R, lenA);

        _fmpz_vec_clear(W, (2 * n1 - 1) + lenB - 1);
    }
    else if (lenA > 2 * lenB - 1)
    {
        /*
           We shift A right until it is of length 2 lenB - 1, call this p1
         */

        const long shift = lenA - 2 * lenB + 1;
        const fmpz * p1 = A + shift;

        fmpz * q1   = Q + shift;
        fmpz * q2   = Q;
        fmpz * W    = R + lenA;
        fmpz * d1q1 = W + (2 * lenB - 1);

        /*
           XXX:  In this case, we expect R to be of length 
           lenA + 2 * (2 * lenB - 1) and A to be modifiable
         */

        /* 
           Set q1 to p1 div B, a 2 lenB - 1 by lenB division, so q1 ends up 
           being of length lenB; set d1q1 = d1 * q1 of length 2 lenB - 1
         */

        _fmpz_poly_divrem_divconquer_recursive(q1, d1q1, W, p1, B, lenB);

        /* 
           We have dq1 = d1 * q1 * x^shift, of length lenA

           Compute R = A - dq1; the first lenB coeffs represent remainder 
           terms (zero if division is exact), leaving lenA - lenB significant 
           terms which we use in the division
         */

        _fmpz_vec_sub((fmpz *) A + shift, A + shift, d1q1, lenB - 1);

        /*
           Compute q2 = trunc(R) div B; it is a smaller division than the 
           original since len(trunc(R)) = lenA - lenB
         */

        __fmpz_poly_divrem_divconquer(q2, R, A, lenA - lenB, B, lenB);

        _fmpz_vec_sub(R + lenA - lenB, A + lenA - lenB, d1q1 + lenB - 1, lenB);

        /*
           We have Q = q1 * x^shift + q2; Q has length lenB + shift; 
           note q2 has length shift since the above division is 
           lenA - lenB by lenB

           We've also written the remainder in place
         */
    }
    else  /* lenA = 2 * lenB - 1 */
    {
        fmpz * W = _fmpz_vec_init(lenA);

        _fmpz_poly_divrem_divconquer_recursive(Q, R, W, A, B, lenB);
        _fmpz_vec_sub(R, A, R, lenA);

        _fmpz_vec_clear(W, lenA);
    }
}
예제 #6
0
void _padic_teichmuller(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N)
{
    if (fmpz_equal_ui(p, 2))
    {
        fmpz_one(rop);
    }
    else if (N == 1)
    {
        fmpz_mod(rop, op, p);
    }
    else
    {
        slong *a, i, n;
        fmpz *pow, *u;
        fmpz_t s, t;
        fmpz_t inv;
        fmpz_t pm1;

        a = _padic_lifts_exps(&n, N);

        pow = _fmpz_vec_init(2 * n);
        u   = pow + n;

        _padic_lifts_pows(pow, a, n, p);

        fmpz_init(s);
        fmpz_init(t);
        fmpz_init(inv);
        fmpz_init(pm1);

        fmpz_sub_ui(pm1, p, 1);

        /* Compute reduced units for (p-1) */
        {
            fmpz_mod(u + 0, pm1, pow + 0);
        }
        for (i = 1; i < n; i++)
        {
            fmpz_mod(u + i, u + (i - 1), pow + i);
        }

        /* Run Newton iteration */
        i = n - 1;
        {
            fmpz_mod(rop, op, pow + i);

            fmpz_set(inv, pm1);
        }
        for (i--; i >= 0; i--)
        {
            /* Lift rop */
            fmpz_powm(s, rop, p, pow + i);
            fmpz_sub(s, s, rop);
            fmpz_mul(t, s, inv);
            fmpz_sub(rop, rop, t);
            fmpz_mod(rop, rop, pow + i);

            /* Lift inv */
            if (i > 0)
            {
                fmpz_mul(s, inv, inv);
                fmpz_mul(t, u + i, s);
                fmpz_mul_2exp(inv, inv, 1);
                fmpz_sub(inv, inv, t);
                fmpz_mod(inv, inv, pow + i);
            }
        }

        fmpz_clear(s);
        fmpz_clear(t);
        fmpz_clear(inv);
        fmpz_clear(pm1);
        _fmpz_vec_clear(pow, 2 * n);
        flint_free(a);
    }
}
void
acb_rising2_ui_rs(acb_t u, acb_t v,
    const acb_t x, ulong n, ulong m, long prec)
{
    if (n == 0)
    {
        acb_zero(v);
        acb_one(u);
    }
    else if (n == 1)
    {
        acb_set(u, x);
        acb_one(v);
    }
    else
    {
        long wp;
        ulong i, j, a, b;
        acb_ptr xs;
        acb_t S, T, U, V;
        fmpz *A, *B;

        wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n));

        if (m == 0)
        {
            ulong m1, m2;
            m1 = 0.6 * pow(wp, 0.4);
            m2 = n_sqrt(n);
            m = FLINT_MIN(m1, m2);
        }

        m = FLINT_MAX(m, 1);

        xs = _acb_vec_init(m + 1);
        A = _fmpz_vec_init(2 * m + 1);
        B = A + (m + 1);

        acb_init(S);
        acb_init(T);
        acb_init(U);
        acb_init(V);
        _acb_vec_set_powers(xs, x, m + 1, wp);

        for (i = 0; i < n; i += m)
        {
            a = i;
            b = FLINT_MIN(n, a + m);

            if (a == 0 || b != a + m)
            {
                _gamma_rf_bsplit(A, a, b);
            }
            else
            {
                fmpz tt = m;
                _fmpz_poly_taylor_shift(A, &tt, m + 1);
            }

            _fmpz_poly_derivative(B, A, b - a + 1);

            acb_set_fmpz(S, A);

            for (j = 1; j <= b - a; j++)
                acb_addmul_fmpz(S, xs + j, A + j, wp);

            acb_set_fmpz(T, B);

            for (j = 1; j < b - a; j++)
                acb_addmul_fmpz(T, xs + j, B + j, wp);

            if (i == 0)
            {
                acb_set(U, S);
                acb_set(V, T);
            }
            else
            {
                acb_mul(V, V, S, wp);
                acb_addmul(V, U, T, wp);
                acb_mul(U, U, S, wp);
            }
        }

        acb_set(u, U);
        acb_set(v, V);

        _acb_vec_clear(xs, m + 1);
        _fmpz_vec_clear(A, 2 * m + 1);

        acb_clear(S);
        acb_clear(T);
        acb_clear(U);
        acb_clear(V);
    }
}
예제 #8
0
파일: radix.c 프로젝트: goens/flint2
void fmpz_mod_poly_radix(fmpz_mod_poly_struct **B, 
                         const fmpz_mod_poly_t F, 
                         const fmpz_mod_poly_radix_t D)
{
    const long lenF = F->length;
    const long degF = F->length - 1;
    const long degR = D->degR;
    const long N    = degF / degR;

    if (N == 0)
    {
        fmpz_mod_poly_set(B[0], F);
    }
    else
    {
        const long k    = FLINT_BIT_COUNT(N);     /* k := ceil{log{N+1}}    */
        const long lenG = (1L << k) * degR;       /* Padded size            */
        const long t    = (lenG - 1) / degR - N;  /* Extra {degR}-blocks    */

        fmpz *G;                                  /* Padded copy of F       */
        fmpz *T;                                  /* Additional B[i]        */
        fmpz **C;                                 /* Enlarged version of B  */
        fmpz *W;                                  /* Temporary space        */

        long i;

        if (lenF < lenG)
        {
            G = flint_malloc(lenG * sizeof(fmpz));
            for (i = 0; i < lenF; i++)
                G[i] = F->coeffs[i];
            mpn_zero((mp_ptr) G + lenF, lenG - lenF);

            T = t ? _fmpz_vec_init(t * degR) : NULL;
        }
        else  /* lenF == lenG */
        {
            G = F->coeffs;
            T = NULL;
        }

        C = flint_malloc((N + 1 + t) * sizeof(fmpz *));
        for (i = 0; i <= N; i++)
        {
            fmpz_mod_poly_fit_length(B[i], degR);
            C[i] = B[i]->coeffs;
        }
        for (i = 0; i < t; i++)
        {
            C[N + 1 + i] = T + i * degR;
        }

        W = _fmpz_vec_init(lenG);

        _fmpz_mod_poly_radix(C, G, D->Rpow, D->Rinv, degR, 0, k-1, W, &(F->p));

        _fmpz_vec_clear(W, lenG);

        for (i = 0; i <= N; i++)
        {
            _fmpz_mod_poly_set_length(B[i], degR);
            _fmpz_mod_poly_normalise(B[i]);
        }
        flint_free(C);
        if (lenF < lenG)
        {
            flint_free(G);
        }
        if (t) 
        {
            _fmpz_vec_clear(T, t * degR);
        }
    }
}
예제 #9
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;
}
예제 #10
0
파일: rising_ui_rs.c 프로젝트: isuruf/arb
void
acb_rising_ui_rs(acb_t y, const acb_t x, ulong n, ulong m, slong prec)
{
    acb_ptr xs;
    acb_t t, u, v;
    ulong i, k, rem;
    fmpz_t c, h;
    fmpz *s, *d;
    slong wp;

    if (n == 0)
    {
        acb_one(y);
        return;
    }

    if (n == 1)
    {
        acb_set_round(y, x, prec);
        return;
    }

    wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n));

    acb_init(t);
    acb_init(u);
    acb_init(v);
    fmpz_init(c);
    fmpz_init(h);

    if (m == 0)
    {
        ulong m1, m2;
        m1 = 0.2 * pow(2.0 * wp, 0.4);
        m2 = n_sqrt(n);
        m = FLINT_MIN(m1, m2);
    }

    m = FLINT_MIN(m, n);
    m = FLINT_MAX(m, 1);

    xs = _acb_vec_init(m + 1);
    d = _fmpz_vec_init(m * m);
    s = _fmpz_vec_init(m + 1);

    _acb_vec_set_powers(xs, x, m + 1, wp);

    rising_difference_polynomial(s, d, m);

    /* tail */
    rem = m;
    while (rem + m <= n)
        rem += m;
    acb_one(y);
    for (k = rem; k < n; k++)
    {
        acb_add_ui(t, xs + 1, k, wp);
        acb_mul(y, y, t, wp);
    }

    /* initial rising factorial */
    acb_zero(t);
    for (i = 1; i <= m; i++)
        acb_addmul_fmpz(t, xs + i, s + i, wp);

    acb_mul(y, y, t, wp);

    /* the leading coefficient is always the same */
    acb_mul_fmpz(xs + m - 1, xs + m - 1, d + m - 1 + 0, wp);

    for (k = 0; k + 2 * m <= n; k += m)
    {
        for (i = 0; i < m - 1; i++)
        {
            fmpz_set_ui(h, k);
            _fmpz_poly_evaluate_horner_fmpz(c, d + i * m, m - i, h);

            if (i == 0)
                acb_add_fmpz(t, t, c, wp);
            else
                acb_addmul_fmpz(t, xs + i, c, wp);
        }

        acb_add(t, t, xs + m - 1, wp);
        acb_mul(y, y, t, wp);
    }

    acb_set_round(y, y, prec);

    acb_clear(t);
    acb_clear(u);
    acb_clear(v);
    _acb_vec_clear(xs, m + 1);
    _fmpz_vec_clear(d, m * m);
    _fmpz_vec_clear(s, m + 1);
    fmpz_clear(c);
    fmpz_clear(h);
}
예제 #11
0
void
bernoulli_rev_init(bernoulli_rev_t iter, ulong nmax)
{
    long j;
    fmpz_t t;
    arb_t x;
    arf_t u;
    int round1, round2;
    long wp;

    nmax -= (nmax % 2);
    iter->n = nmax;

    iter->alloc = 0;
    if (nmax < BERNOULLI_REV_MIN)
        return;

    iter->prec = wp = bernoulli_global_prec(nmax);

    iter->max_power = bernoulli_zeta_terms(nmax, iter->prec);
    iter->alloc = iter->max_power + 1;
    iter->powers = _fmpz_vec_init(iter->alloc);
    fmpz_init(iter->pow_error);
    arb_init(iter->prefactor);
    arb_init(iter->two_pi_squared);

    arb_init(x);
    fmpz_init(t);
    arf_init(u);

    /* precompute powers */
    for (j = 3; j <= iter->max_power; j += 2)
    {
        arb_ui_pow_ui(x, j, nmax, bernoulli_power_prec(j, nmax, wp));
        arb_inv(x, x, bernoulli_power_prec(j, nmax, wp));
        round1 = arf_get_fmpz_fixed_si(t, arb_midref(x), -wp);
        fmpz_set(iter->powers + j, t);

        /* error: the radius, plus two roundings */
        arf_set_mag(u, arb_radref(x));
        round2 = arf_get_fmpz_fixed_si(t, u, -wp);
        fmpz_add_ui(t, t, (round1 != 0) + (round2 != 0));
        if (fmpz_cmp(iter->pow_error, t) < 0)
            fmpz_set(iter->pow_error, t);
    }

    /* precompute (2pi)^2 and 2*(n!)/(2pi)^n */
    arb_fac_ui(iter->prefactor, nmax, wp);
    arb_mul_2exp_si(iter->prefactor, iter->prefactor, 1);

    arb_const_pi(x, wp);
    arb_mul_2exp_si(x, x, 1);
    arb_mul(iter->two_pi_squared, x, x, wp);

    arb_pow_ui(x, iter->two_pi_squared, nmax / 2, wp);
    arb_div(iter->prefactor, iter->prefactor, x, wp);

    fmpz_clear(t);
    arb_clear(x);
    arf_clear(u);
}
예제 #12
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);
    }
}
예제 #13
0
파일: resultant.c 프로젝트: goens/flint2
void _fmpq_poly_resultant(fmpz_t rnum, fmpz_t rden, 
                          const fmpz *poly1, const fmpz_t den1, long len1, 
                          const fmpz *poly2, const fmpz_t den2, long len2)
{
    if (len2 == 1)
    {
        if (len1 == 1)
        {
            fmpz_one(rnum);
            fmpz_one(rden);
        }
        else if (len1 == 2)
        {
            fmpz_set(rnum, poly2);
            fmpz_set(rden, den2);
        }
        else
        {
            fmpz_pow_ui(rnum, poly2, len1 - 1);
            if (fmpz_is_one(den2))
            {
                fmpz_one(rden);
            }
            else
            {
                fmpz_pow_ui(rden, den2, len1 - 1);
            }
        }
    }
    else  /* len1 >= len2 >= 2 */
    {
        fmpz_t c1, c2;
        fmpz *prim1, *prim2, *g;
        long lenG = len2;

        fmpz_init(c1);
        fmpz_init(c2);

        _fmpz_vec_content(c1, poly1, len1);
        _fmpz_vec_content(c2, poly2, len2);

        prim1 = _fmpz_vec_init(len1);
        prim2 = _fmpz_vec_init(len2);
        g     = _fmpz_vec_init(len2);

        _fmpz_vec_scalar_divexact_fmpz(prim1, poly1, len1, c1);
        _fmpz_vec_scalar_divexact_fmpz(prim2, poly2, len2, c2);

        _fmpz_poly_gcd(g, prim1, len1, prim2, len2);
        FMPZ_VEC_NORM(g, lenG);

        if (lenG > 1)
        {
            fmpz_zero(rnum);
            fmpz_one(rden);
        }
        else  /* prim1, prim2 are coprime */
        {
            fmpz_t t;

            fmpz_init(t);
            _fmpz_poly_resultant(rnum, prim1, len1, prim2, len2);

            if (!fmpz_is_one(c1))
            {
                fmpz_pow_ui(t, c1, len2 - 1);
                fmpz_mul(rnum, rnum, t);
            }
            if (!fmpz_is_one(c2))
            {
                fmpz_pow_ui(t, c2, len1 - 1);
                fmpz_mul(rnum, rnum, t);
            }

            if (fmpz_is_one(den1))
            {
                if (fmpz_is_one(den2))
                    fmpz_one(rden);
                else
                    fmpz_pow_ui(rden, den2, len1 - 1);
            }
            else
            {
                if (fmpz_is_one(den2))
                    fmpz_pow_ui(rden, den1, len2 - 1);
                else
                {
                    fmpz_pow_ui(rden, den1, len2 - 1);
                    fmpz_pow_ui(t,    den2, len1 - 1);
                    fmpz_mul(rden, rden, t);
                }
            }
            _fmpq_canonicalise(rnum, rden);
            fmpz_clear(t);
        }

        fmpz_clear(c1);
        fmpz_clear(c2);
        _fmpz_vec_clear(prim1, len1);
        _fmpz_vec_clear(prim2, len2);
        _fmpz_vec_clear(g, len2);
    }
}
예제 #14
0
파일: pow.c 프로젝트: goens/flint2
#include <stdlib.h>
#include <mpir.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "fmpz_poly.h"
#include "fmpz_mod_poly.h"

void _fmpz_mod_poly_pow(fmpz *res, const fmpz *poly, long len, ulong e,
                        const fmpz_t p)
{
    ulong bit = ~((~0UL) >> 1);
    long rlen;
    long alloc = (long) e * (len - 1) + 1;
    fmpz *v = _fmpz_vec_init(alloc);
    fmpz *R, *S, *T;

    /*
       Set bits to the bitmask with a 1 one place lower than the msb of e
     */

    while ((bit & e) == 0UL)
        bit >>= 1;

    bit >>= 1;

    /*
       Trial run without any polynomial arithmetic to determine the parity
       of the number of swaps;  then set R and S accordingly
     */
예제 #15
0
파일: inv.c 프로젝트: goens/flint2
int fmpq_mat_inv(fmpq_mat_t B, const fmpq_mat_t A)
{
    long n = A->r;

    if (n == 0)
    {
        return 1;
    }
    else if (n == 1)
    {
        if (fmpq_is_zero(fmpq_mat_entry(A, 0, 0)))
            return 0;
        fmpq_inv(fmpq_mat_entry(B, 0, 0), fmpq_mat_entry(A, 0, 0));
        return 1;
    }
    else if (n == 2)
    {
        fmpq_t d;
        int success;

        fmpq_init(d);

        fmpq_mul(d, fmpq_mat_entry(A, 0, 0), fmpq_mat_entry(A, 1, 1));
        fmpq_submul(d, fmpq_mat_entry(A, 0, 1), fmpq_mat_entry(A, 1, 0));
        success = !fmpq_is_zero(d);

        if (success)
        {
            fmpq_t t00, t01, t10, t11;
            fmpq_inv(d, d);

            fmpq_init(t00);
            fmpq_init(t01);
            fmpq_init(t10);
            fmpq_init(t11);

            fmpq_mul(t00, fmpq_mat_entry(A, 1, 1), d);
            fmpq_mul(t01, fmpq_mat_entry(A, 0, 1), d);
            fmpq_mul(t10, fmpq_mat_entry(A, 1, 0), d);
            fmpq_mul(t11, fmpq_mat_entry(A, 0, 0), d);

            fmpq_set(fmpq_mat_entry(B, 0, 0), t00);
            fmpq_neg(fmpq_mat_entry(B, 0, 1), t01);
            fmpq_neg(fmpq_mat_entry(B, 1, 0), t10);
            fmpq_set(fmpq_mat_entry(B, 1, 1), t11);

            fmpq_clear(t00);
            fmpq_clear(t01);
            fmpq_clear(t10);
            fmpq_clear(t11);
        }

        fmpq_clear(d);
        return success;
    }
    else
    {
        fmpz_mat_t Aclear, Bclear, I;
        fmpz * den;
        long i;
        int success;

        fmpz_mat_init(Aclear, n, n);
        fmpz_mat_init(Bclear, n, n);
        fmpz_mat_init(I, n, n);
        den = _fmpz_vec_init(n);

        fmpq_mat_get_fmpz_mat_rowwise(Aclear, den, A);
        for (i = 0; i < n; i++)
            fmpz_set(fmpz_mat_entry(I, i, i), den + i);

        success = fmpz_mat_solve(Bclear, den, Aclear, I);
        if (success)
            fmpq_mat_set_fmpz_mat_div_fmpz(B, Bclear, den);

        fmpz_mat_clear(Aclear);
        fmpz_mat_clear(Bclear);
        fmpz_mat_clear(I);
        _fmpz_vec_clear(den, A->r);

        return success;
    }
}
예제 #16
0
void precompute_muex(fmpz **mu, long M, 
                     const long **C, const long *lenC, 
                     const fmpz *a, long n, long p, long N)
{
    const long ve = (p == 2) ? M / 4 + 1 : M / (p * (p - 1)) + 1;

    fmpz_t P, pNe, pe;
    fmpz_t apow, f, g, h;

    fmpz *nu;
    long *v;

    long i, j;

    fmpz_init_set_ui(P, p);
    fmpz_init(pNe);
    fmpz_init(pe);
    fmpz_pow_ui(pNe, P, N + ve);
    fmpz_pow_ui(pe, P, ve);

    fmpz_init(apow);
    fmpz_init(f);
    fmpz_init(g);
    fmpz_init(h);

    /* Precompute $(l!)^{-1}$ */
    nu = _fmpz_vec_init(M + 1);
    v  = malloc((M + 1) * sizeof(long));

    {
        long *D, lenD = 0, k = 0;

        for (i = 0; i <= n; i++)
            lenD += lenC[i];

        D = malloc(lenD * sizeof(long));

        for (i = 0; i <= n; i++)
            for (j = 0; j < lenC[i]; j++)
                D[k++] = C[i][j];

        _remove_duplicates(D, &lenD);
        _sort(D, lenD);

        precompute_nu(nu, v, M, D, lenD, p, N + ve);

        free(D);
    }

    for (i = 0; i <= n; i++)
    {
        long m = -1, quo, idx, w;
        fmpz *z;

        /* Set apow = a[i]^{-(p-1)} mod p^N */
        fmpz_invmod(apow, a + i, pNe);
        fmpz_powm_ui(apow, apow, p - 1, pNe);

        /*
            Run over all relevant m in [0, M]. 
            Note that lenC[i] > 0 for all i.
         */
        for (quo = 0; m <= M; quo++)
        {
            for (idx = 0; idx < lenC[i]; idx++)
            {
                m = quo * p + C[i][idx];

                if (m > M)
                    break;

                /*
                    Note that $\mu_m$ is equal to 
                    $\sum_{k=0}^{\floor{m/p}} p^{\floor{m/p}-k}\nu_{m-pk}\nu_k$
                    where $\nu_i$ denotes the number with unit part nu[i] 
                    and valuation v[i].
                 */
                w = (p == 2) ? (3 * m) / 4 - (m == 3 || m == 7) : m / p;
                z = mu[i] + lenC[i] * quo + idx;
                fmpz_zero(z);
                fmpz_one(h);
                for (j = 0; j <= m / p; j++)
                {
                    fmpz_pow_ui(f, P, ve + w - j + v[m - p*j] + v[j]);
                    fmpz_mul(g, nu + (m - p*j), nu + j);

                    fmpz_mul(f, f, g);
                    fmpz_mul(f, f, h);

                    fmpz_add(z, z, f);
                    fmpz_mod(z, z, pNe);

                    /* Set h = a[i]^{- (j+1)(p-1)} mod p^{N+e} */
                    fmpz_mul(h, h, apow);
                    fmpz_mod(h, h, pNe);
                }
                fmpz_divexact(z, z, pe);
            }
        }
    }

    fmpz_clear(P);
    fmpz_clear(pNe);
    fmpz_clear(pe);

    fmpz_clear(apow);
    fmpz_clear(f);
    fmpz_clear(g);
    fmpz_clear(h);

    _fmpz_vec_clear(nu, M + 1);
    free(v);
} 
예제 #17
0
/* Assumes len1 != 0 != len2 */
int
_fmpz_poly_gcd_heuristic(fmpz * res, const fmpz * poly1, long len1, 
                                        const fmpz * poly2, long len2)
{
	ulong bits1, bits2, max_bits, pack_bits, bound_bits, bits_G, bits_Q;
   ulong limbs1, limbs2, limbsg, pack_limbs, qlimbs;
   ulong log_glen, log_length;
   long sign1, sign2, glen, qlen;
	fmpz_t ac, bc, d, gc;
   fmpz * A, * B, * G, * Q, * t;
   mp_ptr array1, array2, arrayg, q, temp;
   int divides;

   fmpz_init(ac);
   fmpz_init(bc);
   fmpz_init(d);
   
	/* compute gcd of content of poly1 and poly2 */
   _fmpz_poly_content(ac, poly1, len1);
   _fmpz_poly_content(bc, poly2, len2);
   fmpz_gcd(d, ac, bc);

   /* special case, one of the polys is a constant */
   if (len2 == 1) /* if len1 == 1 then so does len2 */
   {
      fmpz_set(res, d);

      fmpz_clear(ac);
      fmpz_clear(bc);
	   fmpz_clear(d);

      return 1;
   }
   
   /* divide poly1 and poly2 by their content */
   A = _fmpz_vec_init(len1);
   B = _fmpz_vec_init(len2);
   _fmpz_vec_scalar_divexact_fmpz(A, poly1, len1, ac);
   _fmpz_vec_scalar_divexact_fmpz(B, poly2, len2, bc);
   fmpz_clear(ac);
   fmpz_clear(bc);
	   
	/* special case, one of the polys is length 2 */
   if (len2 == 2) /* if len1 == 2 then so does len2 */
	{
		Q = _fmpz_vec_init(len1 - len2 + 1);
		if (_fmpz_poly_divides(Q, A, len1, B, 2))
      {
		   _fmpz_vec_scalar_mul_fmpz(res, B, 2, d);
         if (fmpz_sgn(res + 1) < 0)
            _fmpz_vec_neg(res, res, 2);
      }
		else  
      {
			fmpz_set(res, d);
         fmpz_zero(res + 1);
      }

		fmpz_clear(d);
		_fmpz_vec_clear(A, len1);
      _fmpz_vec_clear(B, len2);
      _fmpz_vec_clear(Q, len1 - len2 + 1);
      
      return 1;
	}
	
   /* 
      Determine how many bits (pack_bits) to pack into. The bound 
      bound_bits ensures that if G | A and G | B with G primitive 
      then G is the gcd of A and B. The bound is taken from 
      http://arxiv.org/abs/cs/0206032v1
   */
   bits1 = FLINT_ABS(_fmpz_vec_max_bits(A, len1));
	bits2 = FLINT_ABS(_fmpz_vec_max_bits(B, len2));
	max_bits = FLINT_MAX(bits1, bits2);
   			
	bound_bits = FLINT_MIN(bits1, bits2) + 6; 
	pack_bits = FLINT_MAX(bound_bits, max_bits); /* need to pack original polys */
   pack_limbs = (pack_bits - 1)/FLINT_BITS + 1;
   
	if (pack_bits >= 32) /* pack into multiples of limbs if >= 32 bits */
      pack_bits = FLINT_BITS*pack_limbs;
		
   /* allocate space to pack into */
   limbs1 = (pack_bits*len1 - 1)/FLINT_BITS + 1;
   limbs2 = (pack_bits*len2 - 1)/FLINT_BITS + 1;
	array1 = flint_calloc(limbs1, sizeof(mp_limb_t));
   array2 = flint_calloc(limbs2, sizeof(mp_limb_t));
   arrayg = flint_calloc(limbs2, sizeof(mp_limb_t));
   
   /* pack first poly and normalise */
   sign1 = (long) fmpz_sgn(A + len1 - 1);
	_fmpz_poly_bit_pack(array1, A, len1, pack_bits, sign1);
	while (array1[limbs1 - 1] == 0) limbs1--;

   /* pack second poly and normalise */
   sign2 = (long) fmpz_sgn(B + len2 - 1);
   _fmpz_poly_bit_pack(array2, B, len2, pack_bits, sign2);
	while (array2[limbs2 - 1] == 0) limbs2--;
	
	/* compute integer GCD */
   limbsg = mpn_gcd_full(arrayg, array1, limbs1, array2, limbs2);
	
   /* 
      Make space for unpacked gcd. May have one extra coeff due to 
      1 0 -x being packed as 0 -1 -x. 
   */
   glen = FLINT_MIN((limbsg*FLINT_BITS)/pack_bits + 1, len2); 
   G = _fmpz_vec_init(glen);
   
   /* unpack gcd */
   _fmpz_poly_bit_unpack(G, glen, arrayg, pack_bits, 0);
   while (G[glen - 1] == 0) glen--;
   
	/* divide by any content */
   fmpz_init(gc);
	_fmpz_poly_content(gc, G, glen);

   if (!fmpz_is_one(gc)) 
      limbsg = mpn_tdiv_q_fmpz_inplace(arrayg, limbsg, gc);

   /* make space for quotient and remainder of first poly by gcd */
   qlimbs = limbs1 - limbsg + 1;
   qlen = FLINT_MIN(len1, (qlimbs*FLINT_BITS)/pack_bits + 1);
   qlimbs = (qlen*pack_bits - 1)/FLINT_BITS + 1;
   q = flint_calloc(qlimbs, sizeof(mp_limb_t));
   temp = flint_malloc(limbsg*sizeof(mp_limb_t));
   
	divides = 0;

   if (mpn_divides(q, array1, limbs1, arrayg, limbsg, temp)) 
	{
      /* unpack quotient of first poly by gcd */
      Q = _fmpz_vec_init(len1); 
      t = _fmpz_vec_init(len1 + glen);
      _fmpz_poly_bit_unpack(Q, qlen, q, pack_bits, 0);
      while (Q[qlen - 1] == 0) qlen--;
      
      /* divide by content */
      _fmpz_vec_scalar_divexact_fmpz(G, G, glen, gc);
		
      /* check if we really need to multiply out to check for exact quotient */
      bits_G = FLINT_ABS(_fmpz_vec_max_bits(G, glen));
		bits_Q = FLINT_ABS(_fmpz_vec_max_bits(Q, qlen));
		log_glen = FLINT_BIT_COUNT(glen);
		log_length = FLINT_MIN(log_glen, FLINT_BIT_COUNT(qlen));
       
	   divides = (bits_G + bits_Q + log_length < pack_bits);
     
      if (!divides) /* need to multiply out to check exact quotient */
         divides = multiplies_out(A, len1, Q, qlen, G, glen, sign1, t);

		if (divides) /* quotient really was exact */
		{
         mpn_zero(q, qlimbs);
          
         if (mpn_divides(q, array2, limbs2, arrayg, limbsg, temp)) 
	      {
            /* unpack quotient of second poly by gcd */
            qlimbs = limbs2 - limbsg + 1;
            qlen = FLINT_MIN(len2, (qlimbs*FLINT_BITS - 1)/pack_bits + 1);
            _fmpz_poly_bit_unpack(Q, qlen, q, pack_bits, 0);
            while (Q[qlen - 1] == 0) qlen--;
            
            /* check if we really need to multiply out to check for exact quotient */
            bits_Q = FLINT_ABS(_fmpz_vec_max_bits(Q, qlen));
				log_length = FLINT_MIN(log_glen, FLINT_BIT_COUNT(qlen));

				divides = (bits_G + bits_Q + log_length < pack_bits);
		      
            if (!divides) /* we need to multiply out */
               divides = multiplies_out(B, len2, Q, qlen, G, glen, sign1, t);
			} 
		} 

      _fmpz_vec_clear(t, len1 + glen);
      _fmpz_vec_clear(Q, len1);
	}

   flint_free(q); 
	flint_free(temp); 
	flint_free(arrayg); 
	flint_free(array1); 
	flint_free(array2); 
	fmpz_clear(gc); 
	
	_fmpz_vec_clear(A, len1);
	_fmpz_vec_clear(B, len2);
	
   /* we found the gcd, so multiply by content */
   if (divides)
   {
	   _fmpz_vec_zero(res + glen, len2 - glen);
      _fmpz_vec_scalar_mul_fmpz(res, G, glen, d);
   }
		
   fmpz_clear(d);
   _fmpz_vec_clear(G, glen);
		
   return divides;
}
예제 #18
0
void diagfrob(padic_mat_t F, const fmpz *a, long n, long d, long N, 
              const padic_ctx_t ctx, const int verbose)
{
    const fmpz *P = ctx->p;
    const long p  = fmpz_get_si(P);

    const long delta = diagfrob_delta(n, P);
    const long N2    = N - n + 2 * (padic_val_fac_ui(n - 1, P) + n + delta);
    const long M     = (p * p * (N2 + n_clog(N2 + 3, p) + 4) + (p - 2))
                       / (p - 1) - 1;

    mon_t *B;
    long *iB, lenB, lo, hi;

    long i, j, k, *u, *v;

    long **C, *lenC;

    fmpz *dinv, **mu;

    clock_t t0 = 0, t1 = 0;
    double t;

    gmc_basis_sets(&B, &iB, &lenB, &lo, &hi, n, d);

if (verbose)
{
    printf("Frobenius on the diagonal fibre\n");
    printf("N  = %ld\n", N);
    printf("N2 = %ld\n", N2);
    printf("M  = %ld\n", M);
}

if (verbose)
{
    printf("Basis for H_{dR}^%ld(U)\n", n);
    gmc_basis_print(B, iB, lenB, n, d);
    printf("\n");
}

    C    = malloc((n + 1) * sizeof(long *));
    C[0] = malloc((n + 1) * lenB * sizeof(long));
    for (i = 1; i <= n; i++)
    {
        C[i] = C[i-1] + lenB;
    }
    lenC = malloc((n + 1) * sizeof(long));

    for (i = 0; i <= n; i++)
    {
        _congruence_class(C[i], &lenC[i], i, B, lenB, n, d, p);
    }

    dinv  = _fmpz_vec_init(M/p + 1);
    mu    = malloc((n + 1) * sizeof(fmpz *));
    for (i = 0; i <= n; i++)
    {
        mu[i] = _fmpz_vec_init(((M + 1 + p - 1) / p) * lenC[i]);
    }

    u = malloc((n + 1) * sizeof(long));
    v = malloc((n + 1) * sizeof(long));

if (verbose)
{
    printf("Sequence d^{-r}\n");
    t0 = clock();
}

    precompute_dinv(dinv, M, d, p, N2);

if (verbose)
{
    t1 = clock();
    t  = (double) (t1 - t0) / CLOCKS_PER_SEC;
    printf("T = %f\n", t);
}

if (verbose)
{
    printf("Sequence mu_{m}\n");
    t0 = clock();
}

    precompute_muex(mu, M, (const long **) C, lenC, a, n, p, N2);  /* XXX */

if (verbose)
{
    t1 = clock();
    t  = (double) (t1 - t0) / CLOCKS_PER_SEC;
    printf("T = %f\n", t);
}

if (verbose)
{
    printf("Matrix F\n");
    t0 = clock();
}

    for (i = 0; i < lenB; i++)
        for (j = 0; j < lenB; j++)
        {
            for (k = 0; k <= n; k++)
            {
                u[k] = mon_get_exp(B[i], k);
                v[k] = mon_get_exp(B[j], k);
                if ((p * (u[k] + 1) - (v[k] + 1)) % d != 0)
                {
                     break;
                }
            }
            if (k <= n)
            {
                fmpz_zero(padic_mat_entry(F, i, j));
            }
            else
            {
                long o;

                entry(padic_mat_entry(F, i, j), &o, 
                      u, v, a, dinv, (const fmpz **) mu, M, (const long **) C, lenC, n, d, p, N, N2);

                if (o != - delta)
                {
                    fmpz_t w;
                    fmpz_init(w);
                    fmpz_pow_ui(w, P, o + delta);
                    fmpz_mul(padic_mat_entry(F, i, j), 
                             padic_mat_entry(F, i, j), w);
                    fmpz_clear(w);
                }
            }
        }

    padic_mat_val(F) = - delta;
    _padic_mat_canonicalise(F, ctx);

if (verbose)
{
    t1 = clock();
    t  = (double) (t1 - t0) / CLOCKS_PER_SEC;
    printf("T = %f\n", t);
}

    _fmpz_vec_clear(dinv, M/p + 1);
    for (i = 0; i <= n; i++)
    {
        _fmpz_vec_clear(mu[i], ((M + 1 + p - 1) / p) * lenC[i]);
    }
    free(mu);
    free(C[0]);
    free(C);
    free(lenC);
    free(u);
    free(v);
    free(B);
    free(iB);
}
예제 #19
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;
}
예제 #20
0
void
_fmpq_poly_interpolate_fmpz_vec(fmpz * poly, fmpz_t den,
                                    const fmpz * xs, const fmpz * ys, long n)
{
    fmpz *P, *Q, *w;
    fmpz_t t;

    long i, j;

    /* Constant */
    if (n == 1)
    {
        fmpz_set(poly, ys);
        fmpz_one(den);
        return;
    }

    /* Linear */
    if (n == 2)
    {
        fmpz_sub(den, xs, xs + 1);
        fmpz_sub(poly + 1, ys, ys + 1);
        fmpz_mul(poly, xs, ys + 1);
        fmpz_submul(poly, xs + 1, ys);
        return;
    }

    fmpz_init(t);

    P = _fmpz_vec_init(n + 1);
    Q = _fmpz_vec_init(n);
    w = _fmpz_vec_init(n);

    /* P = (x-x[0])*(x-x[1])*...*(x-x[n-1]) */
    _fmpz_poly_product_roots_fmpz_vec(P, xs, n);

    /* Weights */
    for (i = 0; i < n; i++)
    {
        fmpz_one(w + i);
        for (j = 0; j < n; j++)
        {
            if (i != j)
            {
                fmpz_sub(t, xs + i, xs + j);
                fmpz_mul(w + i, w + i, t);
            }
        }
    }

    _fmpz_vec_zero(poly, n);
    _fmpz_vec_lcm(den, w, n);

    for (i = 0; i < n; i++)
    {
        /* Q = P / (x - x[i]) */
        _fmpz_poly_div_root(Q, P, n + 1, xs + i);

        /* result += Q * weight(i) */
        fmpz_divexact(t, den, w + i);
        fmpz_mul(t, t, ys + i);
        _fmpz_vec_scalar_addmul_fmpz(poly, Q, n, t);
    }

    _fmpz_vec_clear(P, n + 1);
    _fmpz_vec_clear(Q, n);
    _fmpz_vec_clear(w, n);
    fmpz_clear(t);
}
예제 #21
0
void
fmpz_poly_pseudo_divrem_basecase(fmpz_poly_t Q, fmpz_poly_t R,
                                 ulong * d, const fmpz_poly_t A,
                                 const fmpz_poly_t B)
{
    long lenq, lenr;
    fmpz *q, *r;

    if (B->length == 0)
    {
        printf("Exception: division by zero in fmpz_poly_pseudo_divrem_basecase\n");
        abort();
    }
    if (Q == R)
    {
        printf("Exception: output arguments Q and R may not be aliased\n");
        abort();
    }
    if (A->length < B->length)
    {
        fmpz_poly_zero(Q);
        fmpz_poly_set(R, A);
        *d = 0;
        return;
    }

    lenq = A->length - B->length + 1;
    lenr = A->length;
    if (Q == A || Q == B)
        q = _fmpz_vec_init(lenq);
    else
    {
        fmpz_poly_fit_length(Q, lenq);
        q = Q->coeffs;
    }
    if (R == B)
        r = _fmpz_vec_init(lenr);
    else
    {
        fmpz_poly_fit_length(R, lenr);
        r = R->coeffs;
    }
    
    _fmpz_poly_pseudo_divrem_basecase(q, r, d, A->coeffs, A->length, 
                                               B->coeffs, B->length);
    
    for (lenr = B->length - 2; (lenr >= 0) && !r[lenr]; lenr--) ;
    lenr++;
    
    if (Q == A || Q == B)
    {
        _fmpz_vec_clear(Q->coeffs, Q->alloc);
        Q->coeffs = q;
        Q->alloc = lenq;
        Q->length = lenq;
    }
    else
        _fmpz_poly_set_length(Q, lenq);
    if (R == B)
    {
        _fmpz_vec_clear(R->coeffs, R->alloc);
        R->coeffs = r;
        R->alloc = A->length;
        R->length = lenr;
    }
    else
        _fmpz_poly_set_length(R, lenr);
}
예제 #22
0
파일: signature.c 프로젝트: goens/flint2
void _fmpz_poly_signature(long * r1, long * r2, fmpz * poly, long len)
{
    fmpz *A, *B, *f, *g, *h, *w;
    long lenA, lenB;
    int s, t;

    if (len <= 2)
    {
        *r1 = (len == 2);
        *r2 = 0;
        return;
    }

    w = _fmpz_vec_init(2 * len + 2);
    A = w;
    B = w + len;
    lenA = len;
    lenB = lenA - 1;
    f = w + 2 * len - 1;
    g = w + 2 * len;
    h = w + 2 * len + 1;

    _fmpz_poly_primitive_part(A, poly, lenA);
    _fmpz_poly_derivative(B, A, lenA);
    _fmpz_poly_primitive_part(B, B, lenB);

    fmpz_one(g);
    fmpz_one(h);

    s = 1;
    t = (lenA & 1L) ? -s : s;
    *r1 = 1;

    while (1)
    {
        long delta = lenA - lenB;
        int sgnA;

        _fmpz_poly_pseudo_rem_cohen(A, A, lenA, B, lenB);

        lenA = lenB;
        FMPZ_VEC_NORM(A, lenA);

        if (lenA == 0)
        {
            printf("Exception: non-squarefree polynomial detected in fmpz_poly_signature\n");
            _fmpz_vec_clear(w, 2 * len + 2);
            abort();
        }

        if ((fmpz_sgn(B + (lenB - 1)) > 0) || (delta & 1L))
            _fmpz_vec_neg(A, A, lenA);

        sgnA = fmpz_sgn(A + (lenA - 1));
        if (sgnA != s)
        {
            s = -s;
            (*r1)--;
        }
        if (sgnA != ((lenA & 1L) ? t : -t))
        {
            t = -t;
            (*r1)++;
        }

        if (lenA == 1)
        {
            *r2 = ((len - 1) - *r1) / 2;

            _fmpz_vec_clear(w, 2 * len + 2);
            return;
        }
        else
        {
            {
                fmpz * temp = A;
                A = B;
                B = temp;
            }
            {
                long temp = lenA;
                lenA = lenB;
                lenB = temp;
            }

            if (delta == 1)
            {
                fmpz_mul(f, g, h);
                _fmpz_vec_scalar_divexact_fmpz(B, B, lenB, f);
                fmpz_set(g, A + (lenA - 1));
                fmpz_set(h, g);
            }
            else
            {
                fmpz_pow_ui(f, h, delta);
                fmpz_mul(f, f, g);
                _fmpz_vec_scalar_divexact_fmpz(B, B, lenB, f);
                fmpz_pow_ui(f, h, delta - 1);
                fmpz_pow_ui(g, A + (lenA - 1), delta);
                fmpz_divexact(h, g, f);
                fmpz_set(g, A + (lenA - 1));
            }
        }
    }
}
예제 #23
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;
}
예제 #24
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;
}