示例#1
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);
}
示例#2
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    /* compare with fmpz_poly */
    for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++)
    {
        slong zbits1, rbits1, rbits2, trunc;
        ulong e;
        fmpz_poly_t A, B;
        acb_poly_t a, b;

        zbits1 = 2 + n_randint(state, 100);
        rbits1 = 2 + n_randint(state, 200);
        rbits2 = 2 + n_randint(state, 200);
        e = n_randint(state, 50);
        trunc = n_randint(state, 40);

        fmpz_poly_init(A);
        fmpz_poly_init(B);

        acb_poly_init(a);
        acb_poly_init(b);

        fmpz_poly_randtest(A, state, 1 + n_randint(state, 10), zbits1);
        fmpz_poly_pow_trunc(B, A, e, trunc);

        acb_poly_set_fmpz_poly(a, A, rbits1);
        acb_poly_pow_ui_trunc_binexp(b, a, e, trunc, rbits2);

        if (!acb_poly_contains_fmpz_poly(b, B))
        {
            flint_printf("FAIL\n\n");
            flint_printf("bits2 = %wd\n", rbits2);
            flint_printf("e = %wu\n", e);
            flint_printf("trunc = %wd\n", trunc);

            flint_printf("A = "); fmpz_poly_print(A); flint_printf("\n\n");
            flint_printf("B = "); fmpz_poly_print(B); flint_printf("\n\n");

            flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n");
            flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n");

            abort();
        }

        acb_poly_pow_ui_trunc_binexp(a, a, e, trunc, rbits2);
        if (!acb_poly_equal(a, b))
        {
            flint_printf("FAIL (aliasing)\n\n");
            abort();
        }

        fmpz_poly_clear(A);
        fmpz_poly_clear(B);

        acb_poly_clear(a);
        acb_poly_clear(b);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
示例#3
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++)
    {
        slong prec, c;
        fmpz_poly_t A, B, C;
        acb_poly_t a, b;

        fmpz_poly_init(A);
        fmpz_poly_init(B);
        fmpz_poly_init(C);
        acb_poly_init(a);
        acb_poly_init(b);

        fmpz_poly_randtest(A, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000));
        fmpz_poly_randtest(B, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000));
        fmpz_poly_randtest(C, state, 1 + n_randint(state, 10), 1 + n_randint(state, 1000));
        c = 1 + n_randint(state, 1000);

        prec = 2 + n_randint(state, 100);

        for ( ; ; )
        {
            acb_poly_set_fmpz_poly(a, A, prec);
            acb_poly_set2_fmpz_poly(b, B, C, prec);
            acb_poly_scalar_mul_2exp_si(b, b, -c);
            acb_poly_add(a, a, b, prec);
            acb_poly_sub(a, a, b, prec);

            if (acb_poly_get_unique_fmpz_poly(B, a))
            {
                if (!fmpz_poly_equal(A, B))
                {
                    flint_printf("FAIL\n\n");
                    flint_printf("A = "); fmpz_poly_print(A); flint_printf("\n\n");
                    flint_printf("B = "); fmpz_poly_print(B); flint_printf("\n\n");
                    flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n");
                    abort();
                }

                break;
            }
            else
            {
                prec *= 2;
            }
        }

        fmpz_poly_clear(A);
        fmpz_poly_clear(B);
        fmpz_poly_clear(C);
        acb_poly_clear(a);
        acb_poly_clear(b);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}