예제 #1
0
파일: rsqrt.c 프로젝트: isuruf/arb
slong
fmpr_rsqrt(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd)
{
    slong r;

    if (fmpr_is_special(x))
    {
        if (fmpr_is_zero(x))
            fmpr_pos_inf(y);
        else if (fmpr_is_pos_inf(x))
            fmpr_zero(y);
        else
            fmpr_nan(y);

        return FMPR_RESULT_EXACT;
    }

    if (fmpr_sgn(x) < 0)
    {
        fmpr_nan(y);
        return FMPR_RESULT_EXACT;
    }

    /* special case: 4^n */
    if (fmpz_is_one(fmpr_manref(x)) && fmpz_is_even(fmpr_expref(x)))
    {
        r = fmpr_set_round(y, x, prec, rnd);
        fmpz_tdiv_q_2exp(fmpr_expref(y), fmpr_expref(y), 1);
        fmpz_neg(fmpr_expref(y), fmpr_expref(y));
        return r;
    }

    {
        fmpr_t t;
        fmpz_t e;

        fmpr_init(t);
        fmpz_init(e);

        fmpz_neg(e, fmpr_expref(x));
        if (fmpz_is_odd(e))
            fmpz_add_ui(e, e, 1);
        fmpr_mul_2exp_fmpz(t, x, e);

        CALL_MPFR_FUNC(r, mpfr_rec_sqrt, y, t, prec, rnd);

        fmpz_tdiv_q_2exp(e, e, 1);
        fmpr_mul_2exp_fmpz(y, y, e);

        fmpr_clear(t);
        fmpz_clear(e);

        return r;
    }
}
예제 #2
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;
}
예제 #3
0
파일: fib.c 프로젝트: argriffing/arb
void arb_fib_fmpz(arb_t f, const fmpz_t n, slong prec)
{
    arb_t t, u;
    slong wp, sign, i;

    if (fmpz_sgn(n) < 0)
    {
        fmpz_t m;
        fmpz_init(m);
        fmpz_neg(m, n);
        arb_fib_fmpz(f, m, prec);
        if (fmpz_is_even(m))
            arb_neg(f, f);
        fmpz_clear(m);
        return;
    }

    if (fmpz_cmp_ui(n, 4) <= 0)
    {
        ulong x = fmpz_get_ui(n);
        arb_set_ui(f, x - (x > 1));
        return;
    }

    wp = ARF_PREC_ADD(prec, 3 * fmpz_bits(n));

    arb_init(u);
    arb_init(t);
    arb_set_ui(f, UWORD(1));
    arb_set_ui(u, UWORD(1));
    sign = -1;

    for (i = fmpz_flog_ui(n, UWORD(2)) - 1; i > 0; i--)
    {
        arb_mul(t, f, f, wp);
        arb_add(f, f, u, wp);
        arb_mul_2exp_si(f, f, -1);
        arb_mul(f, f, f, wp);
        arb_mul_2exp_si(f, f, 1);
        arb_submul_ui(f, t, 3, wp);
        arb_sub_si(f, f, 2 * sign, wp);
        arb_mul_ui(u, t, 5, wp);
        arb_add_si(u, u, 2 * sign, wp);
        sign = 1;

        if (fmpz_tstbit(n, i))
        {
            arb_set(t, f);
            arb_add(f, f, u, wp);
            arb_mul_2exp_si(f, f, -1);
            arb_mul_2exp_si(t, t, 1);
            arb_add(u, f, t, wp);
            sign = -1;
        }
    }

    if (fmpz_tstbit(n, 0))
    {
        arb_add(f, f, u, wp);
        arb_mul_2exp_si(f, f, -1);
        arb_mul(f, f, u, wp);
        arb_sub_si(f, f, sign, prec);
    }
    else
    {
        arb_mul(f, f, u, prec);
    }

    arb_clear(u);
    arb_clear(t);
}
예제 #4
0
파일: t-factor.c 프로젝트: clear731/lattice
int
main(void)
{
    int iter;
    FLINT_TEST_INIT(state);

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

    /* Default algorithm */
    for (iter = 0; iter < flint_test_multiplier(); iter++)
    {
        int result = 1;
        TEMPLATE(T, poly_t) pol1, poly, quot, rem, product;
        TEMPLATE(T, poly_factor_t) res;
        TEMPLATE(T, ctx_t) ctx;
        TEMPLATE(T, t) lead;
        slong length, num, i, j;
        ulong exp[5], prod1;

        TEMPLATE(T, ctx_randtest) (ctx, state);

        TEMPLATE(T, poly_init) (pol1, ctx);
        TEMPLATE(T, poly_init) (poly, ctx);
        TEMPLATE(T, poly_init) (quot, ctx);
        TEMPLATE(T, poly_init) (rem, ctx);

        TEMPLATE(T, poly_zero) (pol1, ctx);
        TEMPLATE(T, poly_one) (pol1, ctx);

        length = n_randint(state, 4) + 2;
        TEMPLATE(T, poly_randtest_irreducible) (poly, state, length, ctx);

        exp[0] = n_randint(state, 3) + 1;
        prod1 = exp[0];
        for (i = 0; i < exp[0]; i++)
            TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx);

        num = n_randint(state, 3) + 1;
        for (i = 1; i < num; i++)
        {
            do
            {
                length = n_randint(state, 3) + 2;
                TEMPLATE(T, poly_randtest_irreducible) (poly, state, length,
                                                        ctx);
                TEMPLATE(T, poly_divrem) (quot, rem, pol1, poly, ctx);
            }
            while ((poly->length < 2) || (rem->length == 0));

            exp[i] = n_randint(state, 3) + 1;
            prod1 *= exp[i];

            for (j = 0; j < exp[i]; j++)
                TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx);
        }

        TEMPLATE(T, poly_factor_init) (res, ctx);

        TEMPLATE(T, init) (lead, ctx);

        switch (n_randint(state, 4))
        {
            case 0:
                TEMPLATE(T, poly_factor) (res, lead, pol1, ctx);
                break;
            case 1:
                TEMPLATE(T, poly_factor_with_berlekamp) (res, lead, pol1, ctx);
                break;
            case 2:
                if (fmpz_is_even(TEMPLATE(T, ctx_prime) (ctx)))
                    TEMPLATE(T, poly_factor) (res, lead, pol1, ctx);
                else
                    TEMPLATE(T, poly_factor_with_cantor_zassenhaus) (res, lead,
                                                                     pol1,
                                                                     ctx);
                break;
            case 3:
                TEMPLATE(T, poly_factor_with_kaltofen_shoup) (res, lead, pol1,
                                                              ctx);
                break;

        }
        fflush(stdout);

        result &= (res->num == num);
        if (!result)
        {
            flint_printf("Error: number of factors incorrect, %wd, %wd\n",
                         res->num, num);
            abort();
        }

        TEMPLATE(T, poly_init) (product, ctx);
        TEMPLATE(T, poly_one) (product, ctx);
        for (i = 0; i < res->num; i++)
            for (j = 0; j < res->exp[i]; j++)
                TEMPLATE(T, poly_mul) (product, product, res->poly + i, ctx);
        TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (product, product, lead,
                                                   ctx);
        result &= TEMPLATE(T, poly_equal) (pol1, product, ctx);
        if (!result)
        {
            flint_printf
                ("Error: product of factors does not equal original polynomial\n");
            TEMPLATE(T, poly_print_pretty) (pol1, "x", ctx);
            flint_printf("\n");
            TEMPLATE(T, poly_print_pretty) (product, "x", ctx);
            flint_printf("\n");
            abort();
        }
        TEMPLATE(T, poly_clear) (product, ctx);

        TEMPLATE(T, poly_clear) (quot, ctx);
        TEMPLATE(T, poly_clear) (rem, ctx);
        TEMPLATE(T, poly_clear) (pol1, ctx);
        TEMPLATE(T, poly_clear) (poly, ctx);
        TEMPLATE(T, poly_factor_clear) (res, ctx);
        TEMPLATE(T, clear) (lead, ctx);
        TEMPLATE(T, ctx_clear) (ctx);
    }

    /* Test deflation trick */
    for (iter = 0; iter < flint_test_multiplier(); iter++)
    {
        TEMPLATE(T, poly_t) pol1, poly, quot, rem;
        TEMPLATE(T, poly_factor_t) res, res2;
        TEMPLATE(T, ctx_t) ctx;
        TEMPLATE(T, t) lead;
        slong length, num, i, j;
        slong exp[5], prod1;
        ulong inflation;
        int found;

        TEMPLATE(T, ctx_randtest) (ctx, state);

        TEMPLATE(T, poly_init) (pol1, ctx);
        TEMPLATE(T, poly_init) (poly, ctx);
        TEMPLATE(T, poly_init) (quot, ctx);
        TEMPLATE(T, poly_init) (rem, ctx);

        TEMPLATE(T, poly_zero) (pol1, ctx);
        TEMPLATE(T, poly_one) (pol1, ctx);

        inflation = n_randint(state, 7) + 1;

        length = n_randint(state, 4) + 2;
        TEMPLATE(T, poly_randtest_irreducible) (poly, state, length, ctx);
        TEMPLATE(T, poly_inflate) (poly, poly, inflation, ctx);

        exp[0] = n_randint(state, 6) + 1;
        prod1 = exp[0];
        for (i = 0; i < exp[0]; i++)
            TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx);

        num = n_randint(state, 5) + 1;
        for (i = 1; i < num; i++)
        {
            do
            {
                length = n_randint(state, 6) + 2;
                TEMPLATE(T, poly_randtest_irreducible) (poly, state, length,
                                                        ctx);
                TEMPLATE(T, poly_divrem) (quot, rem, pol1, poly, ctx);
            }
            while ((poly->length < 2) || (rem->length == 0));
            exp[i] = n_randint(state, 6) + 1;
            prod1 *= exp[i];
            TEMPLATE(T, poly_inflate) (poly, poly, inflation, ctx);

            for (j = 0; j < exp[i]; j++)
                TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx);
        }

        TEMPLATE(T, poly_factor_init) (res, ctx);
        TEMPLATE(T, poly_factor_init) (res2, ctx);

        TEMPLATE(T, init) (lead, ctx);

        switch (n_randint(state, 4))
        {
            case 0:
                TEMPLATE(T, poly_factor) (res, lead, pol1, ctx);
                break;
            case 1:
                TEMPLATE(T, poly_factor_with_berlekamp) (res, lead, pol1, ctx);
                break;
            case 2:
                TEMPLATE(T, poly_factor_with_cantor_zassenhaus) (res, lead,
                                                                 pol1, ctx);
                break;
            case 3:
                TEMPLATE(T, poly_factor_with_kaltofen_shoup) (res, lead, pol1,
                                                              ctx);
                break;
        }

        TEMPLATE(T, poly_factor_cantor_zassenhaus) (res2, pol1, ctx);

        if (res->num != res2->num)
        {
            flint_printf("FAIL: different number of factors found\n");
            abort();
        }

        for (i = 0; i < res->num; i++)
        {
            found = 0;
            for (j = 0; j < res2->num; j++)
            {
                if (TEMPLATE(T, poly_equal)
                    (res->poly + i, res2->poly + j, ctx)
                    && res->exp[i] == res2->exp[j])
                {
                    found = 1;
                    break;
                }
            }

            if (!found)
            {
                flint_printf("FAIL: factor not found\n");
                abort();
            }
        }

        TEMPLATE(T, poly_clear) (quot, ctx);
        TEMPLATE(T, poly_clear) (rem, ctx);
        TEMPLATE(T, poly_clear) (pol1, ctx);
        TEMPLATE(T, poly_clear) (poly, ctx);
        TEMPLATE(T, poly_factor_clear) (res, ctx);
        TEMPLATE(T, poly_factor_clear) (res2, ctx);

        TEMPLATE(T, clear) (lead, ctx);
        TEMPLATE(T, ctx_clear) (ctx);
    }

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