diff --git a/doc/fmprb.txt b/doc/fmprb.txt index 52244834..0275fd4e 100644 --- a/doc/fmprb.txt +++ b/doc/fmprb.txt @@ -451,6 +451,10 @@ void fmprb_const_pi(fmprb_t x, long prec) Sets x to $\pi$. The value is cached for repeated use. +void fmprb_const_log_sqrt2pi(fmprb_t x, long prec) + + Sets x to $\log \sqrt{2 \pi}$. The value is cached for repeated use. + void fmprb_const_euler_brent_mcmillan(fmprb_t res, long prec) Sets x to Euler's constant $\gamma$, computed using the second diff --git a/fmprb.h b/fmprb.h index 8071add4..14c1b7f8 100644 --- a/fmprb.h +++ b/fmprb.h @@ -234,6 +234,8 @@ void fmprb_fib_ui(fmprb_t f, ulong n, long prec); void fmprb_const_pi_chudnovsky(fmprb_t x, long prec); void fmprb_const_pi(fmprb_t x, long prec); +void fmprb_const_log_sqrt2pi(fmprb_t t, long prec); + void fmprb_const_euler_brent_mcmillan(fmprb_t res, long prec); void fmprb_const_zeta3_bsplit(fmprb_t x, long prec); @@ -329,5 +331,22 @@ void fmprb_randtest(fmprb_t x, flint_rand_t state, long prec, long mag_bits); void fmprb_get_rand_fmpq(fmpq_t q, flint_rand_t state, const fmprb_t x, long bits); +/* TODO: this should be threadsafe */ +#define DEF_CACHED_CONSTANT(name, comp_func) \ + long name ## _cached_prec = 0; \ + fmprb_t name ## _cached_value; \ + void \ + name(fmprb_t x, long prec) \ + { \ + if (name ## _cached_prec < prec) \ + { \ + if (name ## _cached_prec == 0) \ + fmprb_init(name ## _cached_value); \ + comp_func(name ## _cached_value, prec); \ + name ## _cached_prec = prec; \ + } \ + fmprb_set_round(x, name ## _cached_value, prec); \ + } \ + #endif diff --git a/fmprb/const_log_sqrt2pi.c b/fmprb/const_log_sqrt2pi.c new file mode 100644 index 00000000..4c33daed --- /dev/null +++ b/fmprb/const_log_sqrt2pi.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of ARB. + + ARB is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + ARB is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ARB; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include "fmprb.h" + +void +_fmprb_const_log_sqrt2pi(fmprb_t t, long prec) +{ + fmprb_const_pi(t, prec + 2); + fmprb_mul_2exp_si(t, t, 1); + fmprb_log(t, t, prec); + fmprb_mul_2exp_si(t, t, -1); +} + +DEF_CACHED_CONSTANT(fmprb_const_log_sqrt2pi, _fmprb_const_log_sqrt2pi) diff --git a/fmprb/const_pi.c b/fmprb/const_pi.c index ac31a9df..541f66e1 100644 --- a/fmprb/const_pi.c +++ b/fmprb/const_pi.c @@ -25,22 +25,4 @@ #include "fmprb.h" -/* TODO: make threadsafe; round output */ - -long fmprb_const_pi_cached_prec = 0; -fmprb_t fmprb_const_pi_cache; - -void -fmprb_const_pi(fmprb_t x, long prec) -{ - if (fmprb_const_pi_cached_prec < prec) - { - if (fmprb_const_pi_cached_prec == 0) - fmprb_init(fmprb_const_pi_cache); - - fmprb_const_pi_chudnovsky(fmprb_const_pi_cache, prec); - fmprb_const_pi_cached_prec = prec; - } - - fmprb_set_round(x, fmprb_const_pi_cache, prec); -} +DEF_CACHED_CONSTANT(fmprb_const_pi, fmprb_const_pi_chudnovsky) diff --git a/fmprb/gamma.c b/fmprb/gamma.c index 29c75fbc..5e716f5b 100644 --- a/fmprb/gamma.c +++ b/fmprb/gamma.c @@ -54,33 +54,6 @@ bernoulli_cache_compute(long n) } } -/* log(sqrt(2*pi)) */ -void _fmprb_const_log_sqrt2pi(fmprb_t t, long prec) -{ - fmprb_const_pi(t, prec + 2); - fmprb_mul_2exp_si(t, t, 1); - fmprb_log(t, t, prec); - fmprb_mul_2exp_si(t, t, -1); -} - -long fmprb_const_log_sqrt2pi_cached_prec = 0; -fmprb_t fmprb_const_log_sqrt2pi_cache; - -void -fmprb_const_log_sqrt2pi(fmprb_t x, long prec) -{ - if (fmprb_const_log_sqrt2pi_cached_prec < prec) - { - if (fmprb_const_log_sqrt2pi_cached_prec == 0) - fmprb_init(fmprb_const_log_sqrt2pi_cache); - - _fmprb_const_log_sqrt2pi(fmprb_const_log_sqrt2pi_cache, prec); - fmprb_const_log_sqrt2pi_cached_prec = prec; - } - - fmprb_set_round(x, fmprb_const_log_sqrt2pi_cache, prec); -} - double fmpr_get_d(const fmpr_t x) { double r;