Line data Source code
1 : /* Copyright (C) 2000 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 : /********************************************************************/
16 : /** **/
17 : /** GENERIC OPERATIONS **/
18 : /** (third part) **/
19 : /** **/
20 : /********************************************************************/
21 : #include "pari.h"
22 : #include "paripriv.h"
23 :
24 : /********************************************************************/
25 : /** **/
26 : /** PRINCIPAL VARIABLE NUMBER **/
27 : /** **/
28 : /********************************************************************/
29 : static void
30 75236 : recvar(hashtable *h, GEN x)
31 : {
32 75236 : long i = 1, lx = lg(x);
33 : void *v;
34 75236 : switch(typ(x))
35 : {
36 12404 : case t_POL: case t_SER:
37 12404 : v = (void*)varn(x);
38 12404 : if (!hash_search(h, v)) hash_insert(h, v, NULL);
39 12404 : i = 2; break;
40 1274 : case t_POLMOD: case t_RFRAC:
41 1274 : case t_VEC: case t_COL: case t_MAT: break;
42 14 : case t_LIST:
43 14 : x = list_data(x);
44 14 : lx = x? lg(x): 1; break;
45 61544 : default:
46 61544 : return;
47 : }
48 87640 : for (; i < lx; i++) recvar(h, gel(x,i));
49 : }
50 :
51 : GEN
52 1288 : variables_vecsmall(GEN x)
53 : {
54 1288 : hashtable *h = hash_create_ulong(100, 1);
55 1288 : recvar(h, x);
56 1288 : return vars_sort_inplace(hash_keys(h));
57 : }
58 :
59 : GEN
60 42 : variables_vec(GEN x)
61 42 : { return x? vars_to_RgXV(variables_vecsmall(x)): gpolvar(NULL); }
62 :
63 : long
64 137098636 : gvar(GEN x)
65 : {
66 : long i, v, w, lx;
67 137098636 : switch(typ(x))
68 : {
69 50611787 : case t_POL: case t_SER: return varn(x);
70 108664 : case t_POLMOD: return varn(gel(x,1));
71 12862887 : case t_RFRAC: return varn(gel(x,2));
72 3946194 : case t_VEC: case t_COL: case t_MAT:
73 3946194 : lx = lg(x); break;
74 14 : case t_LIST:
75 14 : x = list_data(x);
76 14 : lx = x? lg(x): 1; break;
77 69569090 : default:
78 69569090 : return NO_VARIABLE;
79 : }
80 3946208 : v = NO_VARIABLE;
81 33771867 : for (i=1; i < lx; i++) { w = gvar(gel(x,i)); if (varncmp(w,v) < 0) v = w; }
82 3946236 : return v;
83 : }
84 : /* T main polynomial in R[X], A auxiliary in R[X] (possibly degree 0).
85 : * Guess and return the main variable of R */
86 : static long
87 8477 : var2_aux(GEN T, GEN A)
88 : {
89 8477 : long a = gvar2(T);
90 8477 : long b = (typ(A) == t_POL && varn(A) == varn(T))? gvar2(A): gvar(A);
91 8477 : if (varncmp(a, b) > 0) a = b;
92 8477 : return a;
93 : }
94 : static long
95 4907 : var2_rfrac(GEN x) { return var2_aux(gel(x,2), gel(x,1)); }
96 : static long
97 3570 : var2_polmod(GEN x) { return var2_aux(gel(x,1), gel(x,2)); }
98 :
99 : /* main variable of x, with the convention that the "natural" main
100 : * variable of a POLMOD is mute, so we want the next one. */
101 : static long
102 58814 : gvar9(GEN x)
103 58814 : { return (typ(x) == t_POLMOD)? var2_polmod(x): gvar(x); }
104 :
105 : /* main variable of the ring over wich x is defined */
106 : long
107 20438756 : gvar2(GEN x)
108 : {
109 : long i, v, w;
110 20438756 : switch(typ(x))
111 : {
112 7 : case t_POLMOD:
113 7 : return var2_polmod(x);
114 17227 : case t_POL: case t_SER:
115 17227 : v = NO_VARIABLE;
116 74977 : for (i=2; i < lg(x); i++) {
117 57750 : w = gvar9(gel(x,i));
118 57750 : if (varncmp(w,v) < 0) v=w;
119 : }
120 17227 : return v;
121 4907 : case t_RFRAC:
122 4907 : return var2_rfrac(x);
123 49 : case t_VEC: case t_COL: case t_MAT:
124 49 : v = NO_VARIABLE;
125 147 : for (i=1; i < lg(x); i++) {
126 98 : w = gvar2(gel(x,i));
127 98 : if (varncmp(w,v)<0) v=w;
128 : }
129 49 : return v;
130 : }
131 20416566 : return NO_VARIABLE;
132 : }
133 :
134 : /*******************************************************************/
135 : /* */
136 : /* PRECISION OF SCALAR OBJECTS */
137 : /* */
138 : /*******************************************************************/
139 : static long
140 9759844 : prec0(long e) { return (e < 0)? nbits2prec(-e): LOWDEFAULTPREC; }
141 : static long
142 978893060 : precREAL(GEN x) { return signe(x) ? realprec(x): prec0(expo(x)); }
143 : /* x t_REAL, y an exact noncomplex type. Return precision(|x| + |y|) */
144 : static long
145 878715 : precrealexact(GEN x, GEN y)
146 : {
147 878715 : long lx, ey = gexpo(y), ex, e;
148 878713 : if (ey == -(long)HIGHEXPOBIT) return precREAL(x);
149 188239 : ex = expo(x);
150 188239 : e = ey - ex;
151 188239 : if (!signe(x)) return prec0((e >= 0)? -e: ex);
152 188190 : lx = realprec(x);
153 188190 : return (e > 0)? lx + nbits2extraprec(e): lx;
154 : }
155 : static long
156 21497167 : precCOMPLEX(GEN z)
157 : { /* ~ precision(|x| + |y|) */
158 21497167 : GEN x = gel(z,1), y = gel(z,2);
159 : long e, ex, ey, lz, lx, ly;
160 21497167 : if (typ(x) != t_REAL) {
161 1666190 : if (typ(y) != t_REAL) return 0;
162 866452 : return precrealexact(y, x);
163 : }
164 19830977 : if (typ(y) != t_REAL) return precrealexact(x, y);
165 : /* x, y are t_REALs, cf addrr_sign */
166 19818715 : ex = expo(x);
167 19818715 : ey = expo(y);
168 19818715 : e = ey - ex;
169 19818715 : if (!signe(x)) {
170 595913 : if (!signe(y)) return prec0( minss(ex,ey) );
171 595815 : if (e <= 0) return prec0(ex);
172 595763 : lz = nbits2prec(e);
173 595764 : ly = realprec(y); if (lz > ly) lz = ly;
174 595764 : return lz;
175 : }
176 19222802 : if (!signe(y)) {
177 77272 : if (e >= 0) return prec0(ey);
178 77265 : lz = nbits2prec(-e);
179 77265 : lx = realprec(x); if (lz > lx) lz = lx;
180 77265 : return lz;
181 : }
182 19145530 : if (e < 0) { swap(x, y); e = -e; }
183 19145530 : lx = realprec(x);
184 19145530 : ly = realprec(y);
185 19145530 : if (e) {
186 16002890 : long d = nbits2extraprec(e), l = ly-d;
187 16002904 : return (l > lx)? lx + d: ly;
188 : }
189 3142640 : return minss(lx, ly);
190 : }
191 : long
192 990666234 : precision(GEN z)
193 : {
194 990666234 : switch(typ(z))
195 : {
196 974311002 : case t_REAL: return precREAL(z);
197 15935823 : case t_COMPLEX: return precCOMPLEX(z);
198 : }
199 419409 : return 0;
200 : }
201 :
202 : long
203 14469850 : gprecision(GEN x)
204 : {
205 : long i, k, l;
206 :
207 14469850 : switch(typ(x))
208 : {
209 3891812 : case t_REAL: return precREAL(x);
210 5561364 : case t_COMPLEX: return precCOMPLEX(x);
211 962065 : case t_INT: case t_INTMOD: case t_FRAC: case t_FFELT:
212 : case t_PADIC: case t_QUAD: case t_POLMOD:
213 962065 : return 0;
214 :
215 602 : case t_POL: case t_SER:
216 602 : k = LONG_MAX;
217 2121 : for (i=lg(x)-1; i>1; i--)
218 : {
219 1519 : l = gprecision(gel(x,i));
220 1519 : if (l && l<k) k = l;
221 : }
222 602 : return (k==LONG_MAX)? 0: k;
223 4054019 : case t_VEC: case t_COL: case t_MAT:
224 4054019 : k = LONG_MAX;
225 14912448 : for (i=lg(x)-1; i>0; i--)
226 : {
227 10858403 : l = gprecision(gel(x,i));
228 10858429 : if (l && l<k) k = l;
229 : }
230 4054045 : return (k==LONG_MAX)? 0: k;
231 :
232 7 : case t_RFRAC:
233 : {
234 7 : k=gprecision(gel(x,1));
235 7 : l=gprecision(gel(x,2)); if (l && (!k || l<k)) k=l;
236 7 : return k;
237 : }
238 7 : case t_QFB:
239 7 : return gprecision(gel(x,4));
240 : }
241 48 : return 0;
242 : }
243 :
244 : static long
245 371 : vec_padicprec_relative(GEN x, long imin)
246 : {
247 : long s, t, i;
248 1197 : for (s=LONG_MAX, i=lg(x)-1; i>=imin; i--)
249 : {
250 826 : t = padicprec_relative(gel(x,i)); if (t<s) s = t;
251 : }
252 371 : return s;
253 : }
254 : /* RELATIVE padic precision. Only accept decent types: don't try to make sense
255 : * of everything like padicprec */
256 : long
257 2275 : padicprec_relative(GEN x)
258 : {
259 2275 : switch(typ(x))
260 : {
261 413 : case t_INT: case t_FRAC:
262 413 : return LONG_MAX;
263 1491 : case t_PADIC:
264 1491 : return signe(padic_u(x))? precp(x): 0;
265 224 : case t_POLMOD: case t_VEC: case t_COL: case t_MAT:
266 224 : return vec_padicprec_relative(x, 1);
267 147 : case t_POL: case t_SER:
268 147 : return vec_padicprec_relative(x, 2);
269 : }
270 0 : pari_err_TYPE("padicprec_relative",x);
271 : return 0; /* LCOV_EXCL_LINE */
272 : }
273 :
274 : static long
275 826 : vec_padicprec(GEN x, GEN p, long imin)
276 : {
277 : long s, t, i;
278 4760 : for (s=LONG_MAX, i=lg(x)-1; i>=imin; i--)
279 : {
280 3934 : t = padicprec(gel(x,i),p); if (t<s) s = t;
281 : }
282 826 : return s;
283 : }
284 : static long
285 14 : vec_serprec(GEN x, long v, long imin)
286 : {
287 : long s, t, i;
288 42 : for (s=LONG_MAX, i=lg(x)-1; i>=imin; i--)
289 : {
290 28 : t = serprec(gel(x,i),v); if (t<s) s = t;
291 : }
292 14 : return s;
293 : }
294 :
295 : /* ABSOLUTE padic precision */
296 : long
297 4172 : padicprec(GEN x, GEN p)
298 : {
299 4172 : if (typ(p) != t_INT) pari_err_TYPE("padicprec",p);
300 4165 : switch(typ(x))
301 : {
302 42 : case t_INT: case t_FRAC:
303 42 : return LONG_MAX;
304 :
305 7 : case t_INTMOD:
306 7 : return Z_pval(gel(x,1),p);
307 :
308 3290 : case t_PADIC:
309 3290 : if (!equalii(padic_p(x),p)) pari_err_MODULUS("padicprec", padic_p(x), p);
310 3283 : return precp(x)+valp(x);
311 :
312 14 : case t_POL: case t_SER:
313 14 : return vec_padicprec(x, p, 2);
314 812 : case t_COMPLEX: case t_QUAD: case t_POLMOD: case t_RFRAC:
315 : case t_VEC: case t_COL: case t_MAT:
316 812 : return vec_padicprec(x, p, 1);
317 : }
318 0 : pari_err_TYPE("padicprec",x);
319 : return 0; /* LCOV_EXCL_LINE */
320 : }
321 : GEN
322 105 : gppadicprec(GEN x, GEN p)
323 : {
324 105 : long v = padicprec(x,p);
325 91 : return v == LONG_MAX? mkoo(): stoi(v);
326 : }
327 :
328 : /* ABSOLUTE X-adic precision */
329 : long
330 70 : serprec(GEN x, long v)
331 : {
332 : long w;
333 70 : switch(typ(x))
334 : {
335 21 : case t_INT: case t_REAL: case t_INTMOD: case t_FRAC: case t_FFELT:
336 : case t_COMPLEX: case t_PADIC: case t_QUAD: case t_QFB:
337 21 : return LONG_MAX;
338 :
339 7 : case t_POL:
340 7 : w = varn(x);
341 7 : if (varncmp(v,w) <= 0) return LONG_MAX;
342 7 : return vec_serprec(x, v, 2);
343 42 : case t_SER:
344 42 : w = varn(x);
345 42 : if (w == v)
346 : {
347 35 : long l = lg(x); /* Mod(0,2) + O(x) */
348 35 : if (l == 3 && !signe(x) && !isinexact(gel(x,2))) l--;
349 35 : return l - 2 + valser(x);
350 : }
351 7 : if (varncmp(v,w) < 0) return LONG_MAX;
352 7 : return vec_serprec(x, v, 2);
353 0 : case t_POLMOD: case t_RFRAC: case t_VEC: case t_COL: case t_MAT:
354 0 : return vec_serprec(x, v, 1);
355 : }
356 0 : pari_err_TYPE("serprec",x);
357 : return 0; /* LCOV_EXCL_LINE */
358 : }
359 : GEN
360 42 : gpserprec(GEN x, long v)
361 : {
362 42 : long p = serprec(x,v);
363 42 : return p == LONG_MAX? mkoo(): stoi(p);
364 : }
365 :
366 : /* Degree of x (scalar, t_POL, t_RFRAC) wrt variable v if v >= 0,
367 : * wrt to main variable if v < 0. */
368 : long
369 147237 : poldegree(GEN x, long v)
370 : {
371 147237 : const long DEGREE0 = -LONG_MAX;
372 147237 : long tx = typ(x), lx,w,i,d;
373 :
374 147237 : if (is_scalar_t(tx)) return gequal0(x)? DEGREE0: 0;
375 138393 : switch(tx)
376 : {
377 138274 : case t_POL:
378 138274 : if (!signe(x)) return DEGREE0;
379 138267 : w = varn(x);
380 138267 : if (v < 0 || v == w) return degpol(x);
381 6955 : if (varncmp(v, w) < 0) return 0;
382 6899 : lx = lg(x); d = DEGREE0;
383 41683 : for (i=2; i<lx; i++)
384 : {
385 34784 : long e = poldegree(gel(x,i), v);
386 34784 : if (e > d) d = e;
387 : }
388 6899 : return d;
389 :
390 119 : case t_RFRAC:
391 : {
392 119 : GEN a = gel(x,1), b = gel(x,2);
393 119 : if (gequal0(a)) return DEGREE0;
394 112 : if (v < 0)
395 : {
396 112 : v = varn(b); d = -degpol(b);
397 112 : if (typ(a) == t_POL && varn(a) == v) d += degpol(a);
398 112 : return d;
399 : }
400 0 : return poldegree(a,v) - poldegree(b,v);
401 : }
402 : }
403 0 : pari_err_TYPE("degree",x);
404 : return 0; /* LCOV_EXCL_LINE */
405 : }
406 : GEN
407 31224 : gppoldegree(GEN x, long v)
408 : {
409 31224 : long d = poldegree(x,v);
410 31224 : return d == -LONG_MAX? mkmoo(): stoi(d);
411 : }
412 :
413 : /* assume v >= 0 and x is a POLYNOMIAL in v, return deg_v(x) */
414 : long
415 566866 : RgX_degree(GEN x, long v)
416 : {
417 566866 : long tx = typ(x), lx, w, i, d;
418 :
419 566866 : if (is_scalar_t(tx)) return gequal0(x)? -1: 0;
420 344369 : switch(tx)
421 : {
422 344369 : case t_POL:
423 344369 : if (!signe(x)) return -1;
424 344348 : w = varn(x);
425 344348 : if (v == w) return degpol(x);
426 128126 : if (varncmp(v, w) < 0) return 0;
427 128126 : lx = lg(x); d = -1;
428 548841 : for (i=2; i<lx; i++)
429 : {
430 420716 : long e = RgX_degree(gel(x,i), v);
431 420715 : if (e > d) d = e;
432 : }
433 128125 : return d;
434 :
435 0 : case t_RFRAC:
436 0 : w = varn(gel(x,2));
437 0 : if (varncmp(v, w) < 0) return 0;
438 0 : if (RgX_degree(gel(x,2),v)) pari_err_TYPE("RgX_degree", x);
439 0 : return RgX_degree(gel(x,1),v);
440 : }
441 0 : pari_err_TYPE("RgX_degree",x);
442 : return 0; /* LCOV_EXCL_LINE */
443 : }
444 :
445 : long
446 11314 : degree(GEN x)
447 : {
448 11314 : return poldegree(x,-1);
449 : }
450 :
451 : /* If v<0, leading coeff with respect to the main variable, otherwise wrt v. */
452 : GEN
453 1211 : pollead(GEN x, long v)
454 : {
455 1211 : long tx = typ(x), w;
456 : pari_sp av;
457 :
458 1211 : if (is_scalar_t(tx)) return gcopy(x);
459 1211 : w = varn(x);
460 1211 : switch(tx)
461 : {
462 1176 : case t_POL:
463 1176 : if (v < 0 || v == w)
464 : {
465 1141 : long l = lg(x);
466 1141 : return (l==2)? gen_0: gcopy(gel(x,l-1));
467 : }
468 35 : break;
469 :
470 35 : case t_SER:
471 35 : if (v < 0 || v == w) return signe(x)? gcopy(gel(x,2)): gen_0;
472 14 : if (varncmp(v, w) > 0) x = polcoef_i(x, valser(x), v);
473 14 : break;
474 :
475 0 : default:
476 0 : pari_err_TYPE("pollead",x);
477 : return NULL; /* LCOV_EXCL_LINE */
478 : }
479 49 : if (varncmp(v, w) < 0) return gcopy(x);
480 28 : av = avma; w = fetch_var_higher();
481 28 : x = gsubst(x, v, pol_x(w));
482 28 : x = pollead(x, w);
483 28 : delete_var(); return gc_upto(av, x);
484 : }
485 :
486 : /* returns 1 if there's a real component in the structure, 0 otherwise */
487 : int
488 14707 : isinexactreal(GEN x)
489 : {
490 : long i;
491 14707 : switch(typ(x))
492 : {
493 1246 : case t_REAL: return 1;
494 2597 : case t_COMPLEX: return (typ(gel(x,1))==t_REAL || typ(gel(x,2))==t_REAL);
495 :
496 10276 : case t_INT: case t_INTMOD: case t_FRAC:
497 : case t_FFELT: case t_PADIC: case t_QUAD:
498 10276 : case t_QFB: return 0;
499 :
500 0 : case t_RFRAC: case t_POLMOD:
501 0 : return isinexactreal(gel(x,1)) || isinexactreal(gel(x,2));
502 :
503 588 : case t_POL: case t_SER:
504 5411 : for (i=lg(x)-1; i>1; i--)
505 4872 : if (isinexactreal(gel(x,i))) return 1;
506 539 : return 0;
507 :
508 0 : case t_VEC: case t_COL: case t_MAT:
509 0 : for (i=lg(x)-1; i>0; i--)
510 0 : if (isinexactreal(gel(x,i))) return 1;
511 0 : return 0;
512 0 : default: return 0;
513 : }
514 : }
515 : /* Check if x is approximately real with precision e */
516 : int
517 1886483 : isrealappr(GEN x, long e)
518 : {
519 : long i;
520 1886483 : switch(typ(x))
521 : {
522 698416 : case t_INT: case t_REAL: case t_FRAC:
523 698416 : return 1;
524 1188070 : case t_COMPLEX:
525 1188070 : return (gexpo(gel(x,2)) < e);
526 :
527 0 : case t_POL: case t_SER:
528 0 : for (i=lg(x)-1; i>1; i--)
529 0 : if (! isrealappr(gel(x,i),e)) return 0;
530 0 : return 1;
531 :
532 0 : case t_RFRAC: case t_POLMOD:
533 0 : return isrealappr(gel(x,1),e) && isrealappr(gel(x,2),e);
534 :
535 0 : case t_VEC: case t_COL: case t_MAT:
536 0 : for (i=lg(x)-1; i>0; i--)
537 0 : if (! isrealappr(gel(x,i),e)) return 0;
538 0 : return 1;
539 0 : default: pari_err_TYPE("isrealappr",x); return 0;
540 : }
541 : }
542 :
543 : /* returns 1 if there's an inexact component in the structure, and
544 : * 0 otherwise. */
545 : int
546 126609863 : isinexact(GEN x)
547 : {
548 : long lx, i;
549 :
550 126609863 : switch(typ(x))
551 : {
552 623920 : case t_REAL: case t_PADIC: case t_SER:
553 623920 : return 1;
554 86964231 : case t_INT: case t_INTMOD: case t_FFELT: case t_FRAC:
555 : case t_QFB:
556 86964231 : return 0;
557 2398870 : case t_COMPLEX: case t_QUAD: case t_RFRAC: case t_POLMOD:
558 2398870 : return isinexact(gel(x,1)) || isinexact(gel(x,2));
559 36604006 : case t_POL:
560 120476073 : for (i=lg(x)-1; i>1; i--)
561 84042219 : if (isinexact(gel(x,i))) return 1;
562 36433854 : return 0;
563 18841 : case t_VEC: case t_COL: case t_MAT:
564 22999 : for (i=lg(x)-1; i>0; i--)
565 22488 : if (isinexact(gel(x,i))) return 1;
566 511 : return 0;
567 0 : case t_LIST:
568 0 : x = list_data(x); lx = x? lg(x): 1;
569 0 : for (i=1; i<lx; i++)
570 0 : if (isinexact(gel(x,i))) return 1;
571 0 : return 0;
572 : }
573 0 : return 0;
574 : }
575 :
576 : int
577 0 : isrationalzeroscalar(GEN g)
578 : {
579 0 : switch (typ(g))
580 : {
581 0 : case t_INT: return !signe(g);
582 0 : case t_COMPLEX: return isintzero(gel(g,1)) && isintzero(gel(g,2));
583 0 : case t_QUAD: return isintzero(gel(g,2)) && isintzero(gel(g,3));
584 : }
585 0 : return 0;
586 : }
587 :
588 : int
589 0 : iscomplex(GEN x)
590 : {
591 0 : switch(typ(x))
592 : {
593 0 : case t_INT: case t_REAL: case t_FRAC:
594 0 : return 0;
595 0 : case t_COMPLEX:
596 0 : return !gequal0(gel(x,2));
597 0 : case t_QUAD:
598 0 : return signe(gmael(x,1,2)) > 0;
599 : }
600 0 : pari_err_TYPE("iscomplex",x);
601 : return 0; /* LCOV_EXCL_LINE */
602 : }
603 :
604 : /*******************************************************************/
605 : /* */
606 : /* GENERIC REMAINDER */
607 : /* */
608 : /*******************************************************************/
609 : static int
610 1099 : is_realquad(GEN x) { GEN Q = gel(x,1); return signe(gel(Q,2)) < 0; }
611 : static int
612 177888 : is_realext(GEN x)
613 177888 : { long t = typ(x);
614 177888 : return (t == t_QUAD)? is_realquad(x): is_real_t(t);
615 : }
616 : /* euclidean quotient for scalars of admissible types */
617 : static GEN
618 875 : _quot(GEN x, GEN y)
619 : {
620 875 : GEN q = gdiv(x,y), f = gfloor(q);
621 637 : if (gsigne(y) < 0 && !gequal(f,q)) f = addiu(f, 1);
622 637 : return f;
623 : }
624 : /* y t_REAL, x \ y */
625 : static GEN
626 70 : _quotsr(long x, GEN y)
627 : {
628 : GEN q, f;
629 70 : if (!x) return gen_0;
630 70 : q = divsr(x,y); f = floorr(q);
631 70 : if (signe(y) < 0 && signe(subir(f,q))) f = addiu(f, 1);
632 70 : return f;
633 : }
634 : /* x t_REAL, x \ y */
635 : static GEN
636 28 : _quotrs(GEN x, long y)
637 : {
638 28 : GEN q = divrs(x,y), f = floorr(q);
639 28 : if (y < 0 && signe(subir(f,q))) f = addiu(f, 1);
640 28 : return f;
641 : }
642 : static GEN
643 7 : _quotri(GEN x, GEN y)
644 : {
645 7 : GEN q = divri(x,y), f = floorr(q);
646 7 : if (signe(y) < 0 && signe(subir(f,q))) f = addiu(f, 1);
647 7 : return f;
648 : }
649 : static GEN
650 70 : _quotsq(long x, GEN y)
651 : {
652 70 : GEN f = gfloor(gdivsg(x,y));
653 70 : if (gsigne(y) < 0) f = gaddgs(f, 1);
654 70 : return f;
655 : }
656 : static GEN
657 28 : _quotqs(GEN x, long y)
658 : {
659 28 : GEN f = gfloor(gdivgs(x,y));
660 28 : if (y < 0) f = addiu(f, 1);
661 28 : return f;
662 : }
663 :
664 : /* y t_FRAC, x \ y */
665 : static GEN
666 35 : _quotsf(long x, GEN y)
667 35 : { return truedivii(mulis(gel(y,2),x), gel(y,1)); }
668 : /* x t_FRAC, x \ y */
669 : static GEN
670 301 : _quotfs(GEN x, long y)
671 301 : { return truedivii(gel(x,1),mulis(gel(x,2),y)); }
672 : /* x t_FRAC, y t_INT, x \ y */
673 : static GEN
674 7 : _quotfi(GEN x, GEN y)
675 7 : { return truedivii(gel(x,1),mulii(gel(x,2),y)); }
676 :
677 : static GEN
678 777 : quot(GEN x, GEN y)
679 777 : { pari_sp av = avma; return gc_upto(av, _quot(x, y)); }
680 : static GEN
681 14 : quotrs(GEN x, long y)
682 14 : { pari_sp av = avma; return gc_leaf(av, _quotrs(x,y)); }
683 : static GEN
684 301 : quotfs(GEN x, long s)
685 301 : { pari_sp av = avma; return gc_leaf(av, _quotfs(x,s)); }
686 : static GEN
687 35 : quotsr(long x, GEN y)
688 35 : { pari_sp av = avma; return gc_leaf(av, _quotsr(x, y)); }
689 : static GEN
690 35 : quotsf(long x, GEN y)
691 35 : { pari_sp av = avma; return gc_leaf(av, _quotsf(x, y)); }
692 : static GEN
693 35 : quotsq(long x, GEN y)
694 35 : { pari_sp av = avma; return gc_leaf(av, _quotsq(x, y)); }
695 : static GEN
696 14 : quotqs(GEN x, long y)
697 14 : { pari_sp av = avma; return gc_leaf(av, _quotqs(x, y)); }
698 : static GEN
699 7 : quotfi(GEN x, GEN y)
700 7 : { pari_sp av = avma; return gc_leaf(av, _quotfi(x, y)); }
701 : static GEN
702 7 : quotri(GEN x, GEN y)
703 7 : { pari_sp av = avma; return gc_leaf(av, _quotri(x, y)); }
704 :
705 : static GEN
706 14 : modrs(GEN x, long y)
707 : {
708 14 : pari_sp av = avma;
709 14 : GEN q = _quotrs(x,y);
710 14 : if (!signe(q)) { set_avma(av); return rcopy(x); }
711 7 : return gc_leaf(av, subri(x, mulis(q,y)));
712 : }
713 : static GEN
714 35 : modsr(long x, GEN y)
715 : {
716 35 : pari_sp av = avma;
717 35 : GEN q = _quotsr(x,y);
718 35 : if (!signe(q)) return gc_stoi(av, x);
719 7 : return gc_leaf(av, subsr(x, mulir(q,y)));
720 : }
721 : static GEN
722 35 : modsf(long x, GEN y)
723 : {
724 35 : pari_sp av = avma;
725 35 : return gc_upto(av, Qdivii(modii(mulis(gel(y,2),x), gel(y,1)), gel(y,2)));
726 : }
727 :
728 : /* assume y a t_REAL, x a t_INT, t_FRAC or t_REAL.
729 : * Return x mod y or NULL if accuracy error */
730 : GEN
731 0 : modRr_safe(GEN x, GEN y)
732 : {
733 : GEN q, f;
734 : long e;
735 0 : if (isintzero(x)) return gen_0;
736 0 : q = gdiv(x,y); /* t_REAL */
737 :
738 0 : e = expo(q);
739 0 : if (e >= 0 && nbits2prec(e+1) > realprec(q)) return NULL;
740 0 : f = floorr(q);
741 0 : if (signe(y) < 0 && signe(subri(q,f))) f = addiu(f, 1);
742 0 : return signe(f)? gsub(x, mulir(f,y)): x;
743 : }
744 : GEN
745 5098249 : modRr_i(GEN x, GEN y, GEN iy)
746 : {
747 : GEN q, f;
748 : long e;
749 5098249 : if (isintzero(x)) return gen_0;
750 5098246 : q = gmul(x, iy); /* t_REAL */
751 :
752 5098244 : e = expo(q);
753 5098244 : if (e >= 0 && nbits2prec(e+1) > realprec(q)) return NULL;
754 5098243 : f = floorr(q);
755 5098096 : if (signe(y) < 0 && signe(subri(q,f))) f = addiu(f, 1);
756 5098192 : return signe(f)? gsub(x, mulir(f,y)): x;
757 : }
758 :
759 : GEN
760 46171616 : gmod(GEN x, GEN y)
761 : {
762 : pari_sp av;
763 : long ty, tx;
764 : GEN z;
765 :
766 46171616 : tx = typ(x); if (tx == t_INT && !is_bigint(x)) return gmodsg(itos(x),y);
767 1157491 : ty = typ(y); if (ty == t_INT && !is_bigint(y)) return gmodgs(x,itos(y));
768 1754296 : if (is_matvec_t(tx)) pari_APPLY_same(gmod(gel(x,i), y));
769 816976 : if (tx == t_POL || ty == t_POL) return grem(x,y);
770 511328 : if (!is_scalar_t(tx) || !is_scalar_t(ty)) pari_err_TYPE2("%",x,y);
771 511265 : switch(ty)
772 : {
773 510761 : case t_INT:
774 : switch(tx)
775 : {
776 507661 : case t_INT: return modii(x,y);
777 7 : case t_INTMOD: z=cgetg(3, t_INTMOD);
778 7 : gel(z,1) = gcdii(gel(x,1),y);
779 7 : gel(z,2) = modii(gel(x,2),gel(z,1)); return z;
780 491 : case t_FRAC: return Fp_div(gel(x,1),gel(x,2),y);
781 2567 : case t_PADIC: return padic_to_Fp(x, y);
782 14 : case t_QUAD: if (!is_realquad(x)) break;
783 : case t_REAL:
784 14 : av = avma; /* NB: conflicting semantic with lift(x * Mod(1,y)). */
785 14 : return gc_upto(av, gsub(x, gmul(_quot(x,y),y)));
786 : }
787 21 : break;
788 126 : case t_QUAD:
789 126 : if (!is_realquad(y)) break;
790 : case t_REAL: case t_FRAC:
791 189 : if (!is_realext(x)) break;
792 84 : av = avma;
793 84 : return gc_upto(av, gsub(x, gmul(_quot(x,y),y)));
794 : }
795 441 : pari_err_TYPE2("%",x,y);
796 : return NULL; /* LCOV_EXCL_LINE */
797 : }
798 :
799 : GEN
800 22030548 : gmodgs(GEN x, long y)
801 : {
802 : ulong u;
803 22030548 : long i, tx = typ(x);
804 : GEN z;
805 43824770 : if (is_matvec_t(tx)) pari_APPLY_same(gmodgs(gel(x,i), y));
806 19652250 : if (!y) pari_err_INV("gmodgs",gen_0);
807 19652250 : switch(tx)
808 : {
809 19566496 : case t_INT: return modis(x,y);
810 14 : case t_REAL: return modrs(x,y);
811 :
812 21 : case t_INTMOD: z=cgetg(3, t_INTMOD);
813 21 : u = (ulong)labs(y);
814 21 : i = ugcdiu(gel(x,1), u);
815 21 : gel(z,1) = utoi(i);
816 21 : gel(z,2) = modis(gel(x,2), i); return z;
817 :
818 84317 : case t_FRAC:
819 84317 : u = (ulong)labs(y);
820 84317 : return utoi( Fl_div(umodiu(gel(x,1), u),
821 84317 : umodiu(gel(x,2), u), u) );
822 28 : case t_QUAD:
823 : {
824 28 : pari_sp av = avma;
825 28 : if (!is_realquad(x)) break;
826 14 : return gc_upto(av, gsub(x, gmulgs(_quotqs(x,y),y)));
827 : }
828 1318 : case t_PADIC: return padic_to_Fp(x, stoi(y));
829 14 : case t_POL: return scalarpol(Rg_get_0(x), varn(x));
830 14 : case t_POLMOD: return gmul(gen_0,x);
831 : }
832 42 : pari_err_TYPE2("%",x,stoi(y));
833 : return NULL; /* LCOV_EXCL_LINE */
834 : }
835 : GEN
836 45014125 : gmodsg(long x, GEN y)
837 : {
838 45014125 : switch(typ(y))
839 : {
840 45013768 : case t_INT: return modsi(x,y);
841 35 : case t_REAL: return modsr(x,y);
842 35 : case t_FRAC: return modsf(x,y);
843 63 : case t_QUAD:
844 : {
845 63 : pari_sp av = avma;
846 63 : if (!is_realquad(y)) break;
847 35 : return gc_upto(av, gsubsg(x, gmul(_quotsq(x,y),y)));
848 : }
849 112 : case t_POL:
850 112 : if (!signe(y)) pari_err_INV("gmodsg",y);
851 112 : return degpol(y)? gmulsg(x, Rg_get_1(y)): Rg_get_0(y);
852 : }
853 140 : pari_err_TYPE2("%",stoi(x),y);
854 : return NULL; /* LCOV_EXCL_LINE */
855 : }
856 : /* divisibility: return 1 if y | x, 0 otherwise */
857 : int
858 15890 : gdvd(GEN x, GEN y)
859 : {
860 15890 : pari_sp av = avma;
861 15890 : return gc_bool(av, gequal0( gmod(x,y) ));
862 : }
863 :
864 : GEN
865 1074300 : gmodulss(long x, long y)
866 : {
867 1074300 : if (!y) pari_err_INV("%",gen_0);
868 1074293 : y = labs(y);
869 1074293 : retmkintmod(utoi(umodsu(x, y)), utoipos(y));
870 : }
871 : GEN
872 1341762 : gmodulsg(long x, GEN y)
873 : {
874 1341762 : switch(typ(y))
875 : {
876 1127441 : case t_INT:
877 1127441 : if (!is_bigint(y)) return gmodulss(x,itos(y));
878 62416 : retmkintmod(modsi(x,y), absi(y));
879 214314 : case t_POL:
880 214314 : if (!signe(y)) pari_err_INV("%", y);
881 214307 : retmkpolmod(degpol(y)? stoi(x): gen_0,RgX_copy(y));
882 : }
883 7 : pari_err_TYPE2("%",stoi(x),y);
884 : return NULL; /* LCOV_EXCL_LINE */
885 : }
886 : GEN
887 1958092 : gmodulo(GEN x,GEN y)
888 : {
889 1958092 : long tx = typ(x), vx, vy;
890 1958092 : if (tx == t_INT && !is_bigint(x)) return gmodulsg(itos(x), y);
891 1461053 : if (is_matvec_t(tx)) pari_APPLY_same(gmodulo(gel(x,i), y));
892 578934 : switch(typ(y))
893 : {
894 98223 : case t_INT:
895 98223 : if (!is_const_t(tx)) return gmul(x, gmodulsg(1,y));
896 98174 : if (tx == t_INTMOD) return gmod(x,y);
897 98167 : retmkintmod(Rg_to_Fp(x,y), absi(y));
898 480711 : case t_POL:
899 480711 : vx = gvar(x); vy = varn(y);
900 480711 : if (varncmp(vy, vx) > 0) return gmul(x, gmodulsg(1,y));
901 480620 : if (vx == vy && tx == t_POLMOD) return grem(x,y);
902 467740 : retmkpolmod(grem(x,y), RgX_copy(y));
903 : }
904 0 : pari_err_TYPE2("%",x,y);
905 : return NULL; /* LCOV_EXCL_LINE */
906 : }
907 :
908 : /*******************************************************************/
909 : /* */
910 : /* GENERIC EUCLIDEAN DIVISION */
911 : /* */
912 : /*******************************************************************/
913 : GEN
914 6204793 : gdivent(GEN x, GEN y)
915 : {
916 : long tx, ty;
917 6204793 : tx = typ(x); if (tx == t_INT && !is_bigint(x)) return gdiventsg(itos(x),y);
918 2188 : ty = typ(y); if (ty == t_INT && !is_bigint(y)) return gdiventgs(x,itos(y));
919 1960 : if (is_matvec_t(tx)) pari_APPLY_same(gdivent(gel(x,i), y));
920 1610 : if (tx == t_POL || ty == t_POL) return gdeuc(x,y);
921 1148 : switch(ty)
922 : {
923 112 : case t_INT:
924 : switch(tx)
925 : {
926 7 : case t_INT: return truedivii(x,y);
927 7 : case t_REAL: return quotri(x,y);
928 7 : case t_FRAC: return quotfi(x,y);
929 21 : case t_QUAD:
930 21 : if (!is_realquad(x)) break;
931 7 : return quot(x,y);
932 : }
933 84 : break;
934 252 : case t_QUAD:
935 252 : if (!is_realext(x) || !is_realquad(y)) break;
936 : case t_REAL: case t_FRAC:
937 252 : return quot(x,y);
938 : }
939 868 : pari_err_TYPE2("\\",x,y);
940 : return NULL; /* LCOV_EXCL_LINE */
941 : }
942 :
943 : GEN
944 327749 : gdiventgs(GEN x, long y)
945 : {
946 327749 : switch(typ(x))
947 : {
948 268366 : case t_INT: return truedivis(x,y);
949 14 : case t_REAL: return quotrs(x,y);
950 301 : case t_FRAC: return quotfs(x,y);
951 42 : case t_QUAD: if (!is_realquad(x)) break;
952 14 : return quotqs(x,y);
953 28 : case t_POL: return gdivgs(x,y);
954 316538 : case t_VEC: case t_COL: case t_MAT: pari_APPLY_same(gdiventgs(gel(x,i),y));
955 : }
956 168 : pari_err_TYPE2("\\",x,stoi(y));
957 : return NULL; /* LCOV_EXCL_LINE */
958 : }
959 : GEN
960 6202605 : gdiventsg(long x, GEN y)
961 : {
962 6202605 : switch(typ(y))
963 : {
964 6202150 : case t_INT: return truedivsi(x,y);
965 35 : case t_REAL: return quotsr(x,y);
966 35 : case t_FRAC: return quotsf(x,y);
967 91 : case t_QUAD: if (!is_realquad(y)) break;
968 35 : return quotsq(x,y);
969 70 : case t_POL:
970 70 : if (!signe(y)) pari_err_INV("gdiventsg",y);
971 70 : return degpol(y)? Rg_get_0(y): gdivsg(x,gel(y,2));
972 : }
973 280 : pari_err_TYPE2("\\",stoi(x),y);
974 : return NULL; /* LCOV_EXCL_LINE */
975 : }
976 :
977 : /* with remainder */
978 : static GEN
979 518 : quotrem(GEN x, GEN y, GEN *r)
980 : {
981 518 : GEN q = quot(x,y);
982 448 : pari_sp av = avma;
983 448 : *r = gc_upto(av, gsub(x, gmul(q,y)));
984 448 : return q;
985 : }
986 :
987 : GEN
988 1064 : gdiventres(GEN x, GEN y)
989 : {
990 1064 : long tx = typ(x), ty = typ(y);
991 : GEN z;
992 :
993 1078 : if (is_matvec_t(tx)) pari_APPLY_same(gdiventres(gel(x,i), y));
994 1057 : z = cgetg(3,t_COL);
995 1057 : if (tx == t_POL || ty == t_POL)
996 : {
997 182 : gel(z,1) = poldivrem(x,y,(GEN*)(z+2));
998 168 : return z;
999 : }
1000 875 : switch(ty)
1001 : {
1002 252 : case t_INT:
1003 : switch(tx)
1004 : { /* equal to, but more efficient than next case */
1005 84 : case t_INT:
1006 84 : gel(z,1) = truedvmdii(x,y,(GEN*)(z+2));
1007 84 : return z;
1008 42 : case t_QUAD:
1009 42 : if (!is_realquad(x)) break;
1010 : case t_REAL: case t_FRAC:
1011 63 : gel(z,1) = quotrem(x,y,&gel(z,2));
1012 63 : return z;
1013 : }
1014 105 : break;
1015 154 : case t_QUAD:
1016 154 : if (!is_realext(x) || !is_realquad(y)) break;
1017 : case t_REAL: case t_FRAC:
1018 196 : gel(z,1) = quotrem(x,y,&gel(z,2));
1019 126 : return z;
1020 : }
1021 532 : pari_err_TYPE2("\\",x,y);
1022 : return NULL; /* LCOV_EXCL_LINE */
1023 : }
1024 :
1025 : GEN
1026 1057 : divrem(GEN x, GEN y, long v)
1027 : {
1028 1057 : pari_sp av = avma;
1029 : long vx, vy, vz;
1030 : GEN q, r;
1031 1057 : if (v < 0 || typ(y) != t_POL || typ(x) != t_POL) return gdiventres(x,y);
1032 7 : vz = v; vx = varn(x); vy = varn(y);
1033 7 : if (varncmp(vx, vz) < 0 || varncmp(vy, vz) < 0) vz = fetch_var_higher();
1034 7 : if (vx != vz) x = swap_vars(x, v, vz);
1035 7 : if (vy != vz) y = swap_vars(y, v, vz);
1036 7 : q = RgX_divrem(x,y, &r);
1037 7 : if (vx != v || vy != v)
1038 : {
1039 7 : GEN X = pol_x(v);
1040 7 : q = gsubst(q, vz, X); /* poleval broken for t_RFRAC, subst is safe */
1041 7 : r = gsubst(r, vz, X);
1042 7 : if (vz != v) (void)delete_var();
1043 : }
1044 7 : return gc_GEN(av, mkcol2(q, r));
1045 : }
1046 :
1047 : GEN
1048 67772249 : diviiround(GEN x, GEN y)
1049 : {
1050 67772249 : pari_sp av1, av = avma;
1051 : GEN q,r;
1052 : int fl;
1053 :
1054 67772249 : q = dvmdii(x,y,&r); /* q = x/y rounded towards 0, sgn(r)=sgn(x) */
1055 67760487 : if (r==gen_0) return q;
1056 36882990 : av1 = avma;
1057 36882990 : fl = abscmpii(shifti(r,1),y);
1058 36886652 : set_avma(av1); cgiv(r);
1059 36911682 : if (fl >= 0) /* If 2*|r| >= |y| */
1060 : {
1061 20156728 : long sz = signe(x)*signe(y);
1062 20156728 : if (fl || sz > 0) q = gc_INT(av, addis(q,sz));
1063 : }
1064 36915342 : return q;
1065 : }
1066 :
1067 : static GEN
1068 518 : _abs(GEN x)
1069 : {
1070 518 : if (typ(x) == t_QUAD) return (gsigne(x) < 0)? gneg(x): x;
1071 364 : return R_abs_shallow(x);
1072 : }
1073 :
1074 : /* If x and y are not both scalars, same as gdivent.
1075 : * Otherwise, compute the quotient x/y, rounded to the nearest integer
1076 : * (towards +oo in case of tie). */
1077 : GEN
1078 1459152 : gdivround(GEN x, GEN y)
1079 : {
1080 : pari_sp av;
1081 1459152 : long tx = typ(x), ty = typ(y);
1082 : GEN q, r;
1083 :
1084 1459152 : if (tx == t_INT && ty == t_INT) return diviiround(x,y);
1085 176690 : av = avma;
1086 176690 : if (is_realext(x) && is_realext(y))
1087 : { /* same as diviiround, less efficient */
1088 : pari_sp av1;
1089 : int fl;
1090 259 : q = quotrem(x,y,&r); av1 = avma;
1091 259 : fl = gcmp(gmul2n(_abs(r),1), _abs(y));
1092 259 : set_avma(av1); cgiv(r);
1093 259 : if (fl >= 0) /* If 2*|r| >= |y| */
1094 : {
1095 84 : long sz = gsigne(y);
1096 84 : if (fl || sz > 0) q = gc_upto(av, gaddgs(q, sz));
1097 : }
1098 259 : return q;
1099 : }
1100 1589374 : if (is_matvec_t(tx)) pari_APPLY_same(gdivround(gel(x,i),y));
1101 931 : return gdivent(x,y);
1102 : }
1103 :
1104 : GEN
1105 0 : gdivmod(GEN x, GEN y, GEN *pr)
1106 : {
1107 0 : switch(typ(x))
1108 : {
1109 0 : case t_INT:
1110 0 : switch(typ(y))
1111 : {
1112 0 : case t_INT: return dvmdii(x,y,pr);
1113 0 : case t_POL: *pr=icopy(x); return gen_0;
1114 : }
1115 0 : break;
1116 0 : case t_POL: return poldivrem(x,y,pr);
1117 : }
1118 0 : pari_err_TYPE2("gdivmod",x,y);
1119 : return NULL;/*LCOV_EXCL_LINE*/
1120 : }
1121 :
1122 : /*******************************************************************/
1123 : /* */
1124 : /* SHIFT */
1125 : /* */
1126 : /*******************************************************************/
1127 :
1128 : /* Shift tronque si n<0 (multiplication tronquee par 2^n) */
1129 :
1130 : GEN
1131 47181108 : gshift(GEN x, long n)
1132 : {
1133 47181108 : switch(typ(x))
1134 : {
1135 38985204 : case t_INT: return shifti(x,n);
1136 7467465 : case t_REAL:return shiftr(x,n);
1137 2250633 : case t_VEC: case t_COL: case t_MAT: pari_APPLY_same(gshift(gel(x,i),n));
1138 : }
1139 155198 : return gmul2n(x,n);
1140 : }
1141 :
1142 : /*******************************************************************/
1143 : /* */
1144 : /* SUBSTITUTION DANS UN POLYNOME OU UNE SERIE */
1145 : /* */
1146 : /*******************************************************************/
1147 :
1148 : /* Convert t_SER --> t_POL, ignoring valser. INTERNAL ! */
1149 : GEN
1150 11412844 : ser2pol_i(GEN x, long lx)
1151 : {
1152 11412844 : long i = lx-1;
1153 : GEN y;
1154 15907231 : while (i > 1 && isrationalzero(gel(x,i))) i--;
1155 11412844 : if (!signe(x))
1156 : { /* danger */
1157 77 : if (i == 1) return zeropol(varn(x));
1158 77 : y = cgetg(3,t_POL); y[1] = x[1] & ~VALSERBITS;
1159 77 : gel(y,2) = gel(x,2); return y;
1160 : }
1161 11412767 : y = cgetg(i+1, t_POL); y[1] = x[1] & ~VALSERBITS;
1162 48894996 : for ( ; i > 1; i--) gel(y,i) = gel(x,i);
1163 11412767 : return y;
1164 : }
1165 :
1166 : GEN
1167 864727 : ser2pol_i_normalize(GEN x, long l, long *v)
1168 : {
1169 864727 : long i = 2, j = l-1, k;
1170 : GEN y;
1171 864762 : while (i < l && gequal0(gel(x,i))) i++;
1172 864727 : *v = i - 2; if (i == l) return zeropol(varn(x));
1173 1113520 : while (j > i && gequal0(gel(x,j))) j--;
1174 864713 : l = j - *v + 1;
1175 864713 : y = cgetg(l, t_POL); y[1] = x[1] & ~VALSERBITS;
1176 4445652 : k = l; while (k > 2) gel(y, --k) = gel(x,j--);
1177 864713 : return y;
1178 : }
1179 :
1180 : GEN
1181 48846 : ser_inv(GEN b)
1182 : {
1183 48846 : pari_sp av = avma;
1184 48846 : long e, l = lg(b);
1185 : GEN x, y;
1186 48846 : y = ser2pol_i_normalize(b, l, &e);
1187 48846 : if (e)
1188 : {
1189 0 : pari_warn(warner,"normalizing a series with 0 leading term");
1190 0 : l -= e; if (l <= 2) pari_err_INV("inv_ser", b);
1191 : }
1192 48846 : y = RgXn_inv_i(y, l-2);
1193 48839 : x = RgX_to_ser(y, l); setvalser(x, - valser(b) - e);
1194 48839 : return gc_GEN(av, x);
1195 : }
1196 :
1197 : /* T t_POL in var v, mod out by T components of x which are t_POL/t_RFRAC in v.
1198 : * Recursively. Make sure that resulting polynomials of degree 0 in v are
1199 : * simplified (map K[X]_0 to K) */
1200 : static GEN
1201 210 : mod_r(GEN x, long v, GEN T)
1202 : {
1203 210 : long w, tx = typ(x);
1204 : GEN y;
1205 :
1206 210 : if (is_const_t(tx)) return x;
1207 161 : switch(tx)
1208 : {
1209 7 : case t_POLMOD:
1210 7 : w = varn(gel(x,1));
1211 7 : if (w == v) pari_err_PRIORITY("subst", gel(x,1), "=", v);
1212 7 : if (varncmp(v, w) < 0) return x;
1213 7 : return gmodulo(mod_r(gel(x,2),v,T), mod_r(gel(x,1),v,T));
1214 7 : case t_SER:
1215 7 : w = varn(x);
1216 7 : if (w == v) break; /* fail */
1217 7 : if (varncmp(v, w) < 0 || ser_isexactzero(x)) return x;
1218 21 : pari_APPLY_ser(mod_r(gel(x,i),v,T));
1219 119 : case t_POL:
1220 119 : w = varn(x);
1221 119 : if (w == v)
1222 : {
1223 91 : x = RgX_rem(x, T);
1224 91 : if (!degpol(x)) x = gel(x,2);
1225 91 : return x;
1226 : }
1227 28 : if (varncmp(v, w) < 0) return x;
1228 98 : pari_APPLY_pol(mod_r(gel(x,i),v,T));
1229 14 : case t_RFRAC:
1230 14 : x = gdiv(mod_r(gel(x,1),v,T), mod_r(gel(x,2),v,T));
1231 14 : if (typ(x) == t_POL && varn(x) == v && lg(x) == 3) x = gel(x,2);
1232 14 : return x;
1233 7 : case t_VEC: case t_COL: case t_MAT:
1234 21 : pari_APPLY_same(mod_r(gel(x,i),v,T));
1235 7 : case t_LIST:
1236 7 : y = mklist();
1237 7 : list_data(y) = list_data(x)? mod_r(list_data(x),v,T): NULL;
1238 7 : return y;
1239 : }
1240 0 : pari_err_TYPE("substpol",x);
1241 : return NULL;/*LCOV_EXCL_LINE*/
1242 : }
1243 : GEN
1244 8302 : gsubstpol(GEN x, GEN T, GEN y)
1245 : {
1246 8302 : pari_sp av = avma;
1247 : long v;
1248 : GEN z;
1249 8302 : if (typ(T) == t_POL && RgX_is_monomial(T) && gequal1(leading_coeff(T)))
1250 : { /* T = t^d */
1251 8267 : long d = degpol(T);
1252 8267 : v = varn(T); z = (d==1)? x: gdeflate(x, v, d);
1253 8253 : if (z) return gc_upto(av, gsubst(z, v, y));
1254 : }
1255 63 : v = fetch_var(); T = simplify_shallow(T);
1256 63 : if (typ(T) == t_RFRAC)
1257 21 : z = gsub(gel(T,1), gmul(pol_x(v), gel(T,2)));
1258 : else
1259 42 : z = gsub(T, pol_x(v));
1260 63 : z = mod_r(x, gvar(T), z);
1261 63 : z = gsubst(z, v, y); (void)delete_var();
1262 63 : return gc_upto(av, z);
1263 : }
1264 :
1265 : long
1266 1246530 : RgX_deflate_order(GEN x)
1267 : {
1268 1246530 : ulong d = 0, i, lx = (ulong)lg(x);
1269 2726788 : for (i=3; i<lx; i++)
1270 2351393 : if (!gequal0(gel(x,i))) { d = ugcd(d,i-2); if (d == 1) return 1; }
1271 375395 : return d? (long)d: 1;
1272 : }
1273 : long
1274 526773 : ZX_deflate_order(GEN x)
1275 : {
1276 526773 : ulong d = 0, i, lx = (ulong)lg(x);
1277 1636987 : for (i=3; i<lx; i++)
1278 1440669 : if (signe(gel(x,i))) { d = ugcd(d,i-2); if (d == 1) return 1; }
1279 196318 : return d? (long)d: 1;
1280 : }
1281 :
1282 : /* deflate (non-leaf) x recursively */
1283 : static GEN
1284 63 : vdeflate(GEN x, long v, long d)
1285 : {
1286 63 : long i, lx, tx = typ(x);
1287 63 : GEN y = cgetg_copy(x, &lx);
1288 98 : for(i = 1; i < lontyp[tx]; i++) y[i] = x[i];
1289 154 : for (; i < lx; i++)
1290 : {
1291 133 : gel(y,i) = gdeflate(gel(x,i),v,d);
1292 133 : if (!y[i]) return NULL;
1293 : }
1294 21 : return y;
1295 : }
1296 :
1297 : /* don't return NULL if substitution fails (fallback won't be able to handle
1298 : * t_SER anyway), fail with a meaningful message */
1299 : static GEN
1300 6566 : serdeflate(GEN x, long v, long d)
1301 : {
1302 6566 : long V, dy, lx, vx = varn(x);
1303 : pari_sp av;
1304 : GEN y;
1305 6566 : if (varncmp(vx, v) < 0) return vdeflate(x,v,d);
1306 6559 : if (varncmp(vx, v) > 0) return gcopy(x);
1307 6559 : av = avma;
1308 6559 : V = valser(x);
1309 6559 : lx = lg(x);
1310 6559 : if (lx == 2) return zeroser(v, V / d);
1311 6559 : y = ser2pol_i(x, lx);
1312 6559 : dy = degpol(y);
1313 6559 : if (V % d != 0 || (dy > 0 && RgX_deflate_order(y) % d != 0))
1314 : {
1315 14 : const char *s = stack_sprintf("valuation(x) %% %ld", d);
1316 14 : pari_err_DOMAIN("gdeflate", s, "!=", gen_0,x);
1317 : }
1318 6545 : if (dy > 0) y = RgX_deflate(y, d);
1319 6545 : y = RgX_to_ser(y, 3 + (lx-3)/d);
1320 6545 : setvalser(y, V/d); return gc_GEN(av, y);
1321 : }
1322 : static GEN
1323 8267 : poldeflate(GEN x, long v, long d)
1324 : {
1325 8267 : long vx = varn(x);
1326 : pari_sp av;
1327 8267 : if (varncmp(vx, v) < 0) return vdeflate(x,v,d);
1328 8239 : if (varncmp(vx, v) > 0 || degpol(x) <= 0) return gcopy(x);
1329 8239 : av = avma;
1330 : /* x nonconstant */
1331 8239 : if (RgX_deflate_order(x) % d != 0) return NULL;
1332 8211 : return gc_GEN(av, RgX_deflate(x,d));
1333 : }
1334 : static GEN
1335 21 : listdeflate(GEN x, long v, long d)
1336 : {
1337 21 : GEN y = NULL, z = mklist();
1338 21 : if (list_data(x))
1339 : {
1340 14 : y = vdeflate(list_data(x),v,d);
1341 14 : if (!y) return NULL;
1342 : }
1343 14 : list_data(z) = y; return z;
1344 : }
1345 : /* return NULL if substitution fails */
1346 : GEN
1347 14931 : gdeflate(GEN x, long v, long d)
1348 : {
1349 14931 : if (d <= 0) pari_err_DOMAIN("gdeflate", "degree", "<=", gen_0,stoi(d));
1350 14931 : switch(typ(x))
1351 : {
1352 63 : case t_INT:
1353 : case t_REAL:
1354 : case t_INTMOD:
1355 : case t_FRAC:
1356 : case t_FFELT:
1357 : case t_COMPLEX:
1358 : case t_PADIC:
1359 63 : case t_QUAD: return gcopy(x);
1360 8267 : case t_POL: return poldeflate(x,v,d);
1361 6566 : case t_SER: return serdeflate(x,v,d);
1362 7 : case t_POLMOD:
1363 7 : if (varncmp(varn(gel(x,1)), v) >= 0) return gcopy(x);
1364 : /* fall through */
1365 : case t_RFRAC:
1366 : case t_VEC:
1367 : case t_COL:
1368 14 : case t_MAT: return vdeflate(x,v,d);
1369 21 : case t_LIST: return listdeflate(x,v,d);
1370 : }
1371 0 : pari_err_TYPE("gdeflate",x);
1372 : return NULL; /* LCOV_EXCL_LINE */
1373 : }
1374 :
1375 : /* set *m to the largest d such that x0 = A(X^d); return A */
1376 : GEN
1377 729356 : RgX_deflate_max(GEN x, long *m)
1378 : {
1379 729356 : *m = RgX_deflate_order(x);
1380 729356 : return RgX_deflate(x, *m);
1381 : }
1382 : GEN
1383 327836 : ZX_deflate_max(GEN x, long *m)
1384 : {
1385 327836 : *m = ZX_deflate_order(x);
1386 327834 : return RgX_deflate(x, *m);
1387 : }
1388 :
1389 : static int
1390 24388 : serequalXk(GEN x)
1391 : {
1392 24388 : long i, l = lg(x);
1393 24388 : if (l == 2 || !isint1(gel(x,2))) return 0;
1394 10948 : for (i = 3; i < l; i++)
1395 8638 : if (!isintzero(gel(x,i))) return 0;
1396 2310 : return 1;
1397 : }
1398 :
1399 : static GEN
1400 84 : gsubst_v(GEN e, long v, GEN x)
1401 245 : { pari_APPLY_same(gsubst(e, v, gel(x,i))); }
1402 :
1403 : static GEN
1404 14 : constmat(GEN z, long n)
1405 : {
1406 14 : GEN y = cgetg(n+1, t_MAT), c = const_col(n, gcopy(z));
1407 : long i;
1408 35 : for (i = 1; i <= n; i++) gel(y, i) = c;
1409 14 : return y;
1410 : }
1411 : static GEN
1412 56 : scalarmat2(GEN o, GEN z, long n)
1413 : {
1414 : GEN y;
1415 : long i;
1416 56 : if (n == 0) return cgetg(1, t_MAT);
1417 56 : if (n == 1) retmkmat(mkcol(gcopy(o)));
1418 35 : y = cgetg(n+1, t_MAT); z = gcopy(z); o = gcopy(o);
1419 105 : for (i = 1; i <= n; i++) { gel(y, i) = const_col(n, z); gcoeff(y,i,i) = o; }
1420 35 : return y;
1421 : }
1422 : /* x * y^0, n = dim(y) if t_MAT, else -1 */
1423 : static GEN
1424 731101 : subst_higher(GEN x, GEN y, long n)
1425 : {
1426 731101 : GEN o = Rg_get_1(y);
1427 731101 : if (o == gen_1) return n < 0? gcopy(x): scalarmat(x,n);
1428 98 : x = gmul(x,o); return n < 0? x: scalarmat2(x, Rg_get_0(y), n);
1429 : }
1430 :
1431 : /* x t_POLMOD, v strictly lower priority than var(x) */
1432 : static GEN
1433 574 : subst_polmod(GEN x, long v, GEN y)
1434 : {
1435 : long l, i;
1436 574 : GEN a = gsubst(gel(x,2),v,y), b = gsubst(gel(x,1),v,y), z;
1437 :
1438 574 : if (typ(b) != t_POL) pari_err_TYPE2("substitution",x,y);
1439 574 : if (typ(a) != t_POL || varncmp(varn(a), varn(b)) >= 0) return gmodulo(a, b);
1440 539 : l = lg(a); z = cgetg(l,t_POL); z[1] = a[1];
1441 4151 : for (i = 2; i < l; i++) gel(z,i) = gmodulo(gel(a,i),b);
1442 539 : return normalizepol_lg(z, l);
1443 : }
1444 : /* Trunc to n terms; x + O(t^(n + v(x))). FIXME: export ? */
1445 : static GEN
1446 70 : sertrunc(GEN x, long n)
1447 : {
1448 70 : long i, l = n + 2;
1449 : GEN y;
1450 70 : if (l >= lg(x)) return x;
1451 14 : if (n <= 0) return zeroser(varn(x), n + valser(x));
1452 14 : y = cgetg(l, t_SER);
1453 28 : for (i = 2; i < l; i++) gel(y,i) = gel(x,i);
1454 14 : y[1] = x[1]; return y;
1455 : }
1456 : /* FIXME: export ? */
1457 : static GEN
1458 2317 : sertrunc_copy(GEN x, long n)
1459 : {
1460 2317 : long i, l = minss(n + 2, lg(x));
1461 2317 : GEN y = cgetg(l, t_SER);
1462 15232 : for (i = 2; i < l; i++) gel(y,i) = gcopy(gel(x,i));
1463 2317 : y[1] = x[1]; return y;
1464 : }
1465 :
1466 : GEN
1467 2733810 : gsubst(GEN x, long v, GEN y)
1468 : {
1469 2733810 : long tx = typ(x), ty = typ(y), lx = lg(x), ly = lg(y);
1470 : long l, vx, vy, ex, ey, i, j, k, jb, matn;
1471 : pari_sp av, av2;
1472 : GEN X, t, z;
1473 :
1474 2733810 : switch(ty)
1475 : {
1476 84 : case t_VEC: case t_COL:
1477 84 : return gsubst_v(x, v, y);
1478 175 : case t_MAT:
1479 175 : if (ly==1) return cgetg(1,t_MAT);
1480 168 : if (ly == lgcols(y)) { matn = ly - 1; break; }
1481 : /* fall through */
1482 : case t_QFB:
1483 7 : pari_err_TYPE2("substitution",x,y);
1484 2733551 : default: matn = -1;
1485 : }
1486 2733712 : if (is_scalar_t(tx))
1487 : {
1488 384678 : if (tx == t_POLMOD && varncmp(v, varn(gel(x,1))) > 0)
1489 : {
1490 574 : av = avma;
1491 574 : return gc_upto(av, subst_polmod(x, v, y));
1492 : }
1493 384104 : return subst_higher(x, y, matn);
1494 : }
1495 :
1496 2349034 : switch(tx)
1497 : {
1498 2104120 : case t_POL:
1499 2104120 : vx = varn(x);
1500 2104120 : if (varncmp(vx, v) > 0) return subst_higher(x, y, matn);
1501 2102328 : if (varncmp(vx, v) < 0)
1502 : {
1503 166594 : if (lx == 2) return zeropol(vx);
1504 166503 : av = avma;
1505 166503 : if (lx == 3)
1506 : {
1507 28413 : z = gsubst(gel(x,2), v, y);
1508 28413 : if (typ(z) == t_POL && varn(z) == vx) return z;
1509 28413 : return gc_upto(av, gmul(pol_1(vx), z));
1510 : }
1511 138090 : z = cgetg(lx-1, t_VEC);
1512 736049 : for (i = 2; i < lx; i++) gel(z,i-1) = gsubst(gel(x,i),v,y);
1513 138090 : return gc_upto(av, poleval(z, pol_x(vx)));
1514 : }
1515 : /* v = vx */
1516 1935734 : if (lx == 2)
1517 : {
1518 27433 : z = Rg_get_0(y);
1519 27433 : return matn >= 0? constmat(z, matn): z;
1520 : }
1521 1908301 : if (lx == 3)
1522 : {
1523 345198 : x = subst_higher(gel(x,2), y, matn);
1524 345198 : if (matn >= 0) return x;
1525 345184 : vy = gvar(y);
1526 345184 : return (vy == NO_VARIABLE)? x: gmul(x, pol_1(vy));
1527 : }
1528 1563103 : return matn >= 0? RgX_RgM_eval(x, y): poleval(x,y);
1529 :
1530 30303 : case t_SER:
1531 30303 : vx = varn(x);
1532 30303 : if (varncmp(vx, v) > 0) return subst_higher(x, y, matn);
1533 30296 : ex = valser(x);
1534 30296 : if (varncmp(vx, v) < 0)
1535 : {
1536 56 : if (lx == 2) return matn >= 0? scalarmat(x, matn): gcopy(x);
1537 56 : av = avma; X = pol_x(vx);
1538 56 : av2 = avma;
1539 56 : z = gadd(gsubst(gel(x,lx-1),v,y), zeroser(vx,1));
1540 224 : for (i = lx-2; i>=2; i--)
1541 : {
1542 168 : z = gadd(gmul(z,X), gsubst(gel(x,i),v,y));
1543 168 : if (gc_needed(av2,1))
1544 : {
1545 0 : if(DEBUGMEM>1) pari_warn(warnmem,"gsubst (i = %ld)", i);
1546 0 : z = gc_upto(av2, z);
1547 : }
1548 : }
1549 56 : if (ex) z = gmul(z, pol_xnall(ex,vx));
1550 56 : return gc_upto(av, z);
1551 : }
1552 30240 : switch(ty) /* here vx == v */
1553 : {
1554 24507 : case t_SER:
1555 24507 : vy = varn(y); ey = valser(y);
1556 24507 : if (ey < 1 || lx == 2) return zeroser(vy, ey*(ex+lx-2));
1557 24500 : if (ey == 1 && serequalXk(y)
1558 2310 : && (varncmp(vx,vy) >= 0 || varncmp(gvar2(x), vy) >= 0))
1559 : { /* y = t + O(t^N) */
1560 2310 : if (lx > ly)
1561 : { /* correct number of significant terms */
1562 1981 : l = ly;
1563 1981 : if (!ex)
1564 1967 : for (i = 3; i < lx; i++)
1565 1967 : if (++l >= lx || !gequal0(gel(x,i))) break;
1566 1981 : lx = l;
1567 : }
1568 2310 : z = sertrunc_copy(x, lx - 2); if (vx != vy) setvarn(z,vy);
1569 2310 : return z;
1570 : }
1571 22190 : if (vy != vx)
1572 : {
1573 28 : long nx = lx - 2, n = minss(ey * nx, ly - 2);
1574 28 : av = avma; z = gel(x, nx+1);
1575 91 : for (i = nx; i > 1; i--)
1576 : {
1577 63 : z = gadd(gmul(y,z), gel(x,i));
1578 63 : if (gc_needed(av,1))
1579 : {
1580 0 : if(DEBUGMEM>1) pari_warn(warnmem,"gsubst (i = %ld)", i);
1581 0 : z = gc_upto(av, z);
1582 : }
1583 : }
1584 28 : if (ex)
1585 : {
1586 21 : if (ex < 0) { y = ginv(y); ex = -ex; }
1587 21 : z = gmul(z, gpowgs(sertrunc(y, n), ex));
1588 : }
1589 28 : if (lg(z)-2 > n) z = sertrunc_copy(z, n);
1590 28 : return gc_upto(av,z);
1591 : }
1592 22162 : l = (lx-2)*ey + 2;
1593 22162 : if (ex) { if (l>ly) l = ly; }
1594 22113 : else if (lx != 3)
1595 : {
1596 22141 : for (i = 3; i < lx; i++)
1597 22127 : if (!isexactzero(gel(x,i))) break;
1598 22113 : l = minss(l, (i-2)*ey + (gequal0(y)? 2 : ly));
1599 : }
1600 22162 : av = avma; t = leafcopy(y);
1601 22162 : if (l < ly) setlg(t, l);
1602 22162 : z = scalarser(gen_1, varn(y), l-2);
1603 22162 : gel(z,2) = gel(x,2); /* ensure lg(z) = l even if x[2] = 0 */
1604 88683 : for (i = 3, jb = ey; jb <= l-2; i++,jb += ey)
1605 : {
1606 66528 : if (i < lx) {
1607 149443 : for (j = jb+2; j < minss(l, jb+ly); j++)
1608 83006 : gel(z,j) = gadd(gel(z,j), gmul(gel(x,i),gel(t,j-jb)));
1609 : }
1610 104741 : for (j = minss(ly-1, l-1-jb-ey); j > 1; j--)
1611 : {
1612 38220 : GEN a = gmul(gel(t,2), gel(y,j));
1613 87395 : for (k=2; k<j; k++) a = gadd(a, gmul(gel(t,j-k+2), gel(y,k)));
1614 38220 : gel(t,j) = a;
1615 : }
1616 66521 : if (gc_needed(av,1))
1617 : {
1618 0 : if(DEBUGMEM>1) pari_warn(warnmem,"gsubst");
1619 0 : (void)gc_all(av,2, &z,&t);
1620 : }
1621 : }
1622 22155 : if (!ex) return gc_GEN(av,z);
1623 49 : if (ex < 0) { ex = -ex; y = ginv(y); }
1624 49 : return gc_upto(av, gmul(z, gpowgs(sertrunc(y, l-2), ex)));
1625 :
1626 5691 : case t_POL: case t_RFRAC:
1627 : {
1628 5691 : long N, n = lx-2;
1629 5691 : vy = gvar(y); ey = gval(y,vy);
1630 5691 : if (ey == LONG_MAX)
1631 : { /* y = 0 */
1632 49 : if (ex < 0) pari_err_INV("gsubst",y);
1633 35 : if (!n) return gcopy(x);
1634 28 : if (ex > 0) return Rg_get_0(ty == t_RFRAC? gel(y,2): y);
1635 14 : y = Rg_get_1(ty == t_RFRAC? gel(y,2): y);
1636 14 : return gmul(y, gel(x,2));
1637 : }
1638 5642 : if (ey < 1 || n == 0) return zeroser(vy, ey*(ex+n));
1639 5635 : av = avma;
1640 5635 : n *= ey;
1641 5635 : N = ex? n: maxss(n-ey,1);
1642 5635 : y = (ty == t_RFRAC)? rfrac_to_ser_i(y, N+2): RgX_to_ser(y, N+2);
1643 5635 : if (lg(y)-2 > n) setlg(y, n+2);
1644 5635 : x = ser2pol_i(x, lx);
1645 5635 : if (varncmp(vy,vx) > 0)
1646 49 : z = gadd(poleval(x, y), zeroser(vy,n));
1647 : else
1648 : {
1649 5586 : z = RgXn_eval(x, ser2rfrac_i(y), n);
1650 5586 : if (varn(z) == vy) z = RgX_to_ser(z, n+2);
1651 0 : else z = scalarser(z, vy, n);
1652 : }
1653 5635 : if (!ex) return gc_GEN(av, z);
1654 5530 : return gc_upto(av, gmul(z, gpowgs(y,ex)));
1655 : }
1656 :
1657 42 : default:
1658 42 : if (isexactzero(y))
1659 : {
1660 35 : if (ex < 0) pari_err_INV("gsubst",y);
1661 14 : if (ex > 0) return gcopy(y);
1662 7 : if (lx > 2) return gadd(gel(x,2), y); /*add maps to correct ring*/
1663 : }
1664 7 : pari_err_TYPE2("substitution",x,y);
1665 : }
1666 0 : break;
1667 :
1668 1890 : case t_RFRAC:
1669 : {
1670 1890 : GEN a = gel(x,1), b = gel(x,2);
1671 1890 : av = avma;
1672 1890 : a = gsubst(a, v, y);
1673 1890 : b = gsubst(b, v, y); return gc_upto(av, gdiv(a, b));
1674 : }
1675 :
1676 666842 : case t_VEC: case t_COL: case t_MAT: pari_APPLY_same(gsubst(gel(x,i),v,y));
1677 56 : case t_LIST:
1678 56 : z = mklist();
1679 56 : list_data(z) = list_data(x)? gsubst(list_data(x),v,y): NULL;
1680 56 : return z;
1681 : }
1682 0 : return gcopy(x);
1683 : }
1684 :
1685 : /* Return P(x * h), not memory clean */
1686 : GEN
1687 4193 : ser_unscale(GEN P, GEN h)
1688 : {
1689 4193 : long l = lg(P);
1690 4193 : GEN Q = cgetg(l,t_SER);
1691 4193 : Q[1] = P[1];
1692 4193 : if (l != 2)
1693 : {
1694 4193 : long i = 2;
1695 4193 : GEN hi = gpowgs(h, valser(P));
1696 4193 : gel(Q,i) = gmul(gel(P,i), hi);
1697 200508 : for (i++; i<l; i++) { hi = gmul(hi,h); gel(Q,i) = gmul(gel(P,i), hi); }
1698 : }
1699 4193 : return Q;
1700 : }
1701 :
1702 : static int
1703 1358 : safe_polmod(GEN r)
1704 : {
1705 1358 : GEN a = gel(r,1), b = gel(r,2);
1706 1358 : long t = typ(a);
1707 1358 : return 0;
1708 : if (gvar2(b) != NO_VARIABLE) return 0;
1709 : if (is_scalar_t(t)) return 1;
1710 : return (t == t_POL && varn(a) == varn(b) && gvar2(a) == NO_VARIABLE);
1711 : }
1712 : GEN
1713 980 : gsubstvec(GEN e, GEN v, GEN r)
1714 : {
1715 980 : pari_sp av = avma;
1716 980 : long i, j, k, l = lg(v);
1717 : GEN w, z, R;
1718 980 : if ( !is_vec_t(typ(v)) ) pari_err_TYPE("substvec",v);
1719 980 : if ( !is_vec_t(typ(r)) ) pari_err_TYPE("substvec",r);
1720 980 : if (lg(r)!=l) pari_err_DIM("substvec");
1721 980 : w = cgetg(l, t_VECSMALL);
1722 980 : z = cgetg(l, t_VECSMALL);
1723 980 : R = cgetg(l, t_VEC); k = 0;
1724 4298 : for(i = j = 1; i < l; i++)
1725 : {
1726 3318 : GEN T = gel(v,i), ri = gel(r,i);
1727 3318 : if (!gequalX(T)) pari_err_TYPE("substvec [not a variable]", T);
1728 3318 : if (gvar(ri) == NO_VARIABLE || (typ(ri) == t_POLMOD && safe_polmod(ri)))
1729 : { /* no need to take precautions */
1730 1855 : e = gsubst(e, varn(T), ri);
1731 1855 : if (is_vec_t(typ(ri)) && k++) e = shallowconcat1(e);
1732 : }
1733 : else
1734 : {
1735 1463 : w[j] = varn(T);
1736 1463 : z[j] = fetch_var_higher();
1737 1463 : gel(R,j) = ri; j++;
1738 : }
1739 : }
1740 2443 : for(i = 1; i < j; i++) e = gsubst(e,w[i],pol_x(z[i]));
1741 2443 : for(i = 1; i < j; i++)
1742 : {
1743 1463 : e = gsubst(e,z[i],gel(R,i));
1744 1463 : if (is_vec_t(typ(gel(R,i))) && k++) e = shallowconcat1(e);
1745 : }
1746 2443 : for(i = 1; i < j; i++) (void)delete_var();
1747 980 : return k > 1? gc_GEN(av, e): gc_upto(av, e);
1748 : }
1749 :
1750 : /*******************************************************************/
1751 : /* */
1752 : /* SERIE RECIPROQUE D'UNE SERIE */
1753 : /* */
1754 : /*******************************************************************/
1755 :
1756 : GEN
1757 98 : serreverse(GEN x)
1758 : {
1759 98 : long v=varn(x), lx = lg(x), i, mi;
1760 98 : pari_sp av0 = avma, av;
1761 : GEN a, y, u;
1762 :
1763 98 : if (typ(x)!=t_SER) pari_err_TYPE("serreverse",x);
1764 98 : if (valser(x)!=1) pari_err_DOMAIN("serreverse", "valuation", "!=", gen_1,x);
1765 91 : if (lx < 3) pari_err_DOMAIN("serreverse", "x", "=", gen_0,x);
1766 91 : y = ser_normalize(x);
1767 91 : if (y == x) a = NULL; else { a = gel(x,2); x = y; }
1768 91 : av = avma;
1769 252 : mi = lx-1; while (mi>=3 && gequal0(gel(x,mi))) mi--;
1770 91 : u = cgetg(lx,t_SER);
1771 91 : y = cgetg(lx,t_SER);
1772 91 : u[1] = y[1] = evalsigne(1) | _evalvalser(1) | evalvarn(v);
1773 91 : gel(u,2) = gel(y,2) = gen_1;
1774 91 : if (lx > 3)
1775 : {
1776 84 : gel(u,3) = gmulsg(-2,gel(x,3));
1777 84 : gel(y,3) = gneg(gel(x,3));
1778 : }
1779 1113 : for (i=3; i<lx-1; )
1780 : {
1781 : pari_sp av2;
1782 : GEN p1;
1783 1022 : long j, k, K = minss(i,mi);
1784 8456 : for (j=3; j<i+1; j++)
1785 : {
1786 7434 : av2 = avma; p1 = gel(x,j);
1787 39291 : for (k = maxss(3,j+2-mi); k < j; k++)
1788 31857 : p1 = gadd(p1, gmul(gel(u,k),gel(x,j-k+2)));
1789 7434 : p1 = gneg(p1);
1790 7434 : gel(u,j) = gc_upto(av2, gadd(gel(u,j), p1));
1791 : }
1792 1022 : av2 = avma;
1793 1022 : p1 = gmulsg(i,gel(x,i+1));
1794 8309 : for (k = 2; k < K; k++)
1795 : {
1796 7287 : GEN p2 = gmul(gel(x,k+1),gel(u,i-k+2));
1797 7287 : p1 = gadd(p1, gmulsg(k,p2));
1798 : }
1799 1022 : i++;
1800 1022 : gel(u,i) = gc_upto(av2, gneg(p1));
1801 1022 : gel(y,i) = gdivgu(gel(u,i), i-1);
1802 1022 : if (gc_needed(av,2))
1803 : {
1804 0 : GEN dummy = cgetg(1,t_VEC);
1805 0 : if(DEBUGMEM>1) pari_warn(warnmem,"serreverse");
1806 0 : for(k=i+1; k<lx; k++) gel(u,k) = gel(y,k) = dummy;
1807 0 : (void)gc_all(av,2, &u,&y);
1808 : }
1809 : }
1810 91 : if (a) y = ser_unscale(y, ginv(a));
1811 91 : return gc_GEN(av0,y);
1812 : }
1813 :
1814 : /*******************************************************************/
1815 : /* */
1816 : /* DERIVATION ET INTEGRATION */
1817 : /* */
1818 : /*******************************************************************/
1819 : GEN
1820 28672 : derivser(GEN x)
1821 : {
1822 28672 : long i, vx = varn(x), e = valser(x), lx = lg(x);
1823 : GEN y;
1824 28672 : if (ser_isexactzero(x))
1825 : {
1826 7 : x = gcopy(x);
1827 7 : if (e) setvalser(x,e-1);
1828 7 : return x;
1829 : }
1830 28665 : if (e)
1831 : {
1832 602 : y = cgetg(lx,t_SER); y[1] = evalsigne(1)|evalvalser(e-1) | evalvarn(vx);
1833 22960 : for (i=2; i<lx; i++) gel(y,i) = gmulsg(i+e-2,gel(x,i));
1834 : } else {
1835 28063 : if (lx == 3) return zeroser(vx, 0);
1836 24143 : lx--;
1837 24143 : y = cgetg(lx,t_SER); y[1] = evalsigne(1)|_evalvalser(0) | evalvarn(vx);
1838 77252 : for (i=2; i<lx; i++) gel(y,i) = gmulsg(i-1,gel(x,i+1));
1839 : }
1840 24745 : return normalizeser(y);
1841 : }
1842 :
1843 : static GEN
1844 56 : rfrac_deriv(GEN x, long v)
1845 : {
1846 56 : pari_sp av = avma;
1847 56 : GEN y = cgetg(3,t_RFRAC), a = gel(x,1), b = gel(x,2), bp, b0, t, T;
1848 56 : long vx = varn(b);
1849 :
1850 56 : bp = deriv(b, v);
1851 56 : t = simplify_shallow(RgX_gcd(bp, b));
1852 56 : if (typ(t) != t_POL || varn(t) != vx)
1853 : {
1854 35 : if (gequal1(t)) b0 = b;
1855 : else
1856 : {
1857 0 : b0 = RgX_Rg_div(b, t);
1858 0 : bp = RgX_Rg_div(bp, t);
1859 : }
1860 35 : a = gsub(gmul(b0, deriv(a,v)), gmul(a, bp));
1861 35 : if (isexactzero(a)) return gc_upto(av, a);
1862 35 : if (b0 == b)
1863 : {
1864 35 : gel(y,1) = gc_upto((pari_sp)y, a);
1865 35 : gel(y,2) = RgX_sqr(b);
1866 : }
1867 : else
1868 : {
1869 0 : gel(y,1) = a;
1870 0 : gel(y,2) = RgX_Rg_mul(RgX_sqr(b0), t);
1871 0 : y = gc_GEN(av, y);
1872 : }
1873 35 : return y;
1874 : }
1875 21 : b0 = gdivexact(b, t);
1876 21 : bp = gdivexact(bp,t);
1877 21 : a = gsub(gmul(b0, deriv(a,v)), gmul(a, bp));
1878 21 : if (isexactzero(a)) return gc_upto(av, a);
1879 14 : T = RgX_gcd(a, t);
1880 14 : if (typ(T) != t_POL || varn(T) != vx)
1881 : {
1882 0 : a = gdiv(a, T);
1883 0 : t = gdiv(t, T);
1884 : }
1885 14 : else if (!gequal1(T))
1886 : {
1887 0 : a = gdivexact(a, T);
1888 0 : t = gdivexact(t, T);
1889 : }
1890 14 : gel(y,1) = a;
1891 14 : gel(y,2) = gmul(RgX_sqr(b0), t);
1892 14 : return gc_GEN(av, y);
1893 : }
1894 :
1895 : GEN
1896 114128 : deriv(GEN x, long v)
1897 : {
1898 114128 : long tx = typ(x);
1899 114128 : if (is_const_t(tx))
1900 39830 : switch(tx)
1901 : {
1902 14 : case t_INTMOD: retmkintmod(gen_0, icopy(gel(x,1)));
1903 14 : case t_FFELT: return FF_zero(x);
1904 39802 : default: return gen_0;
1905 : }
1906 74298 : if (v < 0)
1907 : {
1908 49 : if (tx == t_CLOSURE) return closure_deriv(x);
1909 49 : v = gvar9(x);
1910 : }
1911 74298 : switch(tx)
1912 : {
1913 14 : case t_POLMOD:
1914 : {
1915 14 : GEN a = gel(x,2), b = gel(x,1);
1916 14 : if (v == varn(b)) return Rg_get_0(b);
1917 7 : retmkpolmod(deriv(a,v), RgX_copy(b));
1918 : }
1919 74039 : case t_POL:
1920 74039 : switch(varncmp(varn(x), v))
1921 : {
1922 0 : case 1: return Rg_get_0(x);
1923 66444 : case 0: return RgX_deriv(x);
1924 : }
1925 113505 : pari_APPLY_pol(deriv(gel(x,i),v));
1926 :
1927 147 : case t_SER:
1928 147 : switch(varncmp(varn(x), v))
1929 : {
1930 0 : case 1: return Rg_get_0(x);
1931 133 : case 0: return derivser(x);
1932 : }
1933 14 : if (ser_isexactzero(x)) return gcopy(x);
1934 28 : pari_APPLY_ser(deriv(gel(x,i),v));
1935 :
1936 56 : case t_RFRAC:
1937 56 : return rfrac_deriv(x,v);
1938 :
1939 42 : case t_VEC: case t_COL: case t_MAT:
1940 84 : pari_APPLY_same(deriv(gel(x,i),v));
1941 : }
1942 0 : pari_err_TYPE("deriv",x);
1943 : return NULL; /* LCOV_EXCL_LINE */
1944 : }
1945 :
1946 : /* n-th derivative of t_SER x, n > 0 */
1947 : static GEN
1948 210 : derivnser(GEN x, long n)
1949 : {
1950 210 : long i, vx = varn(x), e = valser(x), lx = lg(x);
1951 : GEN y;
1952 210 : if (ser_isexactzero(x))
1953 : {
1954 7 : x = gcopy(x);
1955 7 : if (e) setvalser(x,e-n);
1956 7 : return x;
1957 : }
1958 203 : if (e < 0 || e >= n)
1959 : {
1960 161 : y = cgetg(lx,t_SER);
1961 161 : y[1] = evalsigne(1)| evalvalser(e-n) | evalvarn(vx);
1962 756 : for (i=0; i<lx-2; i++)
1963 595 : gel(y,i+2) = gmul(muls_interval(i+e-n+1,i+e), gel(x,i+2));
1964 : } else {
1965 42 : if (lx <= n+2) return zeroser(vx, 0);
1966 42 : lx -= n;
1967 42 : y = cgetg(lx,t_SER);
1968 42 : y[1] = evalsigne(1)|_evalvalser(0) | evalvarn(vx);
1969 245 : for (i=0; i<lx-2; i++)
1970 203 : gel(y,i+2) = gmul(mulu_interval(i+1,i+n),gel(x,i+2+n-e));
1971 : }
1972 203 : return normalizeser(y);
1973 : }
1974 :
1975 : static GEN
1976 42 : rfrac_derivn(GEN x, long n, long vs)
1977 : {
1978 42 : pari_sp av = avma;
1979 42 : GEN u = gel(x,1), v = gel(x,2);
1980 42 : GEN dv = deriv(v, vs);
1981 : long i;
1982 112 : for (i=1; i<=n; i++)
1983 : {
1984 70 : GEN du = deriv(u, vs);
1985 70 : u = gadd(gmul(du, v), gmulsg (-i, gmul(dv, u)));
1986 : }
1987 42 : v = gpowgs(v, n+1);
1988 42 : return gc_upto(av, gdiv(u, v));
1989 : }
1990 :
1991 : GEN
1992 1379 : derivn(GEN x, long n, long v)
1993 : {
1994 : long tx;
1995 1379 : if (n < 0) pari_err_DOMAIN("derivn","n","<", gen_0, stoi(n));
1996 1372 : if (n == 0) return gcopy(x);
1997 1372 : tx = typ(x);
1998 1372 : if (is_const_t(tx))
1999 84 : switch(tx)
2000 : {
2001 21 : case t_INTMOD: retmkintmod(gen_0, icopy(gel(x,1)));
2002 21 : case t_FFELT: return FF_zero(x);
2003 42 : default: return gen_0;
2004 : }
2005 1288 : if (v < 0)
2006 : {
2007 1085 : if (tx == t_CLOSURE) return closure_derivn(x, n);
2008 973 : v = gvar9(x);
2009 : }
2010 1176 : switch(tx)
2011 : {
2012 21 : case t_POLMOD:
2013 : {
2014 21 : GEN a = gel(x,2), b = gel(x,1);
2015 21 : if (v == varn(b)) return Rg_get_0(b);
2016 14 : retmkpolmod(derivn(a,n,v), RgX_copy(b));
2017 : }
2018 826 : case t_POL:
2019 826 : switch(varncmp(varn(x), v))
2020 : {
2021 0 : case 1: return Rg_get_0(x);
2022 798 : case 0: return RgX_derivn(x,n);
2023 : }
2024 84 : pari_APPLY_pol(derivn(gel(x,i),n,v));
2025 :
2026 217 : case t_SER:
2027 217 : switch(varncmp(varn(x), v))
2028 : {
2029 0 : case 1: return Rg_get_0(x);
2030 210 : case 0: return derivnser(x, n);
2031 : }
2032 7 : if (ser_isexactzero(x)) return gcopy(x);
2033 28 : pari_APPLY_ser(derivn(gel(x,i),n,v));
2034 :
2035 42 : case t_RFRAC:
2036 42 : return rfrac_derivn(x, n, v);
2037 :
2038 63 : case t_VEC: case t_COL: case t_MAT:
2039 126 : pari_APPLY_same(derivn(gel(x,i),n,v));
2040 : }
2041 7 : pari_err_TYPE("derivn",x);
2042 : return NULL; /* LCOV_EXCL_LINE */
2043 : }
2044 :
2045 : static long
2046 833 : lookup(GEN v, long vx)
2047 : {
2048 833 : long i, l = lg(v);
2049 1491 : for(i=1; i<l; i++)
2050 1253 : if (varn(gel(v,i)) == vx) return i;
2051 238 : return 0;
2052 : }
2053 :
2054 : static GEN
2055 119 : serdiffop(GEN x, GEN v, GEN dv) { pari_APPLY_ser(diffop(gel(x,i),v,dv)); }
2056 : GEN
2057 3535 : diffop(GEN x, GEN v, GEN dv)
2058 : {
2059 : pari_sp av;
2060 3535 : long i, idx, lx, tx = typ(x), vx;
2061 : GEN y;
2062 3535 : if (!is_vec_t(typ(v))) pari_err_TYPE("diffop",v);
2063 3535 : if (!is_vec_t(typ(dv))) pari_err_TYPE("diffop",dv);
2064 3535 : if (lg(v)!=lg(dv)) pari_err_DIM("diffop");
2065 3535 : if (is_const_t(tx)) return gen_0;
2066 938 : switch(tx)
2067 : {
2068 84 : case t_POLMOD:
2069 84 : av = avma;
2070 84 : vx = varn(gel(x,1)); idx = lookup(v,vx);
2071 84 : if (idx) /*Assume the users know what they are doing */
2072 0 : y = gmodulo(diffop(gel(x,2),v,dv), gel(x,1));
2073 : else
2074 : {
2075 84 : GEN m = gel(x,1), pol=gel(x,2);
2076 84 : GEN u = gneg(gdiv(diffop(m,v,dv),RgX_deriv(m)));
2077 84 : y = diffop(pol,v,dv);
2078 84 : if (typ(pol)==t_POL && varn(pol)==varn(m))
2079 70 : y = gadd(y, gmul(u,RgX_deriv(pol)));
2080 84 : y = gmodulo(y, gel(x,1));
2081 : }
2082 84 : return gc_upto(av, y);
2083 742 : case t_POL:
2084 742 : if (signe(x)==0) return gen_0;
2085 742 : vx = varn(x); idx = lookup(v,vx);
2086 742 : av = avma; lx = lg(x);
2087 742 : y = diffop(gel(x,lx-1),v,dv);
2088 2842 : for (i=lx-2; i>=2; i--) y = gadd(gmul(y,pol_x(vx)),diffop(gel(x,i),v,dv));
2089 742 : if (idx) y = gadd(y, gmul(gel(dv,idx),RgX_deriv(x)));
2090 742 : return gc_upto(av, y);
2091 :
2092 7 : case t_SER:
2093 7 : if (signe(x)==0) return gen_0;
2094 7 : vx = varn(x); idx = lookup(v,vx);
2095 7 : if (!idx) return gen_0;
2096 7 : av = avma;
2097 7 : if (ser_isexactzero(x)) y = x;
2098 : else
2099 : {
2100 7 : y = serdiffop(x, v, dv); /* y is probably invalid */
2101 7 : y = gsubst(y, vx, pol_x(vx)); /* Fix that */
2102 : }
2103 7 : y = gadd(y, gmul(gel(dv,idx), derivser(x)));
2104 7 : return gc_upto(av, y);
2105 :
2106 105 : case t_RFRAC: {
2107 105 : GEN a = gel(x,1), b = gel(x,2), ap, bp;
2108 105 : av = avma;
2109 105 : ap = diffop(a, v, dv); bp = diffop(b, v, dv);
2110 105 : y = gsub(gdiv(ap,b),gdiv(gmul(a,bp),gsqr(b)));
2111 105 : return gc_upto(av, y);
2112 : }
2113 :
2114 0 : case t_VEC: case t_COL: case t_MAT:
2115 0 : pari_APPLY_same(diffop(gel(x,i),v,dv));
2116 : }
2117 0 : pari_err_TYPE("diffop",x);
2118 : return NULL; /* LCOV_EXCL_LINE */
2119 : }
2120 :
2121 : GEN
2122 42 : diffop0(GEN x, GEN v, GEN dv, long n)
2123 : {
2124 42 : pari_sp av=avma;
2125 : long i;
2126 245 : for(i=1; i<=n; i++)
2127 203 : x = gc_upto(av, diffop(x,v,dv));
2128 42 : return x;
2129 : }
2130 :
2131 : /********************************************************************/
2132 : /** **/
2133 : /** TAYLOR SERIES **/
2134 : /** **/
2135 : /********************************************************************/
2136 : /* swap vars (vx,v) in x (assume vx < v, vx main variable in x), then call
2137 : * act(data, v, x). FIXME: use in other places */
2138 : static GEN
2139 28 : swapvar_act(GEN x, long vx, long v, GEN (*act)(void*, long, GEN), void *data)
2140 : {
2141 28 : long v0 = fetch_var();
2142 28 : GEN y = act(data, v, gsubst(x,vx,pol_x(v0)));
2143 21 : y = gsubst(y,v0,pol_x(vx));
2144 21 : (void)delete_var(); return y;
2145 : }
2146 : /* x + O(v^data) */
2147 : static GEN
2148 14 : tayl_act(void *data, long v, GEN x) { return gadd(zeroser(v, (long)data), x); }
2149 : static GEN
2150 14 : integ_act(void *data, long v, GEN x) { (void)data; return integ(x,v); }
2151 :
2152 : GEN
2153 21 : tayl(GEN x, long v, long precS)
2154 : {
2155 21 : long vx = gvar9(x);
2156 : pari_sp av;
2157 :
2158 21 : if (varncmp(v, vx) <= 0) return gadd(zeroser(v,precS), x);
2159 14 : av = avma;
2160 14 : return gc_upto(av, swapvar_act(x, vx, v, tayl_act, (void*)precS));
2161 : }
2162 :
2163 : GEN
2164 7175 : ggrando(GEN x, long n)
2165 : {
2166 : long m, v;
2167 :
2168 7175 : switch(typ(x))
2169 : {
2170 4130 : case t_INT:/* bug 3 + O(1) */
2171 4130 : if (signe(x) <= 0) pari_err_DOMAIN("O", "x", "<=", gen_0, x);
2172 4130 : if (!is_pm1(x)) return zeropadic(x,n);
2173 : /* +/-1 = x^0 */
2174 91 : v = m = 0; break;
2175 3038 : case t_POL:
2176 3038 : if (!signe(x)) pari_err_DOMAIN("O", "x", "=", gen_0, x);
2177 3038 : v = varn(x);
2178 3038 : m = n * RgX_val(x); break;
2179 7 : case t_RFRAC:
2180 7 : if (gequal0(gel(x,1))) pari_err_DOMAIN("O", "x", "=", gen_0, x);
2181 7 : v = gvar(x);
2182 7 : m = n * gval(x,v); break;
2183 0 : default: pari_err_TYPE("O", x);
2184 : v = m = 0; /* LCOV_EXCL_LINE */
2185 : }
2186 3136 : return zeroser(v,m);
2187 : }
2188 :
2189 : /*******************************************************************/
2190 : /* */
2191 : /* FORMAL INTEGRATION */
2192 : /* */
2193 : /*******************************************************************/
2194 : GEN
2195 77 : RgX_integ(GEN x)
2196 : {
2197 77 : long i, lx = lg(x);
2198 : GEN y;
2199 77 : if (lx == 2) return RgX_copy(x);
2200 77 : y = cgetg(lx+1, t_POL); y[1] = x[1]; gel(y,2) = gen_0;
2201 245 : for (i=3; i<=lx; i++) gel(y,i) = gdivgu(gel(x,i-1),i-2);
2202 77 : return y;
2203 : }
2204 :
2205 : static void
2206 35 : err_intformal(GEN x)
2207 35 : { pari_err_DOMAIN("intformal", "residue(series, pole)", "!=", gen_0, x); }
2208 :
2209 : GEN
2210 29316 : integser(GEN x)
2211 : {
2212 29316 : long i, lx = lg(x), vx = varn(x), e = valser(x);
2213 : GEN y;
2214 29316 : if (lx == 2) return zeroser(vx, e+1);
2215 25375 : y = cgetg(lx, t_SER);
2216 109298 : for (i=2; i<lx; i++)
2217 : {
2218 83930 : long j = i+e-1;
2219 83930 : GEN c = gel(x,i);
2220 83930 : if (j)
2221 83615 : c = gdivgs(c, j);
2222 : else
2223 : { /* should be isexactzero, but try to avoid error */
2224 315 : if (!gequal0(c)) err_intformal(x);
2225 308 : c = gen_0;
2226 : }
2227 83923 : gel(y,i) = c;
2228 : }
2229 25368 : y[1] = evalsigne(1) | evalvarn(vx) | evalvalser(e+1); return y;
2230 : }
2231 :
2232 : GEN
2233 350 : integ(GEN x, long v)
2234 : {
2235 350 : long tx = typ(x), vx, n;
2236 350 : pari_sp av = avma;
2237 : GEN y, p1;
2238 :
2239 350 : if (v < 0) { v = gvar9(x); if (v == NO_VARIABLE) v = 0; }
2240 350 : if (is_scalar_t(tx))
2241 : {
2242 91 : if (tx == t_POLMOD)
2243 : {
2244 14 : GEN a = gel(x,2), b = gel(x,1);
2245 14 : vx = varn(b);
2246 14 : if (varncmp(v, vx) > 0) retmkpolmod(integ(a,v), RgX_copy(b));
2247 7 : if (v == vx) pari_err_PRIORITY("intformal",x,"=",v);
2248 : }
2249 77 : return deg1pol(x, gen_0, v);
2250 : }
2251 :
2252 259 : switch(tx)
2253 : {
2254 84 : case t_POL:
2255 84 : vx = varn(x);
2256 84 : if (v == vx) return RgX_integ(x);
2257 42 : if (lg(x) == 2) {
2258 14 : if (varncmp(vx, v) < 0) v = vx;
2259 14 : return zeropol(v);
2260 : }
2261 28 : if (varncmp(vx, v) > 0) return deg1pol(x, gen_0, v);
2262 84 : pari_APPLY_pol(integ(gel(x,i),v));
2263 :
2264 77 : case t_SER:
2265 77 : vx = varn(x);
2266 77 : if (v == vx) return integser(x);
2267 21 : if (lg(x) == 2) {
2268 14 : if (varncmp(vx, v) < 0) v = vx;
2269 14 : return zeroser(v, valser(x));
2270 : }
2271 7 : if (varncmp(vx, v) > 0) return deg1pol(x, gen_0, v);
2272 28 : pari_APPLY_ser(integ(gel(x,i),v));
2273 :
2274 56 : case t_RFRAC:
2275 : {
2276 56 : GEN a = gel(x,1), b = gel(x,2), c, d, s;
2277 56 : vx = varn(b);
2278 56 : if (varncmp(vx, v) > 0) return deg1pol(x, gen_0, v);
2279 49 : if (varncmp(vx, v) < 0)
2280 14 : return gc_upto(av, swapvar_act(x, vx, v, integ_act, NULL));
2281 :
2282 35 : n = degpol(b);
2283 35 : if (typ(a) == t_POL && varn(a) == vx) n += degpol(a);
2284 35 : y = integ(gadd(x, zeroser(v,n + 2)), v);
2285 35 : y = gdiv(gtrunc(gmul(b, y)), b);
2286 35 : if (typ(y) != t_RFRAC) pari_err_BUG("intformal(t_RFRAC)");
2287 35 : c = gel(y,1); d = gel(y,2);
2288 35 : s = gsub(gmul(deriv(c,v),d), gmul(c,deriv(d,v)));
2289 : /* (c'd-cd')/d^2 = y' = x = a/b ? */
2290 35 : if (!gequal(gmul(s,b), gmul(a,gsqr(d)))) err_intformal(x);
2291 7 : if (typ(y)==t_RFRAC && lg(gel(y,1)) == lg(gel(y,2)))
2292 : {
2293 7 : GEN p2 = leading_coeff(gel(y,2));
2294 7 : p1 = gel(y,1);
2295 7 : if (typ(p1) == t_POL && varn(p1) == vx) p1 = leading_coeff(p1);
2296 7 : y = gsub(y, gdiv(p1,p2));
2297 : }
2298 7 : return gc_upto(av,y);
2299 : }
2300 :
2301 42 : case t_VEC: case t_COL: case t_MAT:
2302 84 : pari_APPLY_same(integ(gel(x,i),v));
2303 : }
2304 0 : pari_err_TYPE("integ",x);
2305 : return NULL; /* LCOV_EXCL_LINE */
2306 : }
2307 :
2308 : /*******************************************************************/
2309 : /* */
2310 : /* FLOOR */
2311 : /* */
2312 : /*******************************************************************/
2313 : static GEN
2314 518 : quad_floor(GEN x)
2315 : {
2316 518 : GEN Q = gel(x,1), D = quad_disc(x), u, v, b, d, z;
2317 518 : if (signe(D) < 0) return NULL;
2318 490 : x = Q_remove_denom(x, &d);
2319 490 : u = gel(x,2);
2320 490 : v = gel(x,3); b = gel(Q,3);
2321 490 : if (typ(u) != t_INT || typ(v) != t_INT) return NULL;
2322 : /* x0 = (2u + v*(-b + sqrt(D))) / (2d) */
2323 483 : z = sqrti(mulii(D, sqri(v)));
2324 483 : if (signe(v) < 0) { z = addiu(z,1); togglesign(z); }
2325 : /* z = floor(v * sqrt(D)) */
2326 483 : z = addii(subii(shifti(u,1), mulii(v,b)), z);
2327 483 : return truedivii(z, d? shifti(d,1): gen_2);
2328 : }
2329 : GEN
2330 5362546 : gfloor(GEN x)
2331 : {
2332 5362546 : switch(typ(x))
2333 : {
2334 5306246 : case t_INT: return icopy(x);
2335 35 : case t_POL: return RgX_copy(x);
2336 37183 : case t_REAL: return floorr(x);
2337 18256 : case t_FRAC: return truedivii(gel(x,1),gel(x,2));
2338 511 : case t_QUAD:
2339 : {
2340 511 : pari_sp av = avma;
2341 : GEN y;
2342 511 : if (!(y = quad_floor(x))) break;
2343 476 : return gc_INT(av, y);
2344 : }
2345 14 : case t_RFRAC: return gdeuc(gel(x,1),gel(x,2));
2346 98 : case t_VEC: case t_COL: case t_MAT:
2347 1533 : pari_APPLY_same(gfloor(gel(x,i)));
2348 : }
2349 238 : pari_err_TYPE("gfloor",x);
2350 : return NULL; /* LCOV_EXCL_LINE */
2351 : }
2352 :
2353 : GEN
2354 426531 : gfrac(GEN x)
2355 : {
2356 : pari_sp av;
2357 : GEN y;
2358 426531 : switch(typ(x))
2359 : {
2360 23868 : case t_INT: return gen_0;
2361 7 : case t_POL: return pol_0(varn(x));
2362 164416 : case t_REAL: av = avma; return gc_leaf(av, subri(x, floorr(x)));
2363 234533 : case t_FRAC: retmkfrac(modii(gel(x,1),gel(x,2)), icopy(gel(x,2)));
2364 7 : case t_QUAD:
2365 7 : av = avma; if (!(y = quad_floor(x))) break;
2366 7 : return gc_upto(av, gsub(x, y));
2367 7 : case t_RFRAC: retmkrfrac(grem(gel(x,1),gel(x,2)), gcopy(gel(x,2)));
2368 3665 : case t_VEC: case t_COL: case t_MAT:
2369 34174 : pari_APPLY_same(gfrac(gel(x,i)));
2370 : }
2371 28 : pari_err_TYPE("gfrac",x);
2372 : return NULL; /* LCOV_EXCL_LINE */
2373 : }
2374 :
2375 : /* assume x t_REAL */
2376 : GEN
2377 2854 : ceilr(GEN x)
2378 : {
2379 2854 : pari_sp av = avma;
2380 2854 : GEN y = floorr(x);
2381 2854 : if (cmpri(x, y)) return gc_INT(av, addui(1,y));
2382 29 : return y;
2383 : }
2384 :
2385 : GEN
2386 236265 : gceil(GEN x)
2387 : {
2388 : pari_sp av;
2389 : GEN y;
2390 236265 : switch(typ(x))
2391 : {
2392 18354 : case t_INT: return icopy(x);
2393 21 : case t_POL: return RgX_copy(x);
2394 2775 : case t_REAL: return ceilr(x);
2395 214990 : case t_FRAC:
2396 214990 : av = avma; y = divii(gel(x,1),gel(x,2));
2397 214990 : if (signe(gel(x,1)) > 0) y = gc_INT(av, addui(1,y));
2398 214989 : return y;
2399 49 : case t_QUAD:
2400 49 : if (!is_realquad(x)) break;
2401 42 : if (gequal0(gel(x,3))) return gceil(gel(x,2));
2402 35 : av = avma; return gc_upto(av, addiu(gfloor(x), 1));
2403 7 : case t_RFRAC:
2404 7 : return gdeuc(gel(x,1),gel(x,2));
2405 35 : case t_VEC: case t_COL: case t_MAT:
2406 105 : pari_APPLY_same(gceil(gel(x,i)));
2407 : }
2408 41 : pari_err_TYPE("gceil",x);
2409 : return NULL; /* LCOV_EXCL_LINE */
2410 : }
2411 :
2412 : GEN
2413 6097 : round0(GEN x, GEN *pte)
2414 : {
2415 6097 : if (pte) { long e; x = grndtoi(x,&e); *pte = stoi(e); }
2416 6090 : return ground(x);
2417 : }
2418 :
2419 : /* x t_REAL, return q=floor(x+1/2), set e = expo(x-q) */
2420 : static GEN
2421 54191106 : round_i(GEN x, long *pe)
2422 : {
2423 : long e;
2424 54191106 : GEN B, q,r, m = mantissa_real(x, &e); /* x = m/2^e */
2425 54187122 : if (e <= 0)
2426 : {
2427 13555783 : if (e) m = shifti(m,-e);
2428 13555679 : if (pe) *pe = -e;
2429 13555679 : return m;
2430 : }
2431 40631339 : B = int2n(e-1);
2432 40631667 : m = addii(m, B);
2433 40631776 : q = shifti(m, -e);
2434 40631632 : r = remi2n(m, e);
2435 : /* 2^e (x+1/2) = m = 2^e q + r, sgn(r)=sgn(m), |r|<2^e */
2436 40633782 : if (!signe(r))
2437 27956 : { if (pe) *pe = -1; }
2438 : else
2439 : {
2440 40605826 : if (signe(m) < 0)
2441 : {
2442 16480340 : q = subiu(q,1);
2443 16480326 : r = addii(r, B);
2444 : }
2445 : else
2446 24125486 : r = subii(r, B);
2447 : /* |x - q| = |r| / 2^e */
2448 40605419 : if (pe) *pe = signe(r)? expi(r) - e: -e;
2449 40605321 : cgiv(r);
2450 : }
2451 40633988 : return q;
2452 : }
2453 : /* assume x a t_REAL */
2454 : GEN
2455 3136468 : roundr(GEN x)
2456 : {
2457 3136468 : long ex, s = signe(x);
2458 : pari_sp av;
2459 3136468 : if (!s || (ex=expo(x)) < -1) return gen_0;
2460 2457404 : if (ex == -1) return s>0? gen_1:
2461 204980 : absrnz_equal2n(x)? gen_0: gen_m1;
2462 1819626 : av = avma; x = round_i(x, &ex);
2463 1819601 : if (ex >= 0) pari_err_PREC( "roundr (precision loss in truncation)");
2464 1819601 : return gc_INT(av, x);
2465 : }
2466 : GEN
2467 302180 : roundr_safe(GEN x)
2468 : {
2469 302180 : long ex, s = signe(x);
2470 : pari_sp av;
2471 :
2472 302180 : if (!s || (ex = expo(x)) < -1) return gen_0;
2473 302136 : if (ex == -1) return s>0? gen_1:
2474 0 : absrnz_equal2n(x)? gen_0: gen_m1;
2475 302109 : av = avma; x = round_i(x, NULL);
2476 302109 : return gc_INT(av, x);
2477 : }
2478 :
2479 : GEN
2480 2839929 : ground(GEN x)
2481 : {
2482 : pari_sp av;
2483 : GEN y;
2484 :
2485 2839929 : switch(typ(x))
2486 : {
2487 577059 : case t_INT: return icopy(x);
2488 14 : case t_INTMOD: return gcopy(x);
2489 1710088 : case t_REAL: return roundr(x);
2490 50718 : case t_FRAC: return diviiround(gel(x,1), gel(x,2));
2491 49 : case t_QUAD:
2492 : {
2493 49 : GEN Q = gel(x,1), u, v, b, d, z;
2494 49 : av = avma;
2495 49 : if (is_realquad(x)) return gc_upto(av, gfloor(gadd(x, ghalf)));
2496 7 : u = gel(x,2);
2497 7 : v = gel(x,3); b = gel(Q,3);
2498 7 : u = ground(gsub(u, gmul2n(gmul(v,b),-1)));
2499 7 : v = Q_remove_denom(v, &d);
2500 7 : if (!d) d = gen_1;
2501 : /* Im x = v sqrt(|D|) / (2d),
2502 : * Im(round(x)) = floor((d + v sqrt(|D|)) / (2d))
2503 : * = floor(floor(d + v sqrt(|D|)) / (2d)) */
2504 7 : z = sqrti(mulii(sqri(v), quad_disc(x)));
2505 7 : if (signe(v) < 0) { z = addiu(z,1); togglesign(z); }
2506 : /* z = floor(v * sqrt(|D|)) */
2507 7 : v = truedivii(addii(z, d), shifti(d,1));
2508 7 : return gc_GEN(av, signe(v)? mkcomplex(u,v): u);
2509 : }
2510 14 : case t_POLMOD:
2511 14 : retmkpolmod(ground(gel(x,2)), RgX_copy(gel(x,1)));
2512 :
2513 4096 : case t_COMPLEX:
2514 4096 : av = avma; y = cgetg(3, t_COMPLEX);
2515 4096 : gel(y,2) = ground(gel(x,2));
2516 4096 : if (!signe(gel(y,2))) { set_avma(av); return ground(gel(x,1)); }
2517 217 : gel(y,1) = ground(gel(x,1)); return y;
2518 :
2519 98 : case t_POL:
2520 4032 : pari_APPLY_pol(ground(gel(x,i)));
2521 182 : case t_SER:
2522 182 : if (ser_isexactzero(x)) return gcopy(x);
2523 42 : pari_APPLY_ser(ground(gel(x,i)));
2524 21 : case t_RFRAC:
2525 21 : av = avma;
2526 21 : return gc_upto(av, gdiv(ground(gel(x,1)), ground(gel(x,2))));
2527 497606 : case t_VEC: case t_COL: case t_MAT:
2528 2463693 : pari_APPLY_same(ground(gel(x,i)));
2529 : }
2530 6 : pari_err_TYPE("ground",x);
2531 : return NULL; /* LCOV_EXCL_LINE */
2532 : }
2533 :
2534 : /* e = number of error bits on integral part */
2535 : GEN
2536 91633908 : grndtoi(GEN x, long *e)
2537 : {
2538 : GEN y;
2539 : long i, lx, e1;
2540 : pari_sp av;
2541 :
2542 91633908 : if (e) *e = -(long)HIGHEXPOBIT;
2543 91633908 : switch(typ(x))
2544 : {
2545 10227928 : case t_INT: return icopy(x);
2546 57175604 : case t_REAL: {
2547 57175604 : long ex = expo(x);
2548 57175604 : if (!signe(x) || ex < -1)
2549 : {
2550 5106052 : if (e) *e = ex;
2551 5106052 : return gen_0;
2552 : }
2553 52069552 : av = avma; x = round_i(x, e);
2554 52067035 : return gc_INT(av, x);
2555 : }
2556 27846 : case t_FRAC:
2557 27846 : y = diviiround(gel(x,1), gel(x,2)); if (!e) return y;
2558 26488 : av = avma; *e = gexpo(gsub(x, y)); set_avma(av);
2559 26488 : return y;
2560 7 : case t_INTMOD: return gcopy(x);
2561 7 : case t_QUAD:
2562 7 : y = ground(x); av = avma; if (!e) return y;
2563 7 : *e = gexpo(gsub(x,y)); set_avma(avma); return y;
2564 1634750 : case t_COMPLEX:
2565 1634750 : av = avma; y = cgetg(3, t_COMPLEX);
2566 1634750 : gel(y,2) = grndtoi(gel(x,2), e);
2567 1634750 : if (!signe(gel(y,2))) {
2568 244715 : set_avma(av);
2569 244715 : y = grndtoi(gel(x,1), e? &e1: NULL);
2570 : }
2571 : else
2572 1390035 : gel(y,1) = grndtoi(gel(x,1), e? &e1: NULL);
2573 1634750 : if (e && e1 > *e) *e = e1;
2574 1634750 : return y;
2575 :
2576 7 : case t_POLMOD:
2577 7 : retmkpolmod(grndtoi(gel(x,2), e), RgX_copy(gel(x,1)));
2578 :
2579 319566 : case t_POL:
2580 319566 : y = cgetg_copy(x, &lx); y[1] = x[1];
2581 3253415 : for (i=2; i<lx; i++)
2582 : {
2583 2933850 : gel(y,i) = grndtoi(gel(x,i), &e1);
2584 2933849 : if (e && e1 > *e) *e = e1;
2585 : }
2586 319565 : return normalizepol_lg(y, lx);
2587 168 : case t_SER:
2588 168 : if (ser_isexactzero(x)) return gcopy(x);
2589 154 : y = cgetg_copy(x, &lx); y[1] = x[1];
2590 441 : for (i=2; i<lx; i++)
2591 : {
2592 287 : gel(y,i) = grndtoi(gel(x,i), &e1);
2593 287 : if (e && e1 > *e) *e = e1;
2594 : }
2595 154 : return normalizeser(y);
2596 7 : case t_RFRAC:
2597 7 : y = cgetg(3,t_RFRAC);
2598 7 : gel(y,1) = grndtoi(gel(x,1), e? &e1: NULL); if (e && e1 > *e) *e = e1;
2599 7 : gel(y,2) = grndtoi(gel(x,2), e? &e1: NULL); if (e && e1 > *e) *e = e1;
2600 7 : return y;
2601 22248889 : case t_VEC: case t_COL: case t_MAT:
2602 22248889 : y = cgetg_copy(x, &lx);
2603 79002319 : for (i=1; i<lx; i++)
2604 : {
2605 56754064 : gel(y,i) = grndtoi(gel(x,i), e? &e1: NULL);
2606 56753385 : if (e && e1 > *e) *e = e1;
2607 : }
2608 22248255 : return y;
2609 : }
2610 6 : pari_err_TYPE("grndtoi",x);
2611 : return NULL; /* LCOV_EXCL_LINE */
2612 : }
2613 :
2614 : /* trunc(x * 2^s). lindep() sanity checks rely on this function to return a
2615 : * t_INT or fail when fed a non-t_COMPLEX input; so do not make this one
2616 : * recursive [ or change the lindep call ] */
2617 : GEN
2618 117589750 : gtrunc2n(GEN x, long s)
2619 : {
2620 : GEN z;
2621 117589750 : switch(typ(x))
2622 : {
2623 37573430 : case t_INT: return shifti(x, s);
2624 62784497 : case t_REAL: return trunc2nr(x, s);
2625 497 : case t_FRAC: {
2626 : pari_sp av;
2627 497 : GEN a = gel(x,1), b = gel(x,2), q;
2628 497 : if (s == 0) return divii(a, b);
2629 497 : av = avma;
2630 497 : if (s < 0) q = divii(shifti(a, s), b);
2631 : else {
2632 : GEN r;
2633 497 : q = dvmdii(a, b, &r);
2634 497 : q = addii(shifti(q,s), divii(shifti(r,s), b));
2635 : }
2636 497 : return gc_INT(av, q);
2637 : }
2638 17318855 : case t_COMPLEX:
2639 17318855 : z = cgetg(3, t_COMPLEX);
2640 17322274 : gel(z,2) = gtrunc2n(gel(x,2), s);
2641 17319527 : if (!signe(gel(z,2))) {
2642 1620096 : set_avma((pari_sp)(z + 3));
2643 1620090 : return gtrunc2n(gel(x,1), s);
2644 : }
2645 15699431 : gel(z,1) = gtrunc2n(gel(x,1), s);
2646 15697529 : return z;
2647 0 : default: pari_err_TYPE("gtrunc2n",x);
2648 : return NULL; /* LCOV_EXCL_LINE */
2649 : }
2650 : }
2651 :
2652 : /* e = number of error bits on integral part */
2653 : GEN
2654 1140546 : gcvtoi(GEN x, long *e)
2655 : {
2656 1140546 : long tx = typ(x), lx, e1;
2657 : GEN y;
2658 :
2659 1140546 : if (tx == t_REAL)
2660 : {
2661 1140413 : long ex = expo(x); if (ex < 0) { *e = ex; return gen_0; }
2662 1140322 : e1 = ex - bit_prec(x) + 1;
2663 1140321 : y = mantissa2nr(x, e1);
2664 1140318 : if (e1 <= 0) { pari_sp av = avma; e1 = expo(subri(x,y)); set_avma(av); }
2665 1140299 : *e = e1; return y;
2666 : }
2667 133 : *e = -(long)HIGHEXPOBIT;
2668 133 : if (is_matvec_t(tx))
2669 : {
2670 : long i;
2671 28 : y = cgetg_copy(x, &lx);
2672 84 : for (i=1; i<lx; i++)
2673 : {
2674 56 : gel(y,i) = gcvtoi(gel(x,i),&e1);
2675 56 : if (e1 > *e) *e = e1;
2676 : }
2677 28 : return y;
2678 : }
2679 105 : return gtrunc(x);
2680 : }
2681 :
2682 : int
2683 492454 : isint(GEN n, GEN *ptk)
2684 : {
2685 492454 : switch(typ(n))
2686 : {
2687 400299 : case t_INT: *ptk = n; return 1;
2688 41447 : case t_REAL: {
2689 41447 : pari_sp av0 = avma;
2690 41447 : GEN z = floorr(n);
2691 41447 : pari_sp av = avma;
2692 41447 : long s = signe(subri(n, z));
2693 41447 : if (s) return gc_bool(av0,0);
2694 15757 : *ptk = z; return gc_bool(av,1);
2695 : }
2696 33558 : case t_FRAC: return 0;
2697 16961 : case t_COMPLEX: return gequal0(gel(n,2)) && isint(gel(n,1),ptk);
2698 0 : case t_QUAD: return gequal0(gel(n,3)) && isint(gel(n,2),ptk);
2699 189 : default: pari_err_TYPE("isint",n);
2700 : return 0; /* LCOV_EXCL_LINE */
2701 : }
2702 : }
2703 :
2704 : int
2705 326463 : issmall(GEN n, long *ptk)
2706 : {
2707 326463 : pari_sp av = avma;
2708 : GEN z;
2709 : long k;
2710 326463 : if (!isint(n, &z)) return 0;
2711 324881 : k = itos_or_0(z); set_avma(av);
2712 324881 : if (k || lgefint(z) == 2) { *ptk = k; return 1; }
2713 0 : return 0;
2714 : }
2715 :
2716 : /* smallest integer greater than any incarnations of the real x
2717 : * Avoid "precision loss in truncation" */
2718 : GEN
2719 1056891 : ceil_safe(GEN x)
2720 : {
2721 1056891 : pari_sp av = avma;
2722 1056891 : long e, tx = typ(x);
2723 : GEN y;
2724 :
2725 1056891 : if (is_rational_t(tx)) return gceil(x);
2726 1056595 : y = gcvtoi(x,&e);
2727 1056577 : if (gsigne(x) >= 0)
2728 : {
2729 1056078 : if (e < 0) e = 0;
2730 1056078 : y = addii(y, int2n(e));
2731 : }
2732 1056577 : return gc_INT(av, y);
2733 : }
2734 : /* largest integer smaller than any incarnations of the real x
2735 : * Avoid "precision loss in truncation" */
2736 : GEN
2737 72120 : floor_safe(GEN x)
2738 : {
2739 72120 : pari_sp av = avma;
2740 72120 : long e, tx = typ(x);
2741 : GEN y;
2742 :
2743 72120 : if (is_rational_t(tx)) return gfloor(x);
2744 72120 : y = gcvtoi(x,&e);
2745 72121 : if (gsigne(x) <= 0)
2746 : {
2747 21 : if (e < 0) e = 0;
2748 21 : y = subii(y, int2n(e));
2749 : }
2750 72121 : return gc_INT(av, y);
2751 : }
2752 :
2753 : GEN
2754 11487 : ser2rfrac_i(GEN x)
2755 : {
2756 11487 : long e = valser(x);
2757 11487 : GEN a = ser2pol_i(x, lg(x));
2758 11487 : if (e) {
2759 6818 : if (e > 0) a = RgX_shift_shallow(a, e);
2760 0 : else a = gred_rfrac_simple(a, pol_xn(-e, varn(a)));
2761 : }
2762 11487 : return a;
2763 : }
2764 :
2765 : static GEN
2766 707 : ser2rfrac(GEN x)
2767 : {
2768 707 : pari_sp av = avma;
2769 707 : return gc_GEN(av, ser2rfrac_i(x));
2770 : }
2771 :
2772 : /* x t_PADIC, truncate to rational (t_INT/t_FRAC) */
2773 : GEN
2774 689507 : padic_to_Q(GEN x)
2775 : {
2776 689507 : GEN u = padic_u(x), p;
2777 : long v;
2778 689507 : if (!signe(u)) return gen_0;
2779 683431 : v = valp(x);
2780 683431 : if (!v) return icopy(u);
2781 258536 : p = padic_p(x);
2782 258536 : if (v > 0)
2783 : {
2784 258422 : pari_sp av = avma;
2785 258422 : return gc_INT(av, mulii(u, powiu(p,v)));
2786 : }
2787 114 : retmkfrac(icopy(u), powiu(p,-v));
2788 : }
2789 : GEN
2790 14 : padic_to_Q_shallow(GEN x)
2791 : {
2792 14 : GEN u = padic_u(x), p, q, q2;
2793 : long v;
2794 14 : if (!signe(u)) return gen_0;
2795 14 : q = padic_pd(x); q2 = shifti(q,-1);
2796 14 : v = valp(x);
2797 14 : u = Fp_center_i(u, q, q2);
2798 14 : if (!v) return u;
2799 7 : p = padic_p(x);
2800 7 : if (v > 0) return mulii(u, powiu(p,v));
2801 7 : return mkfrac(u, powiu(p,-v));
2802 : }
2803 : static GEN
2804 735 : Qp_to_Q(GEN c)
2805 : {
2806 735 : switch(typ(c))
2807 : {
2808 721 : case t_INT:
2809 721 : case t_FRAC: break;
2810 14 : case t_PADIC: c = padic_to_Q_shallow(c); break;
2811 0 : default: pari_err_TYPE("padic_to_Q", c);
2812 : }
2813 735 : return c;
2814 : }
2815 : GEN
2816 931 : QpV_to_QV(GEN x) { pari_APPLY_same(Qp_to_Q(gel(x,i))); }
2817 :
2818 : GEN
2819 597763 : gtrunc(GEN x)
2820 : {
2821 597763 : switch(typ(x))
2822 : {
2823 84175 : case t_INT: return icopy(x);
2824 49098 : case t_REAL: return truncr(x);
2825 56 : case t_FRAC: return divii(gel(x,1),gel(x,2));
2826 432710 : case t_PADIC: return padic_to_Q(x);
2827 42 : case t_POL: return RgX_copy(x);
2828 14 : case t_RFRAC: return gdeuc(gel(x,1),gel(x,2));
2829 679 : case t_SER: return ser2rfrac(x);
2830 187215 : case t_VEC: case t_COL: case t_MAT: pari_APPLY_same(gtrunc(gel(x,i)));
2831 : }
2832 56 : pari_err_TYPE("gtrunc",x);
2833 : return NULL; /* LCOV_EXCL_LINE */
2834 : }
2835 :
2836 : GEN
2837 217 : trunc0(GEN x, GEN *pte)
2838 : {
2839 217 : if (pte) { long e; x = gcvtoi(x,&e); *pte = stoi(e); }
2840 189 : return gtrunc(x);
2841 : }
2842 : /*******************************************************************/
2843 : /* */
2844 : /* CONVERSIONS --> INT, POL & SER */
2845 : /* */
2846 : /*******************************************************************/
2847 :
2848 : /* return a_(n-1) B^(n-1) + ... + a_0, where B = 2^32.
2849 : * The a_i are 32bits integers */
2850 : GEN
2851 24531 : mkintn(long n, ...)
2852 : {
2853 : va_list ap;
2854 : GEN x, y;
2855 : long i;
2856 : #ifdef LONG_IS_64BIT
2857 21060 : long e = (n&1);
2858 21060 : n = (n+1) >> 1;
2859 : #endif
2860 24531 : va_start(ap,n);
2861 24531 : x = cgetipos(n+2);
2862 24531 : y = int_MSW(x);
2863 86748 : for (i=0; i <n; i++)
2864 : {
2865 : #ifdef LONG_IS_64BIT
2866 48600 : ulong a = (e && !i)? 0: (ulong) va_arg(ap, unsigned int);
2867 48600 : ulong b = (ulong) va_arg(ap, unsigned int);
2868 48600 : *y = (a << 32) | b;
2869 : #else
2870 13617 : *y = (ulong) va_arg(ap, unsigned int);
2871 : #endif
2872 62217 : y = int_precW(y);
2873 : }
2874 24531 : va_end(ap);
2875 24531 : return int_normalize(x, 0);
2876 : }
2877 :
2878 : /* 2^32 a + b */
2879 : GEN
2880 328488 : uu32toi(ulong a, ulong b)
2881 : {
2882 : #ifdef LONG_IS_64BIT
2883 268873 : return utoi((a<<32) | b);
2884 : #else
2885 59615 : return uutoi(a, b);
2886 : #endif
2887 : }
2888 : /* - (2^32 a + b), assume a or b != 0 */
2889 : GEN
2890 114618 : uu32toineg(ulong a, ulong b)
2891 : {
2892 : #ifdef LONG_IS_64BIT
2893 98083 : return utoineg((a<<32) | b);
2894 : #else
2895 16535 : return uutoineg(a, b);
2896 : #endif
2897 : }
2898 :
2899 : /* return a_(n-1) x^(n-1) + ... + a_0 */
2900 : GEN
2901 5608704 : mkpoln(long n, ...)
2902 : {
2903 : va_list ap;
2904 : GEN x, y;
2905 5608704 : long i, l = n+2;
2906 5608704 : va_start(ap,n);
2907 5608704 : x = cgetg(l, t_POL); y = x + 2;
2908 5609958 : x[1] = evalvarn(0);
2909 24583522 : for (i=n-1; i >= 0; i--) gel(y,i) = va_arg(ap, GEN);
2910 5615196 : va_end(ap); return normalizepol_lg(x, l);
2911 : }
2912 :
2913 : /* return [a_1, ..., a_n] */
2914 : GEN
2915 1219995 : mkvecn(long n, ...)
2916 : {
2917 : va_list ap;
2918 : GEN x;
2919 : long i;
2920 1219995 : va_start(ap,n);
2921 1219995 : x = cgetg(n+1, t_VEC);
2922 7841649 : for (i=1; i <= n; i++) gel(x,i) = va_arg(ap, GEN);
2923 1219999 : va_end(ap); return x;
2924 : }
2925 :
2926 : GEN
2927 1379 : mkcoln(long n, ...)
2928 : {
2929 : va_list ap;
2930 : GEN x;
2931 : long i;
2932 1379 : va_start(ap,n);
2933 1379 : x = cgetg(n+1, t_COL);
2934 11032 : for (i=1; i <= n; i++) gel(x,i) = va_arg(ap, GEN);
2935 1379 : va_end(ap); return x;
2936 : }
2937 :
2938 : GEN
2939 153610 : mkvecsmalln(long n, ...)
2940 : {
2941 : va_list ap;
2942 : GEN x;
2943 : long i;
2944 153610 : va_start(ap,n);
2945 153610 : x = cgetg(n+1, t_VECSMALL);
2946 1086153 : for (i=1; i <= n; i++) x[i] = va_arg(ap, long);
2947 153610 : va_end(ap); return x;
2948 : }
2949 :
2950 : GEN
2951 9062346 : scalarpol(GEN x, long v)
2952 : {
2953 : GEN y;
2954 9062346 : if (isrationalzero(x)) return zeropol(v);
2955 4241527 : y = cgetg(3,t_POL);
2956 4241587 : y[1] = gequal0(x)? evalvarn(v)
2957 4241583 : : evalvarn(v) | evalsigne(1);
2958 4241583 : gel(y,2) = gcopy(x); return y;
2959 : }
2960 : GEN
2961 3895461 : scalarpol_shallow(GEN x, long v)
2962 : {
2963 : GEN y;
2964 3895461 : if (isrationalzero(x)) return zeropol(v);
2965 3767044 : y = cgetg(3,t_POL);
2966 3767043 : y[1] = gequal0(x)? evalvarn(v)
2967 3767040 : : evalvarn(v) | evalsigne(1);
2968 3767040 : gel(y,2) = x; return y;
2969 : }
2970 :
2971 : /* x0 + x1*T, do not assume x1 != 0 */
2972 : GEN
2973 334360 : deg1pol(GEN x1, GEN x0,long v)
2974 : {
2975 334360 : GEN x = cgetg(4,t_POL);
2976 334361 : x[1] = evalsigne(1) | evalvarn(v);
2977 334361 : gel(x,2) = x0 == gen_0? x0: gcopy(x0); /* gen_0 frequent */
2978 334363 : gel(x,3) = gcopy(x1); return normalizepol_lg(x,4);
2979 : }
2980 :
2981 : /* same, no copy */
2982 : GEN
2983 9569500 : deg1pol_shallow(GEN x1, GEN x0,long v)
2984 : {
2985 9569500 : GEN x = cgetg(4,t_POL);
2986 9569562 : x[1] = evalsigne(1) | evalvarn(v);
2987 9569562 : gel(x,2) = x0;
2988 9569562 : gel(x,3) = x1; return normalizepol_lg(x,4);
2989 : }
2990 :
2991 : GEN
2992 321779 : deg2pol_shallow(GEN x2, GEN x1, GEN x0, long v)
2993 : {
2994 321779 : GEN x = cgetg(5,t_POL);
2995 321780 : x[1] = evalsigne(1) | evalvarn(v);
2996 321780 : gel(x,2) = x0;
2997 321780 : gel(x,3) = x1;
2998 321780 : gel(x,4) = x2;
2999 321780 : return normalizepol_lg(x,5);
3000 : }
3001 :
3002 : static GEN
3003 3477158 : _gtopoly(GEN x, long v, int reverse)
3004 : {
3005 3477158 : long tx = typ(x);
3006 : GEN y;
3007 :
3008 3477158 : if (v<0) v = 0;
3009 3477158 : switch(tx)
3010 : {
3011 21 : case t_POL:
3012 21 : if (varncmp(varn(x), v) < 0) pari_err_PRIORITY("gtopoly", x, "<", v);
3013 21 : y = RgX_copy(x); break;
3014 28 : case t_SER:
3015 28 : if (varncmp(varn(x), v) < 0) pari_err_PRIORITY("gtopoly", x, "<", v);
3016 28 : y = ser2rfrac(x);
3017 28 : if (typ(y) != t_POL)
3018 0 : pari_err_DOMAIN("gtopoly", "valuation", "<", gen_0, x);
3019 28 : break;
3020 42 : case t_RFRAC:
3021 : {
3022 42 : GEN a = gel(x,1), b = gel(x,2);
3023 42 : long vb = varn(b);
3024 42 : if (varncmp(vb, v) < 0) pari_err_PRIORITY("gtopoly", x, "<", v);
3025 42 : if (typ(a) != t_POL || varn(a) != vb) return zeropol(v);
3026 21 : y = RgX_div(a,b); break;
3027 : }
3028 337183 : case t_VECSMALL: x = zv_to_ZV(x); /* fall through */
3029 3476451 : case t_QFB: case t_VEC: case t_COL: case t_MAT:
3030 : {
3031 3476451 : long j, k, lx = lg(x);
3032 : GEN z;
3033 3476451 : if (tx == t_QFB) lx--;
3034 3476451 : if (varncmp(gvar(x), v) <= 0) pari_err_PRIORITY("gtopoly", x, "<=", v);
3035 3476461 : y = cgetg(lx+1, t_POL);
3036 3476460 : y[1] = evalvarn(v);
3037 3476460 : if (reverse) {
3038 2434005 : x--;
3039 26224373 : for (j=2; j<=lx; j++) gel(y,j) = gel(x,j);
3040 : } else {
3041 5355220 : for (j=2, k=lx; k>=2; j++) gel(y,j) = gel(x,--k);
3042 : }
3043 3476460 : z = RgX_copy(normalizepol_lg(y,lx+1));
3044 3476458 : settyp(y, t_VECSMALL);/* left on stack */
3045 3476458 : return z;
3046 : }
3047 616 : default:
3048 616 : if (is_scalar_t(tx)) return scalarpol(x,v);
3049 7 : pari_err_TYPE("gtopoly",x);
3050 : return NULL; /* LCOV_EXCL_LINE */
3051 : }
3052 70 : setvarn(y,v); return y;
3053 : }
3054 :
3055 : GEN
3056 2434040 : gtopolyrev(GEN x, long v) { return _gtopoly(x,v,1); }
3057 :
3058 : GEN
3059 1043117 : gtopoly(GEN x, long v) { return _gtopoly(x,v,0); }
3060 :
3061 : static GEN
3062 1092 : gtovecpost(GEN x, long n)
3063 : {
3064 1092 : long i, imax, lx, tx = typ(x);
3065 1092 : GEN y = zerovec(n);
3066 :
3067 1092 : if (is_scalar_t(tx) || tx == t_RFRAC) { gel(y,1) = gcopy(x); return y; }
3068 343 : switch(tx)
3069 : {
3070 56 : case t_POL:
3071 56 : lx = lg(x); imax = minss(lx-2, n);
3072 224 : for (i=1; i<=imax; i++) gel(y,i) = gcopy(gel(x,lx-i));
3073 56 : return y;
3074 28 : case t_SER:
3075 28 : lx = lg(x); imax = minss(lx-2, n); x++;
3076 84 : for (i=1; i<=imax; i++) gel(y,i) = gcopy(gel(x,i));
3077 28 : return y;
3078 28 : case t_QFB:
3079 28 : lx = lg(x)-1; /* remove discriminant */
3080 28 : imax = minss(lx-1, n);
3081 112 : for (i=1; i<=imax; i++) gel(y,i) = gcopy(gel(x,i));
3082 28 : return y;
3083 28 : case t_VEC: case t_COL:
3084 28 : lx = lg(x); imax = minss(lx-1, n);
3085 84 : for (i=1; i<=imax; i++) gel(y,i) = gcopy(gel(x,i));
3086 28 : return y;
3087 63 : case t_LIST:
3088 63 : if (list_typ(x) == t_LIST_MAP) pari_err_TYPE("gtovec",x);
3089 56 : x = list_data(x); lx = x? lg(x): 1;
3090 56 : imax = minss(lx-1, n);
3091 252 : for (i=1; i<=imax; i++) gel(y,i) = gcopy(gel(x,i));
3092 56 : return y;
3093 56 : case t_STR:
3094 : {
3095 56 : char *s = GSTR(x);
3096 56 : imax = minss(strlen(s), n); s--;
3097 224 : for (i=1; i<=imax; i++) gel(y,i) = chartoGENstr(s[i]);
3098 56 : return y;
3099 : }
3100 28 : case t_VECSMALL:
3101 28 : lx = lg(x); imax = minss(lx-1, n);
3102 84 : for (i=1; i<=imax; i++) gel(y,i) = stoi(x[i]);
3103 28 : return y;
3104 56 : default: pari_err_TYPE("gtovec",x);
3105 : return NULL; /*LCOV_EXCL_LINE*/
3106 : }
3107 : }
3108 :
3109 : static GEN
3110 3773 : init_vectopre(long a, long n, GEN y, long *imax)
3111 : {
3112 3773 : if (n <= a) { *imax = n; return y; }
3113 2975 : *imax = a; return y + n - a;
3114 : }
3115 : /* assume n > 0 */
3116 : static GEN
3117 3829 : gtovecpre(GEN x, long n)
3118 : {
3119 3829 : long a, i, imax, lx, tx = typ(x);
3120 3829 : GEN y = zerovec(n), y0;
3121 :
3122 3829 : if (is_scalar_t(tx) || tx == t_RFRAC) { gel(y,n) = gcopy(x); return y; }
3123 3773 : switch(tx)
3124 : {
3125 56 : case t_POL:
3126 56 : lx = lg(x); a = lx-2;
3127 56 : y0 = init_vectopre(a, n, y, &imax); if (imax == n) x -= a-imax;
3128 224 : for (i=1; i<=imax; i++) gel(y0,i) = gcopy(gel(x,lx-i));
3129 56 : return y;
3130 3458 : case t_SER:
3131 3458 : a = lg(x)-2; x++;
3132 3458 : y0 = init_vectopre(a, n, y, &imax); if (imax == n) x += a-imax;
3133 138796 : for (i=1; i<=imax; i++) gel(y0,i) = gcopy(gel(x,i));
3134 3458 : return y;
3135 28 : case t_QFB:
3136 28 : a = lg(x)-2; /* remove discriminant */
3137 28 : y0 = init_vectopre(a, n, y, &imax); if (imax == n) x += a-imax;
3138 112 : for (i=1; i<=imax; i++) gel(y0,i) = gcopy(gel(x,i));
3139 28 : return y;
3140 28 : case t_VEC: case t_COL:
3141 28 : a = lg(x)-1;
3142 28 : y0 = init_vectopre(a, n, y, &imax); if (imax == n) x += a-imax;
3143 84 : for (i=1; i<=imax; i++) gel(y0,i) = gcopy(gel(x,i));
3144 28 : return y;
3145 63 : case t_LIST:
3146 63 : if (list_typ(x) == t_LIST_MAP) pari_err_TYPE("gtovec",x);
3147 56 : x = list_data(x); a = x? lg(x)-1: 0;
3148 56 : y0 = init_vectopre(a, n, y, &imax); if (imax == n) x += a-imax;
3149 252 : for (i=1; i<=imax; i++) gel(y0,i) = gcopy(gel(x,i));
3150 56 : return y;
3151 56 : case t_STR:
3152 : {
3153 56 : char *s = GSTR(x);
3154 56 : a = strlen(s);
3155 56 : y0 = init_vectopre(a, n, y, &imax); s--; if (imax == n) s += a-imax;
3156 224 : for (i=1; i<=imax; i++) gel(y,i) = chartoGENstr(s[i]);
3157 56 : return y;
3158 : }
3159 28 : case t_VECSMALL:
3160 28 : a = lg(x)-1;
3161 28 : y0 = init_vectopre(a, n, y, &imax); if (imax == n) x += a-imax;
3162 84 : for (i=1; i<=imax; i++) gel(y0,i) = stoi(x[i]);
3163 28 : return y;
3164 56 : default: pari_err_TYPE("gtovec",x);
3165 : return NULL; /*LCOV_EXCL_LINE*/
3166 : }
3167 : }
3168 : GEN
3169 123878 : gtovec0(GEN x, long n)
3170 : {
3171 123878 : if (!n) return gtovec(x);
3172 4921 : if (n > 0) return gtovecpost(x, n);
3173 3829 : return gtovecpre(x, -n);
3174 : }
3175 :
3176 : GEN
3177 119447 : gtovec(GEN x)
3178 : {
3179 119447 : long i, lx, tx = typ(x);
3180 : GEN y;
3181 :
3182 119447 : if (is_scalar_t(tx)) return mkveccopy(x);
3183 119314 : switch(tx)
3184 : {
3185 15477 : case t_POL:
3186 15477 : lx=lg(x); y=cgetg(lx-1,t_VEC);
3187 1501535 : for (i=1; i<=lx-2; i++) gel(y,i) = gcopy(gel(x,lx-i));
3188 15477 : return y;
3189 385 : case t_SER:
3190 385 : lx=lg(x); y=cgetg(lx-1,t_VEC); x++;
3191 12264 : for (i=1; i<=lx-2; i++) gel(y,i) = gcopy(gel(x,i));
3192 385 : return y;
3193 28 : case t_RFRAC: return mkveccopy(x);
3194 70049 : case t_QFB:
3195 70049 : retmkvec3(icopy(gel(x,1)), icopy(gel(x,2)), icopy(gel(x,3)));
3196 31283 : case t_VEC: case t_COL: case t_MAT:
3197 31283 : lx=lg(x); y=cgetg(lx,t_VEC);
3198 1665027 : for (i=1; i<lx; i++) gel(y,i) = gcopy(gel(x,i));
3199 31283 : return y;
3200 426 : case t_LIST:
3201 426 : if (list_typ(x) == t_LIST_MAP) return mapdomain(x);
3202 412 : x = list_data(x); lx = x? lg(x): 1;
3203 412 : y = cgetg(lx, t_VEC);
3204 20373 : for (i=1; i<lx; i++) gel(y,i) = gcopy(gel(x,i));
3205 412 : return y;
3206 105 : case t_STR:
3207 : {
3208 105 : char *s = GSTR(x);
3209 105 : lx = strlen(s)+1; y = cgetg(lx, t_VEC);
3210 105 : s--;
3211 340239 : for (i=1; i<lx; i++) gel(y,i) = chartoGENstr(s[i]);
3212 105 : return y;
3213 : }
3214 1498 : case t_VECSMALL:
3215 1498 : return vecsmall_to_vec(x);
3216 63 : case t_ERROR:
3217 63 : lx=lg(x); y = cgetg(lx,t_VEC);
3218 63 : gel(y,1) = errname(x);
3219 168 : for (i=2; i<lx; i++) gel(y,i) = gcopy(gel(x,i));
3220 63 : return y;
3221 0 : default: pari_err_TYPE("gtovec",x);
3222 : return NULL; /*LCOV_EXCL_LINE*/
3223 : }
3224 : }
3225 :
3226 : GEN
3227 308 : gtovecrev0(GEN x, long n)
3228 : {
3229 308 : GEN y = gtovec0(x, -n);
3230 280 : vecreverse_inplace(y);
3231 280 : return y;
3232 : }
3233 : GEN
3234 0 : gtovecrev(GEN x) { return gtovecrev0(x, 0); }
3235 :
3236 : GEN
3237 4004 : gtocol0(GEN x, long n)
3238 : {
3239 : GEN y;
3240 4004 : if (!n) return gtocol(x);
3241 3654 : y = gtovec0(x, n);
3242 3598 : settyp(y, t_COL); return y;
3243 : }
3244 : GEN
3245 350 : gtocol(GEN x)
3246 : {
3247 : long lx, tx, i, j, h;
3248 : GEN y;
3249 350 : tx = typ(x);
3250 350 : if (tx != t_MAT) { y = gtovec(x); settyp(y, t_COL); return y; }
3251 14 : lx = lg(x); if (lx == 1) return cgetg(1, t_COL);
3252 14 : h = lgcols(x); y = cgetg(h, t_COL);
3253 42 : for (i = 1 ; i < h; i++) {
3254 28 : gel(y,i) = cgetg(lx, t_VEC);
3255 112 : for (j = 1; j < lx; j++) gmael(y,i,j) = gcopy(gcoeff(x,i,j));
3256 : }
3257 14 : return y;
3258 : }
3259 :
3260 : GEN
3261 294 : gtocolrev0(GEN x, long n)
3262 : {
3263 294 : GEN y = gtocol0(x, -n);
3264 266 : long ly = lg(y), lim = ly>>1, i;
3265 763 : for (i = 1; i <= lim; i++) swap(gel(y,i), gel(y,ly-i));
3266 266 : return y;
3267 : }
3268 : GEN
3269 0 : gtocolrev(GEN x) { return gtocolrev0(x, 0); }
3270 :
3271 : static long
3272 19145 : Itos(GEN x)
3273 : {
3274 19145 : if (typ(x) != t_INT) pari_err_TYPE("vectosmall",x);
3275 19145 : return itos(x);
3276 : }
3277 :
3278 : static GEN
3279 98 : gtovecsmallpost(GEN x, long n)
3280 : {
3281 : long i, imax, lx;
3282 98 : GEN y = zero_Flv(n);
3283 :
3284 98 : switch(typ(x))
3285 : {
3286 7 : case t_INT:
3287 7 : y[1] = itos(x); return y;
3288 14 : case t_POL:
3289 14 : lx=lg(x); imax = minss(lx-2, n);
3290 56 : for (i=1; i<=imax; i++) y[i] = Itos(gel(x,lx-i));
3291 14 : return y;
3292 7 : case t_SER:
3293 7 : lx=lg(x); imax = minss(lx-2, n); x++;
3294 21 : for (i=1; i<=imax; i++) y[i] = Itos(gel(x,i));
3295 7 : return y;
3296 7 : case t_VEC: case t_COL:
3297 7 : lx=lg(x); imax = minss(lx-1, n);
3298 21 : for (i=1; i<=imax; i++) y[i] = Itos(gel(x,i));
3299 7 : return y;
3300 14 : case t_LIST:
3301 14 : x = list_data(x); lx = x? lg(x): 1;
3302 14 : imax = minss(lx-1, n);
3303 63 : for (i=1; i<=imax; i++) y[i] = Itos(gel(x,i));
3304 14 : return y;
3305 7 : case t_VECSMALL:
3306 7 : lx=lg(x);
3307 7 : imax = minss(lx-1, n);
3308 21 : for (i=1; i<=imax; i++) y[i] = x[i];
3309 7 : return y;
3310 14 : case t_STR:
3311 : {
3312 14 : unsigned char *s = (unsigned char*)GSTR(x);
3313 14 : imax = minss(strlen((const char *)s), n); s--;
3314 56 : for (i=1; i<=imax; i++) y[i] = (long)s[i];
3315 14 : return y;
3316 : }
3317 28 : default: pari_err_TYPE("gtovecsmall",x);
3318 : return NULL; /*LCOV_EXCL_LINE*/
3319 : }
3320 : }
3321 : static GEN
3322 98 : gtovecsmallpre(GEN x, long n)
3323 : {
3324 98 : GEN y = zero_Flv(n), y0;
3325 : long a, i, imax, lx;
3326 :
3327 98 : switch(typ(x))
3328 : {
3329 7 : case t_INT:
3330 7 : y[n] = itos(x); return y;
3331 14 : case t_POL:
3332 14 : lx = lg(x); a = lx-2;
3333 14 : y0 = init_vectopre(a, n, y, &imax); if (imax == n) x -= a-imax;
3334 56 : for (i=1; i<=imax; i++) y0[i] = Itos(gel(x,lx-i));
3335 14 : return y;
3336 7 : case t_SER:
3337 7 : a = lg(x)-2; x++;
3338 7 : y0 = init_vectopre(a, n, y, &imax); if (imax == n) x += a-imax;
3339 21 : for (i=1; i<=imax; i++) y0[i] = Itos(gel(x,i));
3340 7 : return y;
3341 7 : case t_VEC: case t_COL:
3342 7 : a = lg(x)-1;
3343 7 : y0 = init_vectopre(a, n, y, &imax); if (imax == n) x += a-imax;
3344 21 : for (i=1; i<=imax; i++) y0[i] = Itos(gel(x,i));
3345 7 : return y;
3346 14 : case t_LIST:
3347 14 : x = list_data(x); a = x? lg(x)-1: 0;
3348 14 : y0 = init_vectopre(a, n, y, &imax); if (imax == n) x += a-imax;
3349 63 : for (i=1; i<=imax; i++) y0[i] = Itos(gel(x,i));
3350 14 : return y;
3351 7 : case t_VECSMALL:
3352 7 : a = lg(x)-1;
3353 7 : y0 = init_vectopre(a, n, y, &imax); if (imax == n) x += a-imax;
3354 21 : for (i=1; i<=imax; i++) y0[i] = x[i];
3355 7 : return y;
3356 14 : case t_STR:
3357 : {
3358 14 : unsigned char *s = (unsigned char*)GSTR(x);
3359 14 : a = strlen((const char *)s);
3360 14 : y0 = init_vectopre(a, n, y, &imax); s--; if (imax == n) s += a-imax;
3361 56 : for (i=1; i<=imax; i++) y0[i] = (long)s[i];
3362 14 : return y;
3363 : }
3364 28 : default: pari_err_TYPE("gtovecsmall",x);
3365 : return NULL; /*LCOV_EXCL_LINE*/
3366 : }
3367 : }
3368 :
3369 : GEN
3370 7819 : gtovecsmall0(GEN x, long n)
3371 : {
3372 7819 : if (!n) return gtovecsmall(x);
3373 196 : if (n > 0) return gtovecsmallpost(x, n);
3374 98 : return gtovecsmallpre(x, -n);
3375 : }
3376 :
3377 : GEN
3378 19187 : gtovecsmall(GEN x)
3379 : {
3380 : GEN V;
3381 : long l, i;
3382 :
3383 19187 : switch(typ(x))
3384 : {
3385 126 : case t_INT: return mkvecsmall(itos(x));
3386 140 : case t_STR:
3387 : {
3388 140 : unsigned char *s = (unsigned char*)GSTR(x);
3389 140 : l = strlen((const char *)s);
3390 140 : V = cgetg(l+1, t_VECSMALL);
3391 140 : s--;
3392 2541 : for (i=1; i<=l; i++) V[i] = (long)s[i];
3393 140 : return V;
3394 : }
3395 13139 : case t_VECSMALL: return leafcopy(x);
3396 14 : case t_LIST:
3397 14 : x = list_data(x);
3398 14 : if (!x) return cgetg(1, t_VECSMALL);
3399 : /* fall through */
3400 : case t_VEC: case t_COL:
3401 5733 : l = lg(x); V = cgetg(l,t_VECSMALL);
3402 24577 : for(i=1; i<l; i++) V[i] = Itos(gel(x,i));
3403 5733 : return V;
3404 14 : case t_POL:
3405 14 : l = lg(x); V = cgetg(l-1,t_VECSMALL);
3406 63 : for (i=1; i<=l-2; i++) V[i] = Itos(gel(x,l-i));
3407 14 : return V;
3408 7 : case t_SER:
3409 7 : l = lg(x); V = cgetg(l-1,t_VECSMALL); x++;
3410 21 : for (i=1; i<=l-2; i++) V[i] = Itos(gel(x,i));
3411 7 : return V;
3412 28 : default:
3413 28 : pari_err_TYPE("vectosmall",x);
3414 : return NULL; /* LCOV_EXCL_LINE */
3415 : }
3416 : }
3417 :
3418 : GEN
3419 327 : compo(GEN x, long n)
3420 : {
3421 327 : long tx = typ(x);
3422 327 : ulong l, lx = (ulong)lg(x);
3423 :
3424 327 : if (!is_recursive_t(tx))
3425 : {
3426 63 : if (tx == t_VECSMALL)
3427 : {
3428 21 : if (n < 1) pari_err_COMPONENT("", "<", gen_1, stoi(n));
3429 21 : if ((ulong)n >= lx) pari_err_COMPONENT("", ">", utoi(lx-1), stoi(n));
3430 7 : return stoi(x[n]);
3431 : }
3432 42 : pari_err_TYPE("component [leaf]", x);
3433 : }
3434 264 : if (n < 1) pari_err_COMPONENT("", "<", gen_1, stoi(n));
3435 257 : if (tx == t_LIST) {
3436 28 : x = list_data(x); tx = t_VEC;
3437 28 : lx = (ulong)(x? lg(x): 1);
3438 : }
3439 257 : l = (ulong)lontyp[tx] + (ulong)n-1; /* beware overflow */
3440 257 : if (l >= lx) pari_err_COMPONENT("", ">", utoi(lx-lontyp[tx]), stoi(n));
3441 173 : return gcopy(gel(x,l));
3442 : }
3443 :
3444 : /* assume x a t_POL */
3445 : static GEN
3446 2601156 : _polcoef(GEN x, long n, long v)
3447 : {
3448 2601156 : long i, w, lx = lg(x), dx = lx-3;
3449 : GEN z;
3450 2601156 : if (dx < 0) return gen_0;
3451 2023208 : if (v < 0 || v == (w=varn(x)))
3452 1340472 : return (n < 0 || n > dx)? gen_0: gel(x,n+2);
3453 682736 : if (varncmp(w,v) > 0) return n? gen_0: x;
3454 : /* w < v */
3455 681839 : z = cgetg(lx, t_POL); z[1] = x[1];
3456 2730140 : for (i = 2; i < lx; i++) gel(z,i) = polcoef_i(gel(x,i), n, v);
3457 681838 : z = normalizepol_lg(z, lx);
3458 681838 : switch(lg(z))
3459 : {
3460 28307 : case 2: z = gen_0; break;
3461 412532 : case 3: z = gel(z,2); break;
3462 : }
3463 681838 : return z;
3464 : }
3465 :
3466 : /* assume x a t_SER */
3467 : static GEN
3468 111958 : _sercoef(GEN x, long n, long v)
3469 : {
3470 111958 : long i, w = varn(x), lx = lg(x), dx = lx-3, N;
3471 : GEN z;
3472 111958 : if (v < 0) v = w;
3473 111958 : N = v == w? n - valser(x): n;
3474 111958 : if (dx < 0)
3475 : {
3476 21 : if (N >= 0) pari_err_DOMAIN("polcoef", "t_SER", "=", x, x);
3477 14 : return gen_0;
3478 : }
3479 111937 : if (v == w)
3480 : {
3481 111895 : if (!dx && !signe(x) && !isinexact(gel(x,2))) dx = -1;
3482 111895 : if (N > dx)
3483 28 : pari_err_DOMAIN("polcoef", "degree", ">", stoi(dx+valser(x)), stoi(n));
3484 111867 : return (N < 0)? gen_0: gel(x,N+2);
3485 : }
3486 42 : if (varncmp(w,v) > 0) return N? gen_0: x;
3487 : /* w < v */
3488 28 : z = cgetg(lx, t_SER); z[1] = x[1];
3489 91 : for (i = 2; i < lx; i++) gel(z,i) = polcoef_i(gel(x,i), n, v);
3490 28 : return normalizeser(z);
3491 : }
3492 :
3493 : /* assume x a t_RFRAC(n) */
3494 : static GEN
3495 21 : _rfraccoef(GEN x, long n, long v)
3496 : {
3497 21 : GEN p = gel(x,1), q = gel(x,2), z;
3498 21 : long vp = gvar(p), vq = gvar(q), vz;
3499 21 : if (v < 0) v = varncmp(vp, vq) < 0? vp: vq;
3500 21 : vz = v;
3501 21 : if (varncmp(vp, v) < 0 || varncmp(vq, v) < 0) vz = fetch_var_higher();
3502 21 : if (vp != v) p = swap_vars(p, v, vz);
3503 21 : if (vq != v) q = swap_vars(q, v, vz);
3504 21 : n += degpol(q);
3505 21 : z = gdiv(_polcoef(p, n, vz), leading_coeff(q));
3506 21 : if (vz != v) (void)delete_var();
3507 21 : if (!RgX_is_monomial(q)) pari_err_TYPE("polcoef", x);
3508 21 : return z;
3509 : }
3510 :
3511 : GEN
3512 3613442 : polcoef_i(GEN x, long n, long v)
3513 : {
3514 3613442 : long tx = typ(x);
3515 3613442 : switch(tx)
3516 : {
3517 2601135 : case t_POL: return _polcoef(x,n,v);
3518 111958 : case t_SER: return _sercoef(x,n,v);
3519 21 : case t_RFRAC: return _rfraccoef(x,n,v);
3520 : }
3521 900328 : if (!is_scalar_t(tx)) pari_err_TYPE("polcoef", x);
3522 900137 : return n? gen_0: x;
3523 : }
3524 :
3525 : /* with respect to the main variable if v<0, with respect to the variable v
3526 : * otherwise. v ignored if x is not a polynomial/series. */
3527 : GEN
3528 727580 : polcoef(GEN x, long n, long v)
3529 : {
3530 727580 : pari_sp av = avma;
3531 727580 : x = polcoef_i(x,n,v);
3532 727349 : if (x == gen_0) return x;
3533 130795 : return (avma == av)? gcopy(x): gc_GEN(av, x);
3534 : }
3535 :
3536 : static GEN
3537 242315 : vecdenom(GEN v, long imin, long imax)
3538 : {
3539 242315 : long i = imin;
3540 : GEN s;
3541 242315 : if (imin > imax) return gen_1;
3542 242315 : s = denom_i(gel(v,i));
3543 2104290 : for (i++; i<=imax; i++)
3544 : {
3545 1861975 : GEN t = denom_i(gel(v,i));
3546 1861975 : if (t != gen_1) s = glcm(s,t);
3547 : }
3548 242315 : return s;
3549 : }
3550 : static GEN denompol(GEN x, long v);
3551 : static GEN
3552 14 : vecdenompol(GEN v, long imin, long imax, long vx)
3553 : {
3554 14 : long i = imin;
3555 : GEN s;
3556 14 : if (imin > imax) return gen_1;
3557 14 : s = denompol(gel(v,i), vx);
3558 14 : for (i++; i<=imax; i++)
3559 : {
3560 0 : GEN t = denompol(gel(v,i), vx);
3561 0 : if (t != gen_1) s = glcm(s,t);
3562 : }
3563 14 : return s;
3564 : }
3565 : GEN
3566 12211807 : denom_i(GEN x)
3567 : {
3568 12211807 : switch(typ(x))
3569 : {
3570 4652224 : case t_INT:
3571 : case t_REAL:
3572 : case t_INTMOD:
3573 : case t_FFELT:
3574 : case t_PADIC:
3575 : case t_SER:
3576 4652224 : case t_VECSMALL: return gen_1;
3577 81706 : case t_FRAC: return gel(x,2);
3578 294 : case t_COMPLEX: return vecdenom(x,1,2);
3579 69069 : case t_QUAD: return vecdenom(x,2,3);
3580 42 : case t_POLMOD: return denom_i(gel(x,2));
3581 7234554 : case t_RFRAC: return gel(x,2);
3582 952 : case t_POL: return pol_1(varn(x));
3583 172952 : case t_VEC: case t_COL: case t_MAT: return vecdenom(x, 1, lg(x)-1);
3584 : }
3585 14 : pari_err_TYPE("denom",x);
3586 : return NULL; /* LCOV_EXCL_LINE */
3587 : }
3588 : /* v has lower (or equal) priority as x's main variable */
3589 : static GEN
3590 119 : denompol(GEN x, long v)
3591 : {
3592 119 : long vx, tx = typ(x);
3593 119 : if (is_scalar_t(tx)) return gen_1;
3594 105 : switch(typ(x))
3595 : {
3596 14 : case t_SER:
3597 14 : if (varn(x) != v) return x;
3598 14 : vx = valser(x); return vx < 0? pol_xn(-vx, v): pol_1(v);
3599 63 : case t_RFRAC: x = gel(x,2); return varn(x) == v? x: pol_1(v);
3600 14 : case t_POL: return pol_1(v);
3601 14 : case t_VEC: case t_COL: case t_MAT: return vecdenompol(x, 1, lg(x)-1, v);
3602 : }
3603 0 : pari_err_TYPE("denom",x);
3604 : return NULL; /* LCOV_EXCL_LINE */
3605 : }
3606 : GEN
3607 228909 : denom(GEN x) { pari_sp av = avma; return gc_GEN(av, denom_i(x)); }
3608 :
3609 : static GEN
3610 287 : denominator_v(GEN x, long v)
3611 : {
3612 287 : long v0 = gvar(x);
3613 : GEN d;
3614 287 : if (v0 == NO_VARIABLE || varncmp(v0,v) > 0) return pol_1(v);
3615 105 : if (v0 != v) { v0 = fetch_var_higher(); x = gsubst(x, v, pol_x(v0)); }
3616 105 : d = denompol(x, v0);
3617 105 : if (v0 != v) { d = gsubst(d, v0, pol_x(v)); (void)delete_var(); }
3618 105 : return d;
3619 : }
3620 : GEN
3621 128149 : denominator(GEN x, GEN D)
3622 : {
3623 128149 : pari_sp av = avma;
3624 : GEN d;
3625 128149 : if (!D) return denom(x);
3626 280 : if (isint1(D))
3627 : {
3628 140 : d = Q_denom_safe(x);
3629 140 : if (!d) { set_avma(av); return gen_1; }
3630 105 : return gc_GEN(av, d);
3631 : }
3632 140 : if (!gequalX(D)) pari_err_TYPE("denominator", D);
3633 140 : return gc_upto(av, denominator_v(x, varn(D)));
3634 : }
3635 : GEN
3636 8925 : numerator(GEN x, GEN D)
3637 : {
3638 8925 : pari_sp av = avma;
3639 : long v;
3640 8925 : if (!D) return numer(x);
3641 294 : if (isint1(D)) return Q_remove_denom(x,NULL);
3642 154 : if (!gequalX(D)) pari_err_TYPE("numerator", D);
3643 154 : v = varn(D); /* optimization */
3644 154 : if (typ(x) == t_RFRAC && varn(gel(x,2)) == v) return gcopy(gel(x,1));
3645 147 : return gc_upto(av, gmul(x, denominator_v(x,v)));
3646 : }
3647 : GEN
3648 131005 : content0(GEN x, GEN D)
3649 : {
3650 131005 : pari_sp av = avma;
3651 : long v, v0;
3652 : GEN d;
3653 131005 : if (!D) return content(x);
3654 294 : if (isint1(D))
3655 : {
3656 140 : d = Q_content_safe(x);
3657 140 : return d? d: gen_1;
3658 : }
3659 154 : if (!gequalX(D)) pari_err_TYPE("content", D);
3660 154 : v = varn(D);
3661 154 : v0 = gvar(x); if (v0 == NO_VARIABLE) return gen_1;
3662 56 : if (varncmp(v0,v) > 0)
3663 : {
3664 0 : v0 = gvar2(x);
3665 0 : return v0 == NO_VARIABLE? gen_1: pol_1(v0);
3666 : }
3667 56 : if (v0 != v) { v0 = fetch_var_higher(); x = gsubst(x, v, pol_x(v0)); }
3668 56 : d = content(x);
3669 : /* gsubst is needed because of content([x]) = x */
3670 56 : if (v0 != v) { d = gsubst(d, v0, pol_x(v)); (void)delete_var(); }
3671 56 : return gc_upto(av, d);
3672 : }
3673 :
3674 : GEN
3675 8948607 : numer_i(GEN x)
3676 : {
3677 8948607 : switch(typ(x))
3678 : {
3679 1713892 : case t_INT:
3680 : case t_REAL:
3681 : case t_INTMOD:
3682 : case t_FFELT:
3683 : case t_PADIC:
3684 : case t_SER:
3685 : case t_VECSMALL:
3686 1713892 : case t_POL: return x;
3687 28 : case t_POLMOD: return mkpolmod(numer_i(gel(x,2)), gel(x,1));
3688 7234498 : case t_FRAC:
3689 7234498 : case t_RFRAC: return gel(x,1);
3690 175 : case t_COMPLEX:
3691 : case t_QUAD:
3692 : case t_VEC:
3693 : case t_COL:
3694 175 : case t_MAT: return gmul(denom_i(x),x);
3695 : }
3696 14 : pari_err_TYPE("numer",x);
3697 : return NULL; /* LCOV_EXCL_LINE */
3698 : }
3699 : GEN
3700 8631 : numer(GEN x) { pari_sp av = avma; return gc_GEN(av, numer_i(x)); }
3701 :
3702 : /* Lift only intmods if v does not occur in x, lift with respect to main
3703 : * variable of x if v < 0, with respect to variable v otherwise */
3704 : GEN
3705 2521572 : lift0(GEN x, long v)
3706 : {
3707 : GEN y;
3708 :
3709 2521572 : switch(typ(x))
3710 : {
3711 30422 : case t_INT: return icopy(x);
3712 2368566 : case t_INTMOD: return v < 0? icopy(gel(x,2)): gcopy(x);
3713 92330 : case t_POLMOD:
3714 92330 : if (v < 0 || v == varn(gel(x,1))) return gcopy(gel(x,2));
3715 14 : y = cgetg(3, t_POLMOD);
3716 14 : gel(y,1) = lift0(gel(x,1),v);
3717 14 : gel(y,2) = lift0(gel(x,2),v); return y;
3718 665 : case t_PADIC: return v < 0? padic_to_Q(x): gcopy(x);
3719 8624 : case t_POL:
3720 41223 : pari_APPLY_pol(lift0(gel(x,i), v));
3721 56 : case t_SER:
3722 56 : if (ser_isexactzero(x))
3723 : {
3724 14 : if (lg(x) == 2) return gcopy(x);
3725 14 : y = scalarser(lift0(gel(x,2),v), varn(x), 1);
3726 14 : setvalser(y, valser(x)); return y;
3727 : }
3728 434 : pari_APPLY_ser(lift0(gel(x,i), v));
3729 20720 : case t_COMPLEX: case t_QUAD: case t_RFRAC:
3730 : case t_VEC: case t_COL: case t_MAT:
3731 221970 : pari_APPLY_same(lift0(gel(x,i), v));
3732 189 : default: return gcopy(x);
3733 : }
3734 : }
3735 : /* same as lift, shallow */
3736 : GEN
3737 652411 : lift_shallow(GEN x)
3738 : {
3739 : GEN y;
3740 652411 : switch(typ(x))
3741 : {
3742 212379 : case t_INTMOD: case t_POLMOD: return gel(x,2);
3743 476 : case t_PADIC: return padic_to_Q(x);
3744 0 : case t_SER:
3745 0 : if (ser_isexactzero(x))
3746 : {
3747 0 : if (lg(x) == 2) return x;
3748 0 : y = scalarser(lift_shallow(gel(x,2)), varn(x), 1);
3749 0 : setvalser(y, valser(x)); return y;
3750 : }
3751 0 : pari_APPLY_ser(lift_shallow(gel(x,i)));
3752 56329 : case t_POL:
3753 316978 : pari_APPLY_pol(lift_shallow(gel(x,i)));
3754 11263 : case t_COMPLEX: case t_QUAD: case t_RFRAC:
3755 : case t_VEC: case t_COL: case t_MAT:
3756 275905 : pari_APPLY_same(lift_shallow(gel(x,i)));
3757 371964 : default: return x;
3758 : }
3759 : }
3760 : GEN
3761 2204831 : lift(GEN x) { return lift0(x,-1); }
3762 :
3763 : GEN
3764 2004485 : liftall_shallow(GEN x)
3765 : {
3766 : GEN y;
3767 2004485 : switch(typ(x))
3768 : {
3769 534100 : case t_INTMOD: return gel(x,2);
3770 547624 : case t_POLMOD:
3771 547624 : return liftall_shallow(gel(x,2));
3772 581 : case t_PADIC: return padic_to_Q(x);
3773 556059 : case t_POL:
3774 1357370 : pari_APPLY_pol(liftall_shallow(gel(x,i)));
3775 7 : case t_SER:
3776 7 : if (ser_isexactzero(x))
3777 : {
3778 0 : if (lg(x) == 2) return x;
3779 0 : y = scalarser(liftall_shallow(gel(x,2)), varn(x), 1);
3780 0 : setvalser(y, valser(x)); return y;
3781 : }
3782 35 : pari_APPLY_ser(liftall_shallow(gel(x,i)));
3783 132811 : case t_COMPLEX: case t_QUAD: case t_RFRAC:
3784 : case t_VEC: case t_COL: case t_MAT:
3785 760725 : pari_APPLY_same(liftall_shallow(gel(x,i)));
3786 233303 : default: return x;
3787 : }
3788 : }
3789 : GEN
3790 26264 : liftall(GEN x)
3791 26264 : { pari_sp av = avma; return gc_GEN(av, liftall_shallow(x)); }
3792 :
3793 : GEN
3794 546 : liftint_shallow(GEN x)
3795 : {
3796 : GEN y;
3797 546 : switch(typ(x))
3798 : {
3799 266 : case t_INTMOD: return gel(x,2);
3800 28 : case t_PADIC: return padic_to_Q(x);
3801 21 : case t_POL:
3802 70 : pari_APPLY_pol(liftint_shallow(gel(x,i)));
3803 14 : case t_SER:
3804 14 : if (ser_isexactzero(x))
3805 : {
3806 7 : if (lg(x) == 2) return x;
3807 7 : y = scalarser(liftint_shallow(gel(x,2)), varn(x), 1);
3808 7 : setvalser(y, valser(x)); return y;
3809 : }
3810 35 : pari_APPLY_ser(liftint_shallow(gel(x,i)));
3811 161 : case t_POLMOD: case t_COMPLEX: case t_QUAD: case t_RFRAC:
3812 : case t_VEC: case t_COL: case t_MAT:
3813 504 : pari_APPLY_same(liftint_shallow(gel(x,i)));
3814 56 : default: return x;
3815 : }
3816 : }
3817 : GEN
3818 119 : liftint(GEN x)
3819 119 : { pari_sp av = avma; return gc_GEN(av, liftint_shallow(x)); }
3820 :
3821 : GEN
3822 21928648 : liftpol_shallow(GEN x)
3823 : {
3824 : GEN y;
3825 21928648 : switch(typ(x))
3826 : {
3827 2155955 : case t_POLMOD:
3828 2155955 : return liftpol_shallow(gel(x,2));
3829 2947238 : case t_POL:
3830 12367760 : pari_APPLY_pol(liftpol_shallow(gel(x,i)));
3831 7 : case t_SER:
3832 7 : if (ser_isexactzero(x))
3833 : {
3834 0 : if (lg(x) == 2) return x;
3835 0 : y = scalarser(liftpol(gel(x,2)), varn(x), 1);
3836 0 : setvalser(y, valser(x)); return y;
3837 : }
3838 35 : pari_APPLY_ser(liftpol_shallow(gel(x,i)));
3839 143409 : case t_RFRAC: case t_VEC: case t_COL: case t_MAT:
3840 1014237 : pari_APPLY_same(liftpol_shallow(gel(x,i)));
3841 16682039 : default: return x;
3842 : }
3843 : }
3844 : GEN
3845 5726 : liftpol(GEN x)
3846 5726 : { pari_sp av = avma; return gc_GEN(av, liftpol_shallow(x)); }
3847 :
3848 : static GEN
3849 42518 : centerliftii(GEN x, GEN y)
3850 : {
3851 42518 : pari_sp av = avma;
3852 42518 : long i = cmpii(shifti(x,1), y);
3853 42518 : set_avma(av); return (i > 0)? subii(x,y): icopy(x);
3854 : }
3855 :
3856 : /* see lift0 */
3857 : GEN
3858 707 : centerlift0(GEN x, long v)
3859 707 : { return v < 0? centerlift(x): lift0(x,v); }
3860 : GEN
3861 60473 : centerlift(GEN x)
3862 : {
3863 : GEN u, p, pd;
3864 : long v;
3865 60473 : switch(typ(x))
3866 : {
3867 784 : case t_INT: return icopy(x);
3868 784 : case t_INTMOD: return centerliftii(gel(x,2), gel(x,1));
3869 7 : case t_POLMOD: return gcopy(gel(x,2));
3870 1533 : case t_POL:
3871 9891 : pari_APPLY_pol(centerlift(gel(x,i)));
3872 7 : case t_SER:
3873 7 : if (ser_isexactzero(x)) return lift(x);
3874 35 : pari_APPLY_ser(centerlift(gel(x,i)));
3875 5551 : case t_COMPLEX: case t_QUAD: case t_RFRAC:
3876 : case t_VEC: case t_COL: case t_MAT:
3877 56210 : pari_APPLY_same(centerlift(gel(x,i)));
3878 51800 : case t_PADIC:
3879 51800 : if (!signe(padic_u(x))) return gen_0;
3880 41734 : v = valp(x); u = padic_u(x); p = padic_p(x); pd = padic_pd(x);
3881 41734 : if (v >= 0)
3882 : { /* here p^v is an integer */
3883 41727 : pari_sp av = avma;
3884 41727 : GEN z = centerliftii(u, pd);
3885 41727 : return v? gc_INT(av, mulii(powiu(p,v), z)): z;
3886 : }
3887 7 : retmkfrac(centerliftii(u, pd), powiu(p,-v));
3888 7 : default: return gcopy(x);
3889 : }
3890 : }
3891 :
3892 : /*******************************************************************/
3893 : /* */
3894 : /* REAL & IMAGINARY PARTS */
3895 : /* */
3896 : /*******************************************************************/
3897 :
3898 : static GEN
3899 203999303 : op_ReIm(GEN f(GEN), GEN x)
3900 : {
3901 203999303 : switch(typ(x))
3902 : {
3903 594392099 : case t_POL: pari_APPLY_pol(f(gel(x,i)));
3904 64463 : case t_SER: pari_APPLY_ser(f(gel(x,i)));
3905 42 : case t_RFRAC: {
3906 42 : pari_sp av = avma;
3907 42 : GEN n, d, dxb = conj_i(gel(x,2));
3908 42 : n = gmul(gel(x,1), dxb);
3909 42 : d = gmul(gel(x,2), dxb);
3910 42 : return gc_upto(av, gdiv(f(n), d));
3911 : }
3912 20626168 : case t_VEC: case t_COL: case t_MAT: pari_APPLY_same(f(gel(x, i)));
3913 : }
3914 12 : pari_err_TYPE("greal/gimag",x);
3915 : return NULL; /* LCOV_EXCL_LINE */
3916 : }
3917 :
3918 : GEN
3919 325120561 : real_i(GEN x)
3920 : {
3921 325120561 : switch(typ(x))
3922 : {
3923 173180395 : case t_INT: case t_REAL: case t_FRAC:
3924 173180395 : return x;
3925 47212065 : case t_COMPLEX:
3926 47212065 : return gel(x,1);
3927 0 : case t_QUAD:
3928 0 : return gel(x,2);
3929 : }
3930 104728101 : return op_ReIm(real_i,x);
3931 : }
3932 : GEN
3933 299640130 : imag_i(GEN x)
3934 : {
3935 299640130 : switch(typ(x))
3936 : {
3937 167421518 : case t_INT: case t_REAL: case t_FRAC:
3938 167421518 : return gen_0;
3939 33027086 : case t_COMPLEX:
3940 33027086 : return gel(x,2);
3941 0 : case t_QUAD:
3942 0 : return gel(x,3);
3943 : }
3944 99191526 : return op_ReIm(imag_i,x);
3945 : }
3946 : GEN
3947 6958 : greal(GEN x)
3948 : {
3949 6958 : switch(typ(x))
3950 : {
3951 665 : case t_INT: case t_REAL:
3952 665 : return mpcopy(x);
3953 :
3954 7 : case t_FRAC:
3955 7 : return gcopy(x);
3956 :
3957 6041 : case t_COMPLEX:
3958 6041 : return gcopy(gel(x,1));
3959 :
3960 7 : case t_QUAD:
3961 7 : return gcopy(gel(x,2));
3962 : }
3963 238 : return op_ReIm(greal,x);
3964 : }
3965 : GEN
3966 29365 : gimag(GEN x)
3967 : {
3968 29365 : switch(typ(x))
3969 : {
3970 525 : case t_INT: case t_REAL: case t_FRAC:
3971 525 : return gen_0;
3972 :
3973 28217 : case t_COMPLEX:
3974 28217 : return gcopy(gel(x,2));
3975 :
3976 7 : case t_QUAD:
3977 7 : return gcopy(gel(x,3));
3978 : }
3979 616 : return op_ReIm(gimag,x);
3980 : }
3981 :
3982 : /* return Im(x * y), x and y scalars */
3983 : GEN
3984 103649 : mulimag(GEN x, GEN y)
3985 : {
3986 103649 : if (typ(x) == t_COMPLEX)
3987 : {
3988 79282 : if (typ(y) == t_COMPLEX)
3989 : {
3990 56042 : pari_sp av = avma;
3991 56042 : GEN a = gmul(gel(x,1), gel(y,2));
3992 56042 : GEN b = gmul(gel(x,2), gel(y,1));
3993 56042 : return gc_upto(av, gadd(a, b));
3994 : }
3995 23240 : x = gel(x,2);
3996 : }
3997 24367 : else if (typ(y) == t_COMPLEX) y = gel(y,2);
3998 8750 : else return gen_0;
3999 38857 : return gmul(x,y);
4000 : }
4001 :
4002 : /* return Re(x * y), x and y scalars */
4003 : GEN
4004 15745435 : mulreal(GEN x, GEN y)
4005 : {
4006 15745435 : if (typ(x) == t_COMPLEX)
4007 : {
4008 15592262 : if (typ(y) == t_COMPLEX)
4009 : {
4010 14362733 : pari_sp av = avma;
4011 14362733 : GEN a = gmul(gel(x,1), gel(y,1));
4012 14362723 : GEN b = gmul(gel(x,2), gel(y,2));
4013 14362728 : return gc_upto(av, gsub(a, b));
4014 : }
4015 1229529 : x = gel(x,1);
4016 : }
4017 : else
4018 153173 : if (typ(y) == t_COMPLEX) y = gel(y,1);
4019 1382702 : return gmul(x,y);
4020 : }
4021 : /* Compute Re(x * y), x and y matrices of compatible dimensions
4022 : * assume scalar entries */
4023 : GEN
4024 0 : RgM_mulreal(GEN x, GEN y)
4025 : {
4026 0 : long i, j, k, l, lx = lg(x), ly = lg(y);
4027 0 : GEN z = cgetg(ly,t_MAT);
4028 0 : l = (lx == 1)? 1: lgcols(x);
4029 0 : for (j=1; j<ly; j++)
4030 : {
4031 0 : GEN zj = cgetg(l,t_COL), yj = gel(y,j);
4032 0 : gel(z,j) = zj;
4033 0 : for (i=1; i<l; i++)
4034 : {
4035 0 : pari_sp av = avma;
4036 0 : GEN c = mulreal(gcoeff(x,i,1),gel(yj,1));
4037 0 : for (k=2; k<lx; k++) c = gadd(c, mulreal(gcoeff(x,i,k),gel(yj,k)));
4038 0 : gel(zj, i) = gc_upto(av, c);
4039 : }
4040 : }
4041 0 : return z;
4042 : }
4043 :
4044 : /* Compute Re(x * y), symmetric result, x and y vectors of compatible
4045 : * dimensions; assume scalar entries */
4046 : GEN
4047 21630 : RgC_RgV_mulrealsym(GEN x, GEN y)
4048 : {
4049 21630 : long i, j, l = lg(x);
4050 21630 : GEN q = cgetg(l, t_MAT);
4051 86520 : for (j = 1; j < l; j++)
4052 : {
4053 64890 : gel(q,j) = cgetg(l,t_COL);
4054 194670 : for (i = 1; i <= j; i++)
4055 129780 : gcoeff(q,i,j) = gcoeff(q,j,i) = mulreal(gel(x,i), gel(y,j));
4056 : }
4057 21630 : return q;
4058 : }
4059 :
4060 : /*******************************************************************/
4061 : /* */
4062 : /* LOGICAL OPERATIONS */
4063 : /* */
4064 : /*******************************************************************/
4065 : static long
4066 109040246 : _egal_i(GEN x, GEN y)
4067 : {
4068 109040246 : x = simplify_shallow(x);
4069 109040281 : y = simplify_shallow(y);
4070 109040271 : if (typ(y) == t_INT)
4071 : {
4072 108001891 : if (equali1(y)) return gequal1(x);
4073 62369050 : if (equalim1(y)) return gequalm1(x);
4074 : }
4075 1038380 : else if (typ(x) == t_INT)
4076 : {
4077 140 : if (equali1(x)) return gequal1(y);
4078 91 : if (equalim1(x)) return gequalm1(y);
4079 : }
4080 63275805 : return gequal(x, y);
4081 : }
4082 : static long
4083 109040240 : _egal(GEN x, GEN y)
4084 109040240 : { pari_sp av = avma; return gc_long(av, _egal_i(x, y)); }
4085 :
4086 : GEN
4087 6328208 : glt(GEN x, GEN y) { return gcmp(x,y)<0? gen_1: gen_0; }
4088 :
4089 : GEN
4090 7628237 : gle(GEN x, GEN y) { return gcmp(x,y)<=0? gen_1: gen_0; }
4091 :
4092 : GEN
4093 248443 : gge(GEN x, GEN y) { return gcmp(x,y)>=0? gen_1: gen_0; }
4094 :
4095 : GEN
4096 2374979 : ggt(GEN x, GEN y) { return gcmp(x,y)>0? gen_1: gen_0; }
4097 :
4098 : GEN
4099 47671486 : geq(GEN x, GEN y) { return _egal(x,y)? gen_1: gen_0; }
4100 :
4101 : GEN
4102 61368754 : gne(GEN x, GEN y) { return _egal(x,y)? gen_0: gen_1; }
4103 :
4104 : GEN
4105 606151 : gnot(GEN x) { return gequal0(x)? gen_1: gen_0; }
4106 :
4107 : /*******************************************************************/
4108 : /* */
4109 : /* FORMAL SIMPLIFICATIONS */
4110 : /* */
4111 : /*******************************************************************/
4112 :
4113 : GEN
4114 11020 : geval_gp(GEN x, GEN t)
4115 : {
4116 11020 : long lx, i, tx = typ(x);
4117 : pari_sp av;
4118 : GEN y, z;
4119 :
4120 11020 : if (is_const_t(tx) || tx==t_VECSMALL) return gcopy(x);
4121 10999 : switch(tx)
4122 : {
4123 10992 : case t_STR:
4124 10992 : return localvars_read_str(GSTR(x),t);
4125 :
4126 0 : case t_POLMOD:
4127 0 : av = avma;
4128 0 : return gc_upto(av, gmodulo(geval_gp(gel(x,2),t),
4129 0 : geval_gp(gel(x,1),t)));
4130 :
4131 7 : case t_POL:
4132 7 : lx=lg(x); if (lx==2) return gen_0;
4133 7 : z = fetch_var_value(varn(x),t);
4134 7 : if (!z) return RgX_copy(x);
4135 7 : av = avma; y = geval_gp(gel(x,lx-1),t);
4136 14 : for (i=lx-2; i>1; i--)
4137 7 : y = gadd(geval_gp(gel(x,i),t), gmul(z,y));
4138 7 : return gc_upto(av, y);
4139 :
4140 0 : case t_SER:
4141 0 : pari_err_IMPL( "evaluation of a power series");
4142 :
4143 0 : case t_RFRAC:
4144 0 : av = avma;
4145 0 : return gc_upto(av, gdiv(geval_gp(gel(x,1),t), geval_gp(gel(x,2),t)));
4146 :
4147 0 : case t_QFB: case t_VEC: case t_COL: case t_MAT:
4148 0 : pari_APPLY_same(geval_gp(gel(x,i),t));
4149 :
4150 0 : case t_CLOSURE:
4151 0 : if (closure_arity(x) || closure_is_variadic(x))
4152 0 : pari_err_IMPL("eval on functions with parameters");
4153 0 : return closure_evalres(x);
4154 : }
4155 0 : pari_err_TYPE("geval",x);
4156 : return NULL; /* LCOV_EXCL_LINE */
4157 : }
4158 : GEN
4159 0 : geval(GEN x) { return geval_gp(x,NULL); }
4160 :
4161 : GEN
4162 514720876 : simplify_shallow(GEN x)
4163 : {
4164 : long v, lx;
4165 : GEN y, z;
4166 514720876 : if (!x) pari_err_BUG("simplify, NULL input");
4167 :
4168 514720876 : switch(typ(x))
4169 : {
4170 434319490 : case t_INT: case t_REAL: case t_INTMOD: case t_FRAC: case t_FFELT:
4171 : case t_PADIC: case t_QFB: case t_LIST: case t_STR: case t_VECSMALL:
4172 : case t_CLOSURE: case t_ERROR: case t_INFINITY:
4173 434319490 : return x;
4174 9618 : case t_COMPLEX: return isintzero(gel(x,2))? gel(x,1): x;
4175 441 : case t_QUAD: return isintzero(gel(x,3))? gel(x,2): x;
4176 :
4177 168428 : case t_POLMOD: y = cgetg(3,t_POLMOD);
4178 168428 : z = gel(x,1); v = varn(z); z = simplify_shallow(z);
4179 168428 : if (typ(z) != t_POL || varn(z) != v) z = scalarpol_shallow(z, v);
4180 168428 : gel(y,1) = z;
4181 168428 : gel(y,2) = simplify_shallow(gel(x,2)); return y;
4182 :
4183 73298326 : case t_POL:
4184 73298326 : lx = lg(x);
4185 73298326 : if (lx==2) return gen_0;
4186 70653038 : if (lx==3) return simplify_shallow(gel(x,2));
4187 229083782 : pari_APPLY_pol(simplify_shallow(gel(x,i)));
4188 :
4189 651 : case t_SER:
4190 566888 : pari_APPLY_ser(simplify_shallow(gel(x,i)));
4191 :
4192 642052 : case t_RFRAC: y = cgetg(3,t_RFRAC);
4193 642052 : gel(y,1) = simplify_shallow(gel(x,1));
4194 642052 : z = simplify_shallow(gel(x,2));
4195 642052 : if (typ(z) != t_POL) return gdiv(gel(y,1), z);
4196 642052 : gel(y,2) = z; return y;
4197 :
4198 6281870 : case t_VEC: case t_COL: case t_MAT:
4199 17900189 : pari_APPLY_same(simplify_shallow(gel(x,i)));
4200 : }
4201 0 : pari_err_BUG("simplify_shallow, type unknown");
4202 : return NULL; /* LCOV_EXCL_LINE */
4203 : }
4204 :
4205 : GEN
4206 11572914 : simplify(GEN x)
4207 : {
4208 11572914 : pari_sp av = avma;
4209 11572914 : GEN y = simplify_shallow(x);
4210 11572914 : return av == avma ? gcopy(y): gc_GEN(av, y);
4211 : }
4212 :
4213 : /*******************************************************************/
4214 : /* */
4215 : /* EVALUATION OF SOME SIMPLE OBJECTS */
4216 : /* */
4217 : /*******************************************************************/
4218 : /* q is a real symmetric matrix, x a RgV. Horner-type evaluation of q(x)
4219 : * using (n^2+3n-2)/2 mul */
4220 : GEN
4221 17023 : qfeval(GEN q, GEN x)
4222 : {
4223 17023 : pari_sp av = avma;
4224 17023 : long i, j, l = lg(q);
4225 : GEN z;
4226 17023 : if (lg(x) != l) pari_err_DIM("qfeval");
4227 17016 : if (l==1) return gen_0;
4228 17016 : if (lgcols(q) != l) pari_err_DIM("qfeval");
4229 : /* l = lg(x) = lg(q) > 1 */
4230 17009 : z = gmul(gcoeff(q,1,1), gsqr(gel(x,1)));
4231 74015 : for (i=2; i<l; i++)
4232 : {
4233 57006 : GEN c = gel(q,i), s;
4234 57006 : if (isintzero(gel(x,i))) continue;
4235 43356 : s = gmul(gel(c,1), gel(x,1));
4236 131810 : for (j=2; j<i; j++) s = gadd(s, gmul(gel(c,j),gel(x,j)));
4237 43356 : s = gadd(gshift(s,1), gmul(gel(c,i),gel(x,i)));
4238 43356 : z = gadd(z, gmul(gel(x,i), s));
4239 : }
4240 17009 : return gc_upto(av,z);
4241 : }
4242 :
4243 : static GEN
4244 347816 : qfbeval(GEN q, GEN z)
4245 : {
4246 347816 : GEN A, a = gel(q,1), b = gel(q,2), c = gel(q,3), x = gel(z,1), y = gel(z,2);
4247 347816 : pari_sp av = avma;
4248 347816 : A = gadd(gmul(x, gadd(gmul(a,x), gmul(b,y))), gmul(c, gsqr(y)));
4249 347816 : return gc_upto(av, A);
4250 : }
4251 : static GEN
4252 7 : qfbevalb(GEN q, GEN z, GEN z2)
4253 : {
4254 7 : GEN A, a = gel(q,1), b = gel(q,2), c = gel(q,3);
4255 7 : GEN x = gel(z,1), y = gel(z,2);
4256 7 : GEN X = gel(z2,1), Y = gel(z2,2);
4257 7 : GEN a2 = shifti(a,1), c2 = shifti(c,1);
4258 7 : pari_sp av = avma;
4259 : /* a2 x X + b (x Y + X y) + c2 y Y */
4260 7 : A = gadd(gmul(x, gadd(gmul(a2,X), gmul(b,Y))),
4261 : gmul(y, gadd(gmul(c2,Y), gmul(b,X))));
4262 7 : return gc_upto(av, gmul2n(A, -1));
4263 : }
4264 : static GEN
4265 14 : qfb_ZM_apply_i(GEN q, GEN M)
4266 : {
4267 14 : GEN a = gel(q,1), b = gel(q,2), c = gel(q,3), d = gel(q,4);
4268 14 : GEN x = gcoeff(M,1,1), y = gcoeff(M,2,1);
4269 14 : GEN z = gcoeff(M,1,2), t = gcoeff(M,2,2);
4270 14 : GEN by = mulii(b,y), bt = mulii(b,t), bz = mulii(b,z);
4271 14 : GEN a2 = shifti(a,1), c2 = shifti(c,1);
4272 :
4273 14 : GEN A1 = mulii(x, addii(mulii(a,x), by));
4274 14 : GEN A2 = mulii(c, sqri(y));
4275 14 : GEN B1 = mulii(x, addii(mulii(a2,z), bt));
4276 14 : GEN B2 = mulii(y, addii(mulii(c2,t), bz));
4277 14 : GEN C1 = mulii(z, addii(mulii(a,z), bt));
4278 14 : GEN C2 = mulii(c, sqri(t));
4279 14 : GEN m = sqri(subii(mulii(x,t), mulii(y,z)));
4280 14 : if (signe(m)==0) pari_err_INV("qfapply",M);
4281 14 : retmkqfb(addii(A1,A2), addii(B1,B2), addii(C1, C2), mulii(d, m));
4282 : }
4283 :
4284 : GEN
4285 14 : qfb_ZM_apply(GEN q, GEN M)
4286 : {
4287 14 : pari_sp av = avma;
4288 14 : return gc_upto(av, qfb_ZM_apply_i(q, M));
4289 : }
4290 :
4291 : static GEN
4292 348019 : qfnorm0(GEN q, GEN x)
4293 : {
4294 348019 : if (!q) switch(typ(x))
4295 : {
4296 7 : case t_VEC: case t_COL: return RgV_dotsquare(x);
4297 7 : case t_MAT: return gram_matrix(x);
4298 7 : default: pari_err_TYPE("qfeval",x);
4299 : }
4300 347998 : switch(typ(q))
4301 : {
4302 161 : case t_MAT: break;
4303 347830 : case t_QFB:
4304 347830 : if (lg(x) == 3) switch(typ(x))
4305 : {
4306 347816 : case t_VEC:
4307 347816 : case t_COL: return qfbeval(q,x);
4308 14 : case t_MAT: if (RgM_is_ZM(x)) return qfb_ZM_apply(q,x);
4309 0 : default: pari_err_TYPE("qfeval",x);
4310 : }
4311 7 : default: pari_err_TYPE("qfeval",q);
4312 : }
4313 161 : switch(typ(x))
4314 : {
4315 154 : case t_VEC: case t_COL: break;
4316 7 : case t_MAT: return qf_RgM_apply(q, x);
4317 0 : default: pari_err_TYPE("qfeval",x);
4318 : }
4319 154 : return qfeval(q,x);
4320 : }
4321 : /* obsolete, use qfeval0 */
4322 : GEN
4323 0 : qfnorm(GEN x, GEN q) { return qfnorm0(q,x); }
4324 :
4325 : /* assume q is square, x~ * q * y using n^2+n mul */
4326 : GEN
4327 567 : qfevalb(GEN q, GEN x, GEN y)
4328 : {
4329 567 : pari_sp av = avma;
4330 567 : long l = lg(q);
4331 567 : if (lg(x) != l || lg(y) != l) pari_err_DIM("qfevalb");
4332 560 : return gc_upto(av, RgV_dotproduct(RgV_RgM_mul(x,q), y));
4333 : }
4334 :
4335 : /* obsolete, use qfeval0 */
4336 : GEN
4337 0 : qfbil(GEN x, GEN y, GEN q)
4338 : {
4339 0 : if (!is_vec_t(typ(x))) pari_err_TYPE("qfbil",x);
4340 0 : if (!is_vec_t(typ(y))) pari_err_TYPE("qfbil",y);
4341 0 : if (!q) {
4342 0 : if (lg(x) != lg(y)) pari_err_DIM("qfbil");
4343 0 : return RgV_dotproduct(x,y);
4344 : }
4345 0 : if (typ(q) != t_MAT) pari_err_TYPE("qfbil",q);
4346 0 : return qfevalb(q,x,y);
4347 : }
4348 : GEN
4349 348075 : qfeval0(GEN q, GEN x, GEN y)
4350 : {
4351 348075 : if (!y) return qfnorm0(q, x);
4352 56 : if (!is_vec_t(typ(x))) pari_err_TYPE("qfeval",x);
4353 42 : if (!is_vec_t(typ(y))) pari_err_TYPE("qfeval",y);
4354 42 : if (!q) {
4355 14 : if (lg(x) != lg(y)) pari_err_DIM("qfeval");
4356 7 : return RgV_dotproduct(x,y);
4357 : }
4358 28 : switch(typ(q))
4359 : {
4360 21 : case t_MAT: break;
4361 7 : case t_QFB:
4362 7 : if (lg(x) == 3 && lg(y) == 3) return qfbevalb(q,x,y);
4363 0 : default: pari_err_TYPE("qfeval",q);
4364 : }
4365 21 : return qfevalb(q,x,y);
4366 : }
4367 :
4368 : /* q a hermitian complex matrix, x a RgV */
4369 : GEN
4370 168 : hqfeval(GEN q, GEN x)
4371 : {
4372 168 : pari_sp av = avma;
4373 168 : long i, j, l = lg(q);
4374 : GEN z, xc;
4375 :
4376 168 : if (lg(x) != l) pari_err_DIM("hqfeval");
4377 168 : if (l==1) return gen_0;
4378 168 : if (lgcols(q) != l) pari_err_DIM("hqfeval");
4379 168 : if (l == 2) return gc_upto(av, gmul(gcoeff(q,1,1), gnorm(gel(x,1))));
4380 : /* l = lg(x) = lg(q) > 2 */
4381 168 : xc = conj_i(x);
4382 168 : z = mulreal(gcoeff(q,2,1), gmul(gel(x,2),gel(xc,1)));
4383 1092 : for (i=3;i<l;i++)
4384 5418 : for (j=1;j<i;j++)
4385 4494 : z = gadd(z, mulreal(gcoeff(q,i,j), gmul(gel(x,i),gel(xc,j))));
4386 168 : z = gshift(z,1);
4387 1428 : for (i=1;i<l;i++) z = gadd(z, gmul(gcoeff(q,i,i), gnorm(gel(x,i))));
4388 168 : return gc_upto(av,z);
4389 : }
4390 :
4391 : static void
4392 504697 : init_qf_apply(GEN q, GEN M, long *l)
4393 : {
4394 504697 : long k = lg(M);
4395 504697 : *l = lg(q);
4396 504697 : if (*l == 1) { if (k == 1) return; }
4397 504690 : else { if (k != 1 && lgcols(M) == *l) return; }
4398 0 : pari_err_DIM("qf_RgM_apply");
4399 : }
4400 : /* Return X = M'.q.M, assuming q is a symmetric matrix and M is a
4401 : * matrix of compatible dimensions. X_ij are X_ji identical, not copies */
4402 : GEN
4403 7663 : qf_RgM_apply(GEN q, GEN M)
4404 : {
4405 7663 : pari_sp av = avma;
4406 7663 : long l; init_qf_apply(q, M, &l); if (l == 1) return cgetg(1, t_MAT);
4407 7663 : return gc_upto(av, RgM_transmultosym(M, RgM_mul(q, M)));
4408 : }
4409 : GEN
4410 497034 : qf_ZM_apply(GEN q, GEN M)
4411 : {
4412 497034 : pari_sp av = avma;
4413 497034 : long l; init_qf_apply(q, M, &l); if (l == 1) return cgetg(1, t_MAT);
4414 : /* FIXME: ZM_transmultosym is asymptotically slow, so choose some random
4415 : * threshold defaulting to default implementation: this is suboptimal but
4416 : * has the right complexity in the dimension. Should implement M'*q*M as an
4417 : * atomic operation with the right complexity, see ZM_mul_i. */
4418 497027 : if (l > 20)
4419 161 : M = ZM_mul(shallowtrans(M), ZM_mul(q, M));
4420 : else
4421 496866 : M = ZM_transmultosym(M, ZM_mul(q, M));
4422 497027 : return gc_upto(av, M);
4423 : }
4424 :
4425 : GEN
4426 13302130 : poleval(GEN x, GEN y)
4427 : {
4428 13302130 : long i, j, imin, M = 1, tx = typ(x);
4429 13302130 : pari_sp av0 = avma, av;
4430 : GEN t, t2, r, s;
4431 :
4432 13302130 : if (is_scalar_t(tx)) return gcopy(x);
4433 13123470 : switch(tx)
4434 : {
4435 12977925 : case t_POL:
4436 12977925 : if (typ(y) == t_POL && varn(x) == varn(y))
4437 : {
4438 188174 : y = RgX_deflate_max(y, &M);
4439 188174 : if (degpol(y) == 1)
4440 : {
4441 126140 : GEN a = gel(y,3), b = gel(y,2); /* y = a t + b */
4442 126140 : if (isint1(a))
4443 : {
4444 95914 : y = RgX_Rg_translate(x, b);
4445 95914 : if (M == 1) return y;
4446 : }
4447 : else
4448 30226 : y = RgX_affine(x, a, b);
4449 112630 : if (M != 1) y = RgX_inflate(y, M);
4450 112630 : return gc_GEN(av0, y);
4451 : }
4452 : }
4453 :
4454 12851785 : i = lg(x)-1; imin = 2; break;
4455 :
4456 1568 : case t_RFRAC:
4457 1568 : return gc_upto(av0, gdiv(poleval(gel(x,1),y),
4458 1568 : poleval(gel(x,2),y)));
4459 :
4460 143977 : case t_VEC: case t_COL:
4461 143977 : i = lg(x)-1; imin = 1; break;
4462 0 : default: pari_err_TYPE("poleval",x);
4463 : return NULL; /* LCOV_EXCL_LINE */
4464 : }
4465 12995762 : if (i<=imin) return (i==imin)? gmul(gel(x,imin),Rg_get_1(y)): Rg_get_0(y);
4466 12621696 : if (isintzero(y)) return gcopy(gel(x,imin));
4467 :
4468 12614414 : t = gel(x,i); i--;
4469 12614414 : if (typ(y)!=t_COMPLEX)
4470 : {
4471 : #if 0 /* standard Horner's rule */
4472 : for ( ; i>=imin; i--)
4473 : t = gadd(gmul(t,y),gel(x,i));
4474 : #endif
4475 : /* specific attention to sparse polynomials */
4476 12509142 : av = avma;
4477 49875731 : for ( ; i>=imin; i=j-1)
4478 : {
4479 57485798 : for (j=i; isexactzero(gel(x,j)); j--)
4480 20119182 : if (j==imin)
4481 : {
4482 11003991 : if (i!=j) y = gpowgs(y, i-j+1);
4483 11003991 : y = gmul(t, y);
4484 11003991 : if (M == 1) return gc_upto(av0, y);
4485 0 : return gc_GEN(av0, RgX_inflate(y, M));
4486 : }
4487 37366619 : r = (i==j)? y: gpowgs(y, i-j+1);
4488 37366619 : t = gadd(gmul(t,r), gel(x,j));
4489 37366589 : if (gc_needed(av0,2))
4490 : {
4491 109 : if (DEBUGMEM>1) pari_warn(warnmem,"poleval: i = %ld",i);
4492 109 : t = gc_upto(av, t);
4493 : }
4494 : }
4495 1505124 : if (M == 1) return gc_upto(av0, t);
4496 6 : return gc_GEN(av0, RgX_inflate(t, M));
4497 : }
4498 :
4499 105272 : t2 = gel(x,i); i--; r = gtrace(y); s = gneg_i(gnorm(y));
4500 105272 : av = avma;
4501 4996426 : for ( ; i>=imin; i--)
4502 : {
4503 4891154 : GEN p = gadd(t2, gmul(r, t));
4504 4891154 : t2 = gadd(gel(x,i), gmul(s, t)); t = p;
4505 4891154 : if (gc_needed(av0,2))
4506 : {
4507 0 : if (DEBUGMEM>1) pari_warn(warnmem,"poleval: i = %ld",i);
4508 0 : (void)gc_all(av, 2, &t, &t2);
4509 : }
4510 : }
4511 105272 : return gc_upto(av0, gadd(t2, gmul(y, t)));
4512 : }
4513 :
4514 : /* Evaluate a polynomial using Horner. Unstable!
4515 : * If ui != NULL, ui = 1/u, evaluate P(1/u)*u^(deg P): useful for |u|>1 */
4516 : GEN
4517 2441995 : RgX_cxeval(GEN T, GEN u, GEN ui)
4518 : {
4519 2441995 : pari_sp ltop = avma;
4520 : GEN S;
4521 2441995 : long n, lim = lg(T)-1;
4522 2441995 : if (lim == 1) return gen_0;
4523 2441995 : if (lim == 2) return gcopy(gel(T,2));
4524 2440837 : if (!ui)
4525 : {
4526 1688251 : n = lim; S = gel(T,n);
4527 15470407 : for (n--; n >= 2; n--) S = gadd(gmul(u,S), gel(T,n));
4528 : }
4529 : else
4530 : {
4531 752586 : n = 2; S = gel(T,2);
4532 4522599 : for (n++; n <= lim; n++) S = gadd(gmul(ui,S), gel(T,n));
4533 752591 : S = gmul(gpowgs(u, lim-2), S);
4534 : }
4535 2440615 : return gc_upto(ltop, S);
4536 : }
4537 :
4538 : GEN
4539 63 : RgXY_cxevalx(GEN x, GEN u, GEN ui)
4540 : {
4541 427 : pari_APPLY_pol(typ(gel(x,i))==t_POL? RgX_cxeval(gel(x,i), u, ui): gel(x,i));
4542 : }
|