Advertisement
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_poly.h"
- void acb_poly_onei(acb_poly_t res)
- {
- acb_poly_one(res);
- acb_onei(acb_poly_get_coeff_ptr(res, 0));
- }
- void
- acb_poly_add_acb(acb_poly_t res,
- const acb_poly_t x, const acb_t y, slong prec)
- {
- slong len = x->length;
- if (len == 0)
- {
- acb_poly_set_acb(res, y);
- }
- else
- {
- acb_poly_fit_length(res, len);
- acb_add(res->coeffs, x->coeffs, y, prec);
- if (res != x)
- _acb_vec_set(res->coeffs + 1, x->coeffs + 1, len - 1);
- _acb_poly_set_length(res, len);
- _acb_poly_normalise(res);
- }
- }
- void
- acb_poly_add_arb(acb_poly_t res,
- const acb_poly_t x, const arb_t y, slong prec)
- {
- acb_t z;
- acb_init(z);
- acb_set_arb(z, y);
- acb_poly_add_acb(res, x, z, prec);
- acb_clear(z);
- }
- void _acb_poly_alpha1_series(acb_poly_t z, const acb_poly_t s,
- slong n, slong prec)
- {
- acb_poly_t a;
- acb_poly_init(a);
- acb_poly_zero(z);
- acb_poly_inv_series(a, s, n, prec);
- acb_poly_scalar_mul_2exp_si(a, a, -1);
- acb_poly_add_series(z, z, a, n, prec);
- acb_poly_add_si(a, s, -1, prec);
- acb_poly_inv_series(a, a, n, prec);
- acb_poly_add_series(z, z, a, n, prec);
- acb_poly_log_series(a, s, n, prec);
- acb_poly_scalar_mul_2exp_si(a, a, -1);
- acb_poly_add_series(z, z, a, n, prec);
- {
- arb_t c;
- arb_ptr u;
- arb_init(c);
- arb_const_log_sqrt2pi(c, prec);
- u = acb_realref(acb_poly_get_coeff_ptr(z, 0));
- arb_sub(u, u, c, prec);
- arb_clear(c);
- }
- acb_poly_clear(a);
- }
- void acb_poly_alpha1_series(acb_poly_t z, const acb_poly_t s,
- slong n, slong prec)
- {
- if (z == s)
- {
- acb_poly_t u;
- acb_poly_init(u);
- _acb_poly_alpha1_series(u, s, n, prec);
- acb_poly_swap(z, u);
- acb_poly_clear(u);
- }
- else
- {
- _acb_poly_alpha1_series(z, s, n, prec);
- }
- }
- void _acb_poly_H01_series(acb_poly_t z, const acb_poly_t s,
- slong n, slong prec)
- {
- arb_t c;
- acb_poly_t a, b;
- acb_t u;
- arb_ptr x;
- acb_poly_init(a);
- acb_poly_init(b);
- acb_init(u);
- arb_init(c);
- arb_const_log_sqrt2pi(c, prec);
- acb_poly_zero(z);
- acb_poly_add_si(a, s, -1, prec);
- acb_poly_log_series(a, a, n, prec);
- acb_poly_add_series(z, z, a, n, prec);
- acb_zero(u);
- x = acb_realref(u);
- arb_log_ui(x, 2, prec);
- arb_neg(x, x);
- arb_add_ui(x, x, 1, prec);
- arb_mul_2exp_si(x, x, -1);
- arb_add(x, x, c, prec);
- acb_poly_scalar_mul(a, s, u, prec);
- acb_poly_sub_series(z, z, a, n, prec);
- x = acb_realref(acb_poly_get_coeff_ptr(z, 0));
- arb_add(x, x, c, prec);
- acb_poly_add_si(b, s, 1, prec);
- acb_poly_scalar_mul_2exp_si(a, s, -1);
- acb_poly_log_series(a, a, n, prec);
- acb_poly_scalar_mul_2exp_si(a, a, -1);
- acb_poly_mullow(a, a, b, n, prec);
- acb_poly_add_series(z, z, a, n, prec);
- acb_poly_exp_series(z, z, n, prec);
- acb_poly_clear(a);
- acb_poly_clear(b);
- acb_clear(u);
- arb_clear(c);
- }
- void acb_poly_H01_series(acb_poly_t z, const acb_poly_t s,
- slong n, slong prec)
- {
- if (z == s)
- {
- acb_poly_t u;
- acb_poly_init(u);
- _acb_poly_H01_series(u, s, n, prec);
- acb_poly_swap(z, u);
- acb_poly_clear(u);
- }
- else
- {
- _acb_poly_H01_series(z, s, n, prec);
- }
- }
- static void
- _acb_poly_s_series(acb_poly_t res,
- const acb_poly_t x, const acb_poly_t y,
- slong n, slong prec)
- {
- acb_poly_t ix;
- acb_poly_init(ix);
- acb_poly_onei(ix);
- acb_poly_mullow(ix, ix, x, n, prec);
- acb_poly_sub_series(res, ix, y, n, prec);
- acb_poly_add_si(res, res, 1, prec);
- acb_poly_scalar_mul_2exp_si(res, res, -1);
- acb_poly_clear(ix);
- }
- static void
- _acb_poly_abbeff_summand_series(acb_poly_t res,
- const acb_t logk, const acb_poly_t a, const acb_poly_t b,
- slong n, slong prec)
- {
- acb_poly_scalar_mul(res, a, logk, prec);
- acb_poly_sub_series(res, res, b, n, prec);
- acb_poly_scalar_mul(res, res, logk, prec);
- acb_poly_exp_series(res, res, n, prec);
- }
- void
- abbeff_series(acb_poly_t res,
- const acb_poly_t t, const acb_poly_t x, const acb_poly_t y,
- slong N, slong n, slong prec)
- {
- acb_t logk;
- acb_poly_t s, sc;
- acb_poly_t alph1, alph2;
- acb_poly_t hs, hsc;
- acb_poly_t ta1, ta2;
- acb_poly_t A0, B0;
- acb_poly_t a, b1, b2;
- acb_poly_t summand;
- acb_poly_t Asum, Bsum;
- acb_poly_t A, B;
- acb_poly_init(s);
- _acb_poly_s_series(s, x, y, n, prec);
- acb_poly_init(sc);
- acb_poly_add_si(sc, s, -1, prec);
- acb_poly_neg(sc, sc);
- acb_poly_init(alph1);
- acb_poly_alpha1_series(alph1, s, n, prec);
- acb_poly_init(alph2);
- acb_poly_alpha1_series(alph2, sc, n, prec);
- acb_poly_init(hs);
- acb_poly_H01_series(hs, s, n, prec);
- acb_poly_init(hsc);
- acb_poly_H01_series(hsc, sc, n, prec);
- acb_poly_init(ta1);
- acb_poly_mullow(ta1, t, alph1, n, prec);
- acb_poly_init(ta2);
- acb_poly_mullow(ta2, t, alph2, n, prec);
- acb_poly_init(A0);
- acb_poly_mullow(A0, ta1, alph1, n, prec);
- acb_poly_scalar_mul_2exp_si(A0, A0, -2);
- acb_poly_exp_series(A0, A0, n, prec);
- acb_poly_mullow(A0, A0, hs, n, prec);
- acb_poly_scalar_mul_2exp_si(A0, A0, -3);
- acb_poly_init(B0);
- acb_poly_mullow(B0, ta2, alph2, n, prec);
- acb_poly_scalar_mul_2exp_si(B0, B0, -2);
- acb_poly_exp_series(B0, B0, n, prec);
- acb_poly_mullow(B0, B0, hsc, n, prec);
- acb_poly_scalar_mul_2exp_si(B0, B0, -3);
- acb_poly_init(a);
- acb_poly_scalar_mul_2exp_si(a, t, -2);
- acb_poly_init(b1);
- acb_poly_scalar_mul_2exp_si(b1, ta1, -1);
- acb_poly_add_series(b1, b1, s, n, prec);
- acb_poly_init(b2);
- acb_poly_scalar_mul_2exp_si(b2, ta2, -1);
- acb_poly_add_series(b2, b2, sc, n, prec);
- acb_init(logk);
- acb_poly_init(summand);
- acb_poly_init(Asum);
- acb_poly_init(Bsum);
- {
- slong k;
- for (k = N; k >= 2; k--)
- {
- acb_set_si(logk, k);
- acb_log(logk, logk, prec);
- _acb_poly_abbeff_summand_series(summand, logk, a, b1, n, prec);
- acb_poly_add_series(Asum, Asum, summand, n, prec);
- _acb_poly_abbeff_summand_series(summand, logk, a, b2, n, prec);
- acb_poly_add_series(Bsum, Bsum, summand, n, prec);
- }
- }
- acb_poly_add_si(Asum, Asum, 1, prec);
- acb_poly_add_si(Bsum, Bsum, 1, prec);
- acb_poly_init(A);
- acb_poly_mullow(A, A0, Asum, n, prec);
- acb_poly_init(B);
- acb_poly_mullow(B, B0, Bsum, n, prec);
- acb_poly_div_series(res, A, B0, n, prec);
- acb_poly_add_series(res, res, Bsum, n, prec);
- acb_clear(logk);
- acb_poly_clear(s);
- acb_poly_clear(sc);
- acb_poly_clear(alph1);
- acb_poly_clear(alph2);
- acb_poly_clear(hs);
- acb_poly_clear(hsc);
- acb_poly_clear(ta1);
- acb_poly_clear(ta2);
- acb_poly_clear(A0);
- acb_poly_clear(B0);
- acb_poly_clear(a);
- acb_poly_clear(b1);
- acb_poly_clear(b2);
- acb_poly_clear(summand);
- acb_poly_clear(Asum);
- acb_poly_clear(Bsum);
- acb_poly_clear(A);
- acb_poly_clear(B);
- }
- void arg2(arb_t res, const acb_t v, const acb_t u, slong prec)
- {
- if (acb_is_zero(v))
- {
- acb_arg(res, u, prec);
- }
- else
- {
- acb_t p;
- acb_init(p);
- acb_conj(p, v);
- acb_mul(p, p, u, prec);
- acb_arg(res, p, prec);
- acb_clear(p);
- }
- }
- static void
- _abbeff(acb_t res,
- const arb_t t, const arb_t x, const arb_t y,
- slong N, slong prec)
- {
- acb_poly_t pt, px, py, pr;
- slong n = 1;
- acb_poly_init(pt);
- acb_poly_init(px);
- acb_poly_init(py);
- acb_poly_init(pr);
- acb_poly_one(pt);
- arb_set(acb_realref(acb_poly_get_coeff_ptr(pt, 0)), t);
- acb_poly_one(px);
- arb_set(acb_realref(acb_poly_get_coeff_ptr(px, 0)), x);
- acb_poly_one(py);
- arb_set(acb_realref(acb_poly_get_coeff_ptr(py, 0)), y);
- abbeff_series(pr, pt, px, py, N, n, prec);
- acb_set(res, acb_poly_get_coeff_ptr(pr, 0));
- acb_poly_clear(pt);
- acb_poly_clear(px);
- acb_poly_clear(py);
- acb_poly_clear(pr);
- }
- typedef struct
- {
- acb_struct z;
- acb_struct h;
- } meshpt_struct;
- typedef meshpt_struct meshpt_t[1];
- typedef meshpt_struct *meshpt_ptr;
- typedef const meshpt_struct *meshpt_srcptr;
- #define meshpt_zref(p) (&(p)->z)
- #define meshpt_href(p) (&(p)->h)
- void meshpt_init(meshpt_t p)
- {
- acb_init(meshpt_zref(p));
- acb_init(meshpt_href(p));
- }
- void meshpt_clear(meshpt_t p)
- {
- acb_clear(meshpt_zref(p));
- acb_clear(meshpt_href(p));
- }
- void meshpt_swap(meshpt_t a, meshpt_t b)
- {
- acb_swap(meshpt_zref(a), meshpt_zref(b));
- acb_swap(meshpt_href(a), meshpt_href(b));
- }
- typedef struct
- {
- meshpt_struct left;
- meshpt_srcptr right;
- } meshival_struct;
- typedef meshival_struct meshival_t[1];
- typedef meshival_struct *meshival_ptr;
- typedef const meshival_struct *meshival_srcptr;
- #define meshival_leftref(m) (&(m)->left)
- void meshival_init(meshival_t m)
- {
- meshpt_init(meshival_leftref(m));
- m->right = NULL;
- }
- void meshival_clear(meshival_t m)
- {
- meshpt_clear(meshival_leftref(m));
- m->right = NULL;
- }
- void meshival_center(acb_t res, const meshival_t m, slong prec)
- {
- acb_srcptr z_left = meshpt_zref(meshival_leftref(m));
- acb_srcptr z_right = meshpt_zref(m->right);
- acb_add(res, z_left, z_right, prec);
- acb_mul_2exp_si(res, res, -1);
- }
- void compute_lbound(arb_t res, const acb_t fa, const acb_t fb,
- const acb_t fprime, const acb_t delta, slong prec)
- {
- arb_t afa, afb, afprime, adelta;
- arb_init(afa);
- arb_init(afb);
- arb_init(afprime);
- arb_init(adelta);
- acb_abs(afa, fa, prec);
- acb_abs(afb, fb, prec);
- acb_abs(afprime, fprime, prec);
- acb_abs(adelta, delta, prec);
- arb_add(res, afa, afb, prec);
- arb_submul(res, afprime, adelta, prec);
- arb_mul_2exp_si(res, res, -1);
- arb_clear(afa);
- arb_clear(afb);
- arb_clear(afprime);
- arb_clear(adelta);
- }
- int meshival_validate(const meshival_t m, const arb_t t,
- const arb_t c, slong N, slong prec)
- {
- acb_poly_t hpoly, tpoly, xpoly, ypoly;
- acb_t z, f, fprime, step_delta;
- arb_t lbound;
- acb_srcptr z_left, z_right;
- acb_srcptr h_left, h_right;
- arb_srcptr x, y;
- slong n = 2;
- int result = 0;
- z_left = meshpt_zref(meshival_leftref(m));
- z_right = meshpt_zref(m->right);
- h_left = meshpt_href(meshival_leftref(m));
- h_right = meshpt_href(m->right);
- acb_init(step_delta);
- acb_sub(step_delta, z_right, z_left, prec);
- acb_init(z);
- acb_union(z, z_left, z_right, prec);
- x = acb_realref(z);
- y = acb_imagref(z);
- acb_poly_init(tpoly);
- acb_poly_add_arb(tpoly, tpoly, t, prec);
- acb_poly_init(xpoly);
- acb_poly_one(xpoly);
- acb_poly_shift_left(xpoly, xpoly, 1);
- acb_poly_add_arb(xpoly, xpoly, x, prec);
- acb_poly_init(ypoly);
- acb_poly_add_arb(ypoly, ypoly, y, prec);
- acb_poly_init(hpoly);
- abbeff_series(hpoly, tpoly, xpoly, ypoly, N, n, prec);
- acb_init(f);
- acb_poly_get_coeff_acb(f, hpoly, 0);
- acb_init(fprime);
- acb_poly_get_coeff_acb(fprime, hpoly, 1);
- arb_init(lbound);
- acb_abs(lbound, f, prec);
- if (arb_gt(lbound, c))
- {
- result = 1;
- }
- else
- {
- compute_lbound(lbound, h_left, h_right, fprime, step_delta, prec);
- if (arb_gt(lbound, c))
- {
- result = 1;
- }
- }
- finish:
- acb_poly_clear(hpoly);
- acb_poly_clear(tpoly);
- acb_poly_clear(xpoly);
- acb_poly_clear(ypoly);
- acb_clear(z);
- acb_clear(f);
- acb_clear(fprime);
- acb_clear(step_delta);
- arb_clear(lbound);
- return result;
- }
- void
- evaluate_meshpt(meshpt_t m,
- const arb_t t, const arb_t x, const arb_t y,
- slong N, slong prec)
- {
- acb_ptr z = meshpt_zref(m);
- acb_ptr h = meshpt_href(m);
- acb_set_arb_arb(z, x, y);
- _abbeff(h, t, x, y, N, prec);
- }
- int validate_f(const acb_t f, const arb_t c, slong prec)
- {
- arb_t af;
- arb_init(af);
- acb_abs(af, f, prec);
- int result = 1;
- if (arb_lt(af, c))
- {
- fprintf(stderr, "Failed to compute the winding number because "
- "|(Aeff + Beff)/Beff0| < c\n");
- result = -1;
- goto finish;
- }
- if (!arb_gt(af, c))
- {
- result = 0;
- goto finish;
- }
- if (arb_contains_zero(acb_imagref(f)) && !arb_is_positive(acb_realref(f)))
- {
- result = 0;
- goto finish;
- }
- finish:
- arb_clear(af);
- return result;
- }
- int
- evaluate_mesh(arb_t res,
- const arb_t t, const acb_t za, const acb_t zb,
- const arb_t c, slong maxdepth, slong N, slong prec)
- {
- acb_t center;
- arb_t accum, arg;
- meshpt_t mb;
- meshival_struct *stack;
- slong i, depth;
- meshival_ptr ival;
- int result = 1;
- stack = flint_malloc(maxdepth * sizeof(*stack));
- for (i = 0; i < maxdepth; i++)
- {
- meshival_init(stack + i);
- }
- acb_init(center);
- arb_init(accum);
- arb_init(arg);
- meshpt_init(mb);
- evaluate_meshpt(mb,
- t, acb_realref(zb), acb_imagref(zb), N, prec);
- result = validate_f(meshpt_href(mb), c, prec);
- if (result < 1)
- {
- arb_indeterminate(res);
- goto finish;
- }
- depth = 0;
- ival = stack + depth;
- evaluate_meshpt(meshival_leftref(ival),
- t, acb_realref(za), acb_imagref(za), N, prec);
- ival->right = mb;
- depth++;
- result = validate_f(meshpt_href(meshival_leftref(ival)), c, prec);
- if (result < 1)
- {
- arb_indeterminate(res);
- goto finish;
- }
- while (1)
- {
- meshival_ptr curr = stack + depth - 1;
- meshival_ptr next = stack + depth;
- if (depth + 5 > maxdepth)
- {
- result = 0;
- arb_indeterminate(res);
- goto finish;
- }
- if (!depth)
- {
- break;
- }
- if (meshival_validate(curr, t, c, N, prec))
- {
- acb_srcptr h_left = meshpt_href(meshival_leftref(curr));
- acb_srcptr h_right = meshpt_href(curr->right);
- arg2(arg, h_left, h_right, prec);
- arb_add(accum, accum, arg, prec);
- if (!arb_is_finite(accum))
- {
- result = 0;
- arb_indeterminate(res);
- goto finish;
- }
- depth--;
- }
- else
- {
- meshival_center(center, curr, prec);
- evaluate_meshpt(meshival_leftref(next),
- t, acb_realref(center), acb_imagref(center), N, prec);
- result = validate_f(meshpt_href(meshival_leftref(next)), c, prec);
- if (result < 1)
- {
- arb_indeterminate(res);
- goto finish;
- }
- meshpt_swap(meshival_leftref(curr), meshival_leftref(next));
- next->right = meshival_leftref(curr);
- depth++;
- }
- }
- arb_set(res, accum);
- finish:
- acb_clear(center);
- arb_clear(accum);
- arb_clear(arg);
- meshpt_clear(mb);
- for (i = 0; i < maxdepth; i++)
- {
- meshival_clear(stack + i);
- }
- flint_free(stack);
- return result;
- }
- slong get_N(const arb_t t, const arb_t x, slong prec)
- {
- arb_t pi, u;
- slong N;
- slong result;
- arb_init(pi);
- arb_init(u);
- arb_const_pi(pi, prec);
- arb_mul(u, pi, t, prec);
- arb_mul_2exp_si(u, u, -2);
- arb_add(u, u, x, prec);
- arb_div(u, u, pi, prec);
- arb_mul_2exp_si(u, u, -2);
- arb_sqrt(u, u, prec);
- arb_floor(u, u, prec);
- N = (slong) arf_get_d(arb_midref(u), ARF_RND_DOWN);
- if (arb_contains_si(u, N) &&
- !arb_contains_si(u, N-1) &&
- !arb_contains_si(u, N+1))
- {
- result = N;
- }
- else
- {
- fprintf(stderr, "Unexpected error: could not compute N\n");
- flint_abort();
- }
- arb_clear(pi);
- arb_clear(u);
- return result;
- }
- int main(int argc, char *argv[])
- {
- arb_t c, t, xa, xb, ya, yb;
- arb_t arg, arg_total;
- const char *N_str, *c_str, *t_str, *xa_str, *xb_str, *ya_str, *yb_str;
- acb_t z1, z2;
- slong N_user, N, prec;
- slong prec_base, prec_incr;
- slong maxdepth = 50;
- int mesh_result;
- int result = EXIT_SUCCESS;
- int usage_error = 0;
- arb_init(c);
- arb_init(t);
- arb_init(xa);
- arb_init(xb);
- arb_init(ya);
- arb_init(yb);
- acb_init(z1);
- acb_init(z2);
- arb_init(arg);
- arb_init(arg_total);
- if (argc != 8)
- {
- usage_error = 1;
- result = EXIT_FAILURE;
- goto finish;
- }
- N_str = argv[1];
- c_str = argv[2];
- t_str = argv[3];
- xa_str = argv[4];
- xb_str = argv[5];
- ya_str = argv[6];
- yb_str = argv[7];
- prec_base = 32;
- prec_incr = 32;
- N_user = atol(N_str);
- if (N_user > 0)
- {
- N = N_user;
- }
- else
- {
- prec = 128;
- slong N_low, N_high;
- arb_set_str(t, t_str, prec);
- arb_set_str(xa, xa_str, prec);
- arb_set_str(xb, xb_str, prec);
- if (arb_lt(xb, xa))
- {
- usage_error = 1;
- result = EXIT_FAILURE;
- goto finish;
- }
- N_low = get_N(t, xa, prec);
- N_high = get_N(t, xb, prec);
- if (N_low == N_high)
- {
- N = N_low;
- }
- else
- {
- fprintf(stderr, "Imputed N is ambiguous: [%ld, %ld].\n",
- N_low, N_high);
- fprintf(stderr, "Either specify a positive integer N explicitly, "
- "or choose a smaller range of x.\n");
- usage_error = 1;
- result = EXIT_FAILURE;
- goto finish;
- }
- }
- prec = prec_base;
- while (1)
- {
- arb_set_str(c, c_str, prec);
- 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))
- {
- usage_error = 1;
- result = EXIT_FAILURE;
- goto finish;
- }
- acb_set_arb_arb(z1, xa, ya);
- acb_set_arb_arb(z2, xb, ya);
- mesh_result = evaluate_mesh(arg, t, z1, z2, c, maxdepth, N, prec);
- if (mesh_result == -1)
- {
- result = EXIT_FAILURE;
- goto finish;
- }
- else if (mesh_result == 1)
- {
- break;
- }
- prec += prec_incr;
- }
- arb_add(arg_total, arg_total, arg, prec);
- prec = prec_base;
- while (1)
- {
- arb_set_str(c, c_str, prec);
- 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))
- {
- usage_error = 1;
- result = EXIT_FAILURE;
- goto finish;
- }
- acb_set_arb_arb(z1, xb, ya);
- acb_set_arb_arb(z2, xb, yb);
- mesh_result = evaluate_mesh(arg, t, z1, z2, c, maxdepth, N, prec);
- if (mesh_result == -1)
- {
- result = EXIT_FAILURE;
- goto finish;
- }
- else if (mesh_result == 1)
- {
- break;
- }
- prec += prec_incr;
- }
- arb_add(arg_total, arg_total, arg, prec);
- prec = prec_base;
- while (1)
- {
- arb_set_str(c, c_str, prec);
- 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) || arb_is_negative(c))
- {
- usage_error = 1;
- result = EXIT_FAILURE;
- goto finish;
- }
- acb_set_arb_arb(z1, xb, yb);
- acb_set_arb_arb(z2, xa, yb);
- mesh_result = evaluate_mesh(arg, t, z1, z2, c, maxdepth, N, prec);
- if (mesh_result == -1)
- {
- result = EXIT_FAILURE;
- goto finish;
- }
- else if (mesh_result == 1)
- {
- break;
- }
- prec += prec_incr;
- }
- arb_add(arg_total, arg_total, arg, prec);
- prec = prec_base;
- while (1)
- {
- arb_set_str(c, c_str, prec);
- 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))
- {
- usage_error = 1;
- result = EXIT_FAILURE;
- goto finish;
- }
- acb_set_arb_arb(z1, xa, yb);
- acb_set_arb_arb(z2, xa, ya);
- mesh_result = evaluate_mesh(arg, t, z1, z2, c, maxdepth, N, prec);
- if (mesh_result == -1)
- {
- result = EXIT_FAILURE;
- goto finish;
- }
- else if (mesh_result == 1)
- {
- break;
- }
- prec += prec_incr;
- }
- 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);
- }
- flint_printf("(Aeff+Beff)/Beff0 winding number script\n");
- if (N_user <= 0)
- {
- flint_printf("imputed N: %ld\n", N);
- }
- {
- double d = arf_get_d(arb_midref(arg_total), ARF_RND_NEAR);
- slong nroots = (int) (d + 0.5);
- flint_printf("winding number: ");
- 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 (usage_error && result == EXIT_FAILURE)
- {
- flint_printf("Usage:\n");
- flint_printf("%s N c t xa xb ya yb\n\n", argv[0]);
- flint_printf(
- "This script computes the winding number about 0 of f(p).\n"
- "Let r be a rectangle in the complex plane\n"
- "r : [xa <= x <= xb] + i[ya <= y <= yb]\n"
- "and let p be the counterclockwise path along the boundary of r\n"
- "starting and ending at (xa + i*ya).\n"
- "Let f(z) = (Aeff_t(z) + Beff_t(z)) / Beff0_t(z).\n"
- "Additionally, f(p) is required to stay away from 0 so\n"
- "the script will either abort or will fail to terminate\n"
- "if |f(z)| <= c at any point z on the path p.\n"
- "The Nth partial sum is used in Aeff and Beff.\n");
- }
- arb_clear(c);
- arb_clear(t);
- arb_clear(xa);
- arb_clear(xb);
- arb_clear(ya);
- arb_clear(yb);
- arb_clear(arg);
- arb_clear(arg_total);
- acb_clear(z1);
- acb_clear(z2);
- flint_cleanup();
- return result;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement