Skip to content

Entire (generalised) Bernoulli function #438

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions acb.h
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,9 @@ void acb_lgamma(acb_t y, const acb_t x, slong prec);
void acb_log_sin_pi(acb_t res, const acb_t z, slong prec);
void acb_digamma(acb_t y, const acb_t x, slong prec);
void acb_zeta(acb_t z, const acb_t s, slong prec);
void acb_bernoulli(acb_t z, const acb_t s, slong prec);
void acb_hurwitz_zeta(acb_t z, const acb_t s, const acb_t a, slong prec);
void acb_bernoulli_gen(acb_t z, const acb_t s, const acb_t a, slong prec);
void acb_polygamma(acb_t res, const acb_t s, const acb_t z, slong prec);

void acb_bernoulli_poly_ui(acb_t res, ulong n, const acb_t x, slong prec);
Expand Down
11 changes: 11 additions & 0 deletions acb/zeta.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,14 @@ acb_zeta(acb_t z, const acb_t s, slong prec)
acb_dirichlet_zeta(z, s, prec);
}

void
acb_bernoulli_gen(acb_t z, const acb_t s, const acb_t a, slong prec)
{
acb_dirichlet_bernoulli_gen(z, s, a, prec);
}

void
acb_bernoulli(acb_t z, const acb_t s, slong prec)
{
acb_dirichlet_bernoulli(z, s, prec);
}
2 changes: 2 additions & 0 deletions acb_dirichlet.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ void acb_dirichlet_zeta_rs_bound(mag_t err, const acb_t s, slong K);
void acb_dirichlet_zeta_rs_r(acb_t res, const acb_t s, slong K, slong prec);
void acb_dirichlet_zeta_rs(acb_t res, const acb_t s, slong K, slong prec);
void acb_dirichlet_zeta(acb_t res, const acb_t s, slong prec);
void acb_dirichlet_bernoulli(acb_t res, const acb_t s, slong prec);

void acb_dirichlet_zeta_jet_rs(acb_ptr res, const acb_t s, slong len, slong prec);
void acb_dirichlet_zeta_jet(acb_t res, const acb_t s, int deflate, slong len, slong prec);

void acb_dirichlet_hurwitz(acb_t res, const acb_t s, const acb_t a, slong prec);
void acb_dirichlet_bernoulli_gen(acb_t res, const acb_t s, const acb_t a, slong prec);

void acb_dirichlet_lerch_phi_integral(acb_t res, const acb_t z, const acb_t s, const acb_t a, slong prec);
void acb_dirichlet_lerch_phi_direct(acb_t res, const acb_t z, const acb_t s, const acb_t a, slong prec);
Expand Down
32 changes: 32 additions & 0 deletions acb_dirichlet/hurwitz.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,35 @@ acb_dirichlet_hurwitz(acb_t res, const acb_t s, const acb_t a, slong prec)
_acb_poly_zeta_cpx_series(res, s, a, 0, 1, prec);
}

void
acb_dirichlet_bernoulli_gen(acb_t res, const acb_t s, const acb_t a, slong prec)
{
if (acb_is_zero(s))
{
acb_one(res);
return;
}

if (acb_is_int(s) && arf_sgn(arb_midref(acb_realref(s))) > 0 &&
arf_cmpabs_ui(arb_midref(acb_realref(s)), prec / 2) < 0)
{
slong n = arf_get_si(arb_midref(acb_realref(s)), ARF_RND_FLOOR);

acb_bernoulli_poly_ui(res, n, a, prec);
return;
}
else
{
acb_t t;

acb_init(t);

acb_neg(t, s);
acb_add_ui(res, t, 1, prec);
acb_dirichlet_hurwitz(res, res, a, prec);
acb_mul(res, t, res, prec);

acb_clear(t);
}
}

23 changes: 23 additions & 0 deletions acb_dirichlet/zeta.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,26 @@ acb_dirichlet_zeta(acb_t res, const acb_t s, slong prec)
}
}

void
acb_dirichlet_bernoulli(acb_t res, const acb_t s, slong prec)
{
if (acb_is_zero(s))
{
acb_one(res);
return;
}
else
{
acb_t t;

acb_init(t);

acb_neg(t, s);
acb_add_ui(res, t, 1, prec);
acb_dirichlet_zeta(res, res, prec);
acb_mul(res, t, res, prec);

acb_clear(t);
}
}

2 changes: 2 additions & 0 deletions arb.h
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,9 @@ void arb_gamma_fmpq(arb_t z, const fmpq_t x, slong prec);
void arb_gamma_fmpz(arb_t z, const fmpz_t x, slong prec);
void arb_digamma(arb_t y, const arb_t x, slong prec);
void arb_zeta(arb_t z, const arb_t s, slong prec);
void arb_bernoulli(arb_t z, const arb_t s, slong prec);
void arb_hurwitz_zeta(arb_t z, const arb_t s, const arb_t a, slong prec);
void arb_bernoulli_gen(arb_t z, const arb_t s, const arb_t a, slong prec);

void arb_rising_ui(arb_t z, const arb_t x, ulong n, slong prec);
void arb_rising_fmpq_ui(arb_t y, const fmpq_t x, ulong n, slong prec);
Expand Down
23 changes: 23 additions & 0 deletions arb/hurwitz_zeta.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,26 @@ arb_hurwitz_zeta(arb_t res, const arb_t s, const arb_t z, slong prec)
}
}

void
arb_bernoulli_gen(arb_t res, const arb_t s, const arb_t z, slong prec)
{
if (arb_is_zero(s))
{
arb_one(res);
return;
}
else
{
arb_t t;

arb_init(t);

arb_neg(t, s);
arb_add_ui(res, t, 1, prec);
arb_hurwitz_zeta(res, res, z, prec);
arb_mul(res, t, res, prec);

arb_clear(t);
}
}

23 changes: 23 additions & 0 deletions arb/zeta.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,26 @@ arb_zeta(arb_t y, const arb_t s, slong prec)
acb_clear(t);
}

void
arb_bernoulli(arb_t res, const arb_t s, slong prec)
{
if (arb_is_zero(s))
{
arb_one(res);
return;
}
else
{
arb_t t;

arb_init(t);

arb_neg(t, s);
arb_add_ui(res, t, 1, prec);
arb_zeta(res, res, prec);
arb_mul(res, t, res, prec);

arb_clear(t);
}
}

12 changes: 12 additions & 0 deletions doc/source/acb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,18 @@ Zeta function

This is a wrapper of :func:`acb_dirichlet_hurwitz`.

.. function:: void acb_bernoulli(acb_t z, const acb_t s, slong prec)

Sets *z* to the value of the Bernoulli function `B(s)`.

This is a wrapper of :func:`acb_dirichlet_bernoulli`.

.. function:: void acb_bernoulli_gen(acb_t z, const acb_t s, const acb_t a, slong prec)

Sets *z* to the value of the generalized Bernoulli function `B(s, a)`.

This is a wrapper of :func:`acb_dirichlet_bernoulli_gen`.

.. function:: void acb_bernoulli_poly_ui(acb_t res, ulong n, const acb_t x, slong prec)

Sets *res* to the value of the Bernoulli polynomial `B_n(x)`.
Expand Down
10 changes: 10 additions & 0 deletions doc/source/acb_dirichlet.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ Riemann zeta function
`\xi(s) = \frac{1}{2} s (s-1) \pi^{-s/2} \Gamma(\frac{1}{2} s) \zeta(s)`.
The functional equation for xi is `\xi(1-s) = \xi(s)`.

.. function:: void acb_dirichlet_bernoulli(acb_t res, const acb_t s, slong prec)

Sets *res* to the Bernoulli function `B(s) = -s \zeta(1-s)`, with
the limiting value of 1 used when `s = 0` [Lus2020]_.

Riemann-Siegel formula
-------------------------------------------------------------------------------

Expand Down Expand Up @@ -207,6 +212,11 @@ Hurwitz zeta function
when `a = 1`. Some other special cases may also be handled by direct
formulas. In general, Euler-Maclaurin summation is used.

.. function:: void acb_dirichlet_bernoulli_gen(acb_t res, const acb_t s, const acb_t a, slong prec)

Computes the generalized Bernoulli function `B(s, a) = -s \zeta(1-s, a)`, with
the limiting value of 1 used when `s = 0` [Lus2020]_.

Hurwitz zeta function precomputation
-------------------------------------------------------------------------------

Expand Down
11 changes: 11 additions & 0 deletions doc/source/arb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1455,13 +1455,24 @@ Zeta function
For computing derivatives with respect to `s`,
use :func:`arb_poly_zeta_series`.

.. function:: void arb_bernoulli(arb_t z, const arb_t s, slong prec)

Sets *z* to the value of the Bernoulli function `B(s) = -s \zeta(1-s)`,
with the limiting value of 1 used when `s = 0` [Lus2020]_.

.. function:: void arb_hurwitz_zeta(arb_t z, const arb_t s, const arb_t a, slong prec)

Sets *z* to the value of the Hurwitz zeta function `\zeta(s,a)`.

For computing derivatives with respect to `s`,
use :func:`arb_poly_zeta_series`.

.. function:: void arb_bernoulli_gen(arb_t z, const arb_t s, const arb_t a, slong prec)

Sets *z* to the value of the generalized Bernoulli function
`B(s,a) = -s \zeta(1-s,a)`, with the limiting value of 1 used when
`s = 0` [Lus2020]_.

Bernoulli numbers and polynomials
-------------------------------------------------------------------------------

Expand Down
2 changes: 2 additions & 0 deletions doc/source/credits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ Bibliography

.. [Leh1970] \R. S. Lehman, "On the Distribution of Zeros of the Riemann Zeta-Function", Proc. of the London Mathematical Society 20(3) (1970), 303-320, https://doi.org/10.1112/plms/s3-20.2.303

.. [Lus2020] \P. Luschny, "An introduction to the Bernoulli function", preprint (2020), https://arxiv.org/abs/2009.06743

.. [Mic2007] \N. Michel, "Precise Coulomb wave functions for a wide range of complex l, eta and z", Computer Physics Communications, Volume 176, Issue 3, (2007), 232-249, https://doi.org/10.1016/j.cpc.2006.10.004

.. [Miy2010] \S. Miyajima, "Fast enclosure for all eigenvalues in generalized eigenvalue problems", Journal of Computational and Applied Mathematics, 233 (2010), 2994-3004, https://dx.doi.org/10.1016/j.cam.2009.11.048
Expand Down