Esempio n. 1
0
File: set_str.c Progetto: isuruf/arb
static int
arb_set_float_str(arb_t res, const char * inp, slong prec)
{
    char * emarker;
    char * buf;
    int error;
    slong i;
    fmpz_t exp;
    fmpz_t man;
    slong num_int, num_frac;
    int after_radix;

    if (inp[0] == '+')
    {
        return arb_set_float_str(res, inp + 1, prec);
    }

    if (inp[0] == '-')
    {
        error = arb_set_float_str(res, inp + 1, prec);
        arb_neg(res, res);
        return error;
    }

    if (strcmp(inp, "inf") == 0)
    {
        arb_pos_inf(res);
        return 0;
    }

    if (strcmp(inp, "nan") == 0)
    {
        arb_indeterminate(res);
        return 0;
    }

    error = 0;
    fmpz_init(exp);
    fmpz_init(man);
    buf = flint_malloc(strlen(inp) + 1);

    emarker = strchr(inp, 'e');

    /* parse exponent (0 by default) */
    if (emarker != NULL)
    {
        /* allow e+42 as well as e42 */
        if (emarker[1] == '+')
        {
            if (!(emarker[2] >= '0' && emarker[2] <= '9'))
                error = 1;
            else
                error = fmpz_set_str(exp, emarker + 2, 10);
        }
        else
            error = fmpz_set_str(exp, emarker + 1, 10);

        if (error)
            goto cleanup;
    }

    /* parse floating-point part */
    {
        num_int = 0;
        num_frac = 0;
        after_radix = 0;

        for (i = 0; inp + i != emarker && inp[i] != '\0'; i++)
        {
            if (inp[i] == '.' && !after_radix)
            {
                after_radix = 1;
            }
            else if (inp[i] >= '0' && inp[i] <= '9')
            {
                buf[num_int + num_frac] = inp[i];

                num_frac += after_radix;
                num_int += !after_radix;
            }
            else
            {
                error = 1;
                goto cleanup;
            }
        }

        buf[num_int + num_frac] = '\0';

        /* put trailing zeros into the exponent */
        while (num_int + num_frac > 1 && buf[num_int + num_frac - 1] == '0')
        {
            buf[num_int + num_frac - 1] = '\0';
            num_frac--;
        }

        fmpz_sub_si(exp, exp, num_frac);

        error = fmpz_set_str(man, buf, 10);
        if (error)
            goto cleanup;
    }

    if (fmpz_is_zero(man))
    {
        arb_zero(res);
    }
    else if (fmpz_is_zero(exp))
    {
        arb_set_round_fmpz(res, man, prec);
    }
    else
    {
        arb_t t;
        arb_init(t);
        arb_set_ui(t, 10);
        arb_set_fmpz(res, man);

        if (fmpz_sgn(exp) > 0)
        {
            arb_pow_fmpz_binexp(t, t, exp, prec + 4);
            arb_mul(res, res, t, prec);
        }
        else
        {
            fmpz_neg(exp, exp);
            arb_pow_fmpz_binexp(t, t, exp, prec + 4);
            arb_div(res, res, t, prec);
        }

        arb_clear(t);
    }

cleanup:
    fmpz_clear(exp);
    fmpz_clear(man);
    flint_free(buf);

    if (error)
        arb_indeterminate(res);

    return error;
}
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);

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

    

    /* Check aliasing */
    for (i = 0; i < 10 * flint_test_multiplier(); i++)
    {
        fmpz_poly_t f, g;
        slong n;

        fmpz_poly_init(f);
        fmpz_poly_init(g);
        fmpz_poly_randtest(g, state, n_randint(state, 50),
            1+n_randint(state,100));
        fmpz_poly_set_coeff_ui(g, 0, 0);
        fmpz_poly_set_coeff_ui(g, 1, 1);
        if (n_randlimb(state) % 2)
            fmpz_poly_neg(g, g);  /* get -x term */
        n = n_randint(state, 50);

        fmpz_poly_revert_series_lagrange(f, g, n);
        fmpz_poly_revert_series_lagrange(g, g, n);

        result = (fmpz_poly_equal(f, g));
        if (!result)
        {
            flint_printf("FAIL (aliasing):\n");
            fmpz_poly_print(f), flint_printf("\n\n");
            fmpz_poly_print(g), flint_printf("\n\n");
            abort();
        }

        fmpz_poly_clear(f);
        fmpz_poly_clear(g);
    }

    /* Check f(f^(-1)) = id */
    for (i = 0; i < 10 * flint_test_multiplier(); i++)
    {
        fmpz_poly_t f, g, h;
        slong n;

        fmpz_poly_init(f);
        fmpz_poly_init(g);
        fmpz_poly_init(h);
        fmpz_poly_randtest(g, state, n_randint(state, 50), 1+n_randint(state,100));
        fmpz_poly_set_coeff_ui(g, 0, 0);
        fmpz_poly_set_coeff_ui(g, 1, 1);
        if (n_randlimb(state) % 2)
            fmpz_poly_neg(g, g);  /* get -x term */
        n = n_randint(state, 50);

        fmpz_poly_revert_series_lagrange(f, g, n);
        fmpz_poly_compose_series(h, g, f, n);

        result = ((n <= 1 && fmpz_poly_is_zero(h)) ||
            (h->length == 2 && fmpz_is_zero(h->coeffs + 0) &&
                fmpz_is_one(h->coeffs + 1)));
        if (!result)
        {
            flint_printf("FAIL (comparison):\n");
            fmpz_poly_print(f), flint_printf("\n\n");
            fmpz_poly_print(g), flint_printf("\n\n");
            fmpz_poly_print(h), flint_printf("\n\n");
            abort();
        }

        fmpz_poly_clear(f);
        fmpz_poly_clear(g);
        fmpz_poly_clear(h);
    }

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

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

    /* Just one specific test */
    {
        fmpz_poly_t f, g;
        fmpz_t a, b, div;
        slong nbits;

        fmpz_poly_init(f);
        fmpz_poly_init(g);
        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(div);

        fmpz_poly_set_str(f, "11  -15 -2 -2 17 0 0 6 0 -5 1 -1");
        fmpz_poly_set_str(g, "9  2 1 1 1 1 1 0 -1 -2");
        fmpz_set_str(div, "11", 10);
        nbits = 42;
        fmpz_poly_resultant_modular_div(a, f, g, div, nbits);
        /* The result is -44081924855067 = -4007447714097 * 11
         * We supply 11 and the missing divisor is less then 2^35 */
        fmpz_set_str(b, "-4007447714097", 10);

        result = (fmpz_equal(a, b));
        if (!result)
        {
            flint_printf("FAIL:\n");
            flint_printf("f(x) = "), fmpz_poly_print_pretty(f, "x"), flint_printf("\n\n");
            flint_printf("g(x) = "), fmpz_poly_print_pretty(g, "x"), flint_printf("\n\n");
            flint_printf("res(f, h)/div  = "), fmpz_print(b), flint_printf("\n\n");
            flint_printf("res_mod_div(f, h) = "), fmpz_print(a), flint_printf("\n\n");
            flint_printf("divr = "), fmpz_print(div), flint_printf("\n\n");
            flint_printf("bitsbound = %wd", nbits), flint_printf("\n\n");

            abort();
        }

        fmpz_poly_clear(f);
        fmpz_poly_clear(g);
        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(div);
    }

    /* Check that R(fg, h) = R(f, h) R(g, h) */
    for (i = 0; i < 100; i++)
    {
        fmpz_t a, b, c, d;
        fmpz_poly_t f, g, h, p;
        slong nbits;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(d);
        fmpz_poly_init(f);
        fmpz_poly_init(g);
        fmpz_poly_init(h);
        fmpz_poly_init(p);
        fmpz_poly_randtest(f, state, n_randint(state, 50), 100);
        fmpz_poly_randtest(g, state, n_randint(state, 50), 100);
        fmpz_poly_randtest(h, state, n_randint(state, 50), 100);

        fmpz_poly_resultant_modular(a, f, h);
        fmpz_poly_resultant_modular(b, g, h);

        if (fmpz_is_zero(b) || fmpz_is_zero(a)) 
        {
           fmpz_clear(b);
           fmpz_clear(a);
           fmpz_poly_clear(f);
           fmpz_poly_clear(g);
           fmpz_poly_clear(h);
           continue;
        }

        fmpz_mul(c, a, b);
        fmpz_poly_mul(p, f, g);
        nbits = (slong)fmpz_bits(a) + 1; /* for sign */
        fmpz_poly_resultant_modular_div(d, p, h, b, nbits);

        result = (fmpz_equal(a, d));
        if (!result)
        {
            flint_printf("FAIL:\n");
            flint_printf("p(x) = "), fmpz_poly_print_pretty(p, "x"), flint_printf("\n\n");
            flint_printf("h(x) = "), fmpz_poly_print_pretty(h, "x"), flint_printf("\n\n");
            flint_printf("res(p, h) = "), fmpz_print(c), flint_printf("\n\n");
            flint_printf("res(p, h) = "), fmpz_print(a), flint_printf(" * "), fmpz_print(b), flint_printf("\n\n");
            flint_printf("supplied divisor = "), fmpz_print(b), flint_printf("\n\n");
            flint_printf("result should be = "), fmpz_print(a), flint_printf("\n\n");
            flint_printf("res(p, h)/div    = "), fmpz_print(d), flint_printf("\n\n");
            flint_printf("bitsbound for result = %wd", nbits), flint_printf("\n\n");
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(d);
        fmpz_poly_clear(f);
        fmpz_poly_clear(g);
        fmpz_poly_clear(h);
        fmpz_poly_clear(p);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}
Esempio n. 4
0
void
fmpz_poly_complex_roots_squarefree(const fmpz_poly_t poly,
                                   slong initial_prec,
                                   slong target_prec,
                                   slong print_digits)
{
    slong i, j, prec, deg, deg_deflated, isolated, maxiter, deflation;
    acb_poly_t cpoly, cpoly_deflated;
    fmpz_poly_t poly_deflated;
    acb_ptr roots, roots_deflated;
    int removed_zero;

    if (fmpz_poly_degree(poly) < 1)
        return;

    fmpz_poly_init(poly_deflated);
    acb_poly_init(cpoly);
    acb_poly_init(cpoly_deflated);

    /* try to write poly as poly_deflated(x^deflation), possibly multiplied by x */
    removed_zero = fmpz_is_zero(poly->coeffs);
    if (removed_zero)
        fmpz_poly_shift_right(poly_deflated, poly, 1);
    else
        fmpz_poly_set(poly_deflated, poly);
    deflation = fmpz_poly_deflation(poly_deflated);
    fmpz_poly_deflate(poly_deflated, poly_deflated, deflation);

    deg = fmpz_poly_degree(poly);
    deg_deflated = fmpz_poly_degree(poly_deflated);

    flint_printf("searching for %wd roots, %wd deflated\n", deg, deg_deflated);

    roots = _acb_vec_init(deg);
    roots_deflated = _acb_vec_init(deg_deflated);

    for (prec = initial_prec; ; prec *= 2)
    {
        acb_poly_set_fmpz_poly(cpoly_deflated, poly_deflated, prec);
        maxiter = FLINT_MIN(FLINT_MAX(deg_deflated, 32), prec);

        TIMEIT_ONCE_START
        flint_printf("prec=%wd: ", prec);
        isolated = acb_poly_find_roots(roots_deflated, cpoly_deflated,
                                       prec == initial_prec ? NULL : roots_deflated, maxiter, prec);
        flint_printf("%wd isolated roots | ", isolated);
        TIMEIT_ONCE_STOP

        if (isolated == deg_deflated)
        {
            if (!check_accuracy(roots_deflated, deg_deflated, target_prec))
                continue;

            if (deflation == 1)
            {
                _acb_vec_set(roots, roots_deflated, deg_deflated);
            }
            else  /* compute all nth roots */
            {
                acb_t w, w2;

                acb_init(w);
                acb_init(w2);

                acb_unit_root(w, deflation, prec);
                acb_unit_root(w2, 2 * deflation, prec);

                for (i = 0; i < deg_deflated; i++)
                {
                    if (arf_sgn(arb_midref(acb_realref(roots_deflated + i))) > 0)
                    {
                        acb_root_ui(roots + i * deflation,
                                    roots_deflated + i, deflation, prec);
                    }
                    else
                    {
                        acb_neg(roots + i * deflation, roots_deflated + i);
                        acb_root_ui(roots + i * deflation,
                                    roots + i * deflation, deflation, prec);
                        acb_mul(roots + i * deflation,
                                roots + i * deflation, w2, prec);
                    }

                    for (j = 1; j < deflation; j++)
                    {
                        acb_mul(roots + i * deflation + j,
                                roots + i * deflation + j - 1, w, prec);
                    }
                }

                acb_clear(w);
                acb_clear(w2);
            }

            /* by assumption that poly is squarefree, must be just one */
            if (removed_zero)
                acb_zero(roots + deg_deflated * deflation);

            if (!check_accuracy(roots, deg, target_prec))
                continue;

            acb_poly_set_fmpz_poly(cpoly, poly, prec);

            if (!acb_poly_validate_real_roots(roots, cpoly, prec))
                continue;

            for (i = 0; i < deg; i++)
            {
                if (arb_contains_zero(acb_imagref(roots + i)))
                    arb_zero(acb_imagref(roots + i));
            }

            flint_printf("done!\n");
            break;
        }
    }

    if (print_digits != 0)
    {
        _acb_vec_sort_pretty(roots, deg);

        for (i = 0; i < deg; i++)
        {
            acb_printn(roots + i, print_digits, 0);
            flint_printf("\n");
        }
    }

    fmpz_poly_clear(poly_deflated);
    acb_poly_clear(cpoly);
    acb_poly_clear(cpoly_deflated);
    _acb_vec_clear(roots, deg);
    _acb_vec_clear(roots_deflated, deg_deflated);
}
Esempio n. 5
0
int
main(void)
{
    int i, result;

    padic_ctx_t ctx;
    fmpz_t p;
    slong N;

    FLINT_TEST_INIT(state);

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

    /* Check aliasing */
    for (i = 0; i < 1000; i++)
    {
        padic_poly_t a, b, c;
        slong n;

        fmpz_init_set_ui(p, n_randtest_prime(state, 0));
        N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) 
            + PADIC_TEST_PREC_MIN;
        padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);

        padic_poly_init2(a, 0, N);
        padic_poly_init2(b, 0, N);
        padic_poly_init2(c, 0, N);

        padic_poly_randtest(a, state, n_randint(state, 100) + 1, ctx);
        if (fmpz_is_zero(a->coeffs))
        {
            fmpz_randtest_not_zero(a->coeffs, state, 20);
            fmpz_remove(a->coeffs, a->coeffs, p);
            padic_poly_reduce(a, ctx);
        } else
            fmpz_remove(a->coeffs, a->coeffs, p);
        
        padic_poly_set(b, a, ctx);
        n = n_randint(state, 100) + 1;

        padic_poly_inv_series(c, b, n, ctx);
        padic_poly_inv_series(b, b, n, ctx);

        result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx));
        if (!result)
        {
            flint_printf("FAIL:\n");
            flint_printf("a = "), padic_poly_print(a, ctx), flint_printf("\n\n");
            flint_printf("b = "), padic_poly_print(b, ctx), flint_printf("\n\n");
            flint_printf("c = "), padic_poly_print(c, ctx), flint_printf("\n\n");
            abort();
        }

        padic_poly_clear(a);
        padic_poly_clear(b);
        padic_poly_clear(c);

        padic_ctx_clear(ctx);
        fmpz_clear(p);
    }

    /*
        Check correctness: 

        If ord_p(a) = v then we can compute b = a^{-1} mod p^N 
        and we will have a b = 1 mod p^{N-|v|}.  Thus, require 
        that N - |v| > 0.
     */
    for (i = 0; i < 1000; i++)
    {
        padic_poly_t a, b, c;
        slong n, N2;

        fmpz_init_set_ui(p, n_randtest_prime(state, 0));
        N = n_randint(state, PADIC_TEST_PREC_MAX - 1) + 1;
        padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES);

        padic_poly_init2(a, 0, N);
        padic_poly_init2(b, 0, N);

        {
            slong i, len = n_randint(state, 10) + 1;
            int alloc;
            fmpz_t pow;

            padic_poly_fit_length(a, len);
            _padic_poly_set_length(a, len);
            a->val = n_randint(state, N);
            if (n_randint(state, 2))
                a->val = - a->val;

            alloc = _padic_ctx_pow_ui(pow, N - a->val, ctx);

            for (i = 0; i < len; i++)
                fmpz_randm(a->coeffs + i, state, pow);
            while (fmpz_is_zero(a->coeffs))
                fmpz_randm(a->coeffs, state, pow);
            fmpz_remove(a->coeffs, a->coeffs, p);
            _padic_poly_normalise(a);

            if (alloc)
                fmpz_clear(pow);
        }

        n = n_randint(state, 100) + 1;

        N2 = N - FLINT_ABS(a->val);
        padic_poly_init2(c, 0, N2);

        padic_poly_inv_series(b, a, n, ctx);
        padic_poly_mul(c, a, b, ctx);
        padic_poly_truncate(c, n, p);

        result = (padic_poly_is_one(c) && padic_poly_is_reduced(b, ctx));
        if (!result)
        {
            flint_printf("FAIL:\n");
            flint_printf("a = "), padic_poly_print(a, ctx), flint_printf("\n\n");
            flint_printf("b = "), padic_poly_print(b, ctx), flint_printf("\n\n");
            flint_printf("c = "), padic_poly_print(c, ctx), flint_printf("\n\n");
            flint_printf("N = %wd\n", N);
            flint_printf("N2 = %wd\n", N2);
            abort();
        }

        padic_poly_clear(a);
        padic_poly_clear(b);
        padic_poly_clear(c);

        padic_ctx_clear(ctx);
        fmpz_clear(p);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Esempio n. 6
