zeta.c revision 1.1.1.3
1/* mpfr_zeta -- compute the Riemann Zeta function 2 3Copyright 2003-2018 Free Software Foundation, Inc. 4Contributed by the AriC and Caramba projects, INRIA. 5 6This file is part of the GNU MPFR Library. 7 8The GNU MPFR Library is free software; you can redistribute it and/or modify 9it under the terms of the GNU Lesser General Public License as published by 10the Free Software Foundation; either version 3 of the License, or (at your 11option) any later version. 12 13The GNU MPFR Library is distributed in the hope that it will be useful, but 14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16License for more details. 17 18You should have received a copy of the GNU Lesser General Public License 19along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 23#include <float.h> /* for DBL_MAX */ 24 25#define MPFR_NEED_LONGLONG_H 26#include "mpfr-impl.h" 27 28/* 29 Parameters: 30 s - the input floating-point number 31 n, p - parameters from the algorithm 32 tc - an array of p floating-point numbers tc[1]..tc[p] 33 Output: 34 b is the result, i.e. 35 sum(tc[i]*product((s+2j)*(s+2j-1)/n^2,j=1..i-1), i=1..p)*s*n^(-s-1) 36*/ 37static void 38mpfr_zeta_part_b (mpfr_t b, mpfr_srcptr s, int n, int p, mpfr_t *tc) 39{ 40 mpfr_t s1, d, u; 41 unsigned long n2; 42 int l, t; 43 MPFR_GROUP_DECL (group); 44 45 if (p == 0) 46 { 47 MPFR_SET_ZERO (b); 48 MPFR_SET_POS (b); 49 return; 50 } 51 52 n2 = n * n; 53 MPFR_GROUP_INIT_3 (group, MPFR_PREC (b), s1, d, u); 54 55 /* t equals 2p-2, 2p-3, ... ; s1 equals s+t */ 56 t = 2 * p - 2; 57 mpfr_set (d, tc[p], MPFR_RNDN); 58 for (l = 1; l < p; l++) 59 { 60 mpfr_add_ui (s1, s, t, MPFR_RNDN); /* s + (2p-2l) */ 61 mpfr_mul (d, d, s1, MPFR_RNDN); 62 t = t - 1; 63 mpfr_add_ui (s1, s, t, MPFR_RNDN); /* s + (2p-2l-1) */ 64 mpfr_mul (d, d, s1, MPFR_RNDN); 65 t = t - 1; 66 mpfr_div_ui (d, d, n2, MPFR_RNDN); 67 mpfr_add (d, d, tc[p-l], MPFR_RNDN); 68 /* since s is positive and the tc[i] have alternate signs, 69 the following is unlikely */ 70 if (MPFR_UNLIKELY (mpfr_cmpabs (d, tc[p-l]) > 0)) 71 mpfr_set (d, tc[p-l], MPFR_RNDN); 72 } 73 mpfr_mul (d, d, s, MPFR_RNDN); 74 mpfr_add (s1, s, __gmpfr_one, MPFR_RNDN); 75 mpfr_neg (s1, s1, MPFR_RNDN); 76 mpfr_ui_pow (u, n, s1, MPFR_RNDN); 77 mpfr_mul (b, d, u, MPFR_RNDN); 78 79 MPFR_GROUP_CLEAR (group); 80} 81 82/* Input: p - an integer 83 Output: fills tc[1..p], tc[i] = bernoulli(2i)/(2i)! 84 tc[1]=1/12, tc[2]=-1/720, tc[3]=1/30240, ... 85*/ 86static void 87mpfr_zeta_c (int p, mpfr_t *tc) 88{ 89 mpfr_t d; 90 int k, l; 91 92 if (p > 0) 93 { 94 mpfr_init2 (d, MPFR_PREC (tc[1])); 95 mpfr_div_ui (tc[1], __gmpfr_one, 12, MPFR_RNDN); 96 for (k = 2; k <= p; k++) 97 { 98 mpfr_set_ui (d, k-1, MPFR_RNDN); 99 mpfr_div_ui (d, d, 12*k+6, MPFR_RNDN); 100 for (l=2; l < k; l++) 101 { 102 mpfr_div_ui (d, d, 4*(2*k-2*l+3)*(2*k-2*l+2), MPFR_RNDN); 103 mpfr_add (d, d, tc[l], MPFR_RNDN); 104 } 105 mpfr_div_ui (tc[k], d, 24, MPFR_RNDN); 106 MPFR_CHANGE_SIGN (tc[k]); 107 } 108 mpfr_clear (d); 109 } 110} 111 112/* Input: s - a floating-point number 113 n - an integer 114 Output: sum - a floating-point number approximating sum(1/i^s, i=1..n-1) */ 115static void 116mpfr_zeta_part_a (mpfr_t sum, mpfr_srcptr s, int n) 117{ 118 mpfr_t u, s1; 119 int i; 120 MPFR_GROUP_DECL (group); 121 122 MPFR_GROUP_INIT_2 (group, MPFR_PREC (sum), u, s1); 123 124 mpfr_neg (s1, s, MPFR_RNDN); 125 mpfr_ui_pow (u, n, s1, MPFR_RNDN); 126 mpfr_div_2ui (u, u, 1, MPFR_RNDN); 127 mpfr_set (sum, u, MPFR_RNDN); 128 for (i=n-1; i>1; i--) 129 { 130 mpfr_ui_pow (u, i, s1, MPFR_RNDN); 131 mpfr_add (sum, sum, u, MPFR_RNDN); 132 } 133 mpfr_add (sum, sum, __gmpfr_one, MPFR_RNDN); 134 135 MPFR_GROUP_CLEAR (group); 136} 137 138/* Input: s - a floating-point number >= 1/2. 139 rnd_mode - a rounding mode. 140 Assumes s is neither NaN nor Infinite. 141 Output: z - Zeta(s) rounded to the precision of z with direction rnd_mode 142*/ 143static int 144mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode) 145{ 146 mpfr_t b, c, z_pre, f, s1; 147 double beta, sd, dnep; 148 mpfr_t *tc1; 149 mpfr_prec_t precz, precs, d, dint; 150 int p, n, l, add; 151 int inex; 152 MPFR_GROUP_DECL (group); 153 MPFR_ZIV_DECL (loop); 154 155 MPFR_ASSERTD (MPFR_IS_POS (s) && MPFR_GET_EXP (s) >= 0); 156 157 precz = MPFR_PREC (z); 158 precs = MPFR_PREC (s); 159 160 /* Zeta(x) = 1+1/2^x+1/3^x+1/4^x+1/5^x+O(1/6^x) 161 so with 2^(EXP(x)-1) <= x < 2^EXP(x) 162 So for x > 2^3, k^x > k^8, so 2/k^x < 2/k^8 163 Zeta(x) = 1 + 1/2^x*(1+(2/3)^x+(2/4)^x+...) 164 = 1 + 1/2^x*(1+sum((2/k)^x,k=3..infinity)) 165 <= 1 + 1/2^x*(1+sum((2/k)^8,k=3..infinity)) 166 And sum((2/k)^8,k=3..infinity) = -257+128*Pi^8/4725 ~= 0.0438035 167 So Zeta(x) <= 1 + 1/2^x*2 for x >= 8 168 The error is < 2^(-x+1) <= 2^(-2^(EXP(x)-1)+1) */ 169 if (MPFR_GET_EXP (s) > 3) 170 { 171 mpfr_exp_t err; 172 err = MPFR_GET_EXP (s) - 1; 173 if (err > (mpfr_exp_t) (sizeof (mpfr_exp_t)*CHAR_BIT-2)) 174 err = MPFR_EMAX_MAX; 175 else 176 err = ((mpfr_exp_t)1) << err; 177 err = 1 - (-err+1); /* GET_EXP(one) - (-err+1) = err :) */ 178 MPFR_FAST_COMPUTE_IF_SMALL_INPUT (z, __gmpfr_one, err, 0, 1, 179 rnd_mode, {}); 180 } 181 182 d = precz + MPFR_INT_CEIL_LOG2(precz) + 10; 183 184 /* we want that s1 = s-1 is exact, i.e. we should have PREC(s1) >= EXP(s) */ 185 dint = (mpfr_uexp_t) MPFR_GET_EXP (s); 186 mpfr_init2 (s1, MAX (precs, dint)); 187 inex = mpfr_sub (s1, s, __gmpfr_one, MPFR_RNDN); 188 MPFR_ASSERTD (inex == 0); 189 190 /* case s=1 should have already been handled */ 191 MPFR_ASSERTD (!MPFR_IS_ZERO (s1)); 192 193 MPFR_GROUP_INIT_4 (group, MPFR_PREC_MIN, b, c, z_pre, f); 194 195 MPFR_ZIV_INIT (loop, d); 196 for (;;) 197 { 198 /* Principal loop: we compute, in z_pre, 199 an approximation of Zeta(s), that we send to can_round */ 200 if (MPFR_GET_EXP (s1) <= -(mpfr_exp_t) ((mpfr_prec_t) (d-3)/2)) 201 /* Branch 1: when s-1 is very small, one 202 uses the approximation Zeta(s)=1/(s-1)+gamma, 203 where gamma is Euler's constant */ 204 { 205 dint = MAX (d + 3, precs); 206 /* branch 1, with internal precision dint */ 207 MPFR_GROUP_REPREC_4 (group, dint, b, c, z_pre, f); 208 mpfr_div (z_pre, __gmpfr_one, s1, MPFR_RNDN); 209 mpfr_const_euler (f, MPFR_RNDN); 210 mpfr_add (z_pre, z_pre, f, MPFR_RNDN); 211 } 212 else /* Branch 2 */ 213 { 214 size_t size; 215 216 /* branch 2 */ 217 /* Computation of parameters n, p and working precision */ 218 dnep = (double) d * LOG2; 219 sd = mpfr_get_d (s, MPFR_RNDN); 220 /* beta = dnep + 0.61 + sd * log (6.2832 / sd); 221 but a larger value is OK */ 222#define LOG6dot2832 1.83787940484160805532 223 beta = dnep + 0.61 + sd * (LOG6dot2832 - LOG2 * 224 __gmpfr_floor_log2 (sd)); 225 if (beta <= 0.0) 226 { 227 p = 0; 228 /* n = 1 + (int) (exp ((dnep - LOG2) / sd)); */ 229 n = 1 + (int) __gmpfr_ceil_exp2 ((d - 1.0) / sd); 230 } 231 else 232 { 233 p = 1 + (int) beta / 2; 234 n = 1 + (int) ((sd + 2.0 * (double) p - 1.0) / 6.2832); 235 } 236 /* add = 4 + floor(1.5 * log(d) / log (2)). 237 We should have add >= 10, which is always fulfilled since 238 d = precz + 11 >= 12, thus ceil(log2(d)) >= 4 */ 239 add = 4 + (3 * MPFR_INT_CEIL_LOG2 (d)) / 2; 240 MPFR_ASSERTD(add >= 10); 241 dint = d + add; 242 if (dint < precs) 243 dint = precs; 244 245 /* internal precision is dint */ 246 247 size = (p + 1) * sizeof(mpfr_t); 248 tc1 = (mpfr_t*) mpfr_allocate_func (size); 249 for (l=1; l<=p; l++) 250 mpfr_init2 (tc1[l], dint); 251 MPFR_GROUP_REPREC_4 (group, dint, b, c, z_pre, f); 252 253 /* precision of z is precz */ 254 255 /* Computation of the coefficients c_k */ 256 mpfr_zeta_c (p, tc1); 257 /* Computation of the 3 parts of the function Zeta. */ 258 mpfr_zeta_part_a (z_pre, s, n); 259 mpfr_zeta_part_b (b, s, n, p, tc1); 260 /* s1 = s-1 is already computed above */ 261 mpfr_div (c, __gmpfr_one, s1, MPFR_RNDN); 262 mpfr_ui_pow (f, n, s1, MPFR_RNDN); 263 mpfr_div (c, c, f, MPFR_RNDN); 264 mpfr_add (z_pre, z_pre, c, MPFR_RNDN); 265 mpfr_add (z_pre, z_pre, b, MPFR_RNDN); 266 for (l=1; l<=p; l++) 267 mpfr_clear (tc1[l]); 268 mpfr_free_func (tc1, size); 269 /* End branch 2 */ 270 } 271 272 if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, d-3, precz, rnd_mode))) 273 break; 274 MPFR_ZIV_NEXT (loop, d); 275 } 276 MPFR_ZIV_FREE (loop); 277 278 inex = mpfr_set (z, z_pre, rnd_mode); 279 280 MPFR_GROUP_CLEAR (group); 281 mpfr_clear (s1); 282 283 return inex; 284} 285 286/* return add = 1 + floor(log(c^3*(13+m1))/log(2)) 287 where c = (1+eps)*(1+eps*max(8,m1)), 288 m1 = 1 + max(1/eps,2*sd)*(1+eps), 289 eps = 2^(-precz-14) 290 sd = abs(s-1) 291 */ 292static long 293compute_add (mpfr_srcptr s, mpfr_prec_t precz) 294{ 295 mpfr_t t, u, m1; 296 long add; 297 298 mpfr_inits2 (64, t, u, m1, (mpfr_ptr) 0); 299 if (mpfr_cmp_ui (s, 1) >= 0) 300 mpfr_sub_ui (t, s, 1, MPFR_RNDU); 301 else 302 mpfr_ui_sub (t, 1, s, MPFR_RNDU); 303 /* now t = sd = abs(s-1), rounded up */ 304 mpfr_set_ui_2exp (u, 1, - precz - 14, MPFR_RNDU); 305 /* u = eps */ 306 /* since 1/eps = 2^(precz+14), if EXP(sd) >= precz+14, then 307 sd >= 1/2*2^(precz+14) thus 2*sd >= 2^(precz+14) >= 1/eps */ 308 if (mpfr_get_exp (t) >= precz + 14) 309 mpfr_mul_2exp (t, t, 1, MPFR_RNDU); 310 else 311 mpfr_set_ui_2exp (t, 1, precz + 14, MPFR_RNDU); 312 /* now t = max(1/eps,2*sd) */ 313 mpfr_add_ui (u, u, 1, MPFR_RNDU); /* u = 1+eps, rounded up */ 314 mpfr_mul (t, t, u, MPFR_RNDU); /* t = max(1/eps,2*sd)*(1+eps) */ 315 mpfr_add_ui (m1, t, 1, MPFR_RNDU); 316 if (mpfr_get_exp (m1) <= 3) 317 mpfr_set_ui (t, 8, MPFR_RNDU); 318 else 319 mpfr_set (t, m1, MPFR_RNDU); 320 /* now t = max(8,m1) */ 321 mpfr_div_2exp (t, t, precz + 14, MPFR_RNDU); /* eps*max(8,m1) */ 322 mpfr_add_ui (t, t, 1, MPFR_RNDU); /* 1+eps*max(8,m1) */ 323 mpfr_mul (t, t, u, MPFR_RNDU); /* t = c */ 324 mpfr_add_ui (u, m1, 13, MPFR_RNDU); /* 13+m1 */ 325 mpfr_mul (u, u, t, MPFR_RNDU); /* c*(13+m1) */ 326 mpfr_sqr (t, t, MPFR_RNDU); /* c^2 */ 327 mpfr_mul (u, u, t, MPFR_RNDU); /* c^3*(13+m1) */ 328 add = mpfr_get_exp (u); 329 mpfr_clears (t, u, m1, (mpfr_ptr) 0); 330 return add; 331} 332 333/* return in z a lower bound (for rnd = RNDD) or upper bound (for rnd = RNDU) 334 of |zeta(s)|/2, using: 335 log(|zeta(s)|/2) = (s-1)*log(2*Pi) + lngamma(1-s) 336 + log(|sin(Pi*s/2)| * zeta(1-s)). 337 Assumes s < 1/2 and s1 = 1-s exactly, thus s1 > 1/2. 338 y and p are temporary variables. 339 At input, p is Pi rounded down. 340 The comments in the code are for rnd = RNDD. */ 341static void 342mpfr_reflection_overflow (mpfr_t z, mpfr_t s1, const mpfr_t s, mpfr_t y, 343 mpfr_t p, mpfr_rnd_t rnd) 344{ 345 mpz_t sint; 346 347 MPFR_ASSERTD (rnd == MPFR_RNDD || rnd == MPFR_RNDU); 348 349 /* Since log is increasing, we want lower bounds on |sin(Pi*s/2)| and 350 zeta(1-s). */ 351 mpz_init (sint); 352 mpfr_get_z (sint, s, MPFR_RNDD); /* sint = floor(s) */ 353 /* We first compute a lower bound of |sin(Pi*s/2)|, which is a periodic 354 function of period 2. Thus: 355 if 2k < s < 2k+1, then |sin(Pi*s/2)| is increasing; 356 if 2k-1 < s < 2k, then |sin(Pi*s/2)| is decreasing. 357 These cases are distinguished by testing bit 0 of floor(s) as if 358 represented in two's complement (or equivalently, as an unsigned 359 integer mod 2): 360 0: sint = 0 mod 2, thus 2k < s < 2k+1 and |sin(Pi*s/2)| is increasing; 361 1: sint = 1 mod 2, thus 2k-1 < s < 2k and |sin(Pi*s/2)| is decreasing. 362 Let's recall that the comments are for rnd = RNDD. */ 363 if (mpz_tstbit (sint, 0) == 0) /* |sin(Pi*s/2)| is increasing: round down 364 Pi*s to get a lower bound. */ 365 { 366 mpfr_mul (y, p, s, rnd); 367 if (rnd == MPFR_RNDD) 368 mpfr_nextabove (p); /* we will need p rounded above afterwards */ 369 } 370 else /* |sin(Pi*s/2)| is decreasing: round up Pi*s to get a lower bound. */ 371 { 372 if (rnd == MPFR_RNDD) 373 mpfr_nextabove (p); 374 mpfr_mul (y, p, s, MPFR_INVERT_RND(rnd)); 375 } 376 mpfr_div_2ui (y, y, 1, MPFR_RNDN); /* exact, rounding mode doesn't matter */ 377 /* The rounding direction of sin depends on its sign. We have: 378 if -4k-2 < s < -4k, then -2k-1 < s/2 < -2k, thus sin(Pi*s/2) < 0; 379 if -4k < s < -4k+2, then -2k < s/2 < -2k+1, thus sin(Pi*s/2) > 0. 380 These cases are distinguished by testing bit 1 of floor(s) as if 381 represented in two's complement (or equivalently, as an unsigned 382 integer mod 4): 383 0: sint = {0,1} mod 4, thus -2k < s/2 < -2k+1 and sin(Pi*s/2) > 0; 384 1: sint = {2,3} mod 4, thus -2k-1 < s/2 < -2k and sin(Pi*s/2) < 0. 385 Let's recall that the comments are for rnd = RNDD. */ 386 if (mpz_tstbit (sint, 1) == 0) /* -2k < s/2 < -2k+1; sin(Pi*s/2) > 0 */ 387 { 388 /* Round sin down to get a lower bound of |sin(Pi*s/2)|. */ 389 mpfr_sin (y, y, rnd); 390 } 391 else /* -2k-1 < s/2 < -2k; sin(Pi*s/2) < 0 */ 392 { 393 /* Round sin up to get a lower bound of |sin(Pi*s/2)|. */ 394 mpfr_sin (y, y, MPFR_INVERT_RND(rnd)); 395 mpfr_abs (y, y, MPFR_RNDN); /* exact, rounding mode doesn't matter */ 396 } 397 mpz_clear (sint); 398 /* now y <= |sin(Pi*s/2)| when rnd=RNDD, y >= |sin(Pi*s/2)| when rnd=RNDU */ 399 mpfr_zeta_pos (z, s1, rnd); /* zeta(1-s) */ 400 mpfr_mul (z, z, y, rnd); 401 /* now z <= |sin(Pi*s/2)|*zeta(1-s) */ 402 mpfr_log (z, z, rnd); 403 /* now z <= log(|sin(Pi*s/2)|*zeta(1-s)) */ 404 mpfr_lngamma (y, s1, rnd); 405 mpfr_add (z, z, y, rnd); 406 /* z <= lngamma(1-s) + log(|sin(Pi*s/2)|*zeta(1-s)) */ 407 /* since s-1 < 0, we want to round log(2*pi) upwards */ 408 mpfr_mul_2ui (y, p, 1, MPFR_INVERT_RND(rnd)); 409 mpfr_log (y, y, MPFR_INVERT_RND(rnd)); 410 mpfr_mul (y, y, s1, MPFR_INVERT_RND(rnd)); 411 mpfr_sub (z, z, y, rnd); 412 mpfr_exp (z, z, rnd); 413 if (rnd == MPFR_RNDD) 414 mpfr_nextbelow (p); /* restore original p */ 415} 416 417int 418mpfr_zeta (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode) 419{ 420 mpfr_t z_pre, s1, y, p; 421 long add; 422 mpfr_prec_t precz, prec1, precs, precs1; 423 int inex; 424 MPFR_GROUP_DECL (group); 425 MPFR_ZIV_DECL (loop); 426 MPFR_SAVE_EXPO_DECL (expo); 427 428 MPFR_LOG_FUNC ( 429 ("s[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (s), mpfr_log_prec, s, rnd_mode), 430 ("z[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (z), mpfr_log_prec, z, inex)); 431 432 /* Zero, Nan or Inf ? */ 433 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (s))) 434 { 435 if (MPFR_IS_NAN (s)) 436 { 437 MPFR_SET_NAN (z); 438 MPFR_RET_NAN; 439 } 440 else if (MPFR_IS_INF (s)) 441 { 442 if (MPFR_IS_POS (s)) 443 return mpfr_set_ui (z, 1, MPFR_RNDN); /* Zeta(+Inf) = 1 */ 444 MPFR_SET_NAN (z); /* Zeta(-Inf) = NaN */ 445 MPFR_RET_NAN; 446 } 447 else /* s iz zero */ 448 { 449 MPFR_ASSERTD (MPFR_IS_ZERO (s)); 450 return mpfr_set_si_2exp (z, -1, -1, rnd_mode); 451 } 452 } 453 454 /* s is neither Nan, nor Inf, nor Zero */ 455 456 /* check tiny s: we have zeta(s) = -1/2 - 1/2 log(2 Pi) s + ... around s=0, 457 and for |s| <= 2^(-4), we have |zeta(s) + 1/2| <= |s|. 458 EXP(s) + 1 < -PREC(z) is a sufficient condition to be able to round 459 correctly, for any PREC(z) >= 1 (see algorithms.tex for details). */ 460 if (MPFR_GET_EXP (s) + 1 < - (mpfr_exp_t) MPFR_PREC(z)) 461 { 462 int signs = MPFR_SIGN(s); 463 464 MPFR_SAVE_EXPO_MARK (expo); 465 mpfr_set_si_2exp (z, -1, -1, rnd_mode); /* -1/2 */ 466 if (rnd_mode == MPFR_RNDA) 467 rnd_mode = MPFR_RNDD; /* the result is around -1/2, thus negative */ 468 if ((rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDZ) && signs < 0) 469 { 470 mpfr_nextabove (z); /* z = -1/2 + epsilon */ 471 inex = 1; 472 } 473 else if (rnd_mode == MPFR_RNDD && signs > 0) 474 { 475 mpfr_nextbelow (z); /* z = -1/2 - epsilon */ 476 inex = -1; 477 } 478 else 479 { 480 if (rnd_mode == MPFR_RNDU) /* s > 0: z = -1/2 */ 481 inex = 1; 482 else if (rnd_mode == MPFR_RNDD) 483 inex = -1; /* s < 0: z = -1/2 */ 484 else /* (MPFR_RNDZ and s > 0) or MPFR_RNDN: z = -1/2 */ 485 inex = (signs > 0) ? 1 : -1; 486 } 487 MPFR_SAVE_EXPO_FREE (expo); 488 return mpfr_check_range (z, inex, rnd_mode); 489 } 490 491 /* Check for case s= -2n */ 492 if (MPFR_IS_NEG (s)) 493 { 494 mpfr_t tmp; 495 tmp[0] = *s; 496 MPFR_EXP (tmp) = MPFR_GET_EXP (s) - 1; 497 if (mpfr_integer_p (tmp)) 498 { 499 MPFR_SET_ZERO (z); 500 MPFR_SET_POS (z); 501 MPFR_RET (0); 502 } 503 } 504 505 /* Check for case s=1 before changing the exponent range */ 506 if (mpfr_cmp (s, __gmpfr_one) == 0) 507 { 508 MPFR_SET_INF (z); 509 MPFR_SET_POS (z); 510 MPFR_SET_DIVBY0 (); 511 MPFR_RET (0); 512 } 513 514 MPFR_SAVE_EXPO_MARK (expo); 515 516 /* Compute Zeta */ 517 if (MPFR_IS_POS (s) && MPFR_GET_EXP (s) >= 0) /* Case s >= 1/2 */ 518 inex = mpfr_zeta_pos (z, s, rnd_mode); 519 else /* use reflection formula 520 zeta(s) = 2^s*Pi^(s-1)*sin(Pi*s/2)*gamma(1-s)*zeta(1-s) */ 521 { 522 int overflow = 0; 523 524 precz = MPFR_PREC (z); 525 precs = MPFR_PREC (s); 526 527 /* Precision precs1 needed to represent 1 - s, and s + 2, 528 without any truncation */ 529 precs1 = precs + 2 + MAX (0, - MPFR_GET_EXP (s)); 530 /* Precision prec1 is the precision on elementary computations; 531 it ensures a final precision prec1 - add for zeta(s) */ 532 add = compute_add (s, precz); 533 prec1 = precz + add; 534 /* FIXME: To avoid that the working precision (prec1) depends on the 535 input precision, one would need to take into account the error made 536 when s1 is not exactly 1-s when computing zeta(s1) and gamma(s1) 537 below, and also in the case y=Inf (i.e. when gamma(s1) overflows). 538 Make sure that underflows do not occur in intermediate computations. 539 Due to the limited precision, they are probably not possible 540 in practice; add some MPFR_ASSERTN's to be sure that problems 541 do not remain undetected? */ 542 prec1 = MAX (prec1, precs1) + 10; 543 544 MPFR_GROUP_INIT_4 (group, prec1, z_pre, s1, y, p); 545 MPFR_ZIV_INIT (loop, prec1); 546 for (;;) 547 { 548 mpfr_exp_t ey; 549 mpfr_t z_up; 550 551 mpfr_const_pi (p, MPFR_RNDD); /* p is Pi */ 552 553 mpfr_sub (s1, __gmpfr_one, s, MPFR_RNDN); /* s1 = 1-s */ 554 mpfr_gamma (y, s1, MPFR_RNDN); /* gamma(1-s) */ 555 if (MPFR_IS_INF (y)) /* zeta(s) < 0 for -4k-2 < s < -4k, 556 zeta(s) > 0 for -4k < s < -4k+2 */ 557 { 558 /* FIXME: An overflow in gamma(s1) does not imply that 559 zeta(s) will overflow. A solution: 560 1. Compute 561 log(|zeta(s)|/2) = (s-1)*log(2*pi) + lngamma(1-s) 562 + log(abs(sin(Pi*s/2)) * zeta(1-s)) 563 (possibly sharing computations with the normal case) 564 with a rather good accuracy (see (2)). 565 Memorize the sign of sin(...) for the final sign. 566 2. Take the exponential, ~= |zeta(s)|/2. If there is an 567 overflow, then this means an overflow on the final result 568 (due to the multiplication by 2, which has not been done 569 yet). 570 3. Ziv test. 571 4. Correct the sign from the sign of sin(...). 572 5. Round then multiply by 2. Here, an overflow in either 573 operation means a real overflow. */ 574 mpfr_reflection_overflow (z_pre, s1, s, y, p, MPFR_RNDD); 575 /* z_pre is a lower bound of |zeta(s)|/2, thus if it overflows, 576 or has exponent emax, then |zeta(s)| overflows too. */ 577 if (MPFR_IS_INF (z_pre) || MPFR_GET_EXP(z_pre) == __gmpfr_emax) 578 { /* determine the sign of overflow */ 579 mpfr_div_2ui (s1, s, 2, MPFR_RNDN); /* s/4, exact */ 580 mpfr_frac (s1, s1, MPFR_RNDN); /* exact, -1 < s1 < 0 */ 581 overflow = (mpfr_cmp_si_2exp (s1, -1, -1) > 0) ? -1 : 1; 582 break; 583 } 584 else /* EXP(z_pre) < __gmpfr_emax */ 585 { 586 int ok = 0; 587 mpfr_t z_down; 588 mpfr_init2 (z_up, mpfr_get_prec (z_pre)); 589 mpfr_reflection_overflow (z_up, s1, s, y, p, MPFR_RNDU); 590 /* if the lower approximation z_pre does not overflow, but 591 z_up does, we need more precision */ 592 if (MPFR_IS_INF (z_up) || MPFR_GET_EXP(z_up) == __gmpfr_emax) 593 goto next_loop; 594 /* check if z_pre and z_up round to the same number */ 595 mpfr_init2 (z_down, precz); 596 mpfr_set (z_down, z_pre, rnd_mode); 597 /* Note: it might be that EXP(z_down) = emax here, in that 598 case we will have overflow below when we multiply by 2 */ 599 mpfr_prec_round (z_up, precz, rnd_mode); 600 ok = mpfr_cmp (z_down, z_up) == 0; 601 mpfr_clear (z_up); 602 mpfr_clear (z_down); 603 if (ok) 604 { 605 /* get correct sign and multiply by 2 */ 606 mpfr_div_2ui (s1, s, 2, MPFR_RNDN); /* s/4, exact */ 607 mpfr_frac (s1, s1, MPFR_RNDN); /* exact, -1 < s1 < 0 */ 608 if (mpfr_cmp_si_2exp (s1, -1, -1) > 0) 609 mpfr_neg (z_pre, z_pre, rnd_mode); 610 mpfr_mul_2ui (z_pre, z_pre, 1, rnd_mode); 611 break; 612 } 613 else 614 goto next_loop; 615 } 616 } 617 mpfr_zeta_pos (z_pre, s1, MPFR_RNDN); /* zeta(1-s) */ 618 mpfr_mul (z_pre, z_pre, y, MPFR_RNDN); /* gamma(1-s)*zeta(1-s) */ 619 620 /* multiply z_pre by 2^s*Pi^(s-1) where p=Pi, s1=1-s */ 621 mpfr_mul_2ui (y, p, 1, MPFR_RNDN); /* 2*Pi */ 622 mpfr_neg (s1, s1, MPFR_RNDN); /* s-1 */ 623 mpfr_pow (y, y, s1, MPFR_RNDN); /* (2*Pi)^(s-1) */ 624 mpfr_mul (z_pre, z_pre, y, MPFR_RNDN); 625 mpfr_mul_2ui (z_pre, z_pre, 1, MPFR_RNDN); 626 627 /* multiply z_pre by sin(Pi*s/2) */ 628 mpfr_mul (y, s, p, MPFR_RNDN); 629 mpfr_div_2ui (p, y, 1, MPFR_RNDN); /* p = s*Pi/2 */ 630 /* FIXME: sinpi will be available, we should replace the mpfr_sin 631 call below by mpfr_sinpi(s/2), where s/2 will be exact. 632 Can mpfr_sin underflow? Moreover, the code below should be 633 improved so that the "if" condition becomes unlikely, e.g. 634 by taking a slightly larger working precision. */ 635 mpfr_sin (y, p, MPFR_RNDN); /* y = sin(Pi*s/2) */ 636 ey = MPFR_GET_EXP (y); 637 if (ey < 0) /* take account of cancellation in sin(p) */ 638 { 639 mpfr_t t; 640 641 MPFR_ASSERTN (- ey < MPFR_PREC_MAX - prec1); 642 mpfr_init2 (t, prec1 - ey); 643 mpfr_const_pi (t, MPFR_RNDD); 644 mpfr_mul (t, s, t, MPFR_RNDN); 645 mpfr_div_2ui (t, t, 1, MPFR_RNDN); 646 mpfr_sin (y, t, MPFR_RNDN); 647 mpfr_clear (t); 648 } 649 mpfr_mul (z_pre, z_pre, y, MPFR_RNDN); 650 651 if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, prec1 - add, precz, 652 rnd_mode))) 653 break; 654 655 next_loop: 656 MPFR_ZIV_NEXT (loop, prec1); 657 MPFR_GROUP_REPREC_4 (group, prec1, z_pre, s1, y, p); 658 } 659 MPFR_ZIV_FREE (loop); 660 if (overflow != 0) 661 { 662 inex = mpfr_overflow (z, rnd_mode, overflow); 663 MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW); 664 } 665 else 666 inex = mpfr_set (z, z_pre, rnd_mode); 667 MPFR_GROUP_CLEAR (group); 668 } 669 670 MPFR_SAVE_EXPO_FREE (expo); 671 return mpfr_check_range (z, inex, rnd_mode); 672} 673