Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Copyright (C) 2018 Association des collaborateurs de D.H.J Polymath
- This is free software: you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License (LGPL) as published
- by the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version. See <http://www.gnu.org/licenses/>.
- */
- #include "acb_calc.h"
- void eulerian_polynomial(fmpz_poly_t res, slong len)
- {
- if (len)
- {
- slong n, m;
- fmpz *curr, *prev, *tmp;
- prev = _fmpz_vec_init(len);
- curr = _fmpz_vec_init(len);
- fmpz_one(curr + 0);
- for (n = 1; n < len+1; n++)
- {
- tmp = curr; curr = prev; prev = tmp;
- fmpz_one(curr + 0);
- fmpz_one(curr + n - 1);
- for (m = 1; m < n-1; m++)
- {
- fmpz_mul_si(curr + m, prev + m - 1, n - m);
- fmpz_addmul_ui(curr + m, prev + m, m + 1);
- }
- }
- fmpz_poly_zero(res);
- for (m = 0; m < len; m++)
- {
- fmpz_poly_set_coeff_fmpz(res, m, curr + m);
- }
- _fmpz_vec_clear(prev, len);
- _fmpz_vec_clear(curr, len);
- }
- else
- {
- fmpz_poly_zero(res);
- }
- }
- static void
- generalized_geometric_remainder(arb_t res,
- const arb_t c, ulong n0, ulong k, slong prec)
- {
- fmpz_poly_t zpoly;
- arb_poly_t poly;
- arb_t cc, s, d;
- fmpz_t bin, n0p;
- slong i, j;
- fmpz_poly_init(zpoly);
- arb_poly_init(poly);
- arb_init(cc);
- arb_one(cc);
- arb_sub(cc, cc, c, prec);
- arb_inv(cc, cc, prec);
- fmpz_init(bin);
- fmpz_init(n0p);
- arb_init(s);
- arb_init(d);
- arb_one(d);
- arb_zero(res);
- for (i = 0; i < k+1; i++)
- {
- arb_mul(d, d, cc, prec);
- fmpz_bin_uiui(bin, k, i);
- fmpz_set_ui(n0p, n0);
- fmpz_pow_ui(n0p, n0p, k - i);
- fmpz_mul(n0p, n0p, bin);
- if (i)
- {
- eulerian_polynomial(zpoly, i);
- fmpz_poly_shift_left(zpoly, zpoly, 1);
- arb_poly_set_fmpz_poly(poly, zpoly, prec);
- arb_poly_evaluate(s, poly, c, prec);
- }
- else
- {
- arb_one(s);
- }
- arb_mul_fmpz(s, s, n0p, prec);
- arb_mul(s, s, d, prec);
- arb_add(res, res, s, prec);
- }
- arb_poly_clear(poly);
- fmpz_poly_clear(zpoly);
- arb_clear(cc);
- arb_clear(s);
- arb_clear(d);
- fmpz_clear(bin);
- fmpz_clear(n0p);
- }
- static void
- _gamma_helper(arb_t res, const arb_t theta, slong n, slong prec)
- {
- arb_t beta;
- arb_init(beta);
- arb_const_pi(beta, prec);
- arb_mul_si(beta, beta, n*n, prec);
- arb_mul_2exp_si(res, theta, 2);
- arb_cos(res, res, prec);
- arb_mul(res, res, beta, prec);
- arb_clear(beta);
- }
- static void
- _gamma(arb_t res, const arb_t theta, const arb_t X, slong n, slong prec)
- {
- arb_t g;
- arb_init(g);
- _gamma_helper(g, theta, n, prec);
- arb_mul_2exp_si(res, X, 2);
- arb_exp(res, res, prec);
- arb_mul(res, res, g, prec);
- arb_clear(g);
- }
- void
- integral_remainder_bound_permissibility_lhs(arb_t res,
- const arb_t theta, const arb_t X, slong n, slong prec)
- {
- _gamma(res, theta, X, n, prec);
- }
- void
- integral_bound_permissibility_lhs(arb_t res,
- const arb_t theta, slong n, slong prec)
- {
- _gamma_helper(res, theta, n, prec);
- }
- void
- integral_remainder_bound_permissibility_rhs(arb_t res,
- const arb_t t, const arb_t a, const arb_t X, slong prec)
- {
- arb_t r1, r2;
- arb_init(r1);
- arb_init(r2);
- arb_mul_2exp_si(r1, t, -1);
- arb_mul(r2, t, X, prec);
- arb_mul_2exp_si(r2, r2, 1);
- arb_add(r2, r2, a, prec);
- arb_mul_2exp_si(r2, r2, -2);
- arb_max(res, r1, r2, prec);
- arb_clear(r1);
- arb_clear(r2);
- }
- void
- integral_bound_permissibility_rhs(arb_t res,
- const arb_t t, const arb_t a, slong prec)
- {
- arb_t r1, r2;
- arb_init(r1);
- arb_mul_2exp_si(r1, t, -1);
- arb_init(r2);
- arb_mul_2exp_si(r2, a, -2);
- arb_max(res, r1, r2, prec);
- arb_clear(r1);
- arb_clear(r2);
- }
- int integral_remainder_bound_is_permissible(const arb_t theta, const arb_t t,
- const arb_t a, slong n, const arb_t X, slong prec)
- {
- arb_t lhs, rhs;
- int result;
- arb_init(lhs);
- arb_init(rhs);
- integral_remainder_bound_permissibility_lhs(lhs, theta, X, n, prec);
- integral_remainder_bound_permissibility_rhs(rhs, t, a, X, prec);
- result = arb_gt(lhs, rhs);
- arb_clear(lhs);
- arb_clear(rhs);
- return result;
- }
- int integral_bound_is_permissible(const arb_t theta, const arb_t t,
- const arb_t a, slong n, slong prec)
- {
- arb_t lhs, rhs;
- int result;
- arb_init(lhs);
- arb_init(rhs);
- integral_bound_permissibility_lhs(lhs, theta, n, prec);
- integral_bound_permissibility_rhs(rhs, t, a, prec);
- result = arb_gt(lhs, rhs);
- arb_clear(lhs);
- arb_clear(rhs);
- return result;
- }
- int integral_bounds_are_permissible(
- const arb_t theta, const arb_t t,
- const arb_t y, slong n, slong prec)
- {
- arb_t a;
- int result = 1;
- arb_init(a);
- arb_sub_ui(a, y, 9, prec);
- arb_neg(a, a);
- if (!integral_bound_is_permissible(theta, t, a, n, prec))
- {
- result = 0;
- goto finish;
- }
- arb_sub_ui(a, y, 5, prec);
- arb_neg(a, a);
- if (!integral_bound_is_permissible(theta, t, a, n, prec))
- {
- result = 0;
- goto finish;
- }
- arb_add_ui(a, y, 9, prec);
- if (!integral_bound_is_permissible(theta, t, a, n, prec))
- {
- result = 0;
- goto finish;
- }
- arb_add_ui(a, y, 5, prec);
- if (!integral_bound_is_permissible(theta, t, a, n, prec))
- {
- result = 0;
- goto finish;
- }
- finish:
- arb_clear(a);
- return result;
- }
- static void
- _integral_remainder_helper(arb_t res1, arb_t res2,
- const arb_t theta, const arb_t t, const arb_t x,
- const arb_t a, slong n, const arb_t X, slong prec)
- {
- arb_t z1, z2;
- arb_t w1, w2;
- arb_init(w1);
- arb_mul(w1, t, X, prec);
- arb_add(w1, w1, a, prec);
- arb_mul(w1, w1, X, prec);
- arb_init(w2);
- arb_mul(w2, t, theta, prec);
- arb_add(w2, w2, x, prec);
- arb_mul(w2, w2, theta, prec);
- arb_init(z1);
- _gamma(z1, theta, X, n, prec);
- arb_init(z2);
- arb_mul(z2, t, X, prec);
- arb_mul_2exp_si(z2, z2, 1);
- arb_add(z2, z2, a, prec);
- arb_sub(res1, w1, z1, prec);
- arb_sub(res1, res1, w2, prec);
- arb_exp(res1, res1, prec);
- arb_mul_2exp_si(res2, z1, 2);
- arb_sub(res2, res2, z2, prec);
- arb_clear(z1);
- arb_clear(z2);
- arb_clear(w1);
- arb_clear(w2);
- }
- static void
- _D_integral_remainder_helper(arb_t res1, arb_t res2,
- const arb_t theta, const arb_t t,
- const arb_t a, slong n, const arb_t X, slong prec)
- {
- arb_t z1, z2;
- arb_t w1;
- arb_init(w1);
- arb_mul(w1, t, X, prec);
- arb_add(w1, w1, a, prec);
- arb_mul(w1, w1, X, prec);
- arb_init(z1);
- _gamma(z1, theta, X, n, prec);
- arb_init(z2);
- arb_mul(z2, t, X, prec);
- arb_mul_2exp_si(z2, z2, 1);
- arb_add(z2, z2, a, prec);
- arb_sub(res1, w1, z1, prec);
- arb_exp(res1, res1, prec);
- arb_mul_2exp_si(res2, z1, 2);
- arb_sub(res2, res2, z2, prec);
- arb_clear(z1);
- arb_clear(z2);
- arb_clear(w1);
- }
- static void
- _integral_helper(arb_t res1, arb_t res2,
- const arb_t theta, const arb_t t, const arb_t x,
- const arb_t a, slong n, slong prec)
- {
- arb_t beta, z1, z2;
- arb_init(beta);
- arb_const_pi(beta, prec);
- arb_mul_si(beta, beta, n*n, prec);
- arb_init(z1);
- arb_mul_2exp_si(z1, theta, 2);
- arb_cos(z1, z1, prec);
- arb_mul(z1, z1, beta, prec);
- arb_init(z2);
- arb_mul(z2, t, theta, prec);
- arb_add(z2, z2, x, prec);
- arb_mul(z2, z2, theta, prec);
- arb_add(res1, z1, z2, prec);
- arb_neg(res1, res1);
- arb_exp(res1, res1, prec);
- arb_mul_2exp_si(res2, z1, 2);
- arb_sub(res2, res2, a, prec);
- arb_clear(beta);
- arb_clear(z1);
- arb_clear(z2);
- }
- static void
- _D_integral_helper(arb_t res1, arb_t res2,
- const arb_t theta, const arb_t t,
- const arb_t a, slong n, slong prec)
- {
- arb_t beta, z1;
- arb_init(beta);
- arb_const_pi(beta, prec);
- arb_mul_si(beta, beta, n*n, prec);
- arb_init(z1);
- arb_mul_2exp_si(z1, theta, 2);
- arb_cos(z1, z1, prec);
- arb_mul(z1, z1, beta, prec);
- arb_neg(res1, z1);
- arb_exp(res1, res1, prec);
- arb_mul_2exp_si(res2, z1, 2);
- arb_sub(res2, res2, a, prec);
- arb_clear(beta);
- arb_clear(z1);
- }
- void
- I_integral_remainder_bound(arb_t res,
- const arb_t theta, const arb_t t, const arb_t x,
- const arb_t a, slong n, const arb_t X, slong prec)
- {
- arb_t den;
- arb_init(den);
- _integral_remainder_helper(res, den, theta, t, x, a, n, X, prec);
- arb_div(res, res, den, prec);
- arb_clear(den);
- }
- void I_integral_bound(arb_t res,
- const arb_t theta, const arb_t t, const arb_t x,
- const arb_t a, slong n, slong prec)
- {
- arb_t den;
- arb_init(den);
- _integral_helper(res, den, theta, t, x, a, n, prec);
- arb_div(res, res, den, prec);
- arb_clear(den);
- }
- void
- D_integral_remainder_bound(arb_t res,
- const arb_t theta, const arb_t t,
- const arb_t a, slong n, const arb_t X, slong prec)
- {
- arb_t u, v;
- arb_t q;
- arb_init(u);
- arb_init(v);
- _D_integral_remainder_helper(u, v, theta, t, a, n, X, prec);
- arb_inv(v, v, prec);
- arb_init(q);
- arb_hypot(q, X, theta, prec);
- arb_add(res, q, v, prec);
- arb_mul(res, res, u, prec);
- arb_mul(res, res, v, prec);
- arb_clear(u);
- arb_clear(v);
- arb_clear(q);
- }
- void D_integral_bound(arb_t res,
- const arb_t theta, const arb_t t,
- const arb_t a, slong n, slong prec)
- {
- arb_t u, v;
- arb_init(u);
- arb_init(v);
- _D_integral_helper(u, v, theta, t, a, n, prec);
- arb_inv(v, v, prec);
- arb_add(res, theta, v, prec);
- arb_mul(res, res, u, prec);
- arb_mul(res, res, v, prec);
- arb_clear(u);
- arb_clear(v);
- }
- void
- _acb_get_rad_ubound_mag(mag_t res, const acb_t z, slong prec)
- {
- arf_t err;
- arf_init(err);
- acb_get_rad_ubound_arf(err, z, prec);
- arf_get_mag(res, err);
- arf_clear(err);
- }
- typedef struct
- {
- arb_t t;
- arb_t x;
- arb_t a;
- slong n;
- } IJ_integrand_param_struct;
- typedef IJ_integrand_param_struct IJ_integrand_param_t[1];
- typedef IJ_integrand_param_struct *IJ_integrand_param_ptr;
- typedef const IJ_integrand_param_struct *IJ_integrand_param_srcptr;
- static void
- IJ_integrand_param_init(IJ_integrand_param_t p,
- const arb_t t, const arb_t x, const arb_t a, slong n)
- {
- arb_init(p->t);
- arb_init(p->x);
- arb_init(p->a);
- arb_set(p->t, t);
- arb_set(p->x, x);
- arb_set(p->a, a);
- p->n = n;
- }
- static void
- IJ_integrand_param_clear(IJ_integrand_param_t p)
- {
- arb_clear(p->t);
- arb_clear(p->x);
- arb_clear(p->a);
- }
- typedef struct
- {
- arb_t t;
- arb_t theta;
- arb_t a;
- slong n;
- } D_integrand_param_struct;
- typedef D_integrand_param_struct D_integrand_param_t[1];
- typedef D_integrand_param_struct *D_integrand_param_ptr;
- typedef const D_integrand_param_struct *D_integrand_param_srcptr;
- static void
- D_integrand_param_init(D_integrand_param_t p,
- const arb_t t, const arb_t theta, const arb_t a, slong n)
- {
- arb_init(p->t);
- arb_init(p->theta);
- arb_init(p->a);
- arb_set(p->t, t);
- arb_set(p->theta, theta);
- arb_set(p->a, a);
- p->n = n;
- }
- static void
- D_integrand_param_clear(D_integrand_param_t p)
- {
- arb_clear(p->t);
- arb_clear(p->theta);
- arb_clear(p->a);
- }
- int IJ_integrand_domain_contains(const acb_t u)
- {
- int result;
- acb_t domain;
- arb_ptr x, y;
- acb_init(domain);
- x = acb_realref(domain);
- y = acb_imagref(domain);
- arb_zero_pm_inf(x);
- mag_const_pi_lower(arb_radref(y));
- mag_mul_2exp_si(arb_radref(y), arb_radref(y), -3);
- result = acb_contains(domain, u);
- acb_clear(domain);
- return result;
- }
- static void
- I_integrand(acb_t res, const acb_t u,
- const arb_t t, const arb_t x, const arb_t a, slong n, slong prec)
- {
- arb_t beta;
- acb_t b, ibu, tuu;
- arb_init(beta);
- arb_const_pi(beta, prec);
- arb_mul_si(beta, beta, n*n, prec);
- acb_init(b);
- arb_set(acb_realref(b), x);
- arb_neg(acb_imagref(b), a);
- acb_init(ibu);
- acb_onei(ibu);
- acb_mul(ibu, ibu, b, prec);
- acb_mul(ibu, ibu, u, prec);
- acb_init(tuu);
- acb_sqr(tuu, u, prec);
- acb_mul_arb(tuu, tuu, t, prec);
- acb_mul_2exp_si(res, u, 2);
- acb_exp(res, res, prec);
- acb_mul_arb(res, res, beta, prec);
- acb_neg(res, res);
- acb_add(res, res, tuu, prec);
- acb_add(res, res, ibu, prec);
- acb_exp(res, res, prec);
- arb_clear(beta);
- acb_clear(b);
- acb_clear(ibu);
- acb_clear(tuu);
- }
- static int
- f_I_integrand(acb_ptr res, const acb_t u, void * param,
- slong order, slong prec)
- {
- IJ_integrand_param_srcptr p;
- if (order > 1)
- flint_abort();
- if (!IJ_integrand_domain_contains(u))
- {
- acb_indeterminate(res);
- return 0;
- }
- p = param;
- I_integrand(res, u, p->t, p->x, p->a, p->n, prec);
- return 0;
- }
- void
- I_proper_integral(acb_t res,
- const arb_t lower_limit,
- const arb_t upper_limit,
- const arb_t theta,
- const mag_t abs_estimate,
- const arb_t t, const arb_t x, const arb_t a, slong n, slong prec)
- {
- IJ_integrand_param_t p;
- acb_t a_lim, b_lim;
- acb_calc_integrate_opt_t options;
- int calc_result;
- mag_t abs_tol;
- slong rel_goal = prec;
- IJ_integrand_param_init(p, t, x, a, n);
- acb_init(a_lim);
- acb_init(b_lim);
- acb_set_arb_arb(a_lim, lower_limit, theta);
- acb_set_arb_arb(b_lim, upper_limit, theta);
- mag_init(abs_tol);
- mag_mul_2exp_si(abs_tol, abs_estimate, -prec);
- acb_calc_integrate_opt_init(options);
- options->depth_limit = 100*prec;
- options->use_heap = 1;
- options->verbose = 0;
- calc_result = acb_calc_integrate(
- res, f_I_integrand, p, a_lim, b_lim,
- rel_goal, abs_tol, options, prec);
- if (calc_result == ARB_CALC_NO_CONVERGENCE)
- {
- acb_indeterminate(res);
- }
- IJ_integrand_param_clear(p);
- acb_clear(a_lim);
- acb_clear(b_lim);
- mag_clear(abs_tol);
- }
- void
- I_integral(acb_t res,
- const arb_t theta, const mag_t m_estimate,
- const arb_t t, const arb_t x, const arb_t a, slong n, slong prec)
- {
- arb_t lower, upper, remainder;
- acb_t value, partial;
- mag_t m_partial_sum, tail_mag_lb, tail_mag_ub;
- slong r, p, q, tmp;
- arb_init(lower);
- arb_init(upper);
- arb_init(remainder);
- acb_init(value);
- acb_init(partial);
- arb_init(remainder);
- mag_init(m_partial_sum);
- mag_init(tail_mag_lb);
- mag_init(tail_mag_ub);
- r = 0;
- p = 0;
- q = 1;
- while (1)
- {
- tmp = p + q;
- arb_set_ui(lower, r);
- arb_set_ui(upper, r + q);
- arb_mul_2exp_si(lower, lower, -4);
- arb_mul_2exp_si(upper, upper, -4);
- r = r + q;
- p = q;
- q = tmp;
- I_proper_integral(value, lower, upper,
- theta, m_estimate, t, x, a, n, prec);
- acb_add(partial, partial, value, prec);
- if (integral_remainder_bound_is_permissible(
- theta, t, a, n, upper, prec))
- {
- I_integral_remainder_bound(
- remainder, theta, t, x, a, n, upper, prec);
- arb_get_mag(tail_mag_ub, remainder);
- _acb_get_rad_ubound_mag(m_partial_sum, partial, prec);
- arb_get_mag_lower(tail_mag_lb, remainder);
- if (mag_cmp(tail_mag_lb, m_partial_sum) <= 0)
- {
- acb_set(res, partial);
- acb_add_error_mag(res, tail_mag_ub);
- break;
- }
- }
- }
- arb_clear(lower);
- arb_clear(upper);
- acb_clear(value);
- acb_clear(partial);
- arb_clear(remainder);
- mag_clear(m_partial_sum);
- mag_clear(tail_mag_lb);
- mag_clear(tail_mag_ub);
- }
- static void
- D_integrand(acb_t res, const acb_t u,
- const arb_t t, const arb_t theta, const arb_t a, slong n, slong prec)
- {
- arb_t beta, c4, r;
- acb_t z1, z2, rc;
- arb_init(beta);
- arb_const_pi(beta, prec);
- arb_mul_si(beta, beta, n*n, prec);
- acb_init(rc);
- acb_onei(rc);
- acb_mul(rc, rc, u, prec);
- acb_add_arb(rc, rc, theta, prec);
- arb_init(r);
- acb_abs(r, rc, prec);
- acb_init(z1);
- acb_mul_arb(z1, u, t, prec);
- acb_add_arb(z1, z1, a, prec);
- acb_mul(z1, z1, u, prec);
- arb_init(c4);
- arb_mul_2exp_si(c4, theta, 2);
- arb_cos(c4, c4, prec);
- acb_init(z2);
- acb_mul_2exp_si(z2, u, 2);
- acb_exp(z2, z2, prec);
- acb_mul_arb(z2, z2, beta, prec);
- acb_mul_arb(z2, z2, c4, prec);
- acb_sub(res, z1, z2, prec);
- acb_exp(res, res, prec);
- acb_mul_arb(res, res, r, prec);
- arb_clear(beta);
- arb_clear(c4);
- arb_clear(r);
- acb_clear(z1);
- acb_clear(z2);
- acb_clear(rc);
- }
- static int
- f_D_integrand(acb_ptr res, const acb_t u, void * param,
- slong order, slong prec)
- {
- D_integrand_param_srcptr p;
- if (order > 1)
- flint_abort();
- p = param;
- D_integrand(res, u, p->t, p->theta, p->a, p->n, prec);
- return 0;
- }
- void
- D_proper_integral(arb_t res,
- const arb_t lower_limit,
- const arb_t upper_limit,
- const arb_t theta,
- const mag_t abs_estimate,
- const arb_t t, const arb_t a, slong n, slong prec)
- {
- D_integrand_param_t p;
- acb_t a_lim, b_lim, value;
- acb_calc_integrate_opt_t options;
- int calc_result;
- mag_t abs_tol;
- slong rel_goal = prec;
- D_integrand_param_init(p, t, theta, a, n);
- acb_init(a_lim);
- acb_init(b_lim);
- acb_set_arb(a_lim, lower_limit);
- acb_set_arb(b_lim, upper_limit);
- mag_init(abs_tol);
- mag_mul_2exp_si(abs_tol, abs_estimate, -prec);
- acb_calc_integrate_opt_init(options);
- options->depth_limit = 100*prec;
- options->use_heap = 1;
- options->verbose = 0;
- acb_init(value);
- calc_result = acb_calc_integrate(
- value, f_D_integrand, p, a_lim, b_lim,
- rel_goal, abs_tol, options, prec);
- if (calc_result == ARB_CALC_NO_CONVERGENCE)
- {
- acb_indeterminate(value);
- }
- arb_set(res, acb_realref(value));
- D_integrand_param_clear(p);
- acb_clear(a_lim);
- acb_clear(b_lim);
- acb_clear(value);
- mag_clear(abs_tol);
- }
- void
- D_integral(arb_t res,
- const arb_t theta, const mag_t m_estimate,
- const arb_t t, const arb_t a, slong n, slong prec)
- {
- arb_t lower, upper, remainder;
- arb_t value, partial;
- mag_t m_partial_sum, tail_mag_lb, tail_mag_ub;
- slong r, p, q, tmp;
- arb_init(lower);
- arb_init(upper);
- arb_init(remainder);
- arb_init(value);
- arb_init(partial);
- arb_init(remainder);
- mag_init(m_partial_sum);
- mag_init(tail_mag_lb);
- mag_init(tail_mag_ub);
- r = 0;
- p = 0;
- q = 1;
- while (1)
- {
- tmp = p + q;
- arb_set_ui(lower, r);
- arb_set_ui(upper, r + q);
- arb_mul_2exp_si(lower, lower, -4);
- arb_mul_2exp_si(upper, upper, -4);
- r = r + q;
- p = q;
- q = tmp;
- D_proper_integral(value, lower, upper,
- theta, m_estimate, t, a, n, prec);
- arb_add(partial, partial, value, prec);
- if (integral_remainder_bound_is_permissible(
- theta, t, a, n, upper, prec))
- {
- D_integral_remainder_bound(
- remainder, theta, t, a, n, upper, prec);
- arb_get_mag(tail_mag_ub, remainder);
- mag_set(m_partial_sum, arb_radref(partial));
- arb_get_mag_lower(tail_mag_lb, remainder);
- if (mag_cmp(tail_mag_lb, m_partial_sum) <= 0)
- {
- arb_set(res, partial);
- arb_add_error_mag(res, tail_mag_ub);
- break;
- }
- }
- }
- arb_clear(lower);
- arb_clear(upper);
- arb_clear(value);
- arb_clear(partial);
- arb_clear(remainder);
- mag_clear(m_partial_sum);
- mag_clear(tail_mag_lb);
- mag_clear(tail_mag_ub);
- }
- void
- H_approximation(arb_t res, const arb_t x, const arb_t y, slong prec)
- {
- if (arb_contains_nonpositive(x))
- {
- arb_one(res);
- }
- else
- {
- arb_t logx, pixd8;
- arb_init(logx);
- arb_log(logx, x, prec);
- arb_init(pixd8);
- arb_const_pi(pixd8, prec);
- arb_mul(pixd8, pixd8, x, prec);
- arb_mul_2exp_si(pixd8, pixd8, -3);
- arb_add_si(res, y, 7, prec);
- arb_mul(res, res, logx, prec);
- arb_mul_2exp_si(res, res, -2);
- arb_sub(res, res, pixd8, prec);
- arb_exp(res, res, prec);
- arb_clear(logx);
- arb_clear(pixd8);
- }
- }
- void
- get_theta(arb_t res, const acb_t z, slong prec)
- {
- arb_t pid8;
- arb_init(pid8);
- arb_const_pi(pid8, prec);
- arb_mul_2exp_si(pid8, pid8, -3);
- arb_add_si(res, acb_imagref(z), 9, prec);
- arb_atan2(res, res, acb_realref(z), prec);
- arb_mul_2exp_si(res, res, -2);
- arb_sub(res, pid8, res, prec);
- arb_clear(pid8);
- }
- static void
- H_summand(acb_t res,
- const arb_t theta, mag_t m_estimate,
- const arb_t t, const arb_t x, const arb_t y, slong n, slong prec)
- {
- arb_t a;
- acb_t s, total;
- arb_t beta, c1, c2;
- arb_init(a);
- acb_init(s);
- acb_init(total);
- arb_init(beta);
- arb_const_pi(beta, prec);
- arb_mul_si(beta, beta, n*n, prec);
- arb_init(c1);
- arb_sqr(c1, beta, prec);
- arb_init(c2);
- arb_mul_si(c2, beta, 3, prec);
- arb_mul_2exp_si(c2, c2, -1);
- arb_sub_ui(a, y, 9, prec);
- arb_neg(a, a);
- I_integral(s, theta, m_estimate, t, x, a, n, prec);
- acb_mul_arb(s, s, c1, prec);
- acb_add(total, total, s, prec);
- arb_sub_ui(a, y, 5, prec);
- arb_neg(a, a);
- I_integral(s, theta, m_estimate, t, x, a, n, prec);
- acb_mul_arb(s, s, c2, prec);
- acb_sub(total, total, s, prec);
- arb_add_ui(a, y, 9, prec);
- I_integral(s, theta, m_estimate, t, x, a, n, prec);
- acb_conj(s, s);
- acb_mul_arb(s, s, c1, prec);
- acb_add(total, total, s, prec);
- arb_add_ui(a, y, 5, prec);
- I_integral(s, theta, m_estimate, t, x, a, n, prec);
- acb_conj(s, s);
- acb_mul_arb(s, s, c2, prec);
- acb_sub(total, total, s, prec);
- acb_set(res, total);
- arb_clear(a);
- acb_clear(s);
- acb_clear(total);
- arb_clear(beta);
- arb_clear(c1);
- arb_clear(c2);
- }
- static void
- _summation_alpha(arb_t res, const arb_t theta, slong n0, slong prec)
- {
- arb_t c4;
- arb_init(c4);
- arb_mul_2exp_si(c4, theta, 2);
- arb_cos(c4, c4, prec);
- arb_const_pi(res, prec);
- arb_mul(res, res, c4, prec);
- arb_mul_si(res, res, n0, prec);
- arb_neg(res, res);
- arb_exp(res, res, prec);
- arb_clear(c4);
- }
- static void
- I_summation_remainder_bound(arb_t res,
- const arb_t theta, const arb_t t, const arb_t x, const arb_t y,
- slong n0, slong prec)
- {
- arb_t pi, c1, c2, g2, g4;
- arb_t alpha, a;
- arb_t s, total;
- arb_init(alpha);
- _summation_alpha(alpha, theta, n0, prec);
- arb_init(g2);
- generalized_geometric_remainder(g2, alpha, n0, 2, prec);
- arb_init(g4);
- generalized_geometric_remainder(g4, alpha, n0, 4, prec);
- arb_init(pi);
- arb_const_pi(pi, prec);
- arb_init(c1);
- arb_sqr(c1, pi, prec);
- arb_mul(c1, c1, g4, prec);
- arb_init(c2);
- arb_mul_si(c2, pi, 3, prec);
- arb_mul_2exp_si(c2, c2, -1);
- arb_mul(c2, c2, g2, prec);
- arb_init(a);
- arb_init(total);
- arb_init(s);
- arb_sub_ui(a, y, 9, prec);
- arb_neg(a, a);
- I_integral_bound(s, theta, t, x, a, n0, prec);
- arb_mul(s, s, c1, prec);
- arb_add(total, total, s, prec);
- arb_sub_ui(a, y, 5, prec);
- arb_neg(a, a);
- I_integral_bound(s, theta, t, x, a, n0, prec);
- arb_mul(s, s, c2, prec);
- arb_add(total, total, s, prec);
- arb_add_ui(a, y, 9, prec);
- I_integral_bound(s, theta, t, x, a, n0, prec);
- arb_mul(s, s, c1, prec);
- arb_add(total, total, s, prec);
- arb_add_ui(a, y, 5, prec);
- I_integral_bound(s, theta, t, x, a, n0, prec);
- arb_mul(s, s, c2, prec);
- arb_add(total, total, s, prec);
- arb_set(res, total);
- arb_clear(pi);
- arb_clear(c1);
- arb_clear(c2);
- arb_clear(g2);
- arb_clear(g4);
- arb_clear(alpha);
- arb_clear(a);
- arb_clear(s);
- arb_clear(total);
- }
- void H(acb_t res,
- const arb_t theta, mag_t m_estimate,
- const arb_t t, const arb_t x, const arb_t y, slong prec)
- {
- acb_t h, htotal;
- arb_t remainder;
- mag_t m_partial_sum, tail_mag_lb, tail_mag_ub;
- slong n;
- acb_init(h);
- acb_init(htotal);
- arb_init(remainder);
- mag_init(m_partial_sum);
- mag_init(tail_mag_lb);
- mag_init(tail_mag_ub);
- n = 1;
- while (1)
- {
- H_summand(h, theta, m_estimate, t, x, y, n, prec);
- acb_add(htotal, htotal, h, prec);
- n++;
- if (integral_bounds_are_permissible(theta, t, y, n, prec))
- {
- I_summation_remainder_bound(remainder, theta, t, x, y, n, prec);
- arb_get_mag(tail_mag_ub, remainder);
- _acb_get_rad_ubound_mag(m_partial_sum, htotal, prec);
- arb_get_mag_lower(tail_mag_lb, remainder);
- if (mag_cmp(tail_mag_lb, m_partial_sum) <= 0)
- {
- acb_set(res, htotal);
- acb_add_error_mag(res, tail_mag_ub);
- break;
- }
- }
- }
- if (arb_is_zero(x) || arb_is_zero(y))
- {
- arb_zero(acb_imagref(res));
- }
- acb_clear(h);
- acb_clear(htotal);
- arb_clear(remainder);
- mag_clear(m_partial_sum);
- mag_clear(tail_mag_lb);
- mag_clear(tail_mag_ub);
- }
- static void
- D_summation_remainder_bound(arb_t res,
- const arb_t theta, const arb_t t, const arb_t y,
- slong n0, slong prec)
- {
- arb_t pi, c1, c2, g2, g4;
- arb_t alpha, a;
- arb_t s, total;
- arb_init(alpha);
- _summation_alpha(alpha, theta, n0, prec);
- arb_init(g2);
- generalized_geometric_remainder(g2, alpha, n0, 2, prec);
- arb_init(g4);
- generalized_geometric_remainder(g4, alpha, n0, 4, prec);
- arb_init(pi);
- arb_const_pi(pi, prec);
- arb_init(c1);
- arb_sqr(c1, pi, prec);
- arb_mul(c1, c1, g4, prec);
- arb_init(c2);
- arb_mul_si(c2, pi, 3, prec);
- arb_mul_2exp_si(c2, c2, -1);
- arb_mul(c2, c2, g2, prec);
- arb_init(a);
- arb_init(total);
- arb_init(s);
- arb_sub_ui(a, y, 9, prec);
- arb_neg(a, a);
- D_integral_bound(s, theta, t, a, n0, prec);
- arb_mul(s, s, c1, prec);
- arb_add(total, total, s, prec);
- arb_sub_ui(a, y, 5, prec);
- arb_neg(a, a);
- D_integral_bound(s, theta, t, a, n0, prec);
- arb_mul(s, s, c2, prec);
- arb_add(total, total, s, prec);
- arb_add_ui(a, y, 9, prec);
- D_integral_bound(s, theta, t, a, n0, prec);
- arb_mul(s, s, c1, prec);
- arb_add(total, total, s, prec);
- arb_add_ui(a, y, 5, prec);
- D_integral_bound(s, theta, t, a, n0, prec);
- arb_mul(s, s, c2, prec);
- arb_add(total, total, s, prec);
- arb_set(res, total);
- arb_clear(pi);
- arb_clear(c1);
- arb_clear(c2);
- arb_clear(g2);
- arb_clear(g4);
- arb_clear(alpha);
- arb_clear(a);
- arb_clear(s);
- arb_clear(total);
- }
- static void
- D_summand(arb_t res,
- const arb_t theta, mag_t m_estimate,
- const arb_t t, const arb_t y, slong n, slong prec)
- {
- arb_t a;
- arb_t s, total;
- arb_t beta, c1, c2;
- arb_init(a);
- arb_init(s);
- arb_init(total);
- arb_init(beta);
- arb_const_pi(beta, prec);
- arb_mul_si(beta, beta, n*n, prec);
- arb_init(c1);
- arb_sqr(c1, beta, prec);
- arb_init(c2);
- arb_mul_si(c2, beta, 3, prec);
- arb_mul_2exp_si(c2, c2, -1);
- arb_sub_ui(a, y, 9, prec);
- arb_neg(a, a);
- D_integral(s, theta, m_estimate, t, a, n, prec);
- arb_mul(s, s, c1, prec);
- arb_add(total, total, s, prec);
- arb_sub_ui(a, y, 5, prec);
- arb_neg(a, a);
- D_integral(s, theta, m_estimate, t, a, n, prec);
- arb_mul(s, s, c2, prec);
- arb_add(total, total, s, prec);
- arb_add_ui(a, y, 9, prec);
- D_integral(s, theta, m_estimate, t, a, n, prec);
- arb_mul(s, s, c1, prec);
- arb_add(total, total, s, prec);
- arb_add_ui(a, y, 5, prec);
- D_integral(s, theta, m_estimate, t, a, n, prec);
- arb_mul(s, s, c2, prec);
- arb_add(total, total, s, prec);
- arb_set(res, total);
- arb_clear(a);
- arb_clear(s);
- arb_clear(total);
- arb_clear(beta);
- arb_clear(c1);
- arb_clear(c2);
- }
- void
- D(arb_t res,
- const arb_t theta, mag_t m_estimate,
- const arb_t t, const arb_t y, slong prec)
- {
- arb_t d, dtotal;
- arb_t remainder;
- mag_t m_partial_sum, tail_mag_lb, tail_mag_ub;
- slong n;
- mag_init(m_partial_sum);
- mag_init(tail_mag_lb);
- mag_init(tail_mag_ub);
- arb_init(d);
- arb_init(dtotal);
- arb_init(remainder);
- n = 1;
- while (1)
- {
- D_summand(d, theta, m_estimate, t, y, n, prec);
- arb_add(dtotal, dtotal, d, prec);
- n++;
- if (integral_bounds_are_permissible(theta, t, y, n, prec))
- {
- D_summation_remainder_bound(remainder, theta, t, y, n, prec);
- arb_get_mag(tail_mag_ub, remainder);
- mag_set(m_partial_sum, arb_radref(dtotal));
- arb_get_mag_lower(tail_mag_lb, remainder);
- if (mag_cmp(tail_mag_lb, m_partial_sum) <= 0)
- {
- arb_set(res, dtotal);
- arb_add_error_mag(res, tail_mag_ub);
- break;
- }
- }
- }
- arb_clear(d);
- arb_clear(dtotal);
- arb_clear(remainder);
- mag_clear(m_partial_sum);
- mag_clear(tail_mag_lb);
- mag_clear(tail_mag_ub);
- }
- typedef struct
- {
- acb_struct z;
- acb_struct h;
- arb_struct d;
- arb_struct theta;
- } xmeshpt_struct;
- typedef xmeshpt_struct xmeshpt_t[1];
- typedef xmeshpt_struct *xmeshpt_ptr;
- typedef const xmeshpt_struct *xmeshpt_srcptr;
- #define xmeshpt_zref(p) (&(p)->z)
- #define xmeshpt_href(p) (&(p)->h)
- #define xmeshpt_dref(p) (&(p)->d)
- #define xmeshpt_thetaref(p) (&(p)->theta)
- void xmeshpt_init(xmeshpt_t p)
- {
- acb_init(xmeshpt_zref(p));
- acb_init(xmeshpt_href(p));
- arb_init(xmeshpt_dref(p));
- arb_init(xmeshpt_thetaref(p));
- }
- void xmeshpt_clear(xmeshpt_t p)
- {
- acb_clear(xmeshpt_zref(p));
- acb_clear(xmeshpt_href(p));
- arb_clear(xmeshpt_dref(p));
- arb_clear(xmeshpt_thetaref(p));
- }
- void xmeshpt_swap(xmeshpt_t a, xmeshpt_t b)
- {
- acb_swap(xmeshpt_zref(a), xmeshpt_zref(b));
- acb_swap(xmeshpt_href(a), xmeshpt_href(b));
- arb_swap(xmeshpt_dref(a), xmeshpt_dref(b));
- arb_swap(xmeshpt_thetaref(a), xmeshpt_thetaref(b));
- }
- typedef struct
- {
- acb_struct z;
- acb_struct h;
- } ymeshpt_struct;
- typedef ymeshpt_struct ymeshpt_t[1];
- typedef ymeshpt_struct *ymeshpt_ptr;
- typedef const ymeshpt_struct *ymeshpt_srcptr;
- #define ymeshpt_zref(p) (&(p)->z)
- #define ymeshpt_href(p) (&(p)->h)
- void ymeshpt_init(ymeshpt_t p)
- {
- acb_init(ymeshpt_zref(p));
- acb_init(ymeshpt_href(p));
- }
- void ymeshpt_clear(ymeshpt_t p)
- {
- acb_clear(ymeshpt_zref(p));
- acb_clear(ymeshpt_href(p));
- }
- void ymeshpt_swap(ymeshpt_t a, ymeshpt_t b)
- {
- acb_swap(ymeshpt_zref(a), ymeshpt_zref(b));
- acb_swap(ymeshpt_href(a), ymeshpt_href(b));
- }
- typedef struct
- {
- ymeshpt_struct left;
- ymeshpt_srcptr right;
- } ymeshival_struct;
- typedef ymeshival_struct ymeshival_t[1];
- typedef ymeshival_struct *ymeshival_ptr;
- typedef const ymeshival_struct *ymeshival_srcptr;
- #define ymeshival_leftref(m) (&(m)->left)
- void ymeshival_init(ymeshival_t m)
- {
- ymeshpt_init(ymeshival_leftref(m));
- m->right = NULL;
- }
- void ymeshival_clear(ymeshival_t m)
- {
- ymeshpt_clear(ymeshival_leftref(m));
- m->right = NULL;
- }
- void ymeshival_center(acb_t res, const ymeshival_t m, slong prec)
- {
- acb_srcptr z_left = ymeshpt_zref(ymeshival_leftref(m));
- acb_srcptr z_right = ymeshpt_zref(m->right);
- acb_add(res, z_left, z_right, prec);
- acb_mul_2exp_si(res, res, -1);
- }
- int ymeshival_validate(const ymeshival_t m, const arb_t t, slong prec)
- {
- acb_t z, center;
- arb_t theta;
- arb_t estimate;
- mag_t m_estimate;
- acb_t step_delta;
- arb_t step_width;
- arb_t u, d;
- arb_t lhs, rhs;
- acb_srcptr z_left, z_right;
- acb_srcptr h_left, h_right;
- arb_t abs_h_left, abs_h_right;
- arb_srcptr x, y;
- int result;
- z_left = ymeshpt_zref(ymeshival_leftref(m));
- z_right = ymeshpt_zref(m->right);
- h_left = ymeshpt_href(ymeshival_leftref(m));
- h_right = ymeshpt_href(m->right);
- acb_init(center);
- ymeshival_center(center, m, prec);
- arb_init(theta);
- get_theta(theta, center, prec);
- mag_zero(arb_radref(theta));
- acb_init(step_delta);
- acb_sub(step_delta, z_right, z_left, prec);
- arb_init(step_width);
- acb_abs(step_width, step_delta, prec);
- arb_init(estimate);
- mag_init(m_estimate);
- H_approximation(estimate, acb_realref(center), acb_imagref(center), prec);
- arb_get_mag(m_estimate, estimate);
- acb_init(z);
- acb_union(z, z_left, z_right, prec);
- x = acb_realref(z);
- y = acb_imagref(z);
- arb_init(u);
- arb_init(d);
- D(d, theta, m_estimate, t, y, prec);
- arb_sqr(u, theta, prec);
- arb_mul(u, u, t, prec);
- arb_neg(u, u);
- arb_exp(u, u, prec);
- arb_mul(d, d, u, prec);
- arb_init(lhs);
- arb_mul(lhs, x, theta, prec);
- arb_neg(lhs, lhs);
- arb_exp(lhs, lhs, prec);
- arb_mul(lhs, lhs, d, prec);
- arb_mul(lhs, lhs, step_width, prec);
- arb_init(rhs);
- arb_init(abs_h_left);
- arb_init(abs_h_right);
- acb_abs(abs_h_left, h_left, prec);
- acb_abs(abs_h_right, h_right, prec);
- arb_max(rhs, abs_h_left, abs_h_right, prec);
- result = arb_lt(lhs, rhs);
- acb_clear(z);
- acb_clear(center);
- arb_clear(theta);
- acb_clear(step_delta);
- arb_clear(step_width);
- arb_clear(u);
- arb_clear(d);
- arb_clear(estimate);
- mag_clear(m_estimate);
- arb_clear(lhs);
- arb_clear(rhs);
- arb_clear(abs_h_left);
- arb_clear(abs_h_right);
- return result;
- }
- void
- evaluate_ymeshpt(ymeshpt_t m,
- const arb_t t, const arb_t x, const arb_t y,
- const arb_t htheta_max, slong prec)
- {
- arb_t htheta;
- arb_t estimate;
- mag_t m_estimate;
- acb_ptr z = ymeshpt_zref(m);
- acb_ptr h = ymeshpt_href(m);
- acb_set_arb_arb(z, x, y);
- arb_init(htheta);
- get_theta(htheta, z, prec);
- arb_min(htheta, htheta, htheta_max, prec);
- mag_zero(arb_radref(htheta));
- arb_init(estimate);
- mag_init(m_estimate);
- H_approximation(estimate, x, y, prec);
- arb_get_mag(m_estimate, estimate);
- H(h, htheta, m_estimate, t, x, y, prec);
- arb_clear(htheta);
- arb_clear(estimate);
- mag_clear(m_estimate);
- }
- void
- evaluate_xmeshpt(xmeshpt_t m,
- const arb_t t, const arb_t x, const arb_t y,
- const arb_t htheta_max, slong prec)
- {
- arb_t htheta, u;
- arb_t estimate;
- mag_t m_estimate;
- acb_ptr z = xmeshpt_zref(m);
- acb_ptr h = xmeshpt_href(m);
- arb_ptr d = xmeshpt_dref(m);
- arb_ptr theta = xmeshpt_thetaref(m);
- acb_set_arb_arb(z, x, y);
- get_theta(theta, z, prec);
- arb_init(htheta);
- arb_min(htheta, theta, htheta_max, prec);
- mag_zero(arb_radref(htheta));
- arb_init(estimate);
- mag_init(m_estimate);
- H_approximation(estimate, x, y, prec);
- arb_get_mag(m_estimate, estimate);
- arb_init(u);
- D(d, theta, m_estimate, t, y, prec);
- arb_sqr(u, theta, prec);
- arb_mul(u, u, t, prec);
- arb_neg(u, u);
- arb_exp(u, u, prec);
- arb_mul(d, d, u, prec);
- H(h, htheta, m_estimate, t, x, y, prec);
- arb_clear(htheta);
- arb_clear(u);
- arb_clear(estimate);
- mag_clear(m_estimate);
- }
- int
- evaluate_ymesh(arb_t res,
- const arb_t t, const arb_t x, const arb_t ya, const arb_t yb,
- const arb_t htheta_max, slong maxdepth, slong prec)
- {
- acb_t center;
- arb_t accum, arg;
- acb_t h_ratio;
- ymeshpt_t mb;
- ymeshival_struct *stack;
- slong i, depth;
- ymeshival_ptr ival;
- int result = 1;
- stack = flint_malloc(maxdepth * sizeof(*stack));
- for (i = 0; i < maxdepth; i++)
- {
- ymeshival_init(stack + i);
- }
- acb_init(center);
- arb_init(accum);
- arb_init(arg);
- acb_init(h_ratio);
- ymeshpt_init(mb);
- evaluate_ymeshpt(mb, t, x, yb, htheta_max, prec);
- depth = 0;
- ival = stack + depth;
- evaluate_ymeshpt(ymeshival_leftref(ival), t, x, ya, htheta_max, prec);
- ival->right = mb;
- depth++;
- while (1)
- {
- ymeshival_ptr curr = stack + depth - 1;
- ymeshival_ptr next = stack + depth;
- if (depth + 5 > maxdepth)
- {
- result = 0;
- arb_indeterminate(res);
- goto finish;
- }
- if (!depth)
- {
- break;
- }
- if (ymeshival_validate(curr, t, prec))
- {
- acb_srcptr h_left = ymeshpt_href(ymeshival_leftref(curr));
- acb_srcptr h_right = ymeshpt_href(curr->right);
- acb_div(h_ratio, h_right, h_left, prec);
- acb_arg(arg, h_ratio, prec);
- arb_add(accum, accum, arg, prec);
- if (!arb_is_finite(accum))
- {
- result = 0;
- arb_indeterminate(res);
- goto finish;
- }
- depth--;
- }
- else
- {
- ymeshival_center(center, curr, prec);
- evaluate_ymeshpt(ymeshival_leftref(next),
- t, acb_realref(center), acb_imagref(center),
- htheta_max, prec);
- ymeshpt_swap(
- ymeshival_leftref(curr),
- ymeshival_leftref(next));
- next->right = ymeshival_leftref(curr);
- depth++;
- }
- }
- arb_set(res, accum);
- finish:
- acb_clear(center);
- arb_clear(accum);
- arb_clear(arg);
- acb_clear(h_ratio);
- ymeshpt_clear(mb);
- for (i = 0; i < maxdepth; i++)
- {
- ymeshival_clear(stack + i);
- }
- flint_free(stack);
- return result;
- }
- int
- evaluate_xmesh(arb_t res,
- const arb_t t, const arb_t xa, const arb_t xb,
- const arb_t y, const arb_t htheta_max, slong prec)
- {
- arb_t step, x_next;
- arb_t accum, arg;
- acb_t h_ratio;
- arb_t c1, c2;
- xmeshpt_t ma, mb;
- int result = 1;
- int finished_flag = 0;
- arb_init(step);
- arb_init(x_next);
- arb_init(accum);
- arb_init(arg);
- acb_init(h_ratio);
- arb_init(c1);
- arb_init(c2);
- xmeshpt_init(ma);
- xmeshpt_init(mb);
- evaluate_xmeshpt(ma, t, xa, y, htheta_max, prec);
- while (1)
- {
- arb_mul(c1, xmeshpt_thetaref(ma), acb_realref(xmeshpt_zref(ma)), prec);
- arb_exp(c1, c1, prec);
- acb_abs(c2, xmeshpt_href(ma), prec);
- arb_div(step, c1, xmeshpt_dref(ma), prec);
- arb_mul(step, step, c2, prec);
- arb_mul_2exp_si(step, step, -1);
- arb_add(x_next, acb_realref(xmeshpt_zref(ma)), step, prec);
- arb_get_lbound_arf(arb_midref(x_next), x_next, prec);
- mag_zero(arb_radref(x_next));
- if (arb_lt(x_next, xb))
- {
- evaluate_xmeshpt(mb, t, x_next, y, htheta_max, prec);
- }
- else
- {
- evaluate_xmeshpt(mb, t, xb, y, htheta_max, prec);
- finished_flag = 1;
- }
- acb_div(h_ratio, xmeshpt_href(mb), xmeshpt_href(ma), prec);
- acb_arg(arg, h_ratio, prec);
- arb_add(accum, accum, arg, prec);
- if (!arb_is_finite(accum))
- {
- result = 0;
- break;
- }
- if (finished_flag)
- {
- break;
- }
- else
- {
- xmeshpt_swap(ma, mb);
- }
- }
- arb_set(res, accum);
- arb_clear(step);
- arb_clear(x_next);
- arb_clear(accum);
- arb_clear(arg);
- acb_clear(h_ratio);
- arb_clear(c1);
- arb_clear(c2);
- xmeshpt_clear(ma);
- xmeshpt_clear(mb);
- return result;
- }
- int main(int argc, char *argv[])
- {
- arb_t t, xa, xb, ya, yb;
- arb_t arg, arg_total, htheta_max;
- const char *t_str, *xa_str, *xb_str, *ya_str, *yb_str;
- slong prec;
- slong prec_base = 64;
- slong prec_incr = 32;
- slong maxdepth = 50;
- int result = EXIT_SUCCESS;
- arb_init(t);
- arb_init(xa);
- arb_init(xb);
- arb_init(ya);
- arb_init(yb);
- arb_init(arg);
- arb_init(arg_total);
- arb_init(htheta_max);
- if (argc != 6)
- {
- result = EXIT_FAILURE;
- goto finish;
- }
- t_str = argv[1];
- xa_str = argv[2];
- xb_str = argv[3];
- ya_str = argv[4];
- yb_str = argv[5];
- prec_base = 64;
- prec_incr = 32;
- arb_set_str(htheta_max, "0.369", 32);
- prec = prec_base / 2;
- while (1)
- {
- prec *= 2;
- arb_set_str(t, t_str, prec);
- arb_set_str(xa, xa_str, prec);
- arb_set_str(xb, xb_str, prec);
- arb_set_str(ya, ya_str, prec);
- arb_set_str(yb, yb_str, prec);
- if (arb_lt(xb, xa) || arb_lt(yb, ya))
- {
- result = EXIT_FAILURE;
- goto finish;
- }
- if (evaluate_ymesh(arg, t, xa, ya, yb, htheta_max, maxdepth, prec))
- {
- break;
- }
- }
- arb_neg(arg, arg);
- arb_add(arg_total, arg_total, arg, prec);
- prec = prec_base / 2;
- while (1)
- {
- prec *= 2;
- arb_set_str(t, t_str, prec);
- arb_set_str(xa, xa_str, prec);
- arb_set_str(xb, xb_str, prec);
- arb_set_str(ya, ya_str, prec);
- arb_set_str(yb, yb_str, prec);
- if (arb_lt(xb, xa) || arb_lt(yb, ya))
- {
- result = EXIT_FAILURE;
- goto finish;
- }
- if (evaluate_ymesh(arg, t, xb, ya, yb, htheta_max, maxdepth, prec))
- {
- break;
- }
- }
- arb_add(arg_total, arg_total, arg, prec);
- prec = prec_base / 2;
- while (1)
- {
- prec *= 2;
- arb_set_str(t, t_str, prec);
- arb_set_str(xa, xa_str, prec);
- arb_set_str(xb, xb_str, prec);
- arb_set_str(ya, ya_str, prec);
- arb_set_str(yb, yb_str, prec);
- if (arb_lt(xb, xa) || arb_lt(yb, ya))
- {
- result = EXIT_FAILURE;
- goto finish;
- }
- if (evaluate_xmesh(arg, t, xa, xb, ya, htheta_max, prec))
- {
- break;
- }
- }
- arb_add(arg_total, arg_total, arg, prec);
- prec = prec_base / 2;
- while (1)
- {
- prec *= 2;
- arb_set_str(t, t_str, prec);
- arb_set_str(xa, xa_str, prec);
- arb_set_str(xb, xb_str, prec);
- arb_set_str(ya, ya_str, prec);
- arb_set_str(yb, yb_str, prec);
- if (arb_lt(xb, xa) || arb_lt(yb, ya))
- {
- result = EXIT_FAILURE;
- goto finish;
- }
- if (evaluate_xmesh(arg, t, xa, xb, yb, htheta_max, prec))
- {
- break;
- }
- }
- arb_neg(arg, arg);
- arb_add(arg_total, arg_total, arg, prec);
- {
- arb_t pi;
- arb_init(pi);
- arb_const_pi(pi, prec);
- arb_div(arg_total, arg_total, pi, prec);
- arb_mul_2exp_si(arg_total, arg_total, -1);
- arb_clear(pi);
- }
- {
- double d = arf_get_d(arb_midref(arg_total), ARF_RND_NEAR);
- slong nroots = (int) (d + 0.5);
- if (arb_contains_si(arg_total, nroots) &&
- !arb_contains_si(arg_total, nroots - 1) &&
- !arb_contains_si(arg_total, nroots + 1))
- {
- flint_printf("%ld\n", nroots);
- }
- else
- {
- arb_printd(arg_total, 10);
- flint_printf("\n");
- }
- }
- finish:
- if (result == EXIT_FAILURE)
- {
- flint_printf("%s t xa xb ya yb\n\n", argv[0]);
- flint_printf(
- "Count the roots of H_t(x + yi).\n"
- "xa < x < xb\n"
- "ya < y < yb\n");
- }
- arb_clear(t);
- arb_clear(xa);
- arb_clear(xb);
- arb_clear(ya);
- arb_clear(yb);
- arb_clear(arg);
- arb_clear(arg_total);
- arb_clear(htheta_max);
- flint_cleanup();
- return result;
- }
Add Comment
Please, Sign In to add comment