1 /* Copyright (C) 2000  The PARI group.
2 This file is part of the PARI/GP package.
3 
4 PARI/GP is free software; you can redistribute it and/or modify it under the
5 terms of the GNU General Public License as published by the Free Software
6 Foundation; either version 2 of the License, or (at your option) any later
7 version. It is distributed in the hope that it will be useful, but WITHOUT
8 ANY WARRANTY WHATSOEVER.
9 
10 Check the License for details. You should have received a copy of it, along
11 with the package; see the file 'COPYING'. If not, write to the Free Software
12 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
13 
14 /********************************************************************/
15 /**                                                                **/
16 /**                         MULTIPLE ZETA VALUES                   **/
17 /**                                                                **/
18 /********************************************************************/
19 #include "pari.h"
20 #include "paripriv.h"
21 
22 /********************************************************************/
23 /**                           CONVERSIONS                          **/
24 /********************************************************************/
25 /* vecsmall to binary */
26 static long
fd(GEN evec,long a,long b)27 fd(GEN evec, long a, long b)
28 {
29   long i, s = 0;
30   for (i = a; i <= b; i++) s = evec[i] | (s << 1);
31   return s;
32 }
33 /* 2^(b-a+1) + fd(evec) */
34 static long
fd1(GEN evec,long a,long b)35 fd1(GEN evec, long a, long b)
36 {
37   long i, s = 1;
38   for (i = a; i <= b; i++) s = evec[i] | (s << 1);
39   return s;
40 }
41 
42 /* m > 0 */
43 static GEN
mtoevec(GEN m)44 mtoevec(GEN m)
45 {
46   GEN e = vecsmall_append(binary_zv(m), 1);
47   e[1] = 0; return e;
48 }
49 static GEN
etoindex(GEN evec)50 etoindex(GEN evec) { return utoipos(fd1(evec, 2, lg(evec)-2)); }
51 
52 /* dual of evec[1..l-1] */
53 static GEN
revslice(GEN evec,long l)54 revslice(GEN evec, long l)
55 {
56   GEN res = cgetg(l, t_VECSMALL);
57   long i;
58   for (i = 1; i < l; i++) res[i] = 1 - evec[l-i];
59   return res;
60 }
61 
62 /* N.B. evec[ne] = 1 */
63 static GEN
etoa(GEN evec)64 etoa(GEN evec)
65 {
66   long c = 0, cold = 0, i = 1, l = lg(evec);
67   GEN avec = cgetg(l, t_VECSMALL);
68   while (++c < l)
69     if (evec[c] == 1) { avec[i++] = c - cold; cold = c; }
70   setlg(avec, i); return avec;
71 }
72 
73 static GEN
atoe(GEN avec)74 atoe(GEN avec)
75 {
76   long i, j, l = lg(avec), n = zv_sum(avec);
77   GEN evec = zero_zv(n);
78   for (i = 1, j = 0; i < l; i++) { long a = avec[i]; j += a; evec[j] = 1; }
79   return evec;
80 }
81 
82 
83 /* Conversions: types are evec, avec, m (if evec=0y1, m=(1y)_2).
84    fl is respectively 0, 1, 2. Type of a is autodetected. */
85 static GEN
zetamultconvert_i(GEN a,long fl)86 zetamultconvert_i(GEN a, long fl)
87 {
88   long i, l;
89   if (fl < 0 || fl > 2) pari_err_FLAG("zetamultconvert");
90   switch(typ(a))
91   {
92     case t_INT:
93       if (signe(a) <= 0) pari_err_TYPE("zetamultconvert",a);
94       switch (fl)
95       {
96         case 0: a = mtoevec(a); break;
97         case 1: a = etoa(mtoevec(a)); break;
98         case 2: a = icopy(a); break;
99       }
100       break;
101     case t_VEC: case t_COL: case t_VECSMALL:
102       a = gtovecsmall(a);
103       l = lg(a);
104       if (a[1] == 0)
105       {
106         if (!a[l-1]) pari_err_TYPE("zetamultconvert", a);
107         for (i = 1; i < l; i++)
108           if (a[i] & ~1UL) pari_err_TYPE("zetamultconvert", a);
109         switch (fl)
110         {
111           case 1: a = etoa(a); break;
112           case 2: a = etoindex(a);
113         }
114       }
115       else
116       {
117         if (a[1] < 2) pari_err_TYPE("zetamultconvert", a);
118         for (i = 2; i < l; i++)
119           if (a[i] <= 0) pari_err_TYPE("zetamultconvert", a);
120         switch (fl)
121         {
122           case 0: a = atoe(a); break;
123           case 2: a = etoindex(atoe(a));
124         }
125       }
126       break;
127     default: pari_err_TYPE("zetamultconvert", a);
128   }
129   return a;
130 }
131 GEN
zetamultconvert(GEN a,long fl)132 zetamultconvert(GEN a, long fl)
133 {
134   pari_sp av = avma;
135   return gerepileuptoleaf(av, zetamultconvert_i(a, fl));
136 }
137 
138 GEN
zetamultdual(GEN s)139 zetamultdual(GEN s)
140 {
141   pari_sp av = avma;
142   GEN e = zetamultconvert_i(s, 0);
143   return gerepileuptoleaf(av, etoa(revslice(e, lg(e))));
144 }
145 
146 /********************************************************************/
147 /**                  AVEC -> LIST OF STAR AVECS                    **/
148 /********************************************************************/
149 /* all star avecs corresponding to given t_VECSMALL avec */
150 static GEN
allstar(GEN avec)151 allstar(GEN avec)
152 {
153   long i, la = lg(avec), K = 1 << (la - 2);
154   GEN w = cgetg(K + 1, t_VEC);
155 
156   gel(w, 1) = avec;
157   for (i = 2; i < la; i++)
158   {
159     long L = 1 << (i - 2), j;
160     for (j = 1; j <= L; j++)
161     {
162       GEN u = gel(w,j), v;
163       long k, l = lg(u) - 1, ind = l - la + i;
164       gel(w, L + j) = v = cgetg(l, t_VECSMALL);
165       for (k = 1; k < ind; k++) v[k] = u[k];
166       v[ind] = u[ind] + u[ind + 1];
167       for (k = ind + 1; k < l; k++) v[k] = u[k+1];
168     }
169   }
170   return w;
171 }
172 /* same for multipolylogs */
173 static GEN
allstar2(GEN avec,GEN zvec)174 allstar2(GEN avec, GEN zvec)
175 {
176   long la = lg(avec), i, K = 1 << (la - 2);
177   GEN W = cgetg(K + 1, t_VEC), Z = cgetg(K + 1, t_VEC);
178 
179   gel(W, 1) = avec;
180   gel(Z, 1) = zvec = gtovec(zvec);
181   for (i = 2; i < la; i++)
182   {
183     long L = 1 << (i - 2), j;
184     for (j = 1; j <= L; j++)
185     {
186       GEN u = gel(W, j), w, y = gel(Z, j), z;
187       long l = lg(u) - 1, ind = l - la + i, k;
188       w = cgetg(l, t_VECSMALL);
189       z = cgetg(l, t_VEC);
190       for (k = 1; k < ind; k++) { w[k] = u[k]; gel(z, k) = gel(y, k); }
191       w[ind] = u[ind] + u[ind + 1];
192       gel(z, ind) = gmul(gel(y, ind), gel(y, ind + 1));
193       for (k = ind + 1; k < l; k++) { w[k] = u[k+1]; gel(z, k) = gel(y, k+1); }
194       gel(W, L + j) = w;
195       gel(Z, L + j) = z;
196     }
197   }
198   return mkvec2(W, Z);
199 }
200 
201 /**************************************************************/
202 /*              ZAGIER & RADCHENKO'S ALGORITHM                */
203 /**************************************************************/
204 /* accuracy 2^(-b); s << (b/log b)^2, l << b/sqrt(log b) */
205 static void
zparams(long * s,long * l,long b)206 zparams(long *s, long *l, long b)
207 {
208   double D = b * LOG10_2, E = 3*D/2 / log(3*D);
209   *s = (long)floor(E*E);
210   *l = (long)floor(sqrt(*s * log((double)*s)/2.));
211 }
212 
213 static GEN
zetamult_Zagier(GEN avec,long bit,long prec)214 zetamult_Zagier(GEN avec, long bit, long prec)
215 {
216   pari_sp av;
217   GEN ze, z = NULL, b;
218   long h, r, n, s, l, t = lg(avec) - 1;
219 
220   zparams(&s, &l, bit);
221   ze= cgetg(s + 1, t_VEC);
222   b = cgetg(l + 1, t_VEC);
223   for (r = 1; r <= s; r++) gel(ze,r) = cgetr(prec);
224   for (r = 1; r <= l; r++) { gel(b,r) = cgetr(prec); affur(0,gel(b,r)); }
225   affur(1, gel(b,1)); av = avma;
226   for (r = 1, h = -1; r <= t; r++)
227   {
228     long m, j = avec[r];
229     GEN q;
230 
231     h += j - 1; z = gen_0;
232     q = h? invr(itor(powuu(s,h), prec)): real_1(prec);
233     for (m = 1; m <= l; m++)
234     {
235       pari_sp av2;
236       GEN S = gel(b, m), C;
237       q = divru(q, s); av2 = avma;
238       C = binomialuu(h + m, m);
239       for (n = 1; n < m; n++)
240       { /* C = binom(h+m, m-n+1) */
241         S = gsub(S, mulir(C, gel(b, n)));
242         C = diviuexact(muliu(C, m-n+1), h+n);
243       }
244       affrr(divru(S, h+m), gel(b,m)); set_avma(av2);
245       z = gadd(z, gmul(gel(b, m), q));
246     }
247     for (m = s; m >= 1; m--)
248     {
249       GEN z1 = r == 1? ginv(powuu(m,j)): gdiv(gel(ze, m), powuu(m,j));
250       z1 = gadd(z, z1);
251       affrr(z, gel(ze, m)); z = z1;
252     }
253     set_avma(av);
254   }
255   return z;
256 }
257 
258 /* Compute t-mzvs; slower than Zagier's code for t=0 */
259 static GEN
zetamult_interpolate2_i(GEN avec,GEN t,long prec)260 zetamult_interpolate2_i(GEN avec, GEN t, long prec)
261 {
262   pari_sp av;
263   GEN a, b, ze, _1;
264   long i, j, n, s, l;
265 
266   zparams(&s, &l, prec2nbits(prec));
267   n = lg(avec) - 1;
268   a = zeromatcopy(n + 1, l);
269   b = zerovec(l + 1);
270   for (i = 1; i <= n; i++)
271   {
272     long h = avec[n + 1 - i];
273     if (i == 1) gel(b, h) = gen_1;
274     else
275       for (j = l + 1; j >= 1; j--)
276       {
277         if (j <= h) gel(b, j) = gen_0;
278         else gel(b, j) = gadd(gcoeff(a, i, j-h), gmul(t, gel(b, j-h)));
279       }
280     gcoeff(a, i+1, 1) = gel(b, 2); /* j = 1 */
281     for (j = 2; j <= l; j++)
282     { /* b[j+1] - sum_{0 <= u < j-1} binom(j,u) a[i+1,u+1]*/
283       pari_sp av = avma;
284       GEN S = gel(b, j + 1);
285       S = gsub(S, gcoeff(a, i+1, 1)); /* u = 0 */
286       if (j > 2) S = gsub(S, gmulgs(gcoeff(a, i+1, 2), j)); /* u = 1 */
287       if (j >= 4)
288       {
289         GEN C = utoipos(j*(j-1) / 2);
290         long u, U = (j-1)/2;
291         for (u = 2; u <= U; u++)
292         { /* C = binom(j, u) = binom(j, j-u) */
293           GEN A = gadd(gcoeff(a, i+1, u+1), gcoeff(a, i+1, j-u+1));
294           S = gsub(S, gmul(C, A));
295           C = diviuexact(muliu(C, j-u), u+1);
296         }
297         if (!odd(j)) S = gsub(S, gmul(C, gcoeff(a,i+1, j/2+1)));
298       }
299       gcoeff(a, i+1, j) = gerepileupto(av, gdivgs(S, j));
300     }
301   }
302   _1 = real_1(prec + EXTRAPRECWORD); av = avma;
303   ze = cgetg(n+1, t_VEC);
304   for (i = 1; i <= n; i++)
305   {
306     GEN S = gdivgs(gcoeff(a, n+2-i, 1), s), sj = utoipos(s);
307     for (j = 2; j <= l; j++)
308     {
309       sj = muliu(sj, s); /* = s^j */
310       S = gadd(S, gdiv(gcoeff(a, n+2-i, j), sj));
311     }
312     gel(ze, i) = S;
313   }
314   for (i = s; i >= 1; i--)
315   {
316     GEN b0 = divri(_1, powuu(i, avec[n])), z;
317     z = gel(ze,n); gel(ze,n) = gadd(z, b0);
318     for (j = n-1; j >= 1; j--)
319     {
320       b0 = gdiv(gadd(gmul(t, b0), z), powuu(i, avec[j]));
321       z = gel(ze,j); gel(ze,j) = gadd(gel(ze,j), b0);
322     }
323     if (gc_needed(av, 1))
324     {
325       if (DEBUGMEM>1) pari_warn(warnmem,"zetamult: i = %ld", i);
326       ze = gerepilecopy(av, ze);
327     }
328   }
329   return gel(ze, 1);
330 }
331 
332 /********************************************************************/
333 /**                      AKHILESH ALGORITHM                        **/
334 /********************************************************************/
335 /* a t_VECSMALL, upper bound for -log2(zeta(a)) */
336 static long
log2zeta_bound(GEN a)337 log2zeta_bound(GEN a)
338 { return ceil(-dbllog2(zetamult_Zagier(a, 32, LOWDEFAULTPREC))); }
339 /* ibin[n+1] = 1 / binom(2n, n) as a t_REAL */
340 static void
get_ibin(GEN * pibin,GEN * pibin1,long N,long prec)341 get_ibin(GEN *pibin, GEN *pibin1, long N, long prec)
342 {
343   GEN ibin, ibin1;
344   long n;
345   *pibin = ibin = cgetg(N + 2, t_VEC);
346   *pibin1= ibin1= cgetg(N + 2, t_VEC);
347   gel(ibin,1) = gel(ibin1,1) = gen_0; /* unused */
348   gel(ibin,2) = gel(ibin1,2) = real2n(-1,prec);
349   for (n = 2; n <= N; n++)
350   {
351     gel(ibin, n+1) = divru(mulru(gel(ibin, n), n), 4*n-2);
352     gel(ibin1, n+1) = divru(gel(ibin, n+1), n);
353   }
354 }
355 /**************************************************************/
356 /*                         ALL MZV's                          */
357 /**************************************************************/
358 
359 /* Generalization to Multiple Polylogarithms.
360 The basic function is polylogmult which takes two arguments
361 avec, as above, and zvec, the vector of z_j, and the result
362 is $\sum_{n_1>n_2>...>n_r>0}z_1^{n_1}...z_r^{n_r}/(n_1^a_1...n_r^{a_r})$. */
363 
364 /* Given admissible evec = xe_2....e_{k-1}y, (k>=2), compute a,b,v such that
365 evec = x{1}_{a-1}v{0}_{b-1}y with v empty or admissible.
366 Input: vector w=evec
367 Output: v=wmid, wini, wfin */
368 static void
findabvgen(GEN evec,long _0,long _1,GEN * pwmid,GEN * pwini,GEN * pwfin,long * pa,long * pb)369 findabvgen(GEN evec, long _0, long _1, GEN *pwmid, GEN *pwini, GEN *pwfin,
370            long *pa, long *pb)
371 {
372   long s = lg(evec) - 1, m, a, b, j, x = evec[1], y = evec[s];
373   GEN wmid, wini, wfin;
374   if (s == 2)
375   {
376     *pwmid = cgetg(1, t_VECSMALL);
377     *pwini = mkvecsmall(x);
378     *pwfin = mkvecsmall(y);
379     *pa = *pb = 1; return;
380   }
381   a = s - 1;
382   for (j = 1; j <= s - 2; j++) if (evec[j + 1] != _1) { a = j; break; }
383   *pa = a;
384   b = s - 1;
385   for (j = s - 2; j >= 1; j--) if (evec[j + 1] != _0) { b = s - 1 - j; break; }
386   *pb = b;
387 
388   *pwmid = wmid = a+b < s? vecslice(evec, a+1, s-b): cgetg(1, t_VECSMALL);
389   m = lg(wmid) - 1;
390   *pwini = wini = cgetg(a + m + 1, t_VECSMALL);
391   wini[1] = x; for (j = 2; j <= a; j++) wini[j] = _1;
392   for (; j <= a + m; j++) wini[j] = wmid[j-a];
393   *pwfin = wfin = cgetg(b + m + 1, t_VECSMALL);
394   for (j = 1; j <= m; j++) wfin[j] = wmid[j];
395   for (; j < b + m; j++) wfin[j] = _0;
396   wfin[j] = y;
397 }
398 
399 /* y != 0,1 */
400 static GEN
filllg1(GEN ibin1,GEN r1,GEN y,long N,long prec)401 filllg1(GEN ibin1, GEN r1, GEN y, long N, long prec)
402 {
403   GEN v, y1 = gsubgs(gmulsg(2, y), 1), y3 = gmul(y, gsubsg(1, y));
404   long n;
405 
406   v = cgetg(N + 2, t_VEC); gel(v, N + 1) = gen_0;
407   if (gcmpgs(gnorm(y3),1) > 0)
408   {
409     GEN y2 = gdiv(r1, y3);
410     for (n = N; n >= 1; n--)
411     {
412       pari_sp av2 = avma;
413       GEN z = gmul(y2, gsub(gel(v, n+1), gmul(y1, gel(ibin1, n+1))));
414       gel(v, n) = gerepileupto(av2, z);
415     }
416   }
417   else
418   {
419     pari_sp av0 = avma;
420     gel(v, 1) = gerepileupto(av0, glog(gdiv(y, gsubgs(y, 1)), prec));
421     for (n = 1; n < N; n++)
422     {
423       pari_sp av2 = avma;
424       GEN z = gadd(gmul(y3, gel(v, n)), gmul(y1, gel(ibin1, n+1)));
425       gel(v, n + 1) = gerepileupto(av2, z);
426     }
427   }
428   return v;
429 }
430 static GEN
fillrec(hashtable * H,GEN evec,long _0,long _1,GEN X,GEN pab,GEN r1,long N,long prec)431 fillrec(hashtable *H, GEN evec, long _0, long _1, GEN X, GEN pab, GEN r1,
432         long N, long prec)
433 {
434   long n, a, b, s, x0;
435   GEN xy1, x, y, r, wmid, wini, wfin, mid, ini, fin;
436   hashentry *ep = hash_search(H, evec);
437 
438   if (ep) return (GEN)ep->val;
439   findabvgen(evec, _0, _1, &wmid, &wini, &wfin, &a, &b);
440   x = gel(X, evec[1]); s = lg(evec)-1; /* > 1 */
441   y = gel(X, evec[s]);
442   mid = fillrec(H, wmid, _0, _1, X, pab, r1, N, prec);
443   ini = fillrec(H, wini, _0, _1, X, pab, r1, N, prec);
444   fin = fillrec(H, wfin, _0, _1, X, pab, r1, N, prec);
445   if (evec[1] == _0) { x0 = 1; xy1 = gdiv(r1, y); }
446   else { x0 = 0; xy1 = gdiv(r1, gmul(gsubsg(1, x), y)); }
447   r = cgetg(N+2, t_VEC); gel(r, N+1) = gen_0;
448   for (n = N; n > 1; n--)
449   {
450     pari_sp av = avma;
451     GEN t = gmul(gel(ini, n+1), gmael(pab, n, a));
452     GEN u = gadd(gmul(gel(fin, n+1), gmael(pab, n, b)), gel(mid, n+1));
453     GEN v = gdiv(x0? gadd(t, u): gsub(t, u), gmael(pab, n, a+b));
454     gel(r, n) = gerepileupto(av, gmul(xy1, gadd(gel(r, n+1), v)));
455   }
456   { /* n = 1 */
457     pari_sp av = avma;
458     GEN t = gel(ini, 2), u = gadd(gel(fin, 2), gel(mid, 2));
459     GEN v = x0? gadd(t, u): gsub(t, u);
460     gel(r,1) = gerepileupto(av, gmul(xy1, gadd(gel(r,2), v)));
461   }
462   hash_insert(H, (void*)evec, (void*)r); return r;
463 }
464 
465 static GEN
aztoe(GEN avec,GEN zvec,long prec)466 aztoe(GEN avec, GEN zvec, long prec)
467 {
468   GEN y, E, u = subsr(1, real2n(10-prec2nbits(prec), LOWDEFAULTPREC));
469   long i, l = lg(avec);
470 
471   E = cgetg(l, t_VEC); if (l == 1) return E;
472   y = gen_1;
473   for (i = 1; i < l; i++)
474   {
475     long a = avec[i];
476     GEN e, zi = gel(zvec, i);
477     if (a <= 0 || (a == 1 && i == 1 && gequal1(zi)))
478       pari_err_TYPE("polylogmult [divergent]", avec);
479     if (gequal0(zi)) return NULL;
480     gel(E, i) = e = zerovec(a);
481     gel(e, a) = y = gdiv(y, zi);
482     if (gcmp(gnorm(y), u) < 0) pari_err_TYPE("polylogmult [divergent]", zvec);
483   }
484   return shallowconcat1(E);
485 }
486 
487 /***********************************************************/
488 /* Special case of zvec = [1,1,...], i.e., zetamult.       */
489 /***********************************************************/
490 static void
findabvgens(GEN evec,GEN * pwmid,GEN * pwini,GEN * pwfin,long * pa,long * pb)491 findabvgens(GEN evec, GEN *pwmid, GEN *pwini, GEN *pwfin, long *pa, long *pb)
492 {
493   GEN wmid, wini, wfin;
494   long s = lg(evec) - 1, a, b, j, m;
495   if (s == 2)
496   {
497     *pwmid = cgetg(1, t_VECSMALL);
498     *pwini = mkvecsmall(0);
499     *pwfin = mkvecsmall(1);
500     *pa = *pb = 1; return;
501   }
502   a = s - 1;
503   for (j = 1; j <= s - 2; j++) if (!evec[j + 1]) { a = j; break; }
504   *pa = a;
505   b = s - 1;
506   for (j = s - 2; j >= 1; j--) if (evec[j + 1]) { b = s - 1 - j; break; }
507   *pb = b;
508 
509   *pwmid = wmid = a+b < s? vecslice(evec, a+1, s-b): cgetg(1, t_VECSMALL);
510   m = lg(wmid) - 1;
511   *pwini = wini = cgetg(a + m + 1, t_VECSMALL);
512   wini[1] = 0; for (j = 2; j <= a; j++) wini[j] = 1;
513   for (; j <= a + m; j++) wini[j] = wmid[j-a];
514   *pwfin = wfin = cgetg(b + m + 1, t_VECSMALL);
515   for (j = 1; j <= m; j++) wfin[j] = wmid[j];
516   for (; j < b + m; j++) wfin[j] = 0;
517   wfin[j] = 1;
518 }
519 static GEN
fillrecs(hashtable * H,GEN evec,GEN pab,long N,long prec)520 fillrecs(hashtable *H, GEN evec, GEN pab, long N, long prec)
521 {
522   long n, a, b;
523   GEN r, wmid, wini, wfin, mid, ini, fin;
524   hashentry *ep = hash_search(H, evec);
525 
526   if (ep) return (GEN)ep->val;
527   findabvgens(evec, &wmid, &wini, &wfin, &a, &b);
528   mid = fillrecs(H, wmid, pab, N, prec);
529   ini = fillrecs(H, wini, pab, N, prec);
530   fin = fillrecs(H, wfin, pab, N, prec);
531   r = cgetg(N + 2, t_VEC); gel(r, N+1) = gen_0;
532   for (n = N; n > 1; n--)
533   {
534     GEN z = cgetr(prec);
535     pari_sp av = avma;
536     GEN t = mpmul(gel(ini, n+1), gmael(pab, n, a));
537     GEN u = mpadd(mpmul(gel(fin, n+1), gmael(pab, n, b)), gel(mid,n+1));
538     GEN v = mpdiv(mpadd(t, u), gmael(pab, n, a+b));
539     mpaff(mpadd(gel(r, n+1), v), z); set_avma(av); gel(r,n) = z;
540   }
541   { /* n = 1 */
542     GEN z = cgetr(prec);
543     pari_sp av = avma;
544     GEN t = gel(ini,2), u = mpadd(gel(fin,2), gel(mid,2)), v = mpadd(t, u);
545     mpaff(mpadd(gel(r, 2), v), z); set_avma(av); gel(r,1) = z;
546   }
547   hash_insert(H, (void*)evec, (void*)r); return r;
548 }
549 /* [n, ..., n^k] */
550 static GEN
powersu(ulong n,long k)551 powersu(ulong n, long k)
552 {
553   GEN v, gn = utoipos(n);
554   long i, l = k+1;
555   v = cgetg(l, t_VEC); gel(v,1) = gn;
556   for (i = 2; i < l; i++) gel(v,i) = muliu(gel(v,i-1), n);
557   return v;
558 }
559 /* n^a = pab[n][a] */
560 static GEN
get_pab(long N,long k)561 get_pab(long N, long k)
562 {
563   GEN v = cgetg(N+1, t_VEC);
564   long j;
565   gel(v, 1) = gen_0; /* not needed */
566   for (j = 2; j <= N; j++) gel(v, j) = powersu(j, k);
567   return v;
568 }
569 static hashtable *
zetamult_hash(long _0,long _1,GEN ibin,GEN ibin1)570 zetamult_hash(long _0, long _1, GEN ibin, GEN ibin1)
571 {
572   hashtable *H = hash_create(4096, (ulong(*)(void*))&hash_zv,
573                                    (int(*)(void*,void*))&zv_equal, 1);
574   hash_insert(H, (void*)cgetg(1, t_VECSMALL), (void*)ibin);
575   hash_insert(H, (void*)mkvecsmall(_0), (void*)ibin1);
576   hash_insert(H, (void*)mkvecsmall(_1), (void*)ibin1); return H;
577 }
578 /* Akhilesh recursive algorithm, #a > 1;
579  * e t_VECSMALL, prec final precision, bit required bitprecision */
580 static GEN
zetamult_Akhilesh(GEN e,long bit,long prec)581 zetamult_Akhilesh(GEN e, long bit, long prec)
582 {
583   long k = lg(e) - 1, N = 1 + bit/2, prec2 = nbits2prec(bit);
584   GEN r, pab, ibin, ibin1;
585   hashtable *H;
586 
587   get_ibin(&ibin, &ibin1, N, prec2);
588   pab = get_pab(N, k);
589   H = zetamult_hash(0, 1, ibin, ibin1);
590   r = fillrecs(H, e, pab, lg(pab)-1, prec2);
591   if (DEBUGLEVEL) err_printf("polylogmult: k = %ld, %ld nodes\n", k, H->nb);
592   return gprec_wtrunc(gel(r,1), prec);
593 }
594 /* evec t_VEC */
595 static GEN
zetamultevec(GEN evec,long prec)596 zetamultevec(GEN evec, long prec)
597 {
598   pari_sp av = avma;
599   double *x, *y, z = 0;
600   long i, j, l, lH, bitprec, prec2, N, _0 = 0, _1 = 0, k = lg(evec) - 1;
601   GEN r1, r, pab, ibin, ibin1, X, Evec, v;
602   hashtable *H;
603 
604   if (k == 0) return gen_1;
605   v = vec_equiv(evec); l = lg(v);
606   Evec = cgetg(k+1, t_VECSMALL);
607   X = cgetg(l + 2, t_VEC); /* our alphabet */
608   for (i = lH = 1; i < l; i++)
609   {
610     GEN vi = gel(v,i), xi = gel(evec, vi[1]);
611     long li = lg(vi);
612     gel(X,i) = xi;
613     if (!_0 && gequal0(xi)) _0 = i;
614     else if (!_1 && gequal1(xi)) _1 = i;
615     for (j = 1; j < li; j++) Evec[vi[j]] = i;
616   }
617   /* add 0,1 if needed */
618   if (!_0) { gel(X, i) = gen_0; _0 = i++; }
619   if (!_1) { gel(X, i) = gen_1; _1 = i++; }
620   l = i; setlg(X, l);
621   av = avma;
622   x = (double*)stack_malloc_align(l * sizeof(double), sizeof(double));
623   y = (double*)stack_malloc_align(l * sizeof(double), sizeof(double));
624   for (j = 1; j < l; j++)
625   {
626     GEN t = gel(X,j);
627     x[j] = (j == _1)? 0: -dbllog2(gsubsg(1, t));
628     y[j] = (j == _0)? 0: -dbllog2(t);
629   }
630   for (i = 1; i < l; i++)
631     for (j = i+1; j < l; j++) z = maxdd(z, x[i] + y[j]);
632   set_avma(av);
633   if (z >= 2) pari_err_IMPL("polylogmult in this range");
634   bitprec = prec2nbits(prec) + 64*(1 + (k >> 5));
635   N = 1 + bitprec/ (2 - z);
636   bitprec += z * N;
637   prec2 = nbits2prec(bitprec);
638   X = gprec_wensure(X, prec2);
639   get_ibin(&ibin, &ibin1, N, prec2);
640   pab = get_pab(N, k);
641   H = zetamult_hash(_0, _1, ibin, ibin1);
642   r1 = real_1(prec2);
643   for (i = 1; i < l; i++)
644     if (i != _0 && i != _1)
645       hash_insert(H, mkvecsmall(i), filllg1(ibin1, r1, gel(X,i), N, prec2));
646   r = fillrec(H, Evec, _0, _1, X, pab, r1, N, prec2);
647   if (DEBUGLEVEL) err_printf("polylogmult: k = %ld, %ld nodes\n", k, H->nb);
648   return gprec_wtrunc(gel(r,1), prec);
649 }
650 
651 /* a t_VECSMALL */
652 static GEN
zetamult_i(GEN a,long prec)653 zetamult_i(GEN a, long prec)
654 {
655   long r = lg(a)-1, k, bit;
656   if (r == 0) return gen_1;
657   if (r == 1) return szeta(a[1], prec);
658   bit = prec2nbits(prec);
659   if (bit <= 128)
660     return zetamult_Zagier(a, bit, prec + EXTRAPRECWORD);
661   k = zv_sum(a);
662   if (((double)r) / (k*k) * bit / log((double)10*bit) < 0.5)
663     return zetamult_Zagier(a, bit, prec + EXTRAPRECWORD);
664   bit += maxss(log2zeta_bound(a), 64);
665   return zetamult_Akhilesh(atoe(a), bit, prec);
666 }
667 GEN
zetamult(GEN s,long prec)668 zetamult(GEN s, long prec)
669 {
670   pari_sp av0 = avma, av;
671   GEN z, avec, r = cgetr(prec);
672 
673   av = avma; avec = zetamultconvert_i(s,1);
674   if (lg(avec) == 1) return gc_const(av0, gen_1);
675   z = zetamult_i(avec, prec); affrr(z, r); return gc_const(av, r);
676 }
677 
678 /* If star = NULL: MZV, otherwise Yamamoto interpolation (MZSV for t=1) */
679 GEN
zetamult_interpolate(GEN s,GEN t,long prec)680 zetamult_interpolate(GEN s, GEN t, long prec)
681 {
682   pari_sp av = avma, av2;
683   long i, k, l, la, bit;
684   GEN avec, v, V;
685 
686   if (!t) return zetamult(s, prec);
687   avec = zetamultconvert_i(s, 1); k = zv_sum(avec);
688   bit = prec2nbits(prec);
689   if (bit <= 128 || k > 20 || (bit >> k) < 4)
690     return zetamult_interpolate2_i(vecsmall_reverse(avec), t, prec);
691   v = allstar(avec); l = lg(v); la = lg(avec);
692   V = cgetg(la, t_VEC);
693   for (i = 1; i < la; i++)
694   { gel(V,i) = cgetr(prec + EXTRAPRECWORD); affur(0, gel(V,i)); }
695   av2 = avma;
696   for (i = 1; i < l; i++, set_avma(av2))
697   {
698     GEN a = gel(v,i); /* avec */
699     long n = lg(a)-1; /* > 0 */
700     affrr(addrr(gel(V,n), zetamult_i(a, prec)), gel(V,n));
701   }
702   return gerepileupto(av, poleval(vecreverse(V),t));
703 }
704 
705 
706 GEN
polylogmult(GEN a,GEN z,long prec)707 polylogmult(GEN a, GEN z, long prec)
708 {
709   pari_sp av = avma;
710   if (!z) return zetamult(a, prec);
711   switch(typ(a))
712   {
713     case t_VEC:
714     case t_COL: a = gtovecsmall(a); break;
715     case t_VECSMALL: break;
716     default: pari_err_TYPE("polylogmult", a);
717              return NULL;/*LCOV_EXCL_LINE*/
718   }
719   switch (typ(z))
720   {
721     case t_INT: case t_FRAC: case t_REAL: case t_COMPLEX:
722       z = mkvec(z); break;
723     case t_VEC: case t_COL: break;
724     case t_VECSMALL: z = zv_to_ZV(z); break;
725     default: pari_err_TYPE("polylogmult [z]", z);
726   }
727   if (lg(z) != lg(a))
728     pari_err_TYPE("polylogmult [#s != #z]", mkvec2(a,z));
729   return gerepilecopy(av, zetamultevec(aztoe(a,z,prec), prec));
730 }
731 
732 GEN
polylogmult_interpolate(GEN s,GEN zvec,GEN t,long prec)733 polylogmult_interpolate(GEN s, GEN zvec, GEN t, long prec)
734 {
735   pari_sp av = avma;
736   GEN V, avec, A, AZ, Z;
737   long i, la, l;
738 
739   if (!t) return polylogmult(s, zvec, prec);
740   if (!zvec) return zetamult_interpolate(s, t, prec);
741   avec = zetamultconvert_i(s, 1); la = lg(avec);
742   AZ = allstar2(avec, zvec);
743   A = gel(AZ, 1); l = lg(A);
744   Z = gel(AZ, 2); V = zerovec(la-1);
745   for (i = 1; i < l; i++)
746   {
747     pari_sp av2 = avma;
748     GEN a = gel(A,i), e = aztoe(a, gel(Z,i), prec);
749     long n = lg(a)-1; /* > 0 */
750     gel(V,n) = gerepileupto(av2, gadd(gel(V,n), zetamultevec(e, prec)));
751   }
752   return gerepileupto(av, poleval(vecreverse(V),t));
753 }
754 
755 /**************************************************************/
756 /*                           ALL MZV's                        */
757 /**************************************************************/
758 
759 /* Given admissible evec w = 0e_2....e_{k-1}1, compute a,b,v such that
760  * w=0{1}_{b-1}v{0}_{a-1}1 with v empty or admissible.
761  * Input: binary vector evec */
762 static void
findabv(GEN w,long * pa,long * pb,long * pminit,long * pmmid,long * pmfin)763 findabv(GEN w, long *pa, long *pb, long *pminit, long *pmmid, long *pmfin)
764 {
765   long le = lg(w) - 2;
766   if (le == 0)
767   {
768     *pa = 1;
769     *pb = 1;
770     *pminit = 2;
771     *pmfin = 2;
772     *pmmid = 1;
773   }
774   else
775   {
776     long a, b, j, lv;
777     for (j = 1; j <= le; j++)
778       if (!w[j+1]) break;
779     *pb = b = j;
780     for (j = le; j >= 1; j--)
781       if (w[j+1]) break;
782     *pa = a = le + 1 - j;
783     lv = le + 2 - a - b;
784     if (lv > 0)
785     {
786       long v = fd(w, b + 1, le - a + 2), u = v + (1 << (lv-1));
787       *pminit = (((1 << b) - 1) << (lv - 1)) + (v/2) + 2;
788       *pmfin = (u << (a - 1)) + 2;
789       *pmmid = (u >> 1) + 2;
790     }
791     else
792     {
793       *pminit = (1 << (b - 1)) + 1;
794       *pmfin = (a == 1) ? 2 : (1 << (a - 2)) + 2;
795       *pmmid = 1;
796     }
797   }
798 }
799 
800 /* Returns L:
801 * L[1] contains zeta(emptyset)_{n-1,n-1},
802 * L[2] contains zeta({0})_{n-1,n-1}=zeta({1})_{n-1,n-1} for n >= 2,
803 * L[m+2][n] : 1 <= m < 2^{k-2}, 1 <= n <= N + 1
804 * contains zeta(w)_{n-1,n-1}, w corresponding to m,n
805 * L[m+2] : 2^{k-2} <= m < 2^{k-1} contains zeta(w), w corresponding to m
806 (code: w=0y1 iff m=1y). */
807 static GEN
fillL(long k,long bitprec)808 fillL(long k, long bitprec)
809 {
810   long N = 1 + bitprec/2, prec = nbits2prec(bitprec);
811   long s, j, n, m, K = 1 << (k - 1), K2 = K/2;
812   GEN p1, p2, pab = get_pab(N, k), L = cgetg(K + 2, t_VEC);
813 
814   get_ibin(&gel(L,1), &gel(L,2), N, prec);
815   for (m = 1; m < K2; m++)
816   {
817     gel(L, m+2) = p1 = cgetg(N+1, t_VEC);
818     for (n = 1; n < N; n++) gel(p1, n) = cgetr(prec);
819     gel(p1, n) = gen_0;
820   }
821   for (m = K2; m < K; m++) gel(L, m+2) = utor(0, prec);
822   for (s = 2; s <= k; s++)
823   { /* Assume length evec < s filled */
824     /* If evec = 0e_2...e_{s-1}1 then m = (1e_2...e_{s-1})_2 */
825     GEN w = cgetg(s, t_VECSMALL);
826     long M = 1 << (s - 2);
827     pari_sp av = avma;
828     for (m = M; m < 2*M; m++)
829     {
830       GEN pinit, pfin, pmid;
831       long comp, a, b, mbar, minit, mfin, mmid, mc;
832       p1 = gel(L, m + 2);
833       for (j = s - 1, mc = m, mbar = 1; j >= 2; j--, mc >>= 1)
834       {
835         w[j] = mc & 1;
836         mbar = (1 - w[j]) | (mbar << 1);
837       }
838       /* m, mbar are dual; handle smallest, copy the other */
839       comp = mbar - m; if (comp < 0) continue; /* m > mbar */
840       if (comp)
841       {
842         p2 = gel(L, mbar + 2);
843         setisclone(p2); /* flag as dual */
844       }
845       else
846         p2 = NULL; /* no copy needed if m = mbar */
847       findabv(w, &a,&b,&minit,&mmid,&mfin);
848       pinit= gel(L, minit);
849       pfin = gel(L, mfin);
850       pmid = gel(L, mmid);
851       for (n = N-1; n > 1; n--, set_avma(av))
852       {
853         GEN t = mpmul(gel(pinit,n+1), gmael(pab, n, b));
854         GEN u = mpmul(gel(pfin, n+1), gmael(pab, n, a));
855         GEN v = gel(pmid, n+1), S = s < k ? gel(p1, n+1): p1;
856         S = mpadd(S, mpdiv(mpadd(mpadd(t, u), v), gmael(pab, n, a+b)));
857         mpaff(S, s < k ? gel(p1, n) : p1);
858         if (p2 && s < k) mpaff(S, gel(p2, n));
859       }
860       { /* n = 1: same formula simplifies */
861         GEN t = gel(pinit,2), u = gel(pfin,2), v = gel(pmid,2);
862         GEN S = s < k ? gel(p1,2): p1;
863         S = mpadd(S, mpadd(mpadd(t, u), v));
864         mpaff(S, s < k ? gel(p1,1) : p1);
865         if (p2 && s < k) mpaff(S, gel(p2, 1));
866         set_avma(av);
867       }
868       if (p2 && s == k) mpaff(p1, p2);
869     }
870   }
871   return L;
872 }
873 
874 /* bit 1 of flag unset: full, otherwise up to duality (~ half)
875  * bit 2 of flag unset: all <= k, otherwise only k
876  * half: 2^(k-3)+ delta_{k even} * 2^(k/2-2), sum = 2^(k-2)+2^(floor(k/2)-1)-1
877  * full: 2^(k-2); sum = 2^(k-1)-1 */
878 static GEN
zetamultall_i(long k,long flag,long prec)879 zetamultall_i(long k, long flag, long prec)
880 {
881   GEN res, ind, L = fillL(k, prec2nbits(prec) + 32);
882   long m, K2 = 1 << (k-2), n = lg(L) - 1, m0 = (flag & 4L) ? K2 : 1;
883 
884   if (!(flag & 2L))
885   {
886     res = cgetg(n - m0, t_VEC);
887     ind = cgetg(n - m0, t_VECSMALL);
888     for (m = m0; m < n - 1; m++)
889     {
890       gel(res, m - m0 + 1) = m < K2 ? gmael(L, m + 2, 1) : gel(L, m + 2);
891       ind[m - m0 + 1] = m;
892     }
893   }
894   else
895   { /* up to duality */
896     long nres, c;
897     if (k == 2) nres = 1;
898     else if (!(flag & 2L))
899       nres = (1 << (k - 2)) + (1 << ((k/2) - 1)) - 1;
900     else
901       nres = (1 << (k - 1));
902     res = cgetg(nres + 1, t_VEC);
903     ind = cgetg(nres + 1, t_VECSMALL);
904     for (m = m0, c = 1; m < n - 1; m++)
905     {
906       GEN z = gel(L,m+2);
907       if (isclone(z)) continue; /* dual */
908       if (m < K2) z = gel(z,1);
909       gel(res, c) = z;
910       ind[c] = m; c++;
911     }
912     setlg(res, c);
913     setlg(ind, c);
914   }
915   return mkvec2(res, ind);
916 }
917 
918 /* fd(e, 2, lg(e)-2), e = atoe(avec) */
919 static long
atom(GEN avec)920 atom(GEN avec)
921 {
922   long i, m, l = lg(avec);
923   if (l < 3) return 0;
924   m = 1; /* avec[1] != 0 */
925   for (i = 2; i < l-1; i++) m = (m << avec[i]) + 1;
926   return m << (avec[i]-1);
927 }
928 static long
atoind(GEN avec,long flag)929 atoind(GEN avec, long flag)
930 { return atom(avec) + (flag? 1: (1 << (zv_sum(avec) - 2))); }
931 /* If flag is unset, L has all k1 <= k, otherwise only k */
932 static GEN
zetamultstar_i(GEN L,GEN avec,long flag)933 zetamultstar_i(GEN L, GEN avec, long flag)
934 {
935   GEN s = allstar(avec), S = gen_0;
936   long i, l = lg(s);
937   for (i = 1; i < l; i++) S = gadd(S, gel(L, atoind(gel(s,i), flag)));
938   return S;
939 }
940 
941 /* bit 0: notstar/star
942  * bit 1: full/half (ignored if star, always full)
943  * bit 2: all <= k / only k
944  * bit 3: without / with index */
945 GEN
zetamultall(long k,long flag,long prec)946 zetamultall(long k, long flag, long prec)
947 {
948   pari_sp av = avma;
949   GEN Lind, L, res;
950   long K, k1, ct, fl;
951 
952   if (flag < 0 || flag > 15) pari_err_FLAG("zetamultall");
953   if (k < 1) pari_err_DOMAIN("zetamultall", "k", "<", gen_1, stoi(k));
954   if (k >= 64) pari_err_OVERFLOW("zetamultall");
955   if (!(flag & 1L))
956   { /* not star */
957     Lind = zetamultall_i(k, flag, prec);
958     res = (flag & 8L)? Lind : gel(Lind, 1);
959     return gerepilecopy(av, res);
960   }
961   /* star */
962   fl = flag & 4L; /* 4 if k, else 0 (all <= k) */
963   Lind = gerepilecopy(av, zetamultall_i(k, fl, prec)); /* full */
964   L = gel(Lind, 1);
965   K = 1 << (k - 2);
966   res = cgetg(fl? K+1: 2*K, t_VEC);
967   for (ct = 1, k1 = fl? k: 2; k1 <= k; k1++)
968   {
969     GEN w = cgetg(k1 + 1, t_VECSMALL);
970     long M = 1 << (k1 - 1), m;
971     for (m = 1; m <= M; m += 2)
972     {
973       pari_sp av = avma;
974       long j, mc = m;
975       for (j = k1; j >= 1; j--) { w[j] = mc & 1; mc >>= 1; }
976       gel(res, ct++) = gerepileupto(av, zetamultstar_i(L, etoa(w), fl));
977     }
978   }
979   if (flag & 8L) res = mkvec2(res, gel(Lind, 2));
980   return gerepilecopy(av, res);
981 }
982