Line data Source code
1 : /* Copyright (C) 2007 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 : /*******************************************************************/
19 : /* */
20 : /* ZX */
21 : /* */
22 : /*******************************************************************/
23 : void
24 366274 : RgX_check_QX(GEN x, const char *s)
25 366274 : { if (!RgX_is_QX(x)) pari_err_TYPE(stack_strcat(s," [not in Q[X]]"), x); }
26 : void
27 2713011 : RgX_check_ZX(GEN x, const char *s)
28 2713011 : { if (!RgX_is_ZX(x)) pari_err_TYPE(stack_strcat(s," [not in Z[X]]"), x); }
29 : long
30 107322 : ZX_max_lg(GEN x)
31 : {
32 107322 : long i, l = 0, lx = lg(x);
33 648375 : for (i = 2; i < lx; i++) l = maxss(l, lgefint(gel(x,i)));
34 107322 : return l;
35 : }
36 :
37 : GEN
38 41389848 : ZX_add(GEN x, GEN y)
39 : {
40 : long lx,ly,i;
41 : GEN z;
42 41389848 : lx = lg(x); ly = lg(y); if (lx < ly) swapspec(x,y, lx,ly);
43 41389848 : z = cgetg(lx,t_POL); z[1] = x[1];
44 317242588 : for (i=2; i<ly; i++) gel(z,i) = addii(gel(x,i),gel(y,i));
45 83269841 : for ( ; i<lx; i++) gel(z,i) = icopy(gel(x,i));
46 41269593 : if (lx == ly) z = ZX_renormalize(z, lx);
47 41269753 : if (!lgpol(z)) { set_avma((pari_sp)(z + lx)); return pol_0(varn(x)); }
48 40053413 : return z;
49 : }
50 :
51 : GEN
52 29589581 : ZX_sub(GEN x,GEN y)
53 : {
54 29589581 : long i, lx = lg(x), ly = lg(y);
55 : GEN z;
56 29589581 : if (lx >= ly)
57 : {
58 29135153 : z = cgetg(lx,t_POL); z[1] = x[1];
59 118272008 : for (i=2; i<ly; i++) gel(z,i) = subii(gel(x,i),gel(y,i));
60 29090282 : if (lx == ly)
61 : {
62 23444997 : z = ZX_renormalize(z, lx);
63 23444595 : if (!lgpol(z)) { set_avma((pari_sp)(z + lx)); z = pol_0(varn(x)); }
64 : }
65 : else
66 17419911 : for ( ; i<lx; i++) gel(z,i) = icopy(gel(x,i));
67 : }
68 : else
69 : {
70 454428 : z = cgetg(ly,t_POL); z[1] = y[1];
71 1199299 : for (i=2; i<lx; i++) gel(z,i) = subii(gel(x,i),gel(y,i));
72 1409285 : for ( ; i<ly; i++) gel(z,i) = negi(gel(y,i));
73 : }
74 29585639 : return z;
75 : }
76 :
77 : GEN
78 599057 : ZX_neg(GEN x)
79 : {
80 599057 : long i, l = lg(x);
81 599057 : GEN y = cgetg(l,t_POL);
82 2468682 : y[1] = x[1]; for(i=2; i<l; i++) gel(y,i) = negi(gel(x,i));
83 599138 : return y;
84 : }
85 : GEN
86 5397267 : ZX_copy(GEN x)
87 : {
88 5397267 : long i, l = lg(x);
89 5397267 : GEN y = cgetg(l, t_POL);
90 5397275 : y[1] = x[1];
91 22125069 : for (i=2; i<l; i++)
92 : {
93 16727810 : GEN c = gel(x,i);
94 16727810 : gel(y,i) = lgefint(c) == 2? gen_0: icopy(c);
95 : }
96 5397259 : return y;
97 : }
98 :
99 : GEN
100 56464 : scalar_ZX(GEN x, long v)
101 : {
102 : GEN z;
103 56464 : if (!signe(x)) return pol_0(v);
104 4558 : z = cgetg(3, t_POL);
105 4558 : z[1] = evalsigne(1) | evalvarn(v);
106 4558 : gel(z,2) = icopy(x); return z;
107 : }
108 :
109 : GEN
110 23009 : scalar_ZX_shallow(GEN x, long v)
111 : {
112 : GEN z;
113 23009 : if (!signe(x)) return pol_0(v);
114 22725 : z = cgetg(3, t_POL);
115 22725 : z[1] = evalsigne(1) | evalvarn(v);
116 22725 : gel(z,2) = x; return z;
117 : }
118 :
119 : GEN
120 87350 : ZX_Z_add(GEN y, GEN x)
121 : {
122 : long lz, i;
123 87350 : GEN z = cgetg_copy(y, &lz);
124 87350 : if (lz == 2) { set_avma((pari_sp)(z + 2)); return scalar_ZX(x,varn(y)); }
125 76612 : z[1] = y[1];
126 76612 : gel(z,2) = addii(gel(y,2),x);
127 1773469 : for(i=3; i<lz; i++) gel(z,i) = icopy(gel(y,i));
128 76893 : if (lz==3) z = ZX_renormalize(z,lz);
129 76612 : return z;
130 : }
131 : GEN
132 94656 : ZX_Z_add_shallow(GEN y, GEN x)
133 : {
134 : long lz, i;
135 94656 : GEN z = cgetg_copy(y, &lz);
136 94659 : if (lz == 2) { set_avma((pari_sp)(z + 2)); return scalar_ZX_shallow(x,varn(y)); }
137 94414 : z[1] = y[1];
138 94414 : gel(z,2) = addii(gel(y,2),x);
139 552954 : for(i=3; i<lz; i++) gel(z,i) = gel(y,i);
140 94399 : if (lz==3) z = ZX_renormalize(z,lz);
141 94397 : return z;
142 : }
143 :
144 : GEN
145 181745 : ZX_Z_sub(GEN y, GEN x)
146 : {
147 : long lz, i;
148 181745 : GEN z = cgetg_copy(y, &lz);
149 181745 : if (lz == 2)
150 : { /* scalarpol(negi(x), v) */
151 441 : long v = varn(y);
152 441 : set_avma((pari_sp)(z + 2));
153 441 : if (!signe(x)) return pol_0(v);
154 441 : z = cgetg(3,t_POL);
155 441 : z[1] = evalvarn(v) | evalsigne(1);
156 441 : gel(z,2) = negi(x); return z;
157 : }
158 181304 : z[1] = y[1];
159 181304 : gel(z,2) = subii(gel(y,2),x);
160 909423 : for(i=3; i<lz; i++) gel(z,i) = icopy(gel(y,i));
161 181304 : if (lz==3) z = ZX_renormalize(z,lz);
162 181304 : return z;
163 : }
164 :
165 : GEN
166 2714521 : Z_ZX_sub(GEN x, GEN y)
167 : {
168 : long lz, i;
169 2714521 : GEN z = cgetg_copy(y, &lz);
170 2714557 : if (lz == 2) { set_avma((pari_sp)(z + 2)); return scalar_ZX(x,varn(y)); }
171 2714557 : z[1] = y[1];
172 2714557 : gel(z,2) = subii(x, gel(y,2));
173 13602075 : for(i=3; i<lz; i++) gel(z,i) = negi(gel(y,i));
174 2714993 : if (lz==3) z = ZX_renormalize(z,lz);
175 2714656 : return z;
176 : }
177 :
178 : GEN
179 5083768 : ZX_Z_divexact(GEN y,GEN x)
180 : {
181 5083768 : long i, l = lg(y);
182 5083768 : GEN z = cgetg(l,t_POL); z[1] = y[1];
183 32470984 : for(i=2; i<l; i++) gel(z,i) = diviiexact(gel(y,i),x);
184 5081408 : return z;
185 : }
186 :
187 : GEN
188 977795 : ZX_divuexact(GEN y, ulong x)
189 : {
190 977795 : long i, l = lg(y);
191 977795 : GEN z = cgetg(l,t_POL); z[1] = y[1];
192 9684353 : for(i=2; i<l; i++) gel(z,i) = diviuexact(gel(y,i),x);
193 977795 : return z;
194 : }
195 :
196 : GEN
197 112 : zx_z_divexact(GEN y, long x)
198 : {
199 112 : long i, l = lg(y);
200 112 : GEN z = cgetg(l,t_VECSMALL); z[1] = y[1];
201 595 : for (i=2; i<l; i++) z[i] = y[i]/x;
202 112 : return z;
203 : }
204 :
205 : GEN
206 17810519 : ZX_Z_mul(GEN y,GEN x)
207 : {
208 : GEN z;
209 : long i, l;
210 17810519 : if (!signe(x)) return pol_0(varn(y));
211 14814797 : l = lg(y); z = cgetg(l,t_POL); z[1] = y[1];
212 163000695 : for(i=2; i<l; i++) gel(z,i) = mulii(gel(y,i),x);
213 14809647 : return z;
214 : }
215 :
216 : GEN
217 253094 : ZX_mulu(GEN y, ulong x)
218 : {
219 : GEN z;
220 : long i, l;
221 253094 : if (!x) return pol_0(varn(y));
222 253094 : l = lg(y); z = cgetg(l,t_POL); z[1] = y[1];
223 1025517 : for(i=2; i<l; i++) gel(z,i) = mului(x,gel(y,i));
224 253094 : return z;
225 : }
226 :
227 : GEN
228 6419800 : ZX_shifti(GEN y, long n)
229 : {
230 : GEN z;
231 : long i, l;
232 6419800 : l = lg(y); z = cgetg(l,t_POL); z[1] = y[1];
233 30964084 : for(i=2; i<l; i++) gel(z,i) = shifti(gel(y,i),n);
234 6416341 : return ZX_renormalize(z,l);
235 : }
236 :
237 : GEN
238 105896 : ZX_remi2n(GEN y, long n)
239 : {
240 : GEN z;
241 : long i, l;
242 105896 : l = lg(y); z = cgetg(l,t_POL); z[1] = y[1];
243 4707112 : for(i=2; i<l; i++) gel(z,i) = remi2n(gel(y,i),n);
244 104404 : return ZX_renormalize(z,l);
245 : }
246 :
247 : GEN
248 45402 : ZXT_remi2n(GEN z, long n)
249 : {
250 45402 : if (typ(z) == t_POL)
251 39344 : return ZX_remi2n(z, n);
252 : else
253 : {
254 6058 : long i,l = lg(z);
255 6058 : GEN x = cgetg(l, t_VEC);
256 18200 : for (i=1; i<l; i++) gel(x,i) = ZXT_remi2n(gel(z,i), n);
257 6060 : return x;
258 : }
259 : }
260 :
261 : GEN
262 1330 : zx_to_ZX(GEN z)
263 : {
264 1330 : long i, l = lg(z);
265 1330 : GEN x = cgetg(l,t_POL);
266 100954 : for (i=2; i<l; i++) gel(x,i) = stoi(z[i]);
267 1330 : x[1] = evalsigne(l-2!=0)| z[1]; return x;
268 : }
269 :
270 : GEN
271 7415868 : ZX_deriv(GEN x)
272 : {
273 7415868 : long i,lx = lg(x)-1;
274 : GEN y;
275 :
276 7415868 : if (lx<3) return pol_0(varn(x));
277 7333438 : y = cgetg(lx,t_POL);
278 38945944 : for (i=2; i<lx ; i++) gel(y,i) = mului(i-1,gel(x,i+1));
279 7332122 : y[1] = x[1]; return y;
280 : }
281 :
282 : int
283 2066860 : ZX_equal(GEN V, GEN W)
284 : {
285 2066860 : long i, l = lg(V);
286 2066860 : if (lg(W) != l) return 0;
287 6003398 : for (i = 2; i < l; i++)
288 4672389 : if (!equalii(gel(V,i), gel(W,i))) return 0;
289 1331009 : return 1;
290 : }
291 :
292 : static long
293 334488266 : ZX_valspec(GEN x, long nx)
294 : {
295 : long vx;
296 499166993 : for (vx = 0; vx<nx ; vx++)
297 499181701 : if (signe(gel(x,vx))) break;
298 334488266 : return vx;
299 : }
300 :
301 : long
302 331023 : ZX_val(GEN x)
303 : {
304 : long vx;
305 331023 : if (!signe(x)) return LONG_MAX;
306 265393 : for (vx = 0;; vx++)
307 265393 : if (signe(gel(x,2+vx))) break;
308 215390 : return vx;
309 : }
310 : long
311 30291624 : ZX_valrem(GEN x, GEN *Z)
312 : {
313 : long vx;
314 30291624 : if (!signe(x)) { *Z = pol_0(varn(x)); return LONG_MAX; }
315 51006371 : for (vx = 0;; vx++)
316 51006371 : if (signe(gel(x,2+vx))) break;
317 30291624 : *Z = RgX_shift_shallow(x, -vx);
318 30291621 : return vx;
319 : }
320 :
321 : GEN
322 21 : ZX_div_by_X_1(GEN a, GEN *r)
323 : {
324 21 : long l = lg(a), i;
325 21 : GEN a0, z0, z = cgetg(l-1, t_POL);
326 21 : z[1] = a[1];
327 21 : a0 = a + l-1;
328 21 : z0 = z + l-2; *z0 = *a0--;
329 4732 : for (i=l-3; i>1; i--) /* z[i] = a[i+1] + z[i+1] */
330 : {
331 4711 : GEN t = addii(gel(a0--,0), gel(z0--,0));
332 4711 : gel(z0,0) = t;
333 : }
334 21 : if (r) *r = addii(gel(a0,0), gel(z0,0));
335 21 : return z;
336 : }
337 :
338 : /* return P(X + c) using destructive Horner, optimize for c = 1,-1 */
339 : static GEN
340 3546752 : ZX_translate_basecase(GEN P, GEN c)
341 : {
342 3546752 : pari_sp av = avma;
343 : GEN Q, R;
344 : long i, k, n;
345 :
346 3546752 : if (!signe(P) || !signe(c)) return ZX_copy(P);
347 3506840 : Q = leafcopy(P);
348 3506895 : R = Q+2; n = degpol(P);
349 3506894 : if (equali1(c))
350 : {
351 17217315 : for (i=1; i<=n; i++)
352 : {
353 98365423 : for (k=n-i; k<n; k++) gel(R,k) = addii(gel(R,k), gel(R,k+1));
354 14580425 : if (gc_needed(av,2))
355 : {
356 0 : if(DEBUGMEM>1) pari_warn(warnmem,"ZX_translate(1), i = %ld/%ld", i,n);
357 0 : Q = gc_GEN(av, Q); R = Q+2;
358 : }
359 : }
360 : }
361 870010 : else if (equalim1(c))
362 : {
363 953328 : for (i=1; i<=n; i++)
364 : {
365 3165183 : for (k=n-i; k<n; k++) gel(R,k) = subii(gel(R,k), gel(R,k+1));
366 727196 : if (gc_needed(av,2))
367 : {
368 0 : if(DEBUGMEM>1) pari_warn(warnmem,"ZX_translate(-1), i = %ld/%ld", i,n);
369 0 : Q = gc_GEN(av, Q); R = Q+2;
370 : }
371 : }
372 : }
373 : else
374 : {
375 4577792 : for (i=1; i<=n; i++)
376 : {
377 26237187 : for (k=n-i; k<n; k++) gel(R,k) = addmulii_inplace(gel(R,k), c, gel(R,k+1));
378 3933914 : if (gc_needed(av,2))
379 : {
380 0 : if(DEBUGMEM>1) pari_warn(warnmem,"ZX_translate, i = %ld/%ld", i,n);
381 0 : Q = gc_GEN(av, Q); R = Q+2;
382 : }
383 : }
384 : }
385 3506479 : return gc_GEN(av, Q);
386 : }
387 :
388 : GEN
389 434 : Xpm1_powu(long n, long s, long v)
390 : {
391 : long d, k;
392 : GEN C;
393 434 : if (!n) return pol_1(v);
394 434 : d = (n + 1) >> 1;
395 434 : C = cgetg(n+3, t_POL);
396 434 : C[1] = evalsigne(1)| evalvarn(v);
397 434 : gel(C,2) = gen_1;
398 434 : gel(C,3) = utoipos(n);
399 1771 : for (k=2; k <= d; k++)
400 1337 : gel(C,k+2) = diviuexact(mului(n-k+1, gel(C,k+1)), k);
401 434 : if (s < 0)
402 0 : for (k = odd(n)? 0: 1; k <= d; k += 2)
403 0 : togglesign_safe(&gel(C,k+2));
404 434 : if (s > 0 || !odd(n))
405 2058 : for (k = d+1; k <= n; k++) gel(C,k+2) = gel(C,n-k+2);
406 : else
407 0 : for (k = d+1; k <= n; k++) gel(C,k+2) = negi(gel(C,n-k+2));
408 434 : return C;
409 : }
410 : /* return (x+u)^n */
411 : static GEN
412 0 : Z_XpN_powu(GEN u, long n, long v)
413 : {
414 : pari_sp av;
415 : long k;
416 : GEN B, C, V;
417 0 : if (!n) return pol_1(v);
418 0 : if (is_pm1(u))
419 0 : return Xpm1_powu(n, signe(u), v);
420 0 : av = avma;
421 0 : V = gpowers(u, n);
422 0 : B = vecbinomial(n);
423 0 : C = cgetg(n+3, t_POL);
424 0 : C[1] = evalsigne(1)| evalvarn(v);
425 0 : for (k=1; k <= n+1; k++)
426 0 : gel(C,k+1) = mulii(gel(V,n+2-k), gel(B,k));
427 0 : return gerepileupto(av, C);
428 : }
429 :
430 : GEN
431 3563440 : ZX_translate(GEN P, GEN c)
432 : {
433 3563440 : pari_sp av = avma;
434 : long n;
435 3563440 : if (!signe(c)) return ZX_copy(P);
436 3546755 : n = degpol(P);
437 3546751 : if (n < 220)
438 3546751 : return ZX_translate_basecase(P, c);
439 : else
440 : {
441 0 : long d = n >> 1;
442 0 : GEN Q = ZX_translate(RgX_shift_shallow(P, -d), c);
443 0 : GEN R = ZX_translate(RgXn_red_shallow(P, d), c);
444 0 : GEN S = Z_XpN_powu(c, d, varn(P));
445 0 : return gerepileupto(av, ZX_add(ZX_mul(Q, S), R));
446 : }
447 : }
448 :
449 : /* P(ax + b) */
450 : GEN
451 994797 : ZX_affine(GEN P, GEN a, GEN b)
452 : {
453 994797 : if (signe(b)) P = ZX_translate(P, b);
454 994797 : return ZX_unscale(P, a);
455 : }
456 :
457 : GEN
458 531132 : ZX_Z_eval(GEN x, GEN y)
459 : {
460 531132 : long i = lg(x)-1, j;
461 531132 : pari_sp av = avma;
462 : GEN t, r;
463 :
464 531132 : if (i<=2) return (i==2)? icopy(gel(x,2)): gen_0;
465 493003 : if (!signe(y)) return icopy(gel(x,2));
466 :
467 492884 : t = gel(x,i); i--;
468 : #if 0 /* standard Horner's rule */
469 : for ( ; i>=2; i--)
470 : t = addii(mulii(t,y),gel(x,i));
471 : #endif
472 : /* specific attention to sparse polynomials */
473 2438290 : for ( ; i>=2; i = j-1)
474 : {
475 2121780 : for (j = i; !signe(gel(x,j)); j--)
476 176366 : if (j==2)
477 : {
478 2975 : if (i != j) y = powiu(y, i-j+1);
479 2975 : return gc_INT(av, mulii(t,y));
480 : }
481 1945414 : r = (i==j)? y: powiu(y, i-j+1);
482 1945419 : t = addii(mulii(t,r), gel(x,j));
483 1945408 : if (gc_needed(av,2))
484 : {
485 0 : if (DEBUGMEM>1) pari_warn(warnmem,"ZX_Z_eval: i = %ld",i);
486 0 : t = gc_INT(av, t);
487 : }
488 : }
489 489901 : return gc_INT(av, t);
490 : }
491 :
492 : /* Return 2^(n degpol(P)) P(x >> n) */
493 : GEN
494 0 : ZX_rescale2n(GEN P, long n)
495 : {
496 0 : long i, l = lg(P), ni = n;
497 : GEN Q;
498 0 : if (l==2) return pol_0(varn(P));
499 0 : Q = cgetg(l,t_POL);
500 0 : gel(Q,l-1) = icopy(gel(P,l-1));
501 0 : for (i=l-2; i>=2; i--)
502 : {
503 0 : gel(Q,i) = shifti(gel(P,i), ni);
504 0 : ni += n;
505 : }
506 0 : Q[1] = P[1]; return Q;
507 : }
508 :
509 : /* Return h^deg(P) P(x / h), not memory clean. h integer, P ZX */
510 : GEN
511 35828 : ZX_rescale(GEN P, GEN h)
512 : {
513 35828 : long l = lg(P);
514 35828 : GEN Q = cgetg(l,t_POL);
515 35830 : if (l != 2)
516 : {
517 35830 : long i = l-1;
518 35830 : GEN hi = h;
519 35830 : gel(Q,i) = gel(P,i);
520 35830 : if (l != 3) { i--; gel(Q,i) = mulii(gel(P,i), h); }
521 111381 : for (i--; i>=2; i--) { hi = mulii(hi,h); gel(Q,i) = mulii(gel(P,i), hi); }
522 : }
523 35831 : Q[1] = P[1]; return Q;
524 : }
525 : /* Return h^(deg(P)-1) P(x / h), P!=0, h=lt(P), memory unclean; monic result */
526 : GEN
527 0 : ZX_rescale_lt(GEN P)
528 : {
529 0 : long l = lg(P);
530 0 : GEN Q = cgetg(l,t_POL);
531 0 : gel(Q,l-1) = gen_1;
532 0 : if (l != 3)
533 : {
534 0 : long i = l-1;
535 0 : GEN h = gel(P,i), hi = h;
536 0 : i--; gel(Q,i) = gel(P,i);
537 0 : if (l != 4) { i--; gel(Q,i) = mulii(gel(P,i), h); }
538 0 : for (i--; i>=2; i--) { hi = mulii(hi,h); gel(Q,i) = mulii(gel(P,i), hi); }
539 : }
540 0 : Q[1] = P[1]; return Q;
541 : }
542 :
543 : /*Eval x in 2^(k*BIL) in linear time*/
544 : static GEN
545 95832987 : ZX_eval2BILspec(GEN x, long k, long nx)
546 : {
547 95832987 : pari_sp av = avma;
548 95832987 : long i,j, lz = k*nx, ki;
549 95832987 : GEN pz = cgetipos(2+lz);
550 95828513 : GEN nz = cgetipos(2+lz);
551 4208381197 : for(i=0; i < lz; i++)
552 : {
553 4112542486 : *int_W(pz,i) = 0UL;
554 4112542486 : *int_W(nz,i) = 0UL;
555 : }
556 1284206423 : for(i=0, ki=0; i<nx; i++, ki+=k)
557 : {
558 1188367712 : GEN c = gel(x,i);
559 1188367712 : long lc = lgefint(c)-2;
560 1188367712 : if (signe(c)==0) continue;
561 964672455 : if (signe(c) > 0)
562 2328362810 : for (j=0; j<lc; j++) *int_W(pz,j+ki) = *int_W(c,j);
563 : else
564 340405985 : for (j=0; j<lc; j++) *int_W(nz,j+ki) = *int_W(c,j);
565 : }
566 95838711 : pz = int_normalize(pz,0);
567 95844762 : nz = int_normalize(nz,0); return gc_INT(av, subii(pz,nz));
568 : }
569 :
570 : static long
571 172174376 : ZX_expispec(GEN x, long nx)
572 : {
573 172174376 : long i, m = 0;
574 1556432160 : for(i = 0; i < nx; i++)
575 : {
576 1384299064 : long e = expi(gel(x,i));
577 1384257784 : if (e > m) m = e;
578 : }
579 172133096 : return m;
580 : }
581 :
582 : static GEN
583 57585732 : Z_mod2BIL_ZX(GEN x, long bs, long d, long vx)
584 : {
585 57585732 : long i, offset, lm = lgefint(x)-2, l = d+vx+3, sx = signe(x);
586 57585732 : GEN s1 = int2n(bs*BITS_IN_LONG), pol = cgetg(l, t_POL);
587 57567546 : int carry = 0;
588 57567546 : pol[1] = evalsigne(1);
589 78125218 : for (i=0; i<vx; i++) gel(pol,i+2) = gen_0;
590 1317888674 : for (offset=0; i <= d+vx; i++, offset += bs)
591 : {
592 1260469499 : pari_sp av = avma;
593 1260469499 : long lz = minss(bs, lm-offset);
594 1260377485 : GEN z = lz > 0 ?adduispec_offset(carry, x, offset, lz): utoi(carry);
595 1260205912 : if (lgefint(z) == 3+bs) { carry = 1; z = gen_0;}
596 : else
597 : {
598 1246754880 : carry = (lgefint(z) == 2+bs && (HIGHBIT & *int_W(z,bs-1)));
599 1246754880 : if (carry)
600 57248116 : z = gc_INT(av, (sx==-1)? subii(s1,z): subii(z,s1));
601 1189506764 : else if (sx==-1) togglesign(z);
602 : }
603 1260321128 : gel(pol,i+2) = z;
604 : }
605 57419175 : return ZX_renormalize(pol,l);
606 : }
607 :
608 : static GEN
609 18126895 : ZX_sqrspec_sqri(GEN x, long nx, long ex, long v)
610 : {
611 18126895 : long e = 2*ex + expu(nx) + 3;
612 18126776 : long N = divsBIL(e)+1;
613 18126672 : GEN z = sqri(ZX_eval2BILspec(x,N,nx));
614 18123597 : return Z_mod2BIL_ZX(z, N, nx*2-2, v);
615 : }
616 :
617 : static GEN
618 38208865 : ZX_mulspec_mulii(GEN x, GEN y, long nx, long ny, long ex, long ey, long v)
619 : {
620 38208865 : long e = ex + ey + expu(minss(nx,ny)) + 3;
621 38208460 : long N = divsBIL(e)+1;
622 38208454 : GEN z = mulii(ZX_eval2BILspec(x,N,nx), ZX_eval2BILspec(y,N,ny));
623 38203536 : return Z_mod2BIL_ZX(z, N, nx+ny-2, v);
624 : }
625 :
626 : INLINE GEN
627 315115462 : ZX_sqrspec_basecase_limb(GEN x, long a, long i)
628 : {
629 315115462 : pari_sp av = avma;
630 315115462 : GEN s = gen_0;
631 315115462 : long j, l = (i+1)>>1;
632 621773760 : for (j=a; j<l; j++)
633 : {
634 307583755 : GEN xj = gel(x,j), xx = gel(x,i-j);
635 307583755 : if (signe(xj) && signe(xx))
636 304878984 : s = addii(s, mulii(xj, xx));
637 : }
638 314190005 : s = shifti(s,1);
639 314508308 : if ((i&1) == 0)
640 : {
641 195766151 : GEN t = gel(x, i>>1);
642 195766151 : if (signe(t))
643 195525492 : s = addii(s, sqri(t));
644 : }
645 314086308 : return gc_INT(av,s);
646 : }
647 :
648 : static GEN
649 76327081 : ZX_sqrspec_basecase(GEN x, long nx, long v)
650 : {
651 : long i, lz, nz;
652 : GEN z;
653 :
654 76327081 : lz = (nx << 1) + 1; nz = lz-2;
655 76327081 : lz += v;
656 76327081 : z = cgetg(lz,t_POL); z[1] = evalsigne(1); z += 2;
657 76520241 : for (i=0; i<v; i++) gel(z++, 0) = gen_0;
658 271993579 : for (i=0; i<nx; i++)
659 195825990 : gel(z,i) = ZX_sqrspec_basecase_limb(x, 0, i);
660 195770231 : for ( ; i<nz; i++) gel(z,i) = ZX_sqrspec_basecase_limb(x, i-nx+1, i);
661 76147336 : z -= v+2; return z;
662 : }
663 :
664 : static GEN
665 43543422 : Z_sqrshiftspec_ZX(GEN x, long vx)
666 : {
667 43543422 : long i, nz = 2*vx+1;
668 43543422 : GEN z = cgetg(2+nz, t_POL);
669 43539989 : z[1] = evalsigne(1);
670 46348813 : for(i=2;i<nz+1;i++) gel(z,i) = gen_0;
671 43539989 : gel(z,nz+1) = sqri(x);
672 43503621 : return z;
673 : }
674 :
675 : static GEN
676 47637411 : Z_ZX_mulshiftspec(GEN x, GEN y, long ny, long vz)
677 : {
678 47637411 : long i, nz = vz+ny;
679 47637411 : GEN z = cgetg(2+nz, t_POL);
680 47637420 : z[1] = evalsigne(1);
681 188308948 : for (i=0; i<vz; i++) gel(z,i+2) = gen_0;
682 135150253 : for (i=0; i<ny; i++) gel(z,i+vz+2) = mulii(x, gel(y,i));
683 47630412 : return z;
684 : }
685 :
686 : GEN
687 138669895 : ZX_sqrspec(GEN x, long nx)
688 : {
689 : #ifdef PARI_KERNEL_GMP
690 79790359 : const long low[]={ 17, 32, 96, 112, 160, 128, 128, 160, 160, 160, 160, 160, 176, 192, 192, 192, 192, 192, 224, 224, 224, 240, 240, 240, 272, 288, 288, 240, 288, 304, 304, 304, 304, 304, 304, 352, 352, 368, 352, 352, 352, 368, 368, 432, 432, 496, 432, 496, 496};
691 79790359 : const long high[]={ 102860, 70254, 52783, 27086, 24623, 18500, 15289, 13899, 12635, 11487, 10442, 9493, 8630, 7845, 7132, 7132, 6484, 6484, 5894, 5894, 4428, 4428, 3660, 4428, 3660, 3660, 2749, 2499, 2272, 2066, 1282, 1282, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 963, 963, 724, 658, 658, 658, 528, 528, 528, 528};
692 : #else
693 58879536 : const long low[]={ 17, 17, 32, 32, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 112, 112, 128, 112, 112, 112, 112, 112, 128, 128, 160, 160, 112, 128, 128, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 176, 160, 160, 176, 160, 160, 176, 176, 208, 176, 176, 176, 192, 192, 176, 176, 224, 176, 224, 224, 176, 224, 224, 224, 176, 176, 176, 176, 176, 176, 176, 176, 224, 176, 176, 224, 224, 224, 224, 224, 224, 224, 240, 288, 240, 288, 288, 240, 288, 288, 240, 240, 304, 304};
694 58879536 : const long high[]={ 165657, 85008, 52783, 43622, 32774, 27086, 22385, 15289, 13899, 12635, 11487, 10442, 9493, 7845, 6484, 6484, 5894, 5894, 4871, 4871, 4428, 4026, 3660, 3660, 3660, 3327, 3327, 3024, 2749, 2749, 2272, 2749, 2499, 2499, 2272, 1878, 1878, 1878, 1707, 1552, 1552, 1552, 1552, 1552, 1411, 1411, 1411, 1282, 1282, 1282, 1282, 1282, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1060, 1060, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 876, 876, 876, 876, 796, 658, 724, 658, 724, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 336, 658, 658, 592, 336, 336};
695 : #endif
696 138669895 : const long nblow = numberof(low);
697 : pari_sp av;
698 : long ex, vx;
699 : GEN z;
700 138669895 : if (!nx) return pol_0(0);
701 137880539 : vx = ZX_valspec(x,nx); nx-=vx; x+=vx;
702 137995742 : if (nx==1) return Z_sqrshiftspec_ZX(gel(x, 0), vx);
703 94452210 : av = avma;
704 94452210 : ex = ZX_expispec(x,nx);
705 94445605 : if (nx-2 < nblow && low[nx-2]<=ex && ex<=high[nx-2])
706 76327800 : z = ZX_sqrspec_basecase(x, nx, 2*vx);
707 : else
708 18117805 : z = ZX_sqrspec_sqri(x, nx, ex, 2*vx);
709 94368815 : return gerepileupto(av, z);
710 : }
711 :
712 : GEN
713 138675069 : ZX_sqr(GEN x)
714 : {
715 138675069 : GEN z = ZX_sqrspec(x+2, lgpol(x));
716 138554890 : z[1] = x[1];
717 138554890 : return z;
718 : }
719 :
720 : GEN
721 122680196 : ZX_mulspec(GEN x, GEN y, long nx, long ny)
722 : {
723 : pari_sp av;
724 : long ex, ey, vx, vy, v;
725 122680196 : if (!nx || !ny) return pol_0(0);
726 98259910 : vx = ZX_valspec(x,nx); nx-=vx; x += vx;
727 98260102 : vy = ZX_valspec(y,ny); ny-=vy; y += vy;
728 98263095 : v = vx + vy;
729 98263095 : if (nx==1) return Z_ZX_mulshiftspec(gel(x,0), y, ny, v);
730 60514204 : if (ny==1) return Z_ZX_mulshiftspec(gel(y,0), x, nx, v);
731 50625627 : if (nx == 2 && ny == 2)
732 : {
733 12417611 : GEN a0 = gel(x,0), a1 = gel(x,1), A0, A1, A2;
734 12417611 : GEN b0 = gel(y,0), b1 = gel(y,1), z = cgetg(5 + v, t_POL);
735 : long i;
736 12417658 : z[1] = evalvarn(0) | evalsigne(1);
737 12417658 : A0 = mulii(a0, b0);
738 12417291 : A2 = mulii(a1, b1); av = avma;
739 12417144 : A1 = gc_INT(av, subii(addii(A0,A2),
740 : mulii(subii(a1,a0), subii(b1,b0))));
741 12417474 : i = 4 + v;
742 12417474 : gel(z,i--) = A2;
743 12417474 : gel(z,i--) = A1;
744 14523205 : gel(z,i--) = A0; while (i > 1) gel(z, i--) = gen_0;
745 12417474 : return z;
746 : }
747 : #if 0
748 : /* generically slower even when degrees differ a lot; sometimes about twice
749 : * faster when bitsize is moderate */
750 : if (DEBUGVAR)
751 : return RgX_mulspec(x - vx, y - vy, nx + vx, ny + vy);
752 : #endif
753 38208016 : av = avma;
754 38208016 : ex = ZX_expispec(x, nx);
755 38207968 : ey = ZX_expispec(y, ny);
756 38208388 : return gerepileupto(av, ZX_mulspec_mulii(x,y,nx,ny,ex,ey,v));
757 : }
758 : GEN
759 114217052 : ZX_mul(GEN x, GEN y)
760 : {
761 : GEN z;
762 114217052 : if (x == y) return ZX_sqr(x);
763 113478554 : z = ZX_mulspec(x+2,y+2,lgpol(x),lgpol(y));
764 113471996 : z[1] = x[1];
765 113471996 : if (!signe(y)) z[1] &= VARNBITS;
766 113471996 : return z;
767 : }
768 :
769 : /* x,y two ZX in the same variable; assume y is monic */
770 : GEN
771 11065928 : ZX_rem(GEN x, GEN y)
772 : {
773 : long vx, dx, dy, dz, i, j, sx, lr;
774 : pari_sp av0, av;
775 : GEN z,p1,rem;
776 :
777 11065928 : vx = varn(x);
778 11065928 : dy = degpol(y);
779 11065876 : dx = degpol(x);
780 11065887 : if (dx < dy) return ZX_copy(x);
781 6068620 : if (!dy) return pol_0(vx); /* y is constant */
782 6065855 : av0 = avma; dz = dx-dy;
783 6065855 : z=cgetg(dz+3,t_POL); z[1] = x[1];
784 6065888 : x += 2; y += 2; z += 2;
785 :
786 6065888 : p1 = gel(x,dx);
787 6065888 : gel(z,dz) = icopy(p1);
788 28641996 : for (i=dx-1; i>=dy; i--)
789 : {
790 22576130 : av=avma; p1=gel(x,i);
791 212849748 : for (j=i-dy+1; j<=i && j<=dz; j++)
792 190286675 : p1 = subii(p1, mulii(gel(z,j),gel(y,i-j)));
793 22563073 : gel(z,i-dy) = avma == av? icopy(p1): gc_INT(av, p1);
794 : }
795 6065866 : rem = (GEN)avma; av = (pari_sp)new_chunk(dx+3);
796 8966713 : for (sx=0; ; i--)
797 : {
798 8966713 : p1 = gel(x,i);
799 57520218 : for (j=0; j<=i && j<=dz; j++)
800 48553671 : p1 = subii(p1, mulii(gel(z,j),gel(y,i-j)));
801 8966547 : if (signe(p1)) { sx = 1; break; }
802 3277518 : if (!i) break;
803 2900911 : set_avma(av);
804 : }
805 6065636 : lr=i+3; rem -= lr;
806 6065636 : rem[0] = evaltyp(t_POL) | _evallg(lr);
807 6065636 : rem[1] = z[-1];
808 6065636 : p1 = gc_INT((pari_sp)rem, p1);
809 6065828 : rem += 2; gel(rem,i) = p1;
810 33878112 : for (i--; i>=0; i--)
811 : {
812 27812788 : av=avma; p1 = gel(x,i);
813 249758163 : for (j=0; j<=i && j<=dz; j++)
814 221982801 : p1 = subii(p1, mulii(gel(z,j),gel(y,i-j)));
815 27775362 : gel(rem,i) = avma == av? icopy(p1): gc_INT(av, p1);
816 : }
817 6065324 : rem -= 2;
818 6065324 : if (!sx) (void)ZX_renormalize(rem, lr);
819 6065324 : return gerepileupto(av0,rem);
820 : }
821 :
822 : /* return x(1) */
823 : GEN
824 4718 : ZX_eval1(GEN x)
825 : {
826 4718 : pari_sp av = avma;
827 4718 : long i = lg(x)-1;
828 : GEN s;
829 4718 : if (i < 2) return gen_0;
830 4193 : s = gel(x,i); i--;
831 4193 : if (i == 1) return icopy(s);
832 34608 : for ( ; i>=2; i--)
833 : {
834 31423 : GEN c = gel(x,i);
835 31423 : if (signe(c)) s = addii(s, c);
836 : }
837 3185 : return gc_INT(av,s);
838 : }
839 :
840 : /* reduce T mod X^n - 1. Shallow function */
841 : GEN
842 1735980 : ZX_mod_Xnm1(GEN T, ulong n)
843 : {
844 1735980 : long i, j, L = lg(T), l = n+2;
845 : GEN S;
846 1735980 : if (L <= l) return T;
847 1573366 : S = cgetg(l, t_POL);
848 1573194 : S[1] = T[1];
849 12141063 : for (i = 2; i < l; i++) gel(S,i) = gel(T,i);
850 7388219 : for (j = 2; i < L; i++) {
851 5823634 : gel(S,j) = addii(gel(S,j), gel(T,i));
852 5815025 : if (++j == l) j = 2;
853 : }
854 1564585 : return normalizepol_lg(S, l);
855 : }
856 :
857 : static GEN
858 0 : _ZX_mul(void* E, GEN x, GEN y)
859 0 : { (void) E; return ZX_mul(x, y); }
860 : static GEN
861 0 : _ZX_sqr(void *E, GEN x)
862 0 : { (void) E; return ZX_sqr(x); }
863 :
864 : static GEN
865 0 : _ZX_divrem(void * E, GEN x, GEN y, GEN *r)
866 0 : { (void) E; return RgX_divrem(x, y, r); }
867 :
868 : static GEN
869 0 : _ZX_add(void * E, GEN x, GEN y)
870 0 : { (void) E; return ZX_add(x, y); }
871 :
872 : static struct bb_ring ZX_ring = { _ZX_add,_ZX_mul,_ZX_sqr };
873 :
874 : GEN
875 0 : ZX_digits(GEN x, GEN T)
876 : {
877 0 : long d = degpol(T), n = (lgpol(x)+d-1)/d;
878 0 : if (signe(x)==0) return(cgetg(1, t_VEC));
879 0 : return gen_digits(x, T, n, NULL, &ZX_ring, _ZX_divrem);
880 : }
881 :
882 : GEN
883 0 : ZXV_ZX_fromdigits(GEN x, GEN T)
884 0 : { return gen_fromdigits(x,T, NULL, &ZX_ring); }
885 :
886 : /*******************************************************************/
887 : /* */
888 : /* ZXV */
889 : /* */
890 : /*******************************************************************/
891 :
892 : int
893 28 : ZXV_equal(GEN V, GEN W)
894 : {
895 28 : long l = lg(V);
896 28 : if (l!=lg(W)) return 0;
897 28 : while (--l > 0)
898 28 : if (!ZX_equal(gel(V,l), gel(W,l))) return 0;
899 0 : return 1;
900 : }
901 :
902 : GEN
903 7476 : ZXV_Z_mul(GEN x, GEN y)
904 29904 : { pari_APPLY_same(ZX_Z_mul(gel(x,i), y)) }
905 :
906 : GEN
907 0 : ZXV_remi2n(GEN x, long N)
908 0 : { pari_APPLY_same(ZX_remi2n(gel(x,i), N)) }
909 :
910 : GEN
911 82943 : ZXV_dotproduct(GEN x, GEN y)
912 : {
913 82943 : pari_sp av = avma;
914 82943 : long i, lx = lg(x);
915 : GEN c;
916 82943 : if (lx == 1) return pol_0(varn(x));
917 82943 : c = ZX_mul(gel(x,1), gel(y,1));
918 392175 : for (i = 2; i < lx; i++)
919 : {
920 309232 : GEN t = ZX_mul(gel(x,i), gel(y,i));
921 309232 : if (signe(t)) c = ZX_add(c, t);
922 : }
923 82943 : return gerepileupto(av, c);
924 : }
925 :
926 : GEN
927 107581 : ZXC_to_FlxC(GEN x, ulong p, long sv)
928 4805684 : { pari_APPLY_type(t_COL,typ(gel(x,i))==t_INT ?
929 : Z_to_Flx(gel(x,i), p, sv): ZX_to_Flx(gel(x,i), p)) }
930 :
931 : GEN
932 8344 : ZXM_to_FlxM(GEN x, ulong p, long sv)
933 84179 : { pari_APPLY_same(ZXC_to_FlxC(gel(x,i), p, sv)) }
934 :
935 : /*******************************************************************/
936 : /* */
937 : /* ZXQM */
938 : /* */
939 : /*******************************************************************/
940 :
941 : GEN
942 2605568 : ZXn_mul(GEN x, GEN y, long n)
943 2605568 : { return RgXn_red_shallow(ZX_mul(x, y), n); }
944 :
945 : GEN
946 1575 : ZXn_sqr(GEN x, long n)
947 1575 : { return RgXn_red_shallow(ZX_sqr(x), n); }
948 :
949 : /*******************************************************************/
950 : /* */
951 : /* ZXQM */
952 : /* */
953 : /*******************************************************************/
954 :
955 : static long
956 5554160 : ZX_expi(GEN x)
957 : {
958 5554160 : if (signe(x)==0) return 0;
959 2879989 : if (typ(x)==t_INT) return expi(x);
960 1303084 : return ZX_expispec(x+2, lgpol(x));
961 : }
962 :
963 : static long
964 1090871 : ZXC_expi(GEN x)
965 : {
966 1090871 : long i, l = lg(x), m=0;
967 6645031 : for(i = 1; i < l; i++)
968 : {
969 5554160 : long e = ZX_expi(gel(x,i));
970 5554160 : if (e > m) m = e;
971 : }
972 1090871 : return m;
973 : }
974 :
975 : static long
976 176218 : ZXM_expi(GEN x)
977 : {
978 176218 : long i, l = lg(x), m=0;
979 1267089 : for(i = 1; i < l; i++)
980 : {
981 1090871 : long e = ZXC_expi(gel(x,i));
982 1090871 : if (e > m) m = e;
983 : }
984 176218 : return m;
985 : }
986 :
987 : static GEN
988 5554160 : ZX_eval2BIL(GEN x, long k)
989 : {
990 5554160 : if (signe(x)==0) return gen_0;
991 2879989 : if (typ(x)==t_INT) return x;
992 1303084 : return ZX_eval2BILspec(x+2, k, lgpol(x));
993 : }
994 :
995 : /*Eval x in 2^(k*BIL) in linear time*/
996 : static GEN
997 1090871 : ZXC_eval2BIL(GEN x, long k)
998 : {
999 1090871 : long i, lx = lg(x);
1000 1090871 : GEN A = cgetg(lx, t_COL);
1001 6645031 : for (i=1; i<lx; i++) gel(A,i) = ZX_eval2BIL(gel(x,i), k);
1002 1090871 : return A;
1003 : }
1004 :
1005 : static GEN
1006 176218 : ZXM_eval2BIL(GEN x, long k)
1007 : {
1008 176218 : long i, lx = lg(x);
1009 176218 : GEN A = cgetg(lx, t_MAT);
1010 1267089 : for (i=1; i<lx; i++) gel(A,i) = ZXC_eval2BIL(gel(x,i), k);
1011 176218 : return A;
1012 : }
1013 :
1014 : static GEN
1015 63700 : Z_mod2BIL_ZXQ(GEN x, long bs, GEN T)
1016 : {
1017 63700 : pari_sp av = avma;
1018 63700 : long v = varn(T), d = 2*(degpol(T)-1);
1019 63700 : GEN z = Z_mod2BIL_ZX(x, bs, d, 0);
1020 63700 : setvarn(z, v);
1021 63700 : return gerepileupto(av, ZX_rem(z, T));
1022 : }
1023 :
1024 : static GEN
1025 14000 : ZC_mod2BIL_ZXQC(GEN x, long bs, GEN T)
1026 : {
1027 14000 : long i, lx = lg(x);
1028 14000 : GEN A = cgetg(lx, t_COL);
1029 77700 : for (i=1; i<lx; i++) gel(A,i) = Z_mod2BIL_ZXQ(gel(x,i), bs, T);
1030 14000 : return A;
1031 : }
1032 :
1033 : static GEN
1034 6328 : ZM_mod2BIL_ZXQM(GEN x, long bs, GEN T)
1035 : {
1036 6328 : long i, lx = lg(x);
1037 6328 : GEN A = cgetg(lx, t_MAT);
1038 20328 : for (i=1; i<lx; i++) gel(A,i) = ZC_mod2BIL_ZXQC(gel(x,i), bs, T);
1039 6328 : return A;
1040 : }
1041 :
1042 : GEN
1043 6188 : ZXQM_mul(GEN x, GEN y, GEN T)
1044 : {
1045 6188 : long d = degpol(T);
1046 : GEN z;
1047 6188 : pari_sp av = avma;
1048 6188 : if (d == 0)
1049 0 : z = ZM_mul(simplify_shallow(x),simplify_shallow(y));
1050 : else
1051 : {
1052 6188 : long e, N, ex = ZXM_expi(x), ey = ZXM_expi(y), n = lg(x)-1;
1053 6188 : e = ex + ey + expu(d) + expu(n) + 4;
1054 6188 : N = divsBIL(e)+1;
1055 6188 : z = ZM_mul(ZXM_eval2BIL(x,N), ZXM_eval2BIL(y,N));
1056 6188 : z = ZM_mod2BIL_ZXQM(z, N, T);
1057 : }
1058 6188 : return gerepileupto(av, z);
1059 : }
1060 :
1061 : GEN
1062 140 : ZXQM_sqr(GEN x, GEN T)
1063 : {
1064 140 : long d = degpol(T);
1065 : GEN z;
1066 140 : pari_sp av = avma;
1067 140 : if (d == 0)
1068 0 : z = ZM_sqr(simplify_shallow(x));
1069 : else
1070 : {
1071 140 : long ex = ZXM_expi(x), d = degpol(T), n = lg(x)-1;
1072 140 : long e = 2*ex + expu(d) + expu(n) + 4;
1073 140 : long N = divsBIL(e)+1;
1074 140 : z = ZM_sqr(ZXM_eval2BIL(x,N));
1075 140 : z = ZM_mod2BIL_ZXQM(z, N, T);
1076 : }
1077 140 : return gerepileupto(av, z);
1078 : }
1079 :
1080 : GEN
1081 4725 : QXQM_mul(GEN x, GEN y, GEN T)
1082 : {
1083 4725 : GEN dx, nx = Q_primitive_part(x, &dx);
1084 4725 : GEN dy, ny = Q_primitive_part(y, &dy);
1085 4725 : GEN z = ZXQM_mul(nx, ny, T);
1086 4725 : if (dx || dy)
1087 : {
1088 4725 : GEN d = dx ? dy ? gmul(dx, dy): dx : dy;
1089 4725 : if (!gequal1(d)) z = RgM_Rg_mul(z, d);
1090 : }
1091 4725 : return z;
1092 : }
1093 :
1094 : GEN
1095 7 : QXQM_sqr(GEN x, GEN T)
1096 : {
1097 7 : GEN dx, nx = Q_primitive_part(x, &dx);
1098 7 : GEN z = ZXQM_sqr(nx, T);
1099 7 : if (dx) z = RgM_Rg_mul(z, gsqr(dx));
1100 7 : return z;
1101 : }
1102 :
1103 : static GEN
1104 1199133 : Z_mod2BIL_Fq(GEN x, long bs, GEN T, GEN p)
1105 : {
1106 1199133 : pari_sp av = avma;
1107 1199133 : long v = get_FpX_var(T), d = 2*(get_FpX_degree(T)-1);
1108 1199133 : GEN z = Z_mod2BIL_ZX(x, bs, d, 0);
1109 1199133 : setvarn(z, v);
1110 1199133 : return gerepileupto(av, FpX_rem(z, T, p));
1111 : }
1112 :
1113 : static GEN
1114 305402 : ZC_mod2BIL_FqC(GEN x, long bs, GEN T, GEN p)
1115 : {
1116 305402 : long i, lx = lg(x);
1117 305402 : GEN A = cgetg(lx, t_COL);
1118 1504535 : for (i=1; i<lx; i++) gel(A,i) = Z_mod2BIL_Fq(gel(x,i), bs, T, p);
1119 305402 : return A;
1120 : }
1121 :
1122 : static GEN
1123 81851 : ZM_mod2BIL_FqM(GEN x, long bs, GEN T, GEN p)
1124 : {
1125 81851 : long i, lx = lg(x);
1126 81851 : GEN A = cgetg(lx, t_MAT);
1127 387253 : for (i=1; i<lx; i++) gel(A,i) = ZC_mod2BIL_FqC(gel(x,i), bs, T, p);
1128 81851 : return A;
1129 : }
1130 :
1131 : GEN
1132 81851 : FqM_mul_Kronecker(GEN x, GEN y, GEN T, GEN p)
1133 : {
1134 81851 : pari_sp av = avma;
1135 81851 : long ex = ZXM_expi(x), ey = ZXM_expi(y), d= degpol(T), n = lg(x)-1;
1136 81851 : long e = ex + ey + expu(d) + expu(n) + 4;
1137 81851 : long N = divsBIL(e)+1;
1138 81851 : GEN z = ZM_mul(ZXM_eval2BIL(x,N), ZXM_eval2BIL(y,N));
1139 81851 : return gerepileupto(av, ZM_mod2BIL_FqM(z, N, T, p));
1140 : }
1141 :
1142 : /*******************************************************************/
1143 : /* */
1144 : /* ZXX */
1145 : /* */
1146 : /*******************************************************************/
1147 :
1148 : void
1149 1022 : RgX_check_ZXX(GEN x, const char *s)
1150 : {
1151 1022 : long k = lg(x)-1;
1152 9891 : for ( ; k>1; k--) {
1153 8869 : GEN t = gel(x,k);
1154 8869 : switch(typ(t)) {
1155 7812 : case t_INT: break;
1156 1057 : case t_POL: if (RgX_is_ZX(t)) break;
1157 : /* fall through */
1158 0 : default: pari_err_TYPE(stack_strcat(s, " not in Z[X,Y]"),x);
1159 : }
1160 : }
1161 1022 : }
1162 :
1163 : /*Renormalize (in place) polynomial with t_INT or ZX coefficients.*/
1164 : GEN
1165 313817679 : ZXX_renormalize(GEN x, long lx)
1166 : {
1167 : long i;
1168 385133996 : for (i = lx-1; i>1; i--)
1169 370319278 : if (signe(gel(x,i))) break;
1170 313817679 : stackdummy((pari_sp)(x + lg(x)), (pari_sp)(x + (i+1)));
1171 313811974 : setlg(x, i+1); setsigne(x, i!=1); return x;
1172 : }
1173 :
1174 : GEN
1175 28548 : ZXX_evalx0(GEN y)
1176 : {
1177 28548 : long i, l = lg(y);
1178 28548 : GEN z = cgetg(l,t_POL); z[1] = y[1];
1179 480693 : for(i=2; i<l; i++)
1180 : {
1181 452145 : GEN yi = gel(y,i);
1182 452145 : gel(z,i) = typ(yi)==t_INT? yi: constant_coeff(yi);
1183 : }
1184 28548 : return ZX_renormalize(z,l);
1185 : }
1186 :
1187 : long
1188 5355 : ZXX_max_lg(GEN x)
1189 : {
1190 5355 : long i, prec = 0, lx = lg(x);
1191 37520 : for (i=2; i<lx; i++)
1192 : {
1193 32165 : GEN p = gel(x,i);
1194 32165 : long l = (typ(p) == t_INT)? lgefint(p): ZX_max_lg(p);
1195 32165 : if (l > prec) prec = l;
1196 : }
1197 5355 : return prec;
1198 : }
1199 :
1200 : GEN
1201 8883 : ZXX_Z_mul(GEN y, GEN x)
1202 : {
1203 8883 : long i, l = lg(y);
1204 8883 : GEN z = cgetg(l,t_POL); z[1] = y[1];
1205 230727 : for(i=2; i<l; i++)
1206 221844 : if(typ(gel(y,i))==t_INT)
1207 0 : gel(z,i) = mulii(gel(y,i),x);
1208 : else
1209 221844 : gel(z,i) = ZX_Z_mul(gel(y,i),x);
1210 8883 : return z;
1211 : }
1212 :
1213 : GEN
1214 0 : ZXX_Z_add_shallow(GEN x, GEN y)
1215 : {
1216 0 : long i, l = lg(x);
1217 : GEN z, a;
1218 0 : if (signe(x)==0) return scalarpol(y,varn(x));
1219 0 : z = cgetg(l,t_POL); z[1] = x[1];
1220 0 : a = gel(x,2);
1221 0 : gel(z, 2) = typ(a)==t_INT? addii(a,y): ZX_Z_add(a,y);
1222 0 : for(i=3; i<l; i++)
1223 0 : gel(z,i) = gel(x,i);
1224 0 : return z;
1225 : }
1226 :
1227 : GEN
1228 56469 : ZXX_Z_divexact(GEN y, GEN x)
1229 : {
1230 56469 : long i, l = lg(y);
1231 56469 : GEN z = cgetg(l,t_POL); z[1] = y[1];
1232 467026 : for(i=2; i<l; i++)
1233 410557 : if(typ(gel(y,i))==t_INT)
1234 2989 : gel(z,i) = diviiexact(gel(y,i),x);
1235 : else
1236 407568 : gel(z,i) = ZX_Z_divexact(gel(y,i),x);
1237 56469 : return z;
1238 : }
1239 :
1240 : /* Kronecker substitution, ZXX -> ZX:
1241 : * P(X,Y) = sum_{0<=i<lP} P_i(X) * Y^i, where deg P_i < n.
1242 : * Returns P(X,X^(2n-1)) */
1243 : GEN
1244 10014673 : RgXX_to_Kronecker_spec(GEN P, long lP, long n)
1245 : {
1246 10014673 : long i, k, N = (n<<1) + 1;
1247 : GEN y;
1248 10014673 : if (!lP) return pol_0(0);
1249 9995056 : y = cgetg((N-2)*lP + 2, t_POL) + 2;
1250 45127000 : for (k=i=0; i<lP; i++)
1251 : {
1252 : long j;
1253 45128693 : GEN c = gel(P,i);
1254 45128693 : if (typ(c)!=t_POL)
1255 : {
1256 3208038 : gel(y,k++) = c;
1257 3208038 : j = 3;
1258 : }
1259 : else
1260 : {
1261 41920655 : long l = lg(c);
1262 41920655 : if (l-3 >= n)
1263 0 : pari_err_BUG("RgXX_to_Kronecker, P is not reduced mod Q");
1264 247637011 : for (j=2; j < l; j++) gel(y,k++) = gel(c,j);
1265 : }
1266 45128811 : if (i == lP-1) break;
1267 195665759 : for ( ; j < N; j++) gel(y,k++) = gen_0;
1268 : }
1269 9994213 : y-=2; setlg(y, k+2); y[1] = evalsigne(1); return y;
1270 : }
1271 :
1272 : /* shallow, n = deg(T) */
1273 : GEN
1274 1768075 : Kronecker_to_ZXX(GEN z, long n, long v)
1275 : {
1276 1768075 : long i,j,lx,l, N = (n<<1)+1;
1277 : GEN x, t;
1278 1768075 : l = lg(z); lx = (l-2) / (N-2);
1279 1768075 : x = cgetg(lx+3,t_POL);
1280 1768171 : x[1] = z[1];
1281 8932707 : for (i=2; i<lx+2; i++)
1282 : {
1283 7163907 : t = cgetg(N,t_POL); t[1] = evalvarn(v);
1284 107248729 : for (j=2; j<N; j++) gel(t,j) = gel(z,j);
1285 7163291 : z += (N-2);
1286 7163291 : gel(x,i) = ZX_renormalize(t,N);
1287 : }
1288 1768800 : N = (l-2) % (N-2) + 2;
1289 1768800 : t = cgetg(N,t_POL); t[1] = evalvarn(v);
1290 5133486 : for (j=2; j<N; j++) gel(t,j) = gel(z,j);
1291 1768468 : gel(x,i) = ZX_renormalize(t,N);
1292 1768466 : return ZXX_renormalize(x, i+1);
1293 : }
1294 :
1295 : GEN
1296 6678326 : RgXX_to_Kronecker(GEN P, long n)
1297 : {
1298 6678326 : GEN z = RgXX_to_Kronecker_spec(P+2, lgpol(P), n);
1299 6678068 : setvarn(z,varn(P)); return z;
1300 : }
1301 : GEN
1302 3028362 : ZXX_mul_Kronecker(GEN x, GEN y, long n)
1303 3028362 : { return ZX_mul(RgXX_to_Kronecker(x,n), RgXX_to_Kronecker(y,n)); }
1304 :
1305 : GEN
1306 5306 : ZXX_sqr_Kronecker(GEN x, long n)
1307 5306 : { return ZX_sqr(RgXX_to_Kronecker(x,n)); }
1308 :
1309 : /* shallow, n = deg(T) */
1310 : GEN
1311 24269 : Kronecker_to_ZXQX(GEN z, GEN T)
1312 : {
1313 24269 : long i,j,lx,l, N = (degpol(T)<<1)+1;
1314 : GEN x, t;
1315 24269 : l = lg(z); lx = (l-2) / (N-2);
1316 24269 : x = cgetg(lx+3,t_POL);
1317 24269 : x[1] = z[1];
1318 236283 : for (i=2; i<lx+2; i++)
1319 : {
1320 212014 : t = cgetg(N,t_POL); t[1] = T[1];
1321 1898244 : for (j=2; j<N; j++) gel(t,j) = gel(z,j);
1322 212014 : z += (N-2);
1323 212014 : gel(x,i) = ZX_rem(ZX_renormalize(t,N), T);
1324 : }
1325 24269 : N = (l-2) % (N-2) + 2;
1326 24269 : t = cgetg(N,t_POL); t[1] = T[1];
1327 57152 : for (j=2; j<N; j++) gel(t,j) = gel(z,j);
1328 24269 : gel(x,i) = ZX_rem(ZX_renormalize(t,N), T);
1329 24269 : return ZXX_renormalize(x, i+1);
1330 : }
1331 :
1332 : GEN
1333 1904 : ZXQX_sqr(GEN x, GEN T)
1334 : {
1335 1904 : pari_sp av = avma;
1336 1904 : long n = degpol(T);
1337 1904 : GEN z = ZXX_sqr_Kronecker(x, n);
1338 1904 : z = Kronecker_to_ZXQX(z, T);
1339 1904 : return gc_GEN(av, z);
1340 : }
1341 :
1342 : GEN
1343 22365 : ZXQX_mul(GEN x, GEN y, GEN T)
1344 : {
1345 22365 : pari_sp av = avma;
1346 22365 : long n = degpol(T);
1347 22365 : GEN z = ZXX_mul_Kronecker(x, y, n);
1348 22365 : z = Kronecker_to_ZXQX(z, T);
1349 22365 : return gc_GEN(av, z);
1350 : }
1351 :
1352 : GEN
1353 8988 : ZXQX_ZXQ_mul(GEN P, GEN U, GEN T)
1354 : {
1355 : long i, lP;
1356 : GEN res;
1357 8988 : res = cgetg_copy(P, &lP); res[1] = P[1];
1358 47109 : for(i=2; i<lP; i++)
1359 38120 : gel(res,i) = typ(gel(P,i))==t_POL? ZXQ_mul(U, gel(P,i), T)
1360 38120 : : gmul(U, gel(P,i));
1361 8989 : return ZXX_renormalize(res,lP);
1362 : }
1363 :
1364 : GEN
1365 3532612 : QX_mul(GEN x, GEN y)
1366 : {
1367 3532612 : GEN dx, nx = Q_primitive_part(x, &dx);
1368 3532612 : GEN dy, ny = Q_primitive_part(y, &dy);
1369 3532612 : GEN z = ZX_mul(nx, ny);
1370 3532612 : if (dx || dy)
1371 : {
1372 3440172 : GEN d = dx ? dy ? gmul(dx, dy): dx : dy;
1373 3440172 : return ZX_Q_mul(z, d);
1374 : } else
1375 92440 : return z;
1376 : }
1377 :
1378 : GEN
1379 96667 : QX_sqr(GEN x)
1380 : {
1381 96667 : GEN dx, nx = Q_primitive_part(x, &dx);
1382 96661 : GEN z = ZX_sqr(nx);
1383 96668 : if (dx)
1384 86296 : return ZX_Q_mul(z, gsqr(dx));
1385 : else
1386 10372 : return z;
1387 : }
1388 :
1389 : GEN
1390 1834434 : QX_ZX_rem(GEN x, GEN y)
1391 : {
1392 1834434 : pari_sp av = avma;
1393 1834434 : GEN d, nx = Q_primitive_part(x, &d);
1394 1834434 : GEN r = ZX_rem(nx, y);
1395 1834434 : if (d) r = ZX_Q_mul(r, d);
1396 1834434 : return gerepileupto(av, r);
1397 : }
1398 :
1399 : GEN
1400 13377 : QXQX_mul(GEN x, GEN y, GEN T)
1401 : {
1402 13377 : GEN dx, nx = Q_primitive_part(x, &dx);
1403 13377 : GEN dy, ny = Q_primitive_part(y, &dy);
1404 13377 : GEN z = ZXQX_mul(nx, ny, T);
1405 13377 : if (dx || dy)
1406 : {
1407 8309 : GEN d = dx ? dy ? gmul(dx, dy): dx : dy;
1408 8309 : return ZXX_Q_mul(z, d);
1409 : } else
1410 5068 : return z;
1411 : }
1412 :
1413 : GEN
1414 1904 : QXQX_sqr(GEN x, GEN T)
1415 : {
1416 1904 : GEN dx, nx = Q_primitive_part(x, &dx);
1417 1904 : GEN z = ZXQX_sqr(nx, T);
1418 1904 : if (dx)
1419 588 : return ZXX_Q_mul(z, gsqr(dx));
1420 : else
1421 1316 : return z;
1422 : }
1423 :
1424 : GEN
1425 476 : QXQX_powers(GEN P, long n, GEN T)
1426 : {
1427 476 : GEN v = cgetg(n+2, t_VEC);
1428 : long i;
1429 476 : gel(v, 1) = pol_1(varn(T));
1430 476 : if (n==0) return v;
1431 476 : gel(v, 2) = gcopy(P);
1432 1554 : for (i = 2; i <= n; i++) gel(v,i+1) = QXQX_mul(P, gel(v,i), T);
1433 476 : return v;
1434 : }
1435 :
1436 : GEN
1437 3465 : QXQX_QXQ_mul(GEN P, GEN U, GEN T)
1438 : {
1439 : long i, lP;
1440 : GEN res;
1441 3465 : res = cgetg_copy(P, &lP); res[1] = P[1];
1442 22715 : for(i=2; i<lP; i++)
1443 19250 : gel(res,i) = typ(gel(P,i))==t_POL? QXQ_mul(U, gel(P,i), T)
1444 19250 : : gmul(U, gel(P,i));
1445 3465 : return ZXX_renormalize(res,lP);
1446 : }
|