Line data Source code
1 : /* Copyright (C) 2022 The PARI group.
2 :
3 : This file is part of the PARI/GP package.
4 :
5 : PARI/GP is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 2 of the License, or (at your option) any later
8 : version. It is distributed in the hope that it will be useful, but WITHOUT
9 : ANY WARRANTY WHATSOEVER.
10 :
11 : Check the License for details. You should have received a copy of it, along
12 : with the package; see the file 'COPYING'. If not, write to the Free Software
13 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
14 :
15 : #include "pari.h"
16 : #include "paripriv.h"
17 :
18 : #define DEBUGLEVEL DEBUGLEVEL_trans
19 :
20 : /********************************************************/
21 : /* Hurwitz zeta function */
22 : /********************************************************/
23 : struct Qp_zetahurwitz_t { GEN B, _1, s1; };
24 : static void
25 301 : Qp_zetahurwitz_init(struct Qp_zetahurwitz_t *S, long prec, GEN s)
26 : {
27 301 : GEN B, C = gen_1, s1 = gsubgs(s, 1), p = gel(s, 2);
28 301 : long j, J = ((equaliu(p,2)? (prec >> 1): prec) + 2) >> 1;
29 301 : if (gequal0(s1)) s1 = NULL;
30 301 : B = bernvec(J);
31 3346 : for (j = 1; j <= J; j++)
32 : {
33 3045 : GEN t = (j == 1 && !s1)? s: gmul(gaddgs(s, 2*j-3), gaddgs(s, 2*j-2));
34 3045 : C = gdivgunextu(gmul(C, t), 2*j-1);
35 3045 : gel(B, j+1) = gmul(gel(B, j+1), C); /* B_{2j} * binomial(1-s, 2j) */
36 : }
37 301 : S->_1 = cvtop(gen_1, p, prec);
38 301 : S->s1 = s1;
39 301 : S->B = B;
40 301 : }
41 :
42 : /* v_p(x) < (p==2)?-1: 0; s1 = s-1 or NULL (if s=1) */
43 : static GEN
44 1218 : Qp_zetahurwitz_0(struct Qp_zetahurwitz_t *S, GEN x)
45 : {
46 1218 : GEN z, x2, x2j, s1 = S->s1;
47 1218 : long j, J = lg(S->B) - 2;
48 :
49 1218 : x = cvtop2(ginv(x), S->_1); z = gmul2n(x, -1);
50 1218 : z = s1? gmul(s1, z): gadd(Qp_log(x), z);
51 1218 : x2j = x2 = gsqr(x); z = gaddgs(z, 1);
52 1218 : for (j = 1;; j++)
53 : {
54 21525 : z = gadd(z, gmul(gel(S->B, j + 1), x2j));
55 21525 : if (j == J) break;
56 20307 : x2j = gmul(x2, x2j);
57 : }
58 1218 : if (s1) z = gmul(gdiv(z, s1), Qp_exp(gmul(s1, Qp_log(x))));
59 1218 : return z;
60 : }
61 : /* private (absolute) padicprec */
62 : static long
63 546 : pprec(GEN x) { return maxss(valp(x) + precp(x), 1); }
64 :
65 : /* L_p(s, (D, .)); assume s != 1 if D = 1 */
66 : static GEN
67 14 : Qp_zeta_i(GEN s, long D)
68 : {
69 14 : pari_sp av = avma;
70 14 : GEN z, va, gp = gel(s,2);
71 14 : ulong a, p = itou(gp), m;
72 14 : long prec = pprec(s);
73 : struct Qp_zetahurwitz_t S;
74 :
75 14 : if (D <= 0) pari_err_DOMAIN("p-adic L-function", "D", "<=", gen_0, stoi(D));
76 14 : if (!uposisfundamental(D))
77 0 : pari_err_TYPE("p-adic L-function [D not fundamental]", stoi(D));
78 14 : Qp_zetahurwitz_init(&S, prec, s);
79 14 : m = ulcm(D, p == 2? 4: p); va = coprimes_zv(m);
80 42 : for (a = 1, z = gen_0; a <= (m >> 1); a++)
81 28 : if (va[a])
82 : {
83 21 : GEN h = Qp_zetahurwitz_0(&S, uutoQ(a, m));
84 21 : if (D != 1 && kross(D, a) < 0) h = gneg(h);
85 21 : z = gadd(z, h);
86 : }
87 14 : z = gdivgs(gmul2n(z, 1), m);
88 14 : if (D != 1) z = gmul(z, Qp_exp(gmul(gsubsg(1, s), Qp_log(cvstop2(m, s)))));
89 14 : return gerepileupto(av, z);
90 : }
91 : GEN
92 14 : Qp_zeta(GEN s) { return Qp_zeta_i(s, 1); }
93 :
94 : /* s a t_PADIC; gerepileupto-safe. Could be exported */
95 : static GEN
96 287 : Qp_zetahurwitz_ii(GEN s, GEN x, long k)
97 : {
98 287 : GEN gp = gel(s,2);
99 287 : long p = itou(gp), prec = pprec(s);
100 : struct Qp_zetahurwitz_t S;
101 287 : Qp_zetahurwitz_init(&S, prec, s);
102 287 : if (typ(x) != t_PADIC) x = gadd(x, zeropadic_shallow(gp, prec));
103 287 : if (valp(x) >= ((p==2)? -1: 0))
104 : {
105 280 : GEN z = gen_0;
106 280 : long j, M = (p==2)? 4: p;
107 1869 : for (j = 0; j < M; j++)
108 : {
109 1589 : GEN y = gaddsg(j, x);
110 1589 : if (valp(y) <= 0)
111 : {
112 1190 : GEN tmp = Qp_zetahurwitz_0(&S, gdivgu(y, M));
113 1190 : if (k) tmp = gmul(tmp, gpowgs(teich(y), k));
114 1190 : z = gadd(z, tmp);
115 : }
116 : }
117 280 : return gdivgu(z, M);
118 : }
119 7 : if (valp(s) < 0) pari_err_DOMAIN("Qp_zetahurwitz", "v(s)", "<", gen_0, s);
120 7 : return Qp_zetahurwitz_0(&S, x);
121 : }
122 :
123 : /* x or s must be p-adic */
124 : static GEN
125 287 : Qp_zetahurwitz_i(GEN s, GEN x, long k)
126 : {
127 287 : if (typ(x) == t_PADIC)
128 : {
129 245 : pari_sp av = avma;
130 245 : GEN p = gel(x,2);
131 245 : long e = pprec(x);
132 245 : e += sdivsi(e, subis(p, 1));
133 245 : s = gadd(s, zeropadic_shallow(p, e));
134 245 : return gerepileupto(av, Qp_zetahurwitz_ii(s, x, k));
135 : }
136 42 : return Qp_zetahurwitz_ii(s, x, k);
137 : }
138 :
139 : GEN
140 238 : Qp_zetahurwitz(GEN s, GEN x, long k)
141 : {
142 238 : pari_sp av = avma;
143 238 : return gerepileupto(av, Qp_zetahurwitz_i(s, x, k));
144 : }
145 :
146 : static void
147 8596 : binsplit(GEN *pP, GEN *pR, GEN aN2, GEN isqaN, GEN s, long j, long k, long prec)
148 : {
149 8596 : if (j + 1 == k)
150 : {
151 4347 : long j2 = j << 1;
152 : GEN P;
153 4347 : if (!j) P = gdiv(s, aN2);
154 : else
155 : {
156 4249 : P = gmul(gaddgs(s, j2-1), gaddgs(s, j2));
157 4249 : P = gdivgunextu(gmul(P, isqaN), j2+1);
158 : }
159 4347 : if (pP) *pP = P;
160 4347 : if (pR) *pR = gmul(bernreal(j2+2, prec), P);
161 : }
162 : else
163 : {
164 : GEN P1, R1, P2, R2;
165 4249 : binsplit(&P1,pR? &R1: NULL, aN2, isqaN, s, j, (j+k) >> 1, prec);
166 4249 : binsplit(pP? &P2: NULL, pR? &R2: NULL, aN2, isqaN, s, (j+k) >> 1, k, prec);
167 4249 : if (pP) *pP = gmul(P1,P2);
168 4249 : if (pR) *pR = gadd(R1, gmul(P1, R2));
169 : }
170 8596 : }
171 :
172 : /* a0 + a1 x + O(x^e), e >= 0 */
173 : static GEN
174 77 : deg1ser_shallow(GEN a1, GEN a0, long v, long e)
175 77 : { return RgX_to_ser(deg1pol_shallow(a1, a0, v), e+2); }
176 :
177 : static long
178 532 : hurwitz_cutoff(GEN s, long bit)
179 : {
180 581 : return typ(s) == t_COMPLEX &&
181 49 : fabs(gtodouble(gel(s,2))) > 5.37 * pow(bit, 1.4) / mt_nbthreads();
182 : }
183 :
184 : /* New zetahurwitz, from Fredrik Johansson. */
185 : GEN
186 665 : zetahurwitz(GEN s, GEN x, long der, long bitprec)
187 : {
188 665 : pari_sp av = avma, av2;
189 665 : GEN a, ra, ra0, Nx, S1, S2, S3, N2, rx, sch = NULL, s0 = s, x0 = x, y;
190 665 : long j, k, m, N, prec0 = nbits2prec(bitprec), prec = prec0, fli = 0;
191 : pari_timer T;
192 :
193 665 : if (typ(s) == t_PADIC || typ(x) == t_PADIC)
194 49 : return gerepileupto(av, Qp_zetahurwitz_i(s, x, der));
195 616 : if (der < 0) pari_err_DOMAIN("zetahurwitz", "der", "<", gen_0, stoi(der));
196 616 : if (der)
197 : {
198 : GEN z;
199 21 : if (!is_scalar_t(typ(s)))
200 : {
201 7 : z = deriv(zetahurwitz(s, x, der - 1, bitprec), -1);
202 7 : z = gdiv(z, deriv(s, -1));
203 : }
204 : else
205 : {
206 14 : if (gequal1(s)) pari_err_DOMAIN("zetahurwitz", "s", "=", gen_1, s0);
207 14 : s = deg1ser_shallow(gen_1, s, 0, der+2);
208 14 : z = zetahurwitz(s, x, 0, bitprec + der * log2(der));
209 14 : z = gmul(mpfact(der), polcoef_i(z, der, -1));
210 : }
211 21 : return gerepileupto(av,z);
212 : }
213 595 : switch(typ(x))
214 : {
215 434 : case t_INT: case t_REAL: case t_FRAC: case t_COMPLEX: break;
216 161 : default:
217 161 : if (!(y = toser_i(x))) pari_err_TYPE("zetahurwitz", x);
218 154 : x = y; x0 = polcoef_i(x, 0, -1); break;
219 : }
220 588 : rx = real_i(x0);
221 588 : if (typ(x) != t_SER && typ(rx) == t_INT && signe(rx) <= 0
222 84 : && gequal0(imag_i(x0)))
223 0 : pari_err_DOMAIN("zetahurwitz","x", "=",
224 : strtoGENstr("nonpositive integer"), x0);
225 588 : rx = grndtoi(rx, NULL);
226 588 : if (typ(rx) != t_INT) pari_err_TYPE("zetahurwitz", x);
227 588 : switch (typ(s))
228 : {
229 : long v, pr;
230 518 : case t_INT: case t_REAL: case t_FRAC: case t_COMPLEX:
231 518 : if (!der && hurwitz_cutoff(s, bitprec))
232 7 : return zetahurwitzlarge(s, x, prec);
233 511 : break;
234 70 : default:
235 70 : if (!(y = toser_i(s))) pari_err_TYPE("zetahurwitz", s);
236 70 : if (valser(y) < 0) pari_err_DOMAIN("zetahurwitz", "val(s)", "<", gen_0, s);
237 70 : s0 = polcoef_i(y, 0, -1);
238 70 : switch(typ(s0))
239 : {
240 63 : case t_INT: case t_REAL: case t_FRAC: case t_COMPLEX: break;
241 0 : case t_PADIC: pari_err_IMPL("zetahurwitz(t_SER of t_PADIC)");
242 7 : default: pari_err_TYPE("zetahurwitz", s0);
243 : }
244 63 : sch = gequal0(s0)? y: serchop0(y);
245 63 : v = valser(sch);
246 63 : pr = (lg(y) + v + 1) / v;
247 63 : if (gequal1(s0)) pr += v;
248 63 : s = deg1ser_shallow(gen_1, s0, 0, pr);
249 : }
250 574 : a = gneg(s0); ra = real_i(a); ra0 = ground(ra);
251 574 : if (gequal1(s0) && (!sch || gequal0(sch)))
252 14 : pari_err_DOMAIN("zetahurwitz", "s", "=", gen_1, s0);
253 560 : fli = (gsigne(ra0) >= 0 && gexpo(gsub(a, ra0)) < 17 - bitprec);
254 560 : if (!sch && fli)
255 : { /* a ~ non negative integer */
256 14 : k = itos(gceil(ra)) + 1;
257 14 : if (odd(k)) k++;
258 14 : N = 1;
259 : }
260 : else
261 : {
262 546 : GEN C, ix = imag_i(x0);
263 546 : double c = (typ(s) == t_INT)? 1: 20 * log((double)bitprec);
264 546 : double rs = gtodouble(ra) + 1;
265 : long k0;
266 546 : if (fli) a = gadd(a, ghalf); /* hack */
267 546 : if (rs > 0)
268 : {
269 49 : bitprec += (long)ceil(rs * expu(bitprec));
270 49 : prec = nbits2prec(bitprec);
271 49 : x = gprec_w(x, prec);
272 49 : s = gprec_w(s, prec);
273 49 : if (sch) sch = gprec_w(sch, prec);
274 : }
275 546 : k = bitprec * M_LN2 / (1 + dbllambertW0(M_PI / c));
276 546 : k0 = itos(gceil(gadd(ra, ghalf))) + 1;
277 546 : k = maxss(k0, k);
278 546 : if (odd(k)) k++;
279 : /* R_k < 2 |binom(a,k+1) B_{k+2}/(k+2)| */
280 546 : C = binomial(a, k+1); C = polcoef_i(C, 0, -1);
281 546 : C = gmul(C, gdivgu(bernfrac(k+2), k+2));
282 546 : C = gmul2n(gabs(C,LOWDEFAULTPREC), bitprec + 1);
283 546 : C = gpow(C, ginv(gsubsg(k+1, ra)), LOWDEFAULTPREC);
284 : /* need |N + x - 1|^2 > C^2 */
285 546 : if (!gequal0(ix))
286 : {
287 133 : GEN tmp = gsub(gsqr(C), gsqr(ix));
288 133 : if (gsigne(tmp) >= 0) C = gsqrt(tmp, LOWDEFAULTPREC);
289 : }
290 : /* need |N + re(x) - 1| > C */
291 546 : C = gceil(gadd(C, gsubsg(1, rx)));
292 546 : if (typ(C) != t_INT) pari_err_TYPE("zetahurwitz",s);
293 546 : N = signe(C) > 0? itos(C) : 1;
294 546 : if (N == 1 && signe(a) > 0)
295 : { /* May reduce k if 2Pix > a */
296 : /* Need 2 |x^(-K) (B_K/K) binom(a, K-1)| < 2^-bit |x|^-rs |zeta(s,x)|
297 : * with K = k+2; N = 1; |zeta(s,x)| ~ |x|^(rs-1);
298 : * if a > 0, (B_K/K) binom(a, K-1) < 2 |a / 2Pi|^K */
299 0 : double dx = dbllog2(x0), d = 1 + dx + log2(M_PI) - dbllog2(s0);
300 0 : if (d > 0)
301 : { /* d ~ log2 |2Pi x / a| */
302 0 : long K = (long)ceil((bitprec + 1 + dx) / d);
303 0 : K = maxss(k0, K);
304 0 : if (odd(K)) K++;
305 0 : if (K < k) k = K;
306 : }
307 : }
308 : }
309 560 : if (gsigne(rx) < 0) N = maxss(N, 1 - itos(rx));
310 560 : a = gneg(s);
311 560 : if (DEBUGLEVEL>2) timer_start(&T);
312 560 : incrprec(prec);
313 560 : Nx = gaddsg(N - 1, x);
314 560 : Nx = typ(Nx) == t_SER? RgX_gtofp(Nx, prec): gtofp(Nx, prec);
315 560 : S1 = S3 = gpow(Nx, a, prec);
316 560 : av2 = avma;
317 560 : if (gequal1(x)) S1 = dirpowerssum(N, a, 0, prec);
318 : else
319 7826 : for (m = N - 2; m >= 0; m--)
320 : {
321 7322 : S1 = gadd(S1, gpow(gaddsg(m,x), a, prec));
322 7322 : if ((m & 0xff) == 0) S1 = gerepileupto(av2, S1);
323 : }
324 560 : if (DEBUGLEVEL>2) timer_printf(&T,"sum from 0 to N - 1");
325 560 : constbern(k >> 1);
326 560 : N2 = ginv(gsqr(Nx));
327 560 : if (typ(s0) == t_INT)
328 : {
329 462 : S2 = divru(bernreal(k, prec), k);
330 10773 : for (j = k - 2; j >= 2; j -= 2)
331 : {
332 10311 : GEN t = gsubgs(a, j), u = gmul(t, gaddgs(t, 1));
333 10311 : u = gmul(gdivgunextu(u, j), gmul(S2, N2));
334 10311 : S2 = gadd(divru(bernreal(j, prec), j), u);
335 : }
336 462 : S2 = gmul(S2, gdiv(a, Nx));
337 : }
338 : else
339 : {
340 98 : binsplit(NULL,&S2, gmul2n(Nx,1), N2, s, 0, k >> 1, prec);
341 98 : S2 = gneg(S2);
342 : }
343 560 : S2 = gadd(ghalf, S2);
344 560 : if (DEBUGLEVEL>2) timer_printf(&T,"Bernoulli sum");
345 560 : S2 = gmul(S3, gadd(gdiv(Nx, gaddsg(1, a)), S2));
346 560 : S1 = gprec_wtrunc(gsub(S1, S2), prec0);
347 560 : if (sch) return gerepileupto(av, gsubst(S1, 0, sch));
348 504 : return gerepilecopy(av, S1);
349 : }
350 :
351 : /* New Lerch, inspired by Fredrik Johansson. */
352 :
353 : GEN
354 153648 : lerch_worker(GEN t, GEN E)
355 : {
356 153648 : GEN n, d, T, s = gel(E,1), a = gmul(gel(E,2), t), z = gel(E,3);
357 153177 : long p = itos(gel(E,4)), prec = labs(p);
358 153188 : d = gadd(gexp(t, prec), z);
359 153512 : T = p > 0? t: gneg(t);
360 153557 : if (typ(s) == t_INT)
361 58396 : n = gmul(gpow(T, s, prec), gexp(a, prec));
362 : else /* save one exp */
363 95161 : n = gexp(gadd(gmul(s, glog(T, prec)), a), prec);
364 153739 : return gdiv(n, d);
365 : }
366 :
367 : /* tab already computed with N = #tab[1] even */
368 : static GEN
369 441 : parintnumgauss(GEN f, GEN a, GEN b, GEN tab, long prec)
370 : {
371 441 : GEN R = gel(tab, 1), W = gel(tab, 2), bma, bpa, S = gen_0, VP, VM, V;
372 441 : long n = lg(R) - 1, i, prec2 = prec + EXTRAPREC64;
373 441 : a = gprec_wensure(a, prec2);
374 441 : b = gprec_wensure(b, prec2);
375 441 : VP = cgetg(n + 1, t_VEC); bma = gmul2n(gsub(b, a), -1);
376 441 : VM = cgetg(n + 1, t_VEC); bpa = gadd(bma, a);
377 28203 : for (i = 1; i <= n; i++)
378 : {
379 27762 : GEN h = gmul(bma, gel(R, i));
380 27762 : gel(VP, i) = gadd(bpa, h);
381 27762 : gel(VM, i) = gsub(bpa, h);
382 : }
383 441 : V = gadd(parapply(f, VP), parapply(f, VM));
384 28203 : for (i = 1; i <= n; i++)
385 : {
386 27762 : S = gadd(S, gmul(gel(W, i), gel(V, i)));
387 27762 : S = gprec_wensure(S, prec2);
388 : }
389 441 : return gprec_wtrunc(gmul(bma, S), prec);
390 : }
391 :
392 : /* Assume tab computed and a >= 0 */
393 : static GEN
394 119 : parintnum(GEN f, GEN a, GEN tab)
395 : {
396 : pari_sp av;
397 119 : GEN tabx0 = gel(tab, 2), tabw0 = gel(tab, 3), tabxm = gel(tab, 6);
398 119 : GEN tabxp = gel(tab, 4), tabwp = gel(tab, 5), tabwm = gel(tab, 7);
399 119 : GEN VP = tabxp, VM = tabxm, x0 = tabx0, S;
400 119 : long prec = gprecision(tabw0), L = lg(tabxp), i, fla = 0;
401 119 : if (!gequal0(a))
402 : {
403 91 : if (gexpo(a) <= 0)
404 : {
405 63 : x0 = gadd(a, x0);
406 30357 : for (i = 1; i < L; i++)
407 : {
408 30294 : gel(VP, i) = gadd(a, gel(VP, i));
409 30294 : gel(VM, i) = gadd(a, gel(VM, i));
410 : }
411 : }
412 : else
413 : {
414 28 : x0 = gmul(a, gaddsg(1, x0)); fla = 1;
415 5404 : for (i = 1; i < L; i++)
416 : {
417 5376 : gel(VP, i) = gmul(a, gaddsg(1, gel(VP, i)));
418 5376 : gel(VM, i) = gmul(a, gaddsg(1, gel(VM, i)));
419 : }
420 : }
421 : }
422 119 : VP = parapply(f, VP);
423 119 : VM = parapply(f, VM); av = avma;
424 119 : S = gmul(tabw0, closure_callgen1(f, x0));
425 49257 : for (i = 1; i < L; i++)
426 : {
427 49138 : S = gadd(S, gadd(gmul(gel(tabwp, i), gel(VP, i)),
428 49138 : gmul(gel(tabwm, i), gel(VM, i))));
429 49138 : if ((i & 0x7f) == 1) S = gerepileupto(av, S);
430 49138 : S = gprec_wensure(S, prec);
431 : }
432 119 : if (fla) S = gmul(S, a);
433 119 : return gmul(S, gel(tab, 1));
434 : }
435 :
436 : static GEN
437 84 : refine(GEN A)
438 : {
439 84 : long n = lg(A) - 1, i;
440 84 : GEN B = cgetg(2 * n, t_VEC);
441 231 : for (i = 1; i < n; i++)
442 : {
443 147 : gel(B, 2 * i - 1) = gel(A, i);
444 147 : gel(B, 2 * i) = gmul2n(gadd(gel(A, i), gel(A, i + 1)), -1);
445 : }
446 84 : gel(B, 2 * n - 1) = gel(A, n); return B;
447 : }
448 :
449 : /* Here L = [a1, a2, a3,...] integration vertices. Refine by splitting
450 : * intervals. */
451 : static GEN
452 84 : parintnumgaussadapt(GEN f, GEN L, GEN tab, long bit)
453 : {
454 84 : GEN Rold = gen_0, Rnew;
455 84 : long i, ct = 0, prec = nbits2prec(bit);
456 168 : while (ct <= 5)
457 : {
458 168 : Rnew = gen_0;
459 609 : for (i = 1; i < lg(L) - 1; i++)
460 441 : Rnew = gadd(Rnew, parintnumgauss(f, gel(L, i), gel(L, i + 1), tab, prec));
461 168 : if (ct && gexpo(gsub(Rnew, Rold)) - gexpo(Rnew) < 10 - bit) return Rnew;
462 84 : ct++; Rold = Rnew; L = refine(L);
463 : }
464 0 : if (DEBUGLEVEL) err_printf("intnumgaussadapt: possible accuracy loss");
465 0 : return Rnew; /* Possible accuracy loss */
466 : }
467 :
468 : /* Here b = [oo, r], so refine by increasing integration step m */
469 : static GEN
470 42 : parintnumadapt(GEN f, GEN a, GEN b, GEN tab, long bit)
471 : {
472 42 : GEN Rold = gen_0, Rnew;
473 42 : long m = 0, prec = nbits2prec(bit);
474 42 : if (!tab) tab = intnuminit(gen_0, b, 0, prec);
475 119 : while (m <= 5)
476 : {
477 119 : Rnew = parintnum(f, a, tab);
478 119 : if (m && gexpo(gsub(Rnew, Rold)) - gexpo(Rnew) < 10 - bit) return Rnew;
479 77 : m++; Rold = Rnew; tab = intnuminit(gen_0, b, m, prec);
480 : }
481 0 : if (DEBUGLEVEL) err_printf("intnumadapt: possible accuracy loss");
482 0 : return Rnew; /* Possible accuracy loss */
483 : }
484 :
485 : static int
486 210 : iscplx(GEN z) { long t = typ(z); return is_real_t(t) || t == t_COMPLEX; }
487 :
488 : static GEN
489 14 : lerch_easy(GEN z, GEN s, GEN a, long B)
490 : {
491 14 : long n, prec = nbits2prec(B + 32);
492 14 : GEN zn, ms = gneg(s), S = gpow(a, ms, prec);
493 14 : zn = z = gtofp(z, prec);
494 3808 : for (n = 1;; n++, zn = gmul(zn, z))
495 : {
496 3808 : S = gadd(S, gmul(zn, gpow(gaddgs(a, n), ms, prec)));
497 3808 : if (gexpo(zn) <= - B - 5) return S;
498 : }
499 : }
500 :
501 : static GEN
502 112 : _lerchphi(GEN z, GEN s, GEN a, long prec)
503 : {
504 112 : GEN res = NULL, L, LT, J, rs, mleft, left, right, top, w, Linf, tabg;
505 : GEN E, f, fm;
506 112 : long B = prec2nbits(prec), MB = 3 - B, NB, prec2;
507 : entree *ep;
508 :
509 112 : if (gexpo(z) < MB) return gpow(a, gneg(s), prec);
510 112 : if (gexpo(gsubgs(z, 1)) < MB) return zetahurwitz(s, a, 0, B); /* z ~ 1 */
511 112 : if (gexpo(gaddgs(z, 1)) < MB) /* z ~ -1 */
512 : {
513 7 : GEN tmp = gsub(zetahurwitz(s, gmul2n(a, -1), 0, B),
514 : zetahurwitz(s, gmul2n(gaddgs(a, 1), -1), 0, B));
515 7 : return gmul(gpow(gen_2, gneg(s), prec), tmp);
516 : }
517 105 : if (gcmpgs(gmulsg(10, gabs(z, prec)), 9) <= 0) /* |z| <= 9/10 */
518 14 : return lerch_easy(z, s, a, B);
519 91 : if (gcmpgs(real_i(a), 2) < 0)
520 49 : return gadd(gpow(a, gneg(s), prec),
521 : gmul(z, _lerchphi(z, s, gaddgs(a, 1), prec)));
522 42 : NB = (long)ceil(B + M_PI * fabs(gtodouble(imag_i(s))));
523 42 : prec2 = nbits2prec(NB);
524 42 : z = gprec_w(z, prec2); /* |z| > 9/10 */
525 42 : s = gprec_w(s, prec2);
526 42 : a = gprec_w(a, prec2); /* Re(a) >= 2 */
527 42 : rs = ground(real_i(s)); L = glog(z, prec2); /* Re(L) > -0.11 */
528 42 : ep = is_entry("_lerch_worker");
529 42 : E = mkvec4(gsubgs(s, 1), gsubsg(1, a), gneg(z), stoi(prec2));
530 42 : f = snm_closure(ep, mkvec(E));
531 42 : E = shallowcopy(E); gel(E,4) = stoi(-prec2);
532 42 : fm = snm_closure(ep, mkvec(E));
533 42 : Linf = mkvec2(mkoo(), real_i(a));
534 42 : if (gexpo(gsub(s, rs)) < MB && gcmpgs(rs, 1) >= 0)
535 : { /* s ~ positive integer */
536 14 : if (gcmp(gabs(imag_i(L), prec2), sstoQ(1, 4)) < 0 && gsigne(real_i(L)) >= 0)
537 7 : { /* Re(L) >= 0, |Im(L)| < 1/4 */
538 7 : GEN t = gsigne(imag_i(z)) > 0 ? gen_m1: gen_1;
539 7 : GEN LT1 = gaddgs(gabs(L, prec2), 1);
540 7 : LT = mkvec4(gen_0, mkcomplex(gen_0, t), mkcomplex(LT1, t), LT1);
541 7 : tabg = intnumgaussinit(2*(NB >> 2) + 60, prec2);
542 7 : J = parintnumgaussadapt(f, LT, tabg, NB);
543 7 : J = gadd(J, parintnumadapt(f, LT1, Linf, NULL, NB));
544 : }
545 7 : else J = parintnumadapt(f, gen_0, Linf, NULL, NB);
546 14 : return gdiv(J, ggamma(s, prec2));
547 : }
548 28 : tabg = intnumgaussinit(2*(NB >> 2) + 60, prec2);
549 28 : if (gcmp(gabs(imag_i(L), prec2), ghalf) > 0) /* |Im(L)| > 1/2 */
550 14 : left = right = top = gmin(gmul2n(gabs(imag_i(L), prec2), -1), gen_1);
551 : else
552 : {
553 14 : res = gdiv(gpow(gneg(L), s, prec2), gmul(L, gpow(z, a, prec2)));
554 14 : left = gaddgs(gmax(gen_0, gneg(real_i(L))), 1);
555 14 : top = gaddgs(gabs(imag_i(L), prec2), 1);
556 14 : right = gaddgs(gabs(L, prec2), 1);
557 : }
558 28 : w = expIPiC(gsubgs(s, 1), prec2);
559 28 : mleft = gneg(left);
560 28 : if (gexpo(imag_i(z)) < MB && gexpo(imag_i(a)) < MB && gexpo(imag_i(s)) < MB
561 7 : && gcmpgs(real_i(z), 1) < 0)
562 : { /* (z, s, a) real, z < 1 */
563 7 : LT = mkvec3(right, mkcomplex(right, top), mkcomplex(mleft, top));
564 7 : J = imag_i(gdiv(parintnumgaussadapt(f, LT, tabg, NB), w));
565 7 : LT = mkvec2(mkcomplex(mleft, top), mleft);
566 7 : J = gmul2n(gadd(J, imag_i(parintnumgaussadapt(fm, LT, tabg, NB))), 1);
567 7 : J = mulcxI(J);
568 : }
569 : else
570 : {
571 21 : GEN mtop = gneg(top);
572 21 : LT = mkvec3(right, mkcomplex(right, top), mkcomplex(mleft, top));
573 21 : J = gdiv(parintnumgaussadapt(f, LT, tabg, NB), w);
574 21 : LT = mkvec2(mkcomplex(mleft, top), mkcomplex(mleft, mtop));
575 21 : J = gadd(J, parintnumgaussadapt(fm, LT, tabg, NB));
576 21 : LT = mkvec3(mkcomplex(mleft, mtop), mkcomplex(right, mtop), right);
577 21 : J = gadd(J, gmul(parintnumgaussadapt(f, LT, tabg, NB), w));
578 : }
579 28 : J = gadd(J, gmul(gsub(w, ginv(w)), parintnumadapt(f, right, Linf, NULL, NB)));
580 28 : J = gdiv(J, PiI2(prec2)); if (res) J = gadd(J, res);
581 28 : return gneg(gmul(ggamma(gsubsg(1, s), prec2), J));
582 : }
583 : /* lerchphi(z,-k,a)=
584 : * -1/(z-1)*sum(q=0,k,(z/(z-1))^q*sum(j=0,q,(-1)^j*(j+a)^k*binomial(q,j)))
585 : * zetahurwitz(-k,a)=-B(k+1,a)/(k+1) */
586 : GEN
587 56 : lerchphi(GEN z, GEN s, GEN a, long prec)
588 : {
589 56 : pari_sp av = avma;
590 56 : if (!iscplx(z)) pari_err_TYPE("lerchphi", z);
591 56 : if (!iscplx(s)) pari_err_TYPE("lerchphi", s);
592 56 : if (!iscplx(a)) pari_err_TYPE("lerchphi", a);
593 56 : return gerepileupto(av, _lerchphi(z, s, a, prec));
594 : }
595 :
596 : GEN
597 14 : lerchzeta(GEN s, GEN a, GEN lam, long prec)
598 : {
599 14 : pari_sp av = avma;
600 14 : GEN z = gexp(gmul(PiI2(prec), lam), prec);
601 14 : if (!iscplx(z)) pari_err_TYPE("lerchzeta", z);
602 14 : if (!iscplx(s)) pari_err_TYPE("lerchzeta", s);
603 14 : if (!iscplx(a)) pari_err_TYPE("lerchzeta", a);
604 14 : if (hurwitz_cutoff(s, prec)) return lerchzetalarge(s, a, lam, prec);
605 7 : return gerepileupto(av, _lerchphi(z, s, a, prec));
606 : }
|