2014-06-19 15:43:48 +02:00
|
|
|
/* This file is public domain. Author: Fredrik Johansson. */
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include "arb_calc.h"
|
|
|
|
#include "profiler.h"
|
|
|
|
|
|
|
|
long eval_count = 0;
|
|
|
|
|
|
|
|
int
|
2015-11-05 18:02:07 +00:00
|
|
|
z_function(arb_ptr out, const arb_t inp, void * params, slong order, slong prec)
|
2014-06-19 15:43:48 +02:00
|
|
|
{
|
|
|
|
arb_struct x[2];
|
|
|
|
|
|
|
|
arb_init(x);
|
|
|
|
arb_init(x + 1);
|
|
|
|
|
|
|
|
arb_set(x, inp);
|
|
|
|
arb_one(x + 1);
|
|
|
|
|
|
|
|
_arb_poly_riemann_siegel_z_series(out, x, FLINT_MIN(2, order), order, prec);
|
|
|
|
|
|
|
|
arb_clear(x);
|
|
|
|
arb_clear(x + 1);
|
|
|
|
|
|
|
|
eval_count++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2015-11-05 18:02:07 +00:00
|
|
|
sin_x(arb_ptr out, const arb_t inp, void * params, slong order, slong prec)
|
2014-06-19 15:43:48 +02:00
|
|
|
{
|
|
|
|
int xlen = FLINT_MIN(2, order);
|
|
|
|
|
|
|
|
arb_set(out, inp);
|
|
|
|
if (xlen > 1)
|
|
|
|
arb_one(out + 1);
|
|
|
|
|
|
|
|
_arb_poly_sin_series(out, out, xlen, order, prec);
|
|
|
|
|
|
|
|
eval_count++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2015-11-05 18:02:07 +00:00
|
|
|
sin_x2(arb_ptr out, const arb_t inp, void * params, slong order, slong prec)
|
2014-06-19 15:43:48 +02:00
|
|
|
{
|
|
|
|
arb_ptr x;
|
|
|
|
|
|
|
|
int xlen = FLINT_MIN(2, order);
|
|
|
|
int ylen = FLINT_MIN(3, order);
|
|
|
|
|
|
|
|
x = _arb_vec_init(xlen);
|
|
|
|
|
|
|
|
arb_set(x, inp);
|
|
|
|
if (xlen > 1)
|
|
|
|
arb_one(x + 1);
|
|
|
|
|
|
|
|
_arb_poly_mullow(out, x, xlen, x, xlen, ylen, prec);
|
|
|
|
_arb_poly_sin_series(out, out, ylen, order, prec);
|
|
|
|
|
|
|
|
_arb_vec_clear(x, xlen);
|
|
|
|
|
|
|
|
eval_count++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2015-11-05 18:02:07 +00:00
|
|
|
sin_1x(arb_ptr out, const arb_t inp, void * params, slong order, slong prec)
|
2014-06-19 15:43:48 +02:00
|
|
|
{
|
|
|
|
arb_ptr x;
|
|
|
|
int xlen = FLINT_MIN(2, order);
|
|
|
|
|
|
|
|
x = _arb_vec_init(xlen);
|
|
|
|
|
|
|
|
arb_set(x, inp);
|
|
|
|
if (xlen > 1)
|
|
|
|
arb_one(x + 1);
|
|
|
|
|
|
|
|
_arb_poly_inv_series(out, x, xlen, order, prec);
|
|
|
|
_arb_poly_sin_series(out, out, order, order, prec);
|
|
|
|
|
|
|
|
_arb_vec_clear(x, xlen);
|
|
|
|
|
|
|
|
eval_count++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
arf_interval_ptr blocks;
|
|
|
|
arb_calc_func_t function;
|
|
|
|
int * info;
|
2015-11-05 18:02:07 +00:00
|
|
|
slong digits, low_prec, high_prec, i, num, found_roots, found_unknown;
|
|
|
|
slong maxdepth, maxeval, maxfound;
|
2014-06-19 15:43:48 +02:00
|
|
|
int refine;
|
|
|
|
double a, b;
|
|
|
|
arf_t C;
|
|
|
|
arf_interval_t t, interval;
|
|
|
|
arb_t v, w, z;
|
|
|
|
|
|
|
|
if (argc < 4)
|
|
|
|
{
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("real_roots function a b [-refine d] [-verbose] "
|
2014-06-19 15:43:48 +02:00
|
|
|
"[-maxdepth n] [-maxeval n] [-maxfound n] [-prec n]\n");
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("available functions:\n");
|
|
|
|
flint_printf(" 0 Z(x), Riemann-Siegel Z-function\n");
|
|
|
|
flint_printf(" 1 sin(x)\n");
|
|
|
|
flint_printf(" 2 sin(x^2)\n");
|
|
|
|
flint_printf(" 3 sin(1/x)\n");
|
2014-06-19 15:43:48 +02:00
|
|
|
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:
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("require a function 0-3\n");
|
2014-06-19 15:43:48 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
a = atof(argv[2]);
|
|
|
|
b = atof(argv[3]);
|
|
|
|
|
|
|
|
if (a >= b)
|
|
|
|
{
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("require a < b!\n");
|
2014-06-19 15:43:48 +02:00
|
|
|
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);
|
|
|
|
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("interval: "); arf_interval_printd(interval, 15); flint_printf("\n");
|
|
|
|
flint_printf("maxdepth = %wd, maxeval = %wd, maxfound = %wd, low_prec = %wd\n",
|
2014-06-19 15:43:48 +02:00
|
|
|
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)
|
|
|
|
{
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("unable to count roots in ");
|
2014-06-19 15:43:48 +02:00
|
|
|
arf_interval_printd(blocks + i, 15);
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("\n");
|
2014-06-19 15:43:48 +02:00
|
|
|
}
|
|
|
|
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)
|
|
|
|
{
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("warning: some bisection steps failed!\n");
|
2014-06-19 15:43:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (arb_calc_verbose)
|
|
|
|
{
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("after bisection 1: ");
|
2014-06-19 15:43:48 +02:00
|
|
|
arf_interval_printd(t, 15);
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("\n");
|
2014-06-19 15:43:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (arb_calc_refine_root_bisect(blocks + i,
|
|
|
|
function, NULL, t, 5, low_prec)
|
|
|
|
!= ARB_CALC_SUCCESS)
|
|
|
|
{
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("warning: some bisection steps failed!\n");
|
2014-06-19 15:43:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (arb_calc_verbose)
|
|
|
|
{
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("after bisection 2: ");
|
2014-06-19 15:43:48 +02:00
|
|
|
arf_interval_printd(blocks + i, 15);
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("\n");
|
2014-06-19 15:43:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("warning: some newton steps failed!\n");
|
2014-06-19 15:43:48 +02:00
|
|
|
}
|
|
|
|
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("refined root:\n");
|
2014-06-19 15:43:48 +02:00
|
|
|
arb_printd(z, digits + 2);
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("\n\n");
|
2014-06-19 15:43:48 +02:00
|
|
|
}
|
|
|
|
|
2015-11-06 16:17:27 +00:00
|
|
|
flint_printf("---------------------------------------------------------------\n");
|
|
|
|
flint_printf("Found roots: %wd\n", found_roots);
|
|
|
|
flint_printf("Subintervals possibly containing undetected roots: %wd\n", found_unknown);
|
|
|
|
flint_printf("Function evaluations: %wd\n", eval_count);
|
2014-06-19 15:43:48 +02:00
|
|
|
|
|
|
|
TIMEIT_ONCE_STOP
|
|
|
|
SHOW_MEMORY_USAGE
|
|
|
|
|
2015-02-13 16:17:00 +01:00
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
arf_interval_clear(blocks + i);
|
|
|
|
flint_free(blocks);
|
|
|
|
flint_free(info);
|
|
|
|
|
2014-06-19 15:43:48 +02:00
|
|
|
arf_interval_clear(t);
|
|
|
|
arf_interval_clear(interval);
|
|
|
|
arf_clear(C);
|
|
|
|
arb_clear(v);
|
|
|
|
arb_clear(w);
|
|
|
|
arb_clear(z);
|
|
|
|
flint_cleanup();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|