0
void
fmpz_fdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h)
{
    fmpz c1 = *g;
    fmpz c2 = *h;

    if (fmpz_is_zero(h))
    {
        printf("Exception: division by zero in fmpz_fdiv_q\n");
        abort();
    }

    if (!COEFF_IS_MPZ(c1))      /* g is small */
    {
        if (!COEFF_IS_MPZ(c2))  /* h is also small */
        {
            fmpz q = c1 / c2;   /* compute C quotient */
            fmpz r = c1 - c2 * q;   /* compute remainder */

            if ((c2 > 0L && r < 0L) || (c2 < 0L && r > 0L))
            {
                q--;            /* q cannot overflow as remainder implies |c2| != 1 */
                r += c2;
            }

            fmpz_set_si(f, q);
            fmpz_set_si(s, r);
        }
        else                    /* h is large and g is small */
        {
            if (c1 == 0L)
            {
                fmpz_set_ui(f, 0L); /* g is zero */
                fmpz_set_si(s, c1);
            }
            else if ((c1 < 0L && fmpz_sgn(h) < 0) || (c1 > 0L && fmpz_sgn(h) > 0))  /* signs are the same */
            {
                fmpz_zero(f);   /* quotient is positive, round down to zero */
                fmpz_set_si(s, c1);
            }
            else
            {
                fmpz_add(s, g, h);
                fmpz_set_si(f, -1L);    /* quotient is negative, round down to minus one */
            }
        }
    }
    else                        /* g is large */
    {
        __mpz_struct *mpz_ptr, *mpz_ptr2;

        _fmpz_promote(f); /* must not hang on to ptr whilst promoting s */
        mpz_ptr2 = _fmpz_promote(s);
		mpz_ptr  = COEFF_TO_PTR(*f);

		if (!COEFF_IS_MPZ(c2))  /* h is small */
        {
            if (c2 > 0)         /* h > 0 */
            {
                mpz_fdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), c2);
            }
            else
            {
                mpz_cdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), -c2);
                mpz_neg(mpz_ptr, mpz_ptr);
            }
        }
        else                    /* both are large */
        {
            mpz_fdiv_qr(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2));
        }
        _fmpz_demote_val(f);    /* division by h may result in small value */
        _fmpz_demote_val(s);    /* division by h may result in small value */
    }
}
Esempio n. 7
0
int main()
{
    long iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 1000; iter++)
    {
        long qbits1, rbits1, rbits2, n;
        fmpq_poly_t A, B;
        fmpcb_poly_t a, b, c;

        qbits1 = 2 + n_randint(state, 200);
        rbits1 = 2 + n_randint(state, 200);
        rbits2 = 2 + n_randint(state, 200);
        n = 2 + n_randint(state, 25);

        fmpq_poly_init(A);
        fmpq_poly_init(B);

        fmpcb_poly_init(a);
        fmpcb_poly_init(b);
        fmpcb_poly_init(c);

        do {
            fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1);
            fmpq_poly_set_coeff_ui(A, 0, 0);
        } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1));

        fmpq_poly_revert_series(B, A, n);

        fmpcb_poly_set_fmpq_poly(a, A, rbits1);
        fmpcb_poly_revert_series_lagrange(b, a, n, rbits2);

        if (!fmpcb_poly_contains_fmpq_poly(b, B))
        {
            printf("FAIL\n\n");
            printf("n = %ld, bits2 = %ld\n", n, rbits2);

            printf("A = "); fmpq_poly_print(A); printf("\n\n");
            printf("B = "); fmpq_poly_print(B); printf("\n\n");

            printf("a = "); fmpcb_poly_printd(a, 15); printf("\n\n");
            printf("b = "); fmpcb_poly_printd(b, 15); printf("\n\n");

            abort();
        }

        fmpcb_poly_set(c, a);
        fmpcb_poly_revert_series_lagrange(c, c, n, rbits2);
        if (!fmpcb_poly_equal(c, b))
        {
            printf("FAIL (aliasing)\n\n");
            abort();
        }

        fmpq_poly_clear(A);
        fmpq_poly_clear(B);

        fmpcb_poly_clear(a);
        fmpcb_poly_clear(b);
        fmpcb_poly_clear(c);
    }

    flint_randclear(state);
    flint_cleanup();
    printf("PASS\n");
    return EXIT_SUCCESS;
}
Esempio n. 8
0
bool
poly_inverse_poly_q(fmpz_poly_t Fq,
		const fmpz_poly_t a,
		const ntru_params *params)
{
	bool retval = false;
	int k = 0,
		j = 0;
	fmpz *b_last;
	fmpz_poly_t a_tmp,
				b,
				c,
				f,
				g;

	/* general initialization of temp variables */
	fmpz_poly_init(b);
	fmpz_poly_set_coeff_ui(b, 0, 1);
	fmpz_poly_init(c);
	fmpz_poly_init(f);
	fmpz_poly_set(f, a);

	/* set g(x) = x^N − 1 */
	fmpz_poly_init(g);
	fmpz_poly_set_coeff_si(g, 0, -1);
	fmpz_poly_set_coeff_si(g, params->N, 1);

	/* avoid side effects */
	fmpz_poly_init(a_tmp);
	fmpz_poly_set(a_tmp, a);
	fmpz_poly_zero(Fq);

	while (1) {
		while (fmpz_poly_get_coeff_ptr(f, 0) &&
				fmpz_is_zero(fmpz_poly_get_coeff_ptr(f, 0))) {
			for (uint32_t i = 1; i <= params->N; i++) {
				fmpz *f_coeff = fmpz_poly_get_coeff_ptr(f, i);
				fmpz *c_coeff = fmpz_poly_get_coeff_ptr(c, params->N - i);

				/* f(x) = f(x) / x */
				fmpz_poly_set_coeff_fmpz_n(f, i - 1,
						f_coeff);

				/* c(x) = c(x) * x */
				fmpz_poly_set_coeff_fmpz_n(c, params->N + 1 - i,
						c_coeff);
			}

			fmpz_poly_set_coeff_si(f, params->N, 0);
			fmpz_poly_set_coeff_si(c, 0, 0);

			k++;

			if (fmpz_poly_degree(f) == -1)
				goto cleanup;
		}

		if (fmpz_poly_is_zero(g) == 1)
			goto cleanup;

		if (fmpz_poly_degree(f) == 0)
			break;

		if (fmpz_poly_degree(f) < fmpz_poly_degree(g)) {
			fmpz_poly_swap(f, g);
			fmpz_poly_swap(b, c);
		}

		fmpz_poly_add(f, g, f);
		fmpz_poly_mod_unsigned(f, 2);

		fmpz_poly_add(b, c, b);
		fmpz_poly_mod_unsigned(b, 2);
	}

	k = k % params->N;

	b_last = fmpz_poly_get_coeff_ptr(b, params->N);
	if (fmpz_cmp_si_n(b_last, 0))
		goto cleanup;

	/* Fq(x) = x^(N-k) * b(x) */
	for (int i = params->N - 1; i >= 0; i--) {
		fmpz *b_i;

		j = i - k;

		if (j < 0)
			j = j + params->N;

		b_i = fmpz_poly_get_coeff_ptr(b, i);
		fmpz_poly_set_coeff_fmpz_n(Fq, j, b_i);
	}

	poly_mod2_to_modq(Fq, a_tmp, params);

	/* check if the f * Fq = 1 (mod p) condition holds true */
	fmpz_poly_set(a_tmp, a);
	poly_starmultiply(a_tmp, a_tmp, Fq, params, params->q);
	if (fmpz_poly_is_one(a_tmp))
		retval = true;
	else
		fmpz_poly_zero(Fq);

cleanup:
	fmpz_poly_clear(a_tmp);
	fmpz_poly_clear(b);
	fmpz_poly_clear(c);
	fmpz_poly_clear(f);
	fmpz_poly_clear(g);

	return retval;
}
Esempio n. 9
0
bool
poly_inverse_poly_p(fmpz_poly_t Fp,
		const fmpz_poly_t a,
		const ntru_params *params)
{
	bool retval = false;
	int k = 0,
		j = 0;
	fmpz *b_last;
	fmpz_poly_t a_tmp,
				b,
				c,
				f,
				g;

	/* general initialization of temp variables */
	fmpz_poly_init(b);
	fmpz_poly_set_coeff_ui(b, 0, 1);
	fmpz_poly_init(c);
	fmpz_poly_init(f);
	fmpz_poly_set(f, a);

	/* set g(x) = x^N − 1 */
	fmpz_poly_init(g);
	fmpz_poly_set_coeff_si(g, 0, -1);
	fmpz_poly_set_coeff_si(g, params->N, 1);

	/* avoid side effects */
	fmpz_poly_init(a_tmp);
	fmpz_poly_set(a_tmp, a);
	fmpz_poly_zero(Fp);

	while (1) {
		while (fmpz_poly_get_coeff_ptr(f, 0) &&
				fmpz_is_zero(fmpz_poly_get_coeff_ptr(f, 0))) {
			for (uint32_t i = 1; i <= params->N; i++) {
				fmpz *f_coeff = fmpz_poly_get_coeff_ptr(f, i);
				fmpz *c_coeff = fmpz_poly_get_coeff_ptr(c, params->N - i);

				/* f(x) = f(x) / x */
				fmpz_poly_set_coeff_fmpz_n(f, i - 1,
						f_coeff);

				/* c(x) = c(x) * x */
				fmpz_poly_set_coeff_fmpz_n(c, params->N + 1 - i,
						c_coeff);
			}

			fmpz_poly_set_coeff_si(f, params->N, 0);
			fmpz_poly_set_coeff_si(c, 0, 0);

			k++;

			if (fmpz_poly_degree(f) == -1)
				goto cleanup;
		}

		if (fmpz_poly_is_zero(g) == 1)
			goto cleanup;

		if (fmpz_poly_degree(f) == 0)
			break;

		if (fmpz_poly_degree(f) < fmpz_poly_degree(g)) {
			/* exchange f and g and exchange b and c */
			fmpz_poly_swap(f, g);
			fmpz_poly_swap(b, c);
		}

		{
			fmpz_poly_t c_tmp,
						g_tmp;
			fmpz_t u,
				   mp_tmp;

			fmpz_init(u);
			fmpz_zero(u);

			fmpz_init_set(mp_tmp, fmpz_poly_get_coeff_ptr(f, 0));

			fmpz_poly_init(g_tmp);
			fmpz_poly_set(g_tmp, g);

			fmpz_poly_init(c_tmp);
			fmpz_poly_set(c_tmp, c);

			/* u = f[0] * g[0]^(-1) mod p */
			  /* = (f[0] mod p) * (g[0] inverse mod p) mod p */
			fmpz_invmod_ui(u,
					fmpz_poly_get_coeff_ptr(g, 0),
					params->p);
			fmpz_mod_ui(mp_tmp, mp_tmp, params->p);
			fmpz_mul(u, mp_tmp, u);
			fmpz_mod_ui(u, u, params->p);

			/* f = f - u * g mod p */
			fmpz_poly_scalar_mul_fmpz(g_tmp, g_tmp, u);
			fmpz_poly_sub(f, f, g_tmp);
			fmpz_poly_mod_unsigned(f, params->p);

			/* b = b - u * c mod p */
			fmpz_poly_scalar_mul_fmpz(c_tmp, c_tmp, u);
			fmpz_poly_sub(b, b, c_tmp);
			fmpz_poly_mod_unsigned(b, params->p);

			fmpz_clear(u);
			fmpz_poly_clear(g_tmp);
			fmpz_poly_clear(c_tmp);
		}
	}

	k = k % params->N;

	b_last = fmpz_poly_get_coeff_ptr(b, params->N);
	if (fmpz_cmp_si_n(b_last, 0))
		goto cleanup;

	/* Fp(x) = x^(N-k) * b(x) */
	for (int i = params->N - 1; i >= 0; i--) {
		fmpz *b_i;

		/* b(X) = f[0]^(-1) * b(X) (mod p) */
		{
			fmpz_t mp_tmp;

			fmpz_init(mp_tmp);

			fmpz_invmod_ui(mp_tmp,
					fmpz_poly_get_coeff_ptr(f, 0),
					params->p);

			if (fmpz_poly_get_coeff_ptr(b, i)) {
				fmpz_mul(fmpz_poly_get_coeff_ptr(b, i),
						fmpz_poly_get_coeff_ptr(b, i),
						mp_tmp);
				fmpz_mod_ui(fmpz_poly_get_coeff_ptr(b, i),
						fmpz_poly_get_coeff_ptr(b, i),
						params->p);
			}
		}

		j = i - k;
		if (j < 0)
			j = j + params->N;

		b_i = fmpz_poly_get_coeff_ptr(b, i);
		fmpz_poly_set_coeff_fmpz_n(Fp, j, b_i);
	}

	/* check if the f * Fp = 1 (mod p) condition holds true */
	fmpz_poly_set(a_tmp, a);
	poly_starmultiply(a_tmp, a_tmp, Fp, params, params->p);
	if (fmpz_poly_is_one(a_tmp))
		retval = true;
	else
		fmpz_poly_zero(Fp);

cleanup:
	fmpz_poly_clear(a_tmp);
	fmpz_poly_clear(b);
	fmpz_poly_clear(c);
	fmpz_poly_clear(f);
	fmpz_poly_clear(g);

	return retval;
}
Esempio n. 10
0
/* note: z should be exact here */
void acb_lambertw_main(acb_t res, const acb_t z,
                const acb_t ez1, const fmpz_t k, int flags, slong prec)
{
    acb_t w, t, oldw, ew;
    mag_t err;
    slong i, wp, accuracy, ebits, kbits, mbits, wp_initial, extraprec;
    int have_ew;

    acb_init(t);
    acb_init(w);
    acb_init(oldw);
    acb_init(ew);
    mag_init(err);

    /* We need higher precision for large k, large exponents, or very close
       to the branch point at -1/e. todo: we should be recomputing
       ez1 to higher precision when close... */
    acb_get_mag(err, z);
    if (fmpz_is_zero(k) && mag_cmp_2exp_si(err, 0) < 0)
        ebits = 0;
    else
        ebits = fmpz_bits(MAG_EXPREF(err));

    if (fmpz_is_zero(k) || (fmpz_is_one(k) && arb_is_negative(acb_imagref(z)))
                        || (fmpz_equal_si(k, -1) && arb_is_nonnegative(acb_imagref(z))))
    {
        acb_get_mag(err, ez1);
        mbits = -MAG_EXP(err);
        mbits = FLINT_MAX(mbits, 0);
        mbits = FLINT_MIN(mbits, prec);
    }
    else
    {
        mbits = 0;
    }

    kbits = fmpz_bits(k);

    extraprec = FLINT_MAX(ebits, kbits);
    extraprec = FLINT_MAX(extraprec, mbits);

    wp = wp_initial = 40 + extraprec;

    accuracy = acb_lambertw_initial(w, z, ez1, k, wp_initial);
    mag_zero(arb_radref(acb_realref(w)));
    mag_zero(arb_radref(acb_imagref(w)));

    /* We should be able to compute e^w for the final certification
       during the Halley iteration. */
    have_ew = 0;

    for (i = 0; i < 5 + FLINT_BIT_COUNT(prec + extraprec); i++)
    {
        /* todo: should we restart? */
        if (!acb_is_finite(w))
            break;

        wp = FLINT_MIN(3 * accuracy, 1.1 * prec + 10);
        wp = FLINT_MAX(wp, 40);
        wp += extraprec;

        acb_set(oldw, w);
        acb_lambertw_halley_step(t, ew, z, w, wp);

        /* estimate the error (conservatively) */
        acb_sub(w, w, t, wp);
        acb_get_mag(err, w);
        acb_set(w, t);
        acb_add_error_mag(t, err);
        accuracy = acb_rel_accuracy_bits(t);

        if (accuracy > 2 * extraprec)
            accuracy *= 2.9;  /* less conservatively */

        accuracy = FLINT_MIN(accuracy, wp);
        accuracy = FLINT_MAX(accuracy, 0);

        if (accuracy > prec + extraprec)
        {
            /* e^w = e^oldw * e^(w-oldw) */
            acb_sub(t, w, oldw, wp);
            acb_exp(t, t, wp);
            acb_mul(ew, ew, t, wp);
            have_ew = 1;
            break;
        }

        mag_zero(arb_radref(acb_realref(w)));
        mag_zero(arb_radref(acb_imagref(w)));
    }

    wp = FLINT_MIN(3 * accuracy, 1.1 * prec + 10);
    wp = FLINT_MAX(wp, 40);
    wp += extraprec;

    if (acb_lambertw_check_branch(w, k, wp))
    {
        acb_t u, r, eu1;
        mag_t err, rad;

        acb_init(u);
        acb_init(r);
        acb_init(eu1);

        mag_init(err);
        mag_init(rad);

        if (have_ew)
            acb_set(t, ew);
        else
            acb_exp(t, w, wp);
        /* t = w e^w */
        acb_mul(t, t, w, wp);

        acb_sub(r, t, z, wp);

        /* Bound W' on the straight line path between t and z */
        acb_union(u, t, z, wp);

        arb_const_e(acb_realref(eu1), wp);
        arb_zero(acb_imagref(eu1));
        acb_mul(eu1, eu1, u, wp);
        acb_add_ui(eu1, eu1, 1, wp);

        if (acb_lambertw_branch_crossing(u, eu1, k))
        {
            mag_inf(err);
        }
        else
        {
            acb_lambertw_bound_deriv(err, u, eu1, k);
            acb_get_mag(rad, r);
            mag_mul(err, err, rad);
        }

        acb_add_error_mag(w, err);

        acb_set(res, w);

        acb_clear(u);
        acb_clear(r);
        acb_clear(eu1);
        mag_clear(err);
        mag_clear(rad);
    }
    else
    {
        acb_indeterminate(res);
    }

    acb_clear(t);
    acb_clear(w);
    acb_clear(oldw);
    acb_clear(ew);
    mag_clear(err);
}
Esempio n. 11
0
void
_acb_lambertw(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, int flags, slong prec)
{
    slong goal, ebits, ebits2, ls, lt;
    const fmpz * expo;

    /* Estimated accuracy goal. */
    /* todo: account for exponent bits and bits in k. */
    goal = acb_rel_accuracy_bits(z);
    goal = FLINT_MAX(goal, 10);
    goal = FLINT_MIN(goal, prec);

    /* Handle tiny z directly. For k >= 2, |c_k| <= 4^k / 16. */
    if (fmpz_is_zero(k)
        && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -goal / 2) < 0
        && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -goal / 2) < 0)
    {
        mag_t err;
        mag_init(err);
        acb_get_mag(err, z);
        mag_mul_2exp_si(err, err, 2);
        acb_set(res, z);
        acb_submul(res, res, res, prec);
        mag_geom_series(err, err, 3);
        mag_mul_2exp_si(err, err, -4);
        acb_add_error_mag(res, err);
        mag_clear(err);
        return;
    }

    if (arf_cmpabs(arb_midref(acb_realref(z)), arb_midref(acb_imagref(z))) >= 0)
        expo = ARF_EXPREF(arb_midref(acb_realref(z)));
    else
        expo = ARF_EXPREF(arb_midref(acb_imagref(z)));

    ebits = fmpz_bits(expo);

    /* ebits ~= log2(|log(z) + 2 pi i k|) */
    /* ebits2 ~= log2(log(log(z))) */
    ebits = FLINT_MAX(ebits, fmpz_bits(k));
    ebits = FLINT_MAX(ebits, 1) - 1;
    ebits2 = FLINT_BIT_COUNT(ebits);
    ebits2 = FLINT_MAX(ebits2, 1) - 1;

    /* We gain accuracy from the exponent when W ~ log - log log */
    if (fmpz_sgn(expo) > 0 || (fmpz_sgn(expo) < 0 && !fmpz_is_zero(k)))
    {
        goal += ebits - ebits2;
        goal = FLINT_MAX(goal, 10);
        goal = FLINT_MIN(goal, prec);

        /* The asymptotic series with truncation L, M gives us about 
           t - max(2+lt+L*(2+ls), M*(2+lt)) bits of accuracy where
           ls = -ebits, lt = ebits2 - ebits. */
        ls = 2 - ebits;
        lt = 2 + ebits2 - ebits;

        if (ebits - FLINT_MAX(lt + 1*ls, 1*lt) > goal)
        {
            acb_lambertw_asymp(res, z, k, 1, 1, goal);
            acb_set_round(res, res, prec);
            return;
        }
        else if (ebits - FLINT_MAX(lt + 3*ls, 5*lt) > goal)
        {
            acb_lambertw_asymp(res, z, k, 3, 5, goal);
            acb_set_round(res, res, prec);
            return;
        }
    }

    /* Extremely close to the branch point at -1/e, use the series expansion directly. */
    if (acb_lambertw_try_near_branch_point(res, z, ez1, k, flags, goal))
    {
        acb_set_round(res, res, prec);
        return;
    }

    /* compute union of both sides */
    if (acb_lambertw_branch_crossing(z, ez1, k))
    {
        acb_t za, zb, eza1, ezb1;
        fmpz_t kk;

        acb_init(za);
        acb_init(zb);
        acb_init(eza1);
        acb_init(ezb1);
        fmpz_init(kk);

        fmpz_neg(kk, k);

        acb_set(za, z);
        acb_conj(zb, z);
        arb_nonnegative_part(acb_imagref(za), acb_imagref(za));
        arb_nonnegative_part(acb_imagref(zb), acb_imagref(zb));

        acb_set(eza1, ez1);
        acb_conj(ezb1, ez1);
        arb_nonnegative_part(acb_imagref(eza1), acb_imagref(eza1));
        arb_nonnegative_part(acb_imagref(ezb1), acb_imagref(ezb1));

        /* Check series expansion again, because now there is no crossing. */
        if (!acb_lambertw_try_near_branch_point(res, za, eza1, k, flags, goal))
            acb_lambertw_cleared_cut_fix_small(za, za, eza1, k, flags, goal);

        if (!acb_lambertw_try_near_branch_point(res, zb, ezb1, kk, flags, goal))
            acb_lambertw_cleared_cut_fix_small(zb, zb, ezb1, kk, flags, goal);

        acb_conj(zb, zb);
        acb_union(res, za, zb, prec);

        acb_clear(za);
        acb_clear(zb);
        acb_clear(eza1);
        acb_clear(ezb1);
        fmpz_clear(kk);
    }
    else
    {
        acb_lambertw_cleared_cut_fix_small(res, z, ez1, k, flags, goal);
        acb_set_round(res, res, prec);
    }
}
Esempio n. 12
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;
}
Esempio n. 13
0
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);

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

    

    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;
        slong j;


        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randbits(a, state, 1000);
        do { 
           fmpz_randbits(b, state, 500);
        } while(fmpz_is_zero(b));

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        for (j = 1; j < 100; j++)
           fmpz_fdiv_qr(c, r, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, c);
        fmpz_get_mpz(h, r);

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

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    /* Check aliasing of c and a */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randtest(a, state, 200);
        fmpz_randtest_not_zero(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_fdiv_qr(a, r, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, a);
        fmpz_get_mpz(h, r);

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

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    /* Check aliasing of c and b */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randtest(a, state, 200);
        fmpz_randtest_not_zero(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_fdiv_qr(b, r, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, b);
        fmpz_get_mpz(h, r);

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

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    /* Check aliasing of r and a */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randtest(a, state, 200);
        fmpz_randtest_not_zero(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_fdiv_qr(c, a, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, c);
        fmpz_get_mpz(h, a);

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

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    /* Check aliasing of r and b */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randtest(a, state, 200);
        fmpz_randtest_not_zero(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_fdiv_qr(c, b, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, c);
        fmpz_get_mpz(h, b);

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

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}
Esempio n. 14
0
void acb_modular_transform(acb_t w, const psl2z_t g, const acb_t z, slong prec)
{
#define a (&g->a)
#define b (&g->b)
#define c (&g->c)
#define d (&g->d)
#define x acb_realref(z)
#define y acb_imagref(z)

    if (fmpz_is_zero(c))
    {
        /* (az+b)/d, where we must have a = d = 1 */
        acb_add_fmpz(w, z, b, prec);
    }
    else if (fmpz_is_zero(a))
    {
        /* b/(cz+d), where -bc = 1, c = 1 => -1/(z+d) */
        acb_add_fmpz(w, z, d, prec);
        acb_inv(w, w, prec);
        acb_neg(w, w);
    }
    else if (0)
    {
        acb_t t, u;

        acb_init(t);
        acb_init(u);

        acb_set_fmpz(t, b);
        acb_addmul_fmpz(t, z, a, prec);

        acb_set_fmpz(u, d);
        acb_addmul_fmpz(u, z, c, prec);

        acb_div(w, t, u, prec);

        acb_clear(t);
        acb_clear(u);
    }
    else
    {
        /* (az+b)/(cz+d) = (re+im*i)/den where

            re = bd + (bc+ad)x + ac(x^2+y^2)
            im = (ad-bc)y
            den = c^2(x^2+y^2) + 2cdx + d^2
        */

        fmpz_t t;
        arb_t re, im, den;

        arb_init(re);
        arb_init(im);
        arb_init(den);
        fmpz_init(t);

        arb_mul(im, x, x, prec);
        arb_addmul(im, y, y, prec);

        fmpz_mul(t, b, d);
        arb_set_fmpz(re, t);
        fmpz_mul(t, b, c);
        fmpz_addmul(t, a, d);
        arb_addmul_fmpz(re, x, t, prec);
        fmpz_mul(t, a, c);
        arb_addmul_fmpz(re, im, t, prec);

        fmpz_mul(t, d, d);
        arb_set_fmpz(den, t);
        fmpz_mul(t, c, d);
        fmpz_mul_2exp(t, t, 1);
        arb_addmul_fmpz(den, x, t, prec);
        fmpz_mul(t, c, c);
        arb_addmul_fmpz(den, im, t, prec);

        fmpz_mul(t, a, d);
        fmpz_submul(t, b, c);
        arb_mul_fmpz(im, y, t, prec);

        arb_div(acb_realref(w), re, den, prec);
        arb_div(acb_imagref(w), im, den, prec);

        arb_clear(re);
        arb_clear(im);
        arb_clear(den);
        fmpz_clear(t);
    }

#undef a
#undef b
#undef c
#undef d
#undef x
#undef y
}
Esempio n. 15
0
long
fmpz_mat_nullspace(fmpz_mat_t res, const fmpz_mat_t mat)
{
    long i, j, k, m, n, rank, nullity;
    long * pivots;
    long * nonpivots;
    fmpz_mat_t tmp;
    fmpz_t den;

    m = mat->r;
    n = mat->c;

    fmpz_mat_init_set(tmp, mat);
    fmpz_init(den);

    rank = fmpz_mat_rref(tmp, den, NULL, mat);
    nullity = n - rank;

    fmpz_mat_zero(res);
    if (rank == 0)
    {
        for (i = 0; i < nullity; i++)
            fmpz_one(res->rows[i] + i);
    }
    else if (nullity)
    {
        pivots = flint_malloc(rank * sizeof(long));
        nonpivots = flint_malloc(nullity * sizeof(long));

        for (i = j = k = 0; i < rank; i++)
        {
            while (fmpz_is_zero(tmp->rows[i] + j))
            {
                nonpivots[k] = j;
                k++;
                j++;
            }
            pivots[i] = j;
            j++;
        }
        while (k < nullity)
        {
            nonpivots[k] = j;
            k++;
            j++;
        }

        fmpz_set(den, tmp->rows[0] + pivots[0]);

        for (i = 0; i < nullity; i++)
        {
            for (j = 0; j < rank; j++)
                fmpz_set(res->rows[pivots[j]] + i, tmp->rows[j] + nonpivots[i]);
            fmpz_neg(res->rows[nonpivots[i]] + i, den);
        }

        flint_free(pivots);
        flint_free(nonpivots);
    }

    fmpz_clear(den);
    fmpz_mat_clear(tmp);

    return nullity;
}
Esempio n. 16
0
void _nf_elem_sub_qf(nf_elem_t a, const nf_elem_t b, 
                                   const nf_elem_t c, const nf_t nf, int can)
{
   fmpz_t d;

   const fmpz * const bnum = QNF_ELEM_NUMREF(b);
   const fmpz * const bden = QNF_ELEM_DENREF(b);
   
   const fmpz * const cnum = QNF_ELEM_NUMREF(c);
   const fmpz * const cden = QNF_ELEM_DENREF(c);
   
   fmpz * const anum = QNF_ELEM_NUMREF(a);
   fmpz * const aden = QNF_ELEM_DENREF(a);

   fmpz_init(d);
   fmpz_one(d);

   if (fmpz_equal(bden, cden))
   {
      fmpz_sub(anum, bnum, cnum);
      fmpz_sub(anum + 1, bnum + 1, cnum + 1);
      fmpz_sub(anum + 2, bnum + 2, cnum + 2);
      fmpz_set(aden, bden);

      if (can && !fmpz_is_one(aden))
      {
         fmpz_gcd(d, anum, anum + 1);
         fmpz_gcd(d, d, anum + 2);
         if (!fmpz_is_one(d))
         {
            fmpz_gcd(d, d, aden);

            if (!fmpz_is_one(d))
            {
               fmpz_divexact(anum, anum, d);
               fmpz_divexact(anum + 1, anum + 1, d);
               fmpz_divexact(anum + 2, anum + 2, d);
               fmpz_divexact(aden, aden, d);
            }
         }
      }

      fmpz_clear(d);

      return;
   }

   if (!fmpz_is_one(bden) && !fmpz_is_one(cden))
      fmpz_gcd(d, bden, cden);

   if (fmpz_is_one(d))
   {
      fmpz_mul(anum, bnum, cden);
      fmpz_mul(anum + 1, bnum + 1, cden);
      fmpz_mul(anum + 2, bnum + 2, cden);
      fmpz_submul(anum, cnum, bden);
      fmpz_submul(anum + 1, cnum + 1, bden);
      fmpz_submul(anum + 2, cnum + 2, bden);
      fmpz_mul(aden, bden, cden);
   } else
   {
      fmpz_t bden1;
      fmpz_t cden1;
      
      fmpz_init(bden1);
      fmpz_init(cden1);
      
      fmpz_divexact(bden1, bden, d);
      fmpz_divexact(cden1, cden, d);
        
      fmpz_mul(anum, bnum, cden1);
      fmpz_mul(anum + 1, bnum + 1, cden1);
      fmpz_mul(anum + 2, bnum + 2, cden1);
      fmpz_submul(anum, cnum, bden1);
      fmpz_submul(anum + 1, cnum + 1, bden1);
      fmpz_submul(anum + 2, cnum + 2, bden1);
      
      if (fmpz_is_zero(anum) && fmpz_is_zero(anum + 1) && fmpz_is_zero(anum + 2))
         fmpz_one(aden);
      else
      {
         if (can)
         {
            fmpz_t e;
            
            fmpz_init(e);
              
            fmpz_gcd(e, anum, anum + 1);
            fmpz_gcd(e, e, anum + 2);
            if (!fmpz_is_one(e))
               fmpz_gcd(e, e, d);
            
            if (fmpz_is_one(e))
               fmpz_mul(aden, bden, cden1);
            else
            {
                fmpz_divexact(anum, anum, e);
                fmpz_divexact(anum + 1, anum + 1, e);
                fmpz_divexact(anum + 2, anum + 2, e);
                fmpz_divexact(bden1, bden, e);
                fmpz_mul(aden, bden1, cden1);
            }
            
            fmpz_clear(e);
         } else
            fmpz_mul(aden, bden, cden1);
      }

      fmpz_clear(bden1);
      fmpz_clear(cden1);
   }

   fmpz_clear(d);
}
Esempio n. 17
0
void _fmpq_poly_divrem(fmpz * Q, fmpz_t q, fmpz * R, fmpz_t r, 
                       const fmpz * A, const fmpz_t a, long lenA, 
                       const fmpz * B, const fmpz_t b, long lenB)
{
    long lenQ = lenA - lenB + 1;
    long lenR = lenB - 1;
    ulong d;
    const fmpz * lead = B + (lenB - 1);
    
    if (lenB == 1)
    {
        _fmpq_poly_scalar_div_mpq(Q, q, A, a, lenA, B, b);
        fmpz_set_ui(r, 1);
        return;
    }
    
    /* 
       From pseudo division over Z we have 
           lead^d * A = Q * B + R
       and thus
           {A, a} = {b * Q, a * lead^d} * {B, b} + {R, a * lead^d}.
     */
    _fmpz_poly_pseudo_divrem(Q, R, &d, A, lenA, B, lenB);
    
    /* Determine the actual length of R */
    for ( ; lenR != 0 && fmpz_is_zero(R + (lenR - 1)); lenR--) ;
    
    /* 1.  lead^d == +-1.  {Q, q} = {b Q, a}, {R, r} = {R, a} up to sign */
    if (d == 0UL || *lead == 1L || *lead == -1L)
    {
        fmpz_set_ui(q, 1);
        _fmpq_poly_scalar_mul_fmpz(Q, q, Q, q, lenQ, b);
        _fmpq_poly_scalar_div_fmpz(Q, q, Q, q, lenQ, a);
        
        fmpz_set_ui(r, 1);
        if (lenR > 0)
            _fmpq_poly_scalar_div_fmpz(R, r, R, r, lenR, a);
        
        if (*lead == -1L && d % 2UL)
        {
            _fmpz_vec_neg(Q, Q, lenQ);
            _fmpz_vec_neg(R, R, lenR);
        }
    }
    /* 2.  lead^d != +-1.  {Q, q} = {b Q, a lead^d}, {R, r} = {R, a lead^d} */
    else
    {
        /*
           TODO:  Improve this.  Clearly we do not need to compute 
           den = a lead^d in many cases, but can determine the GCD from 
           lead alone already.
         */
        fmpz_t den;
        fmpz_init(den);
        fmpz_pow_ui(den, lead, d);
        fmpz_mul(den, a, den);
        
        fmpz_set_ui(q, 1);
        _fmpq_poly_scalar_mul_fmpz(Q, q, Q, q, lenQ, b);
        _fmpq_poly_scalar_div_fmpz(Q, q, Q, q, lenQ, den);
        
        fmpz_set_ui(r, 1);
        if (lenR > 0)
            _fmpq_poly_scalar_div_fmpz(R, r, R, r, lenR, den);
        
        fmpz_clear(den);
    }
}
Esempio n. 18
0
void
arb_exp_arf_bb(arb_t z, const arf_t x, slong prec, int minus_one)
{
    slong k, iter, bits, r, mag, q, wp, N;
    slong argred_bits, start_bits;
    mp_bitcnt_t Qexp[1];
    int inexact;
    fmpz_t t, u, T, Q;
    arb_t w;

    if (arf_is_zero(x))
    {
        if (minus_one)
            arb_zero(z);
        else
            arb_one(z);
        return;
    }

    if (arf_is_special(x))
    {
        abort();
    }

    mag = arf_abs_bound_lt_2exp_si(x);

    /* We assume that this function only gets called with something
       reasonable as input (huge/tiny input will be handled by
       the main exp wrapper). */
    if (mag > 200 || mag < -2 * prec - 100)
    {
        flint_printf("arb_exp_arf_bb: unexpectedly large/small input\n");
        abort();
    }

    if (prec < 100000000)
    {
        argred_bits = 16;
        start_bits = 32;
    }
    else
    {
        argred_bits = 32;
        start_bits = 64;
    }

    /* Argument reduction: exp(x) -> exp(x/2^q). This improves efficiency
       of the first iteration in the bit-burst algorithm. */
    q = FLINT_MAX(0, mag + argred_bits);

    /* Determine working precision. */
    wp = prec + 10 + 2 * q + 2 * FLINT_BIT_COUNT(prec);
    if (minus_one && mag < 0)
        wp += (-mag);

    fmpz_init(t);
    fmpz_init(u);
    fmpz_init(Q);
    fmpz_init(T);
    arb_init(w);

    /* Convert x/2^q to a fixed-point number. */
    inexact = arf_get_fmpz_fixed_si(t, x, -wp + q);

    /* Aliasing of z and x is safe now that only use t. */
    /* Start with z = 1. */
    arb_one(z);

    /* Bit-burst loop. */
    for (iter = 0, bits = start_bits; !fmpz_is_zero(t);
        iter++, bits *= 2)
    {
        /* Extract bits. */
        r = FLINT_MIN(bits, wp);
        fmpz_tdiv_q_2exp(u, t, wp - r);

        /* Binary splitting (+1 fixed-point ulp truncation error). */
        mag = fmpz_bits(u) - r;
        N = bs_num_terms(mag, wp);

       _arb_exp_sum_bs_powtab(T, Q, Qexp, u, r, N);

        /* T = T / Q  (+1 fixed-point ulp error). */
        if (*Qexp >= wp)
        {
            fmpz_tdiv_q_2exp(T, T, *Qexp - wp);
            fmpz_tdiv_q(T, T, Q);
        }
        else
        {
            fmpz_mul_2exp(T, T, wp - *Qexp);
            fmpz_tdiv_q(T, T, Q);
        }

        /* T = 1 + T */
        fmpz_one(Q);
        fmpz_mul_2exp(Q, Q, wp);
        fmpz_add(T, T, Q);

        /* Now T = exp(u) with at most 2 fixed-point ulp error. */
        /* Set z = z * T. */
        arf_set_fmpz(arb_midref(w), T);
        arf_mul_2exp_si(arb_midref(w), arb_midref(w), -wp);
        mag_set_ui_2exp_si(arb_radref(w), 2, -wp);
        arb_mul(z, z, w, wp);

        /* Remove used bits. */
        fmpz_mul_2exp(u, u, wp - r);
        fmpz_sub(t, t, u);
    }

    /* We have exp(x + eps) - exp(x) < 2*eps (by assumption that the argument
       reduction is large enough). */
    if (inexact)
        arb_add_error_2exp_si(z, -wp + 1);

    fmpz_clear(t);
    fmpz_clear(u);
    fmpz_clear(Q);
    fmpz_clear(T);
    arb_clear(w);

    /* exp(x) = exp(x/2^q)^(2^q) */
    for (k = 0; k < q; k++)
        arb_mul(z, z, z, wp);

    if (minus_one)
        arb_sub_ui(z, z, 1, wp);

    arb_set_round(z, z, prec);
}