示例#1
0
int arb_calc_refine_root_bisect(arf_interval_t r, arb_calc_func_t func,
    void * param, const arf_interval_t start, slong iter, slong prec)
{
    int asign, bsign, msign, result;
    slong i;
    arf_interval_t t, u;
    arb_t m, v;

    arf_interval_init(t);
    arf_interval_init(u);
    arb_init(m);
    arb_init(v);

    arb_set_arf(m, &start->a);
    func(v, m, param, 1, prec);
    asign = _arb_sign(v);

    arb_set_arf(m, &start->b);
    func(v, m, param, 1, prec);
    bsign = _arb_sign(v);

    /* must have proper sign changes */
    if (asign == 0 || bsign == 0 || asign == bsign)
    {
        result = ARB_CALC_IMPRECISE_INPUT;
    }
    else
    {
        arf_interval_set(r, start);

        result = ARB_CALC_SUCCESS;

        for (i = 0; i < iter; i++)
        {
            msign = arb_calc_partition(t, u, func, param, r, prec);

            /* the algorithm fails if the value at the midpoint cannot
               be distinguished from zero */
            if (msign == 0)
            {
                result = ARB_CALC_NO_CONVERGENCE;
                break;
            }

            if (msign == asign)
                arf_interval_swap(r, u);
            else
                arf_interval_swap(r, t);
        }
    }

    arf_interval_clear(t);
    arf_interval_clear(u);
    arb_clear(m);
    arb_clear(v);

    return result;
}
示例#2
0
文件: real_roots.c 项目: jdemeyer/arb
int main(int argc, char *argv[])
{
    arf_interval_ptr blocks;
    arb_calc_func_t function;
    int * info;
    long digits, low_prec, high_prec, i, num, found_roots, found_unknown;
    long maxdepth, maxeval, maxfound;
    int refine;
    double a, b;
    arf_t C;
    arf_interval_t t, interval;
    arb_t v, w, z;

    if (argc < 4)
    {
        printf("real_roots function a b [-refine d] [-verbose] "
               "[-maxdepth n] [-maxeval n] [-maxfound n] [-prec n]\n");
        printf("available functions:\n");
        printf("  0  Z(x), Riemann-Siegel Z-function\n");
        printf("  1  sin(x)\n");
        printf("  2  sin(x^2)\n");
        printf("  3  sin(1/x)\n");
        return 1;
    }

    switch (atoi(argv[1]))
    {
    case 0:
        function = z_function;
        break;
    case 1:
        function = sin_x;
        break;
    case 2:
        function = sin_x2;
        break;
    case 3:
        function = sin_1x;
        break;
    default:
        printf("require a function 0-3\n");
        return 1;
    }

    a = atof(argv[2]);
    b = atof(argv[3]);

    if (a >= b)
    {
        printf("require a < b!\n");
        return 1;
    }

    refine = 0;
    digits = 0;
    maxdepth = 30;
    maxeval = 100000;
    maxfound = 100000;
    low_prec = 30;

    for (i = 4; i < argc; i++)
    {
        if (!strcmp(argv[i], "-refine"))
        {
            refine = 1;
            digits = atol(argv[i+1]);
        }
        else if (!strcmp(argv[i], "-verbose"))
        {
            arb_calc_verbose = 1;
        }
        else if (!strcmp(argv[i], "-maxdepth"))
        {
            maxdepth = atol(argv[i+1]);
        }
        else if (!strcmp(argv[i], "-maxeval"))
        {
            maxeval = atol(argv[i+1]);
        }
        else if (!strcmp(argv[i], "-maxfound"))
        {
            maxfound = atol(argv[i+1]);
        }
        else if (!strcmp(argv[i], "-prec"))
        {
            low_prec = atol(argv[i+1]);
        }
    }

    high_prec = digits * 3.32192809488736 + 10;
    found_roots = 0;
    found_unknown = 0;

    arf_init(C);
    arf_interval_init(t);
    arf_interval_init(interval);
    arb_init(v);
    arb_init(w);
    arb_init(z);

    arf_set_d(&interval->a, a);
    arf_set_d(&interval->b, b);

    printf("interval: ");
    arf_interval_printd(interval, 15);
    printf("\n");
    printf("maxdepth = %ld, maxeval = %ld, maxfound = %ld, low_prec = %ld\n",
           maxdepth, maxeval, maxfound, low_prec);

    TIMEIT_ONCE_START

    num = arb_calc_isolate_roots(&blocks, &info, function,
                                 NULL, interval, maxdepth, maxeval, maxfound, low_prec);

    for (i = 0; i < num; i++)
    {
        if (info[i] != 1)
        {
            if (arb_calc_verbose)
            {
                printf("unable to count roots in ");
                arf_interval_printd(blocks + i, 15);
                printf("\n");
            }
            found_unknown++;
            continue;
        }

        found_roots++;

        if (!refine)
            continue;

        if (arb_calc_refine_root_bisect(t,
                                        function, NULL, blocks + i, 5, low_prec)
                != ARB_CALC_SUCCESS)
        {
            printf("warning: some bisection steps failed!\n");
        }

        if (arb_calc_verbose)
        {
            printf("after bisection 1: ");
            arf_interval_printd(t, 15);
            printf("\n");
        }

        if (arb_calc_refine_root_bisect(blocks + i,
                                        function, NULL, t, 5, low_prec)
                != ARB_CALC_SUCCESS)
        {
            printf("warning: some bisection steps failed!\n");
        }

        if (arb_calc_verbose)
        {
            printf("after bisection 2: ");
            arf_interval_printd(blocks + i, 15);
            printf("\n");
        }

        arf_interval_get_arb(v, t, high_prec);
        arb_calc_newton_conv_factor(C, function, NULL, v, low_prec);

        arf_interval_get_arb(w, blocks + i, high_prec);
        if (arb_calc_refine_root_newton(z, function, NULL,
                                        w, v, C, 10, high_prec) != ARB_CALC_SUCCESS)
        {
            printf("warning: some newton steps failed!\n");
        }

        printf("refined root:\n");
        arb_printd(z, digits + 2);
        printf("\n\n");
    }

    printf("---------------------------------------------------------------\n");
    printf("Found roots: %ld\n", found_roots);
    printf("Subintervals possibly containing undetected roots: %ld\n", found_unknown);
    printf("Function evaluations: %ld\n", eval_count);

    TIMEIT_ONCE_STOP
    SHOW_MEMORY_USAGE

    for (i = 0; i < num; i++)
        arf_interval_clear(blocks + i);
    flint_free(blocks);
    flint_free(info);

    arf_interval_clear(t);
    arf_interval_clear(interval);
    arf_clear(C);
    arb_clear(v);
    arb_clear(w);
    arb_clear(z);
    flint_cleanup();
    return 0;
}
示例#3
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 40; iter++)
    {
        slong m, r, a, b, maxdepth, maxeval, maxfound, prec, i, j, num;
        arf_interval_ptr blocks;
        int * info;
        arf_interval_t interval;
        arb_t t;
        fmpz_t nn;

        prec = 2 + n_randint(state, 50);

        m = n_randint(state, 80);
        r = 1 + n_randint(state, 80);
        a = m - r;
        b = m + r;

        maxdepth = 1 + n_randint(state, 60);
        maxeval = 1 + n_randint(state, 5000);
        maxfound = 1 + n_randint(state, 100);

        arf_interval_init(interval);
        arb_init(t);
        fmpz_init(nn);

        arf_set_si(&interval->a, a);
        arf_set_si(&interval->b, b);

        num = arb_calc_isolate_roots(&blocks, &info, sin_pi2_x, NULL,
            interval, maxdepth, maxeval, maxfound, prec);

        /* check that all roots are accounted for */
        for (i = a; i <= b; i++)
        {
            if (i % 2 == 0)
            {
                int found = 0;

                for (j = 0; j < num; j++)
                {
                    arf_interval_get_arb(t, blocks + j, ARF_PREC_EXACT);

                    if (arb_contains_si(t, i))
                    {
                        found = 1;
                        break;
                    }
                }

                if (!found)
                {
                    flint_printf("FAIL: missing root %wd\n", i);
                    flint_printf("a = %wd, b = %wd, maxdepth = %wd, maxeval = %wd, maxfound = %wd, prec = %wd\n",
                        a, b, maxdepth, maxeval, maxfound, prec);

                    for (j = 0; j < num; j++)
                    {
                        arf_interval_printd(blocks + j, 15);
                        flint_printf("   %d \n", info[i]);
                    }

                    abort();
                }
            }
        }

        /* check that all reported single roots are good */
        for (i = 0; i < num; i++)
        {
            if (info[i] == 1)
            {
                /* b contains unique 2n -> b/2 contains unique n */
                arf_interval_get_arb(t, blocks + i, ARF_PREC_EXACT);
                arb_mul_2exp_si(t, t, -1);

                if (!arb_get_unique_fmpz(nn, t))
                {
                    flint_printf("FAIL: bad root %wd\n", i);
                    flint_printf("a = %wd, b = %wd, maxdepth = %wd, maxeval = %wd, maxfound = %wd, prec = %wd\n",
                        a, b, maxdepth, maxeval, maxfound, prec);

                    for (j = 0; j < num; j++)
                    {
                        arf_interval_printd(blocks + j, 15);
                        flint_printf("   %d \n", info[i]);
                    }

                    abort();
                }
            }
        }

        _arf_interval_vec_clear(blocks, num);
        flint_free(info);

        arf_interval_clear(interval);
        arb_clear(t);
        fmpz_clear(nn);
    }

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