Skip to content

Question on the real_root.c example #425

@reneruhr

Description

@reneruhr

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();
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions