2017-03-20 18:57:53 +01:00
|
|
|
/*
|
|
|
|
Copyright (C) 2017 Fredrik Johansson
|
|
|
|
|
|
|
|
This file is part of Arb.
|
|
|
|
|
|
|
|
Arb 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.h"
|
|
|
|
|
|
|
|
int
|
2017-03-30 21:54:43 +02:00
|
|
|
_acb_lambertw_check_branch(const acb_t w, const fmpz_t k, slong prec)
|
2017-03-20 18:57:53 +01:00
|
|
|
{
|
|
|
|
arb_t t, u, v, a, b;
|
|
|
|
int res = 0;
|
|
|
|
|
|
|
|
arb_init(t);
|
|
|
|
arb_init(u);
|
|
|
|
arb_init(v);
|
|
|
|
arb_init(a);
|
|
|
|
arb_init(b);
|
|
|
|
|
|
|
|
/* t = x sinc(y), v = -cos(y) */
|
2017-04-22 13:59:37 +02:00
|
|
|
if (arb_is_exact(acb_imagref(w)))
|
|
|
|
{
|
|
|
|
if (arb_is_zero(acb_imagref(w)))
|
|
|
|
{
|
|
|
|
arb_one(t);
|
|
|
|
arb_one(v);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
arb_sin_cos(t, v, acb_imagref(w), prec);
|
|
|
|
arb_div(t, t, acb_imagref(w), prec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
arb_sinc(t, acb_imagref(w), prec);
|
|
|
|
arb_cos(v, acb_imagref(w), prec);
|
|
|
|
}
|
2017-03-20 18:57:53 +01:00
|
|
|
arb_mul(t, t, acb_realref(w), prec);
|
|
|
|
arb_neg(v, v);
|
|
|
|
|
|
|
|
/* u = y / pi, with conjugate relation for k */
|
|
|
|
arb_const_pi(u, prec);
|
|
|
|
arb_div(u, acb_imagref(w), u, prec);
|
|
|
|
if (fmpz_sgn(k) < 0)
|
|
|
|
arb_neg(u, u);
|
|
|
|
|
|
|
|
if (fmpz_is_zero(k))
|
|
|
|
{
|
|
|
|
/* -1 < u < 1 and t > v */
|
|
|
|
arb_set_si(a, -1);
|
|
|
|
arb_set_si(b, 1);
|
|
|
|
|
|
|
|
if (arb_gt(u, a) && arb_lt(u, b) && arb_gt(t, v))
|
|
|
|
{
|
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
arb_set_fmpz(a, k);
|
|
|
|
arb_abs(a, a);
|
|
|
|
arb_mul_2exp_si(a, a, 1);
|
|
|
|
arb_add_ui(b, a, 1, prec);
|
|
|
|
arb_sub_ui(a, a, 2, prec);
|
|
|
|
|
|
|
|
/* if u > 2|k|-2 and u < 2|k|+1 */
|
|
|
|
if (arb_gt(u, a) && arb_lt(u, b))
|
|
|
|
{
|
|
|
|
arb_add_ui(a, a, 1, prec);
|
|
|
|
arb_sub_ui(b, b, 1, prec);
|
|
|
|
|
|
|
|
/* if u > 2|k|-1 and u < 2|k| */
|
|
|
|
if (arb_gt(u, a) && arb_lt(u, b))
|
|
|
|
{
|
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
else if (arb_lt(u, b) && arb_lt(t, v)) /* u < 2|k| and t < v */
|
|
|
|
{
|
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
else if (arb_gt(u, a) && arb_gt(t, v)) /* u > 2|k|-1 and t > v */
|
|
|
|
{
|
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
arb_clear(t);
|
|
|
|
arb_clear(u);
|
|
|
|
arb_clear(v);
|
|
|
|
arb_clear(a);
|
|
|
|
arb_clear(b);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2017-03-30 21:54:43 +02:00
|
|
|
int
|
|
|
|
acb_lambertw_check_branch(const acb_t w, const fmpz_t k, slong prec)
|
|
|
|
{
|
|
|
|
if (prec > 64 && _acb_lambertw_check_branch(w, k, 32))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return _acb_lambertw_check_branch(w, k, prec);
|
|
|
|
}
|
|
|
|
|