-
Notifications
You must be signed in to change notification settings - Fork 144
Description
Hi,
I am trying to extend the real_root.c example to finding the root of f(x)=sinh(2Jx)sinh(2Kx)-1 for J=K=1.
To create this function, I do
_arb_poly_sinh_series(out, x, xlen, order, prec);
_arb_poly_sinh_series(factor2, x2, xlen, order, prec);
_arb_poly_mullow(out, out, order, factor2, order, order, prec);
_arb_poly_sub(out, out, order, one->coeffs, one->length, prec);
where
arb_poly_one(one)
,
x2 is setup exactly like x,
and arb_struct factor2[2]
.
It results in a segfault after a couple of bisection steps.
The segfault is caused by _arb_poly_sinh_series(factor2, x2, xlen, order, prec) from which I deduce that I have not setup factor2 (since it persists when setting x = x2). Taking arb_t factor2
also gives a segfault.
Another issue:
Simplifying the function to f(x)=sinh(2*x)-1, given by
_arb_poly_sinh_series(out, x, xlen, order, prec);
_arb_poly_sub(out, out, order, one->coeffs, one->length, prec);
will find the correct root for the interval bounds a=0, b=5:
after bisection 2: [0.439453125000000, 0.444335937500000]
refined root (0/1):
[0.4418938 +/- 3.77e-10]
but will fail for a=0, b=10 which is surprising to me. It yells
after bisection 2: [0.439453125000000, 0.449218750000000]
warning: some newton steps failed! refined root (0/1):
0
I have further removed the if(arb_calc_verbose)
clauses appearing in real_root.c since they cause the following compile error, when compiling with c++ with the gcc 11 on an ARM Mac.
Undefined symbols for architecture arm64:
"___emutls_v.arb_calc_verbose", referenced from:
__ZN7Onsager3runEv in cc2Pzdb0.o
ld: symbol(s) not found for architecture arm64
Here is the modified example, I have commented code that I added (compared to real_root.c) with ^'s. Any help is appreciated, I hope this is an appropiate place to request for such.
#include "arb.h"
#include "arb_calc.h"
slong eval_count = 0;
struct Interactions
{
arb_t J;
arb_t K;
};
Interactions interactions;
int critical_temp(arb_ptr out, const arb_t inp, void * params, slong order, slong prec)
{
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_ptr x2; //^^^^^^
x2 = _arb_vec_init(xlen); //^^^^^^
arb_set(x2, inp); //^^^^^^
if (xlen > 1) //^^^^^^
arb_one(x2 + 1); //^^^^^^
auto inter_ptr = static_cast<Interactions*>(params); //^^^^^^
auto J = inter_ptr->J; //^^^^^^
auto K = inter_ptr->K; //^^^^^^
arb_mul(x, x, J, prec); //^^^^^^
arb_mul(x2, x2, K, prec); //^^^^^^
arb_t two; //^^^^^^
arb_init(two); //^^^^^^
arb_set_ui(two,2); //^^^^^^
arb_mul(x, x, two, prec); //^^^^^^
arb_mul(x2, x, two, prec); //^^^^^^
arb_clear(two); //^^^^^^
arb_poly_t one; //^^^^^^
arb_poly_init(one); //^^^^^^
arb_poly_one(one); //^^^^^^
arb_struct factor2[2]; // as in arb_calc::check_block //^^^^^^
arb_init(factor2); //^^^^^^
arb_init(factor2+1); //^^^^^^
//or arb_t factor2; // as in arb_calc::arb_calc_isolate_roots
_arb_poly_sinh_series(out, x, xlen, order, prec); //^^^^^^
_arb_poly_sinh_series(factor2, x2, xlen, order, prec); //^^^^^^
_arb_poly_mullow(out, out, order, factor2, order, order, prec); //^^^^^^
_arb_poly_sub(out, out, order, one->coeffs, one->length, prec); //^^^^^^
_arb_vec_clear(x, xlen);
_arb_vec_clear(x2, xlen); //^^^^^^
arb_poly_clear(one); //^^^^^^
arb_clear(factor2); //^^^^^^
arb_clear(factor2+1); //^^^^^^
eval_count++;
return 0;
}
void run()
{
arf_interval_ptr blocks;
arb_calc_func_t function;
int * info;
void * params;
int param1;
slong digits, low_prec, high_prec, i, num, found_roots, found_unknown;
slong maxdepth, maxeval, maxfound;
int refine;
double a, b;
arf_t C;
arf_interval_t t, interval;
arb_t v, w, z;
auto inter = Interactions(); //^^^^^^
arb_init(inter.J); //^^^^^^
arb_init(inter.K); //^^^^^^
arb_one(inter.J); //^^^^^^
arb_one(inter.K); //^^^^^^
params = (void*)(&inter); //^^^^^^
function = critical_temp;
a = 0;
b = 5; // fails for b=10: after bisection 2: [0.439453125000000, 0.449218750000000] warning: some newton steps failed! refined root (0/1): 0
refine = 1;
digits = 5;
maxdepth = 20;
maxeval = 1000;
maxfound = 1;
low_prec = 60;
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);
flint_printf("interval: "); arf_interval_printd(interval, 15); flint_printf("\n");
flint_printf("maxdepth = %wd, maxeval = %wd, maxfound = %wd, low_prec = %wd\n",
maxdepth, maxeval, maxfound, low_prec);
num = arb_calc_isolate_roots(&blocks, &info, function,
params, interval, maxdepth, maxeval, maxfound, low_prec);
for (i = 0; i < num; i++) {
if (info[i] != 1) {
if (1) //(arb_calc_verbose)
// else the following compile error: Undefined symbols for architecture arm64: "___emutls_v.arb_calc_verbose", referenced from: __ZN7Onsager3runEv in ccSUd03Y.o ld: symbol(s) not found for architecture arm64
{
flint_printf("unable to count roots in ");
arf_interval_printd(blocks + i, 15);
flint_printf("\n");
}
found_unknown++;
continue;
}
found_roots++;
if (!refine)
continue;
if (arb_calc_refine_root_bisect(t, function, params, blocks + i, 5, low_prec) != ARB_CALC_SUCCESS) {
flint_printf("warning: some bisection steps failed!\n");
}
if (1) //(arb_calc_verbose)
{
flint_printf("after bisection 1: ");
arf_interval_printd(t, 15);
flint_printf("\n");
}
if (arb_calc_refine_root_bisect(blocks + i, function, params, t, 5, low_prec) != ARB_CALC_SUCCESS) {
flint_printf("warning: some bisection steps failed!\n");
}
if (1)// (arb_calc_verbose)
{
flint_printf("after bisection 2: ");
arf_interval_printd(blocks + i, 15);
flint_printf("\n");
}
arf_interval_get_arb(v, t, high_prec);
arb_calc_newton_conv_factor(C, function, params, v, low_prec);
arf_interval_get_arb(w, blocks + i, high_prec);
if (arb_calc_refine_root_newton(z, function, params, w, v, C, 10, high_prec) != ARB_CALC_SUCCESS) {
flint_printf("warning: some newton steps failed!\n");
}
flint_printf("refined root (%wd/%wd):\n", i, num);
arb_printn(z, digits + 2, 0);
flint_printf("\n\n");
}
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);
for (i = 0; i < num; i++)
arf_interval_clear(blocks + i);
flint_free(blocks);
flint_free(info);
arb_clear(interactions.J); //^^^^^^
arb_clear(interactions.K); //^^^^^^
arf_interval_clear(t);
arf_interval_clear(interval);
arf_clear(C);
arb_clear(v);
arb_clear(w);
arb_clear(z);
flint_cleanup();
}