1 /* Copyright (C) 2000-2010  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 /*                       MALLOC/FREE WRAPPERS                        */
17 /*********************************************************************/
18 #define BLOCK_SIGALRM_START          \
19 {                                    \
20   int block=PARI_SIGINT_block;       \
21   PARI_SIGINT_block = 2;             \
22   MT_SIGINT_BLOCK(block);
23 
24 #define BLOCK_SIGINT_START           \
25 {                                    \
26   int block=PARI_SIGINT_block;       \
27   PARI_SIGINT_block = 1;             \
28   MT_SIGINT_BLOCK(block);
29 
30 #define BLOCK_SIGINT_END             \
31   PARI_SIGINT_block = block;         \
32   MT_SIGINT_UNBLOCK(block);          \
33   if (!block && PARI_SIGINT_pending) \
34   {                                  \
35     int sig = PARI_SIGINT_pending;   \
36     PARI_SIGINT_pending = 0;         \
37     raise(sig);                      \
38   }                                  \
39 }
40 
41 /*******************************************************************/
42 /*                                                                 */
43 /*                          CONSTRUCTORS                           */
44 /*                                                                 */
45 /*******************************************************************/
46 #define retmkfrac(x,y)\
47   do { GEN _v = cgetg(3, t_FRAC);\
48        gel(_v,1) = (x);\
49        gel(_v,2) = (y); return _v; } while(0)
50 #define retmkrfrac(x,y)\
51   do { GEN _v = cgetg(3, t_RFRAC);\
52        gel(_v,1) = (x);\
53        gel(_v,2) = (y); return _v; } while(0)
54 #define retmkintmod(x,y)\
55   do { GEN _v = cgetg(3, t_INTMOD);\
56        gel(_v,1) = (y);\
57        gel(_v,2) = (x); return _v; } while(0)
58 #define retmkcomplex(x,y)\
59   do { GEN _v = cgetg(3, t_COMPLEX);\
60        gel(_v,1) = (x);\
61        gel(_v,2) = (y); return _v; } while(0)
62 #define retmkpolmod(x,y)\
63   do { GEN _v = cgetg(3, t_POLMOD);\
64        gel(_v,1) = (y);\
65        gel(_v,2) = (x); return _v; } while(0)
66 #define retmkvec(x)\
67   do { GEN _v = cgetg(2, t_VEC);\
68        gel(_v,1) = (x); return _v; } while(0)
69 #define retmkvec2(x,y)\
70   do { GEN _v = cgetg(3, t_VEC);\
71        gel(_v,1) = (x);\
72        gel(_v,2) = (y); return _v; } while(0)
73 #define retmkvec3(x,y,z)\
74   do { GEN _v = cgetg(4, t_VEC);\
75        gel(_v,1) = (x);\
76        gel(_v,2) = (y);\
77        gel(_v,3) = (z); return _v; } while(0)
78 #define retmkqfi(x,y,z)\
79   do { GEN _v = cgetg(4, t_QFI);\
80        gel(_v,1) = (x);\
81        gel(_v,2) = (y);\
82        gel(_v,3) = (z); return _v; } while(0)
83 #define retmkqfr(x,y,z,d)\
84   do { GEN _v = cgetg(5, t_QFR);\
85        gel(_v,1) = (x);\
86        gel(_v,2) = (y);\
87        gel(_v,3) = (z);\
88        gel(_v,4) = (d); return _v; } while(0)
89 #define retmkquad(x,y,z)\
90   do { GEN _v = cgetg(4, t_QUAD);\
91        gel(_v,1) = (x);\
92        gel(_v,2) = (y);\
93        gel(_v,3) = (z); return _v; } while(0)
94 #define retmkvec4(x,y,z,t)\
95   do { GEN _v = cgetg(5, t_VEC);\
96        gel(_v,1) = (x);\
97        gel(_v,2) = (y);\
98        gel(_v,3) = (z);\
99        gel(_v,4) = (t); return _v; } while(0)
100 #define retmkvec5(x,y,z,t,u)\
101   do { GEN _v = cgetg(6, t_VEC);\
102        gel(_v,1) = (x);\
103        gel(_v,2) = (y);\
104        gel(_v,3) = (z);\
105        gel(_v,4) = (t);\
106        gel(_v,5) = (u); return _v; } while(0)
107 #define retmkcol(x)\
108   do { GEN _v = cgetg(2, t_COL);\
109        gel(_v,1) = (x); return _v; } while(0)
110 #define retmkcol2(x,y)\
111   do { GEN _v = cgetg(3, t_COL);\
112        gel(_v,1) = (x);\
113        gel(_v,2) = (y); return _v; } while(0)
114 #define retmkcol3(x,y,z)\
115   do { GEN _v = cgetg(4, t_COL);\
116        gel(_v,1) = (x);\
117        gel(_v,2) = (y);\
118        gel(_v,3) = (z); return _v; } while(0)
119 #define retmkcol4(x,y,z,t)\
120   do { GEN _v = cgetg(5, t_COL);\
121        gel(_v,1) = (x);\
122        gel(_v,2) = (y);\
123        gel(_v,3) = (z);\
124        gel(_v,4) = (t); return _v; } while(0)
125 #define retmkcol5(x,y,z,t,u)\
126   do { GEN _v = cgetg(6, t_COL);\
127        gel(_v,1) = (x);\
128        gel(_v,2) = (y);\
129        gel(_v,3) = (z);\
130        gel(_v,4) = (t);\
131        gel(_v,5) = (u); return _v; } while(0)
132 #define retmkcol6(x,y,z,t,u,v)\
133   do { GEN _v = cgetg(7, t_COL);\
134        gel(_v,1) = (x);\
135        gel(_v,2) = (y);\
136        gel(_v,3) = (z);\
137        gel(_v,4) = (t);\
138        gel(_v,5) = (u);\
139        gel(_v,6) = (v); return _v; } while(0)
140 #define retmkmat(x)\
141   do { GEN _v = cgetg(2, t_MAT);\
142        gel(_v,1) = (x); return _v; } while(0)
143 #define retmkmat2(x,y)\
144   do { GEN _v = cgetg(3, t_MAT);\
145        gel(_v,1) = (x);\
146        gel(_v,2) = (y); return _v; } while(0)
147 #define retmkmat3(x,y,z)\
148   do { GEN _v = cgetg(4, t_MAT);\
149        gel(_v,1) = (x);\
150        gel(_v,2) = (y);\
151        gel(_v,3) = (z); return _v; } while(0)
152 #define retmkmat4(x,y,z,t)\
153   do { GEN _v = cgetg(5, t_MAT);\
154        gel(_v,1) = (x);\
155        gel(_v,2) = (y);\
156        gel(_v,3) = (z);\
157        gel(_v,4) = (t); return _v; } while(0)
158 #define retmkmat5(x,y,z,t,u)\
159   do { GEN _v = cgetg(6, t_MAT);\
160        gel(_v,1) = (x);\
161        gel(_v,2) = (y);\
162        gel(_v,3) = (z);\
163        gel(_v,4) = (t);\
164        gel(_v,5) = (u); return _v; } while(0)
165 
166 INLINE GEN
mkintmod(GEN x,GEN y)167 mkintmod(GEN x, GEN y) { retmkintmod(x,y); }
168 INLINE GEN
mkintmodu(ulong x,ulong y)169 mkintmodu(ulong x, ulong y) {
170   GEN v = cgetg(3,t_INTMOD);
171   gel(v,1) = utoipos(y);
172   gel(v,2) = utoi(x); return v;
173 }
174 INLINE GEN
mkpolmod(GEN x,GEN y)175 mkpolmod(GEN x, GEN y) { retmkpolmod(x,y); }
176 INLINE GEN
mkfrac(GEN x,GEN y)177 mkfrac(GEN x, GEN y) { retmkfrac(x,y); }
178 INLINE GEN
mkfracss(long x,long y)179 mkfracss(long x, long y) { retmkfrac(stoi(x),utoipos(y)); }
180 /* q = n/d a t_FRAC or t_INT; recover (n,d) */
181 INLINE void
Qtoss(GEN q,long * n,long * d)182 Qtoss(GEN q, long *n, long *d)
183 {
184   if (typ(q) == t_INT) { *n = itos(q); *d = 1; }
185   else { *n = itos(gel(q,1)); *d = itou(gel(q,2)); }
186 }
187 INLINE GEN
sstoQ(long n,long d)188 sstoQ(long n, long d)
189 {
190   ulong r;
191   long g, q;
192   if (!n)
193   {
194     if (!d) pari_err_INV("sstoQ",gen_0);
195     return gen_0;
196   }
197   if (d < 0) { d = -d; n = -n; }
198   if (d == 1) return stoi(n);
199   q = udivuu_rem(labs(n),d,&r);
200   if (!r) return n > 0? utoipos(q): utoineg(q);
201   g = ugcd(d,r); /* gcd(n,d) */
202   if (g != 1) { n /= g; d /= g; }
203   retmkfrac(stoi(n), utoi(d));
204 }
205 
206 INLINE GEN
mkfraccopy(GEN x,GEN y)207 mkfraccopy(GEN x, GEN y) { retmkfrac(icopy(x), icopy(y)); }
208 INLINE GEN
mkrfrac(GEN x,GEN y)209 mkrfrac(GEN x, GEN y) { GEN v = cgetg(3, t_RFRAC);
210   gel(v,1) = x; gel(v,2) = y; return v; }
211 INLINE GEN
mkrfraccopy(GEN x,GEN y)212 mkrfraccopy(GEN x, GEN y) { GEN v = cgetg(3, t_RFRAC);
213   gel(v,1) = gcopy(x); gel(v,2) = gcopy(y); return v; }
214 INLINE GEN
mkcomplex(GEN x,GEN y)215 mkcomplex(GEN x, GEN y) { retmkcomplex(x,y); }
216 INLINE GEN
gen_I(void)217 gen_I(void) { return mkcomplex(gen_0, gen_1); }
218 INLINE GEN
cgetc(long l)219 cgetc(long l) { retmkcomplex(cgetr(l), cgetr(l)); }
220 INLINE GEN
mkquad(GEN n,GEN x,GEN y)221 mkquad(GEN n, GEN x, GEN y) { GEN v = cgetg(4, t_QUAD);
222   gel(v,1) = n; gel(v,2) = x; gel(v,3) = y; return v; }
223 /* vecsmall */
224 INLINE GEN
mkvecsmall(long x)225 mkvecsmall(long x) { GEN v = cgetg(2, t_VECSMALL); v[1] = x; return v; }
226 INLINE GEN
mkvecsmall2(long x,long y)227 mkvecsmall2(long x,long y) { GEN v = cgetg(3, t_VECSMALL);
228   v[1]=x; v[2]=y; return v; }
229 INLINE GEN
mkvecsmall3(long x,long y,long z)230 mkvecsmall3(long x,long y,long z) { GEN v = cgetg(4, t_VECSMALL);
231   v[1]=x; v[2]=y; v[3]=z; return v; }
232 INLINE GEN
mkvecsmall4(long x,long y,long z,long t)233 mkvecsmall4(long x,long y,long z,long t) { GEN v = cgetg(5, t_VECSMALL);
234   v[1]=x; v[2]=y; v[3]=z; v[4]=t; return v; }
235 INLINE GEN
mkvecsmall5(long x,long y,long z,long t,long u)236 mkvecsmall5(long x,long y,long z,long t,long u) { GEN v = cgetg(6, t_VECSMALL);
237   v[1]=x; v[2]=y; v[3]=z; v[4]=t; v[5]=u; return v; }
238 
239 INLINE GEN
mkqfi(GEN x,GEN y,GEN z)240 mkqfi(GEN x, GEN y, GEN z) { retmkqfi(x,y,z); }
241 /* vec */
242 INLINE GEN
mkvec(GEN x)243 mkvec(GEN x) { retmkvec(x); }
244 INLINE GEN
mkvec2(GEN x,GEN y)245 mkvec2(GEN x, GEN y) { retmkvec2(x,y); }
246 INLINE GEN
mkvec3(GEN x,GEN y,GEN z)247 mkvec3(GEN x, GEN y, GEN z) { retmkvec3(x,y,z); }
248 INLINE GEN
mkvec4(GEN x,GEN y,GEN z,GEN t)249 mkvec4(GEN x, GEN y, GEN z, GEN t) { retmkvec4(x,y,z,t); }
250 INLINE GEN
mkvec5(GEN x,GEN y,GEN z,GEN t,GEN u)251 mkvec5(GEN x, GEN y, GEN z, GEN t, GEN u) { retmkvec5(x,y,z,t,u); }
252 INLINE GEN
mkvecs(long x)253 mkvecs(long x) { retmkvec(stoi(x)); }
254 INLINE GEN
mkvec2s(long x,long y)255 mkvec2s(long x, long y) { retmkvec2(stoi(x),stoi(y)); }
256 INLINE GEN
mkvec3s(long x,long y,long z)257 mkvec3s(long x, long y, long z) { retmkvec3(stoi(x),stoi(y),stoi(z)); }
258 INLINE GEN
mkvec4s(long x,long y,long z,long t)259 mkvec4s(long x, long y, long z, long t) { retmkvec4(stoi(x),stoi(y),stoi(z),stoi(t)); }
260 INLINE GEN
mkveccopy(GEN x)261 mkveccopy(GEN x) { GEN v = cgetg(2, t_VEC); gel(v,1) = gcopy(x); return v; }
262 INLINE GEN
mkvec2copy(GEN x,GEN y)263 mkvec2copy(GEN x, GEN y) {
264   GEN v = cgetg(3,t_VEC); gel(v,1) = gcopy(x); gel(v,2) = gcopy(y); return v; }
265 /* col */
266 INLINE GEN
mkcol(GEN x)267 mkcol(GEN x) { retmkcol(x); }
268 INLINE GEN
mkcol2(GEN x,GEN y)269 mkcol2(GEN x, GEN y) { retmkcol2(x,y); }
270 INLINE GEN
mkcol3(GEN x,GEN y,GEN z)271 mkcol3(GEN x, GEN y, GEN z) { retmkcol3(x,y,z); }
272 INLINE GEN
mkcol4(GEN x,GEN y,GEN z,GEN t)273 mkcol4(GEN x, GEN y, GEN z, GEN t) { retmkcol4(x,y,z,t); }
274 INLINE GEN
mkcol5(GEN x,GEN y,GEN z,GEN t,GEN u)275 mkcol5(GEN x, GEN y, GEN z, GEN t, GEN u) { retmkcol5(x,y,z,t,u); }
276 INLINE GEN
mkcol6(GEN x,GEN y,GEN z,GEN t,GEN u,GEN v)277 mkcol6(GEN x, GEN y, GEN z, GEN t, GEN u, GEN v) { retmkcol6(x,y,z,t,u,v); }
278 INLINE GEN
mkcols(long x)279 mkcols(long x) { retmkcol(stoi(x)); }
280 INLINE GEN
mkcol2s(long x,long y)281 mkcol2s(long x, long y) { retmkcol2(stoi(x),stoi(y)); }
282 INLINE GEN
mkcol3s(long x,long y,long z)283 mkcol3s(long x, long y, long z) { retmkcol3(stoi(x),stoi(y),stoi(z)); }
284 INLINE GEN
mkcol4s(long x,long y,long z,long t)285 mkcol4s(long x, long y, long z, long t) { retmkcol4(stoi(x),stoi(y),stoi(z),stoi(t)); }
286 INLINE GEN
mkcolcopy(GEN x)287 mkcolcopy(GEN x) { GEN v = cgetg(2, t_COL); gel(v,1) = gcopy(x); return v; }
288 /* mat */
289 INLINE GEN
mkmat(GEN x)290 mkmat(GEN x) { retmkmat(x); }
291 INLINE GEN
mkmat2(GEN x,GEN y)292 mkmat2(GEN x, GEN y) { retmkmat2(x,y); }
293 INLINE GEN
mkmat3(GEN x,GEN y,GEN z)294 mkmat3(GEN x, GEN y, GEN z) { retmkmat3(x,y,z); }
295 INLINE GEN
mkmat4(GEN x,GEN y,GEN z,GEN t)296 mkmat4(GEN x, GEN y, GEN z, GEN t) { retmkmat4(x,y,z,t); }
297 INLINE GEN
mkmat5(GEN x,GEN y,GEN z,GEN t,GEN u)298 mkmat5(GEN x, GEN y, GEN z, GEN t, GEN u) { retmkmat5(x,y,z,t,u); }
299 INLINE GEN
mkmatcopy(GEN x)300 mkmatcopy(GEN x) { GEN v = cgetg(2, t_MAT); gel(v,1) = gcopy(x); return v; }
301 INLINE GEN
mkerr(long x)302 mkerr(long x) { GEN v = cgetg(2, t_ERROR); v[1] = x; return v; }
303 INLINE GEN
mkoo(void)304 mkoo(void) { GEN v = cgetg(2, t_INFINITY); gel(v,1) = gen_1; return v; }
305 INLINE GEN
mkmoo(void)306 mkmoo(void) { GEN v = cgetg(2, t_INFINITY); gel(v,1) = gen_m1; return v; }
307 INLINE long
inf_get_sign(GEN x)308 inf_get_sign(GEN x) { return signe(gel(x,1)); }
309 INLINE GEN
mkmat22s(long a,long b,long c,long d)310 mkmat22s(long a, long b, long c, long d) {retmkmat2(mkcol2s(a,c),mkcol2s(b,d));}
311 INLINE GEN
mkmat22(GEN a,GEN b,GEN c,GEN d)312 mkmat22(GEN a, GEN b, GEN c, GEN d) { retmkmat2(mkcol2(a,c),mkcol2(b,d)); }
313 
314 /* pol */
315 INLINE GEN
pol_x(long v)316 pol_x(long v) {
317   GEN p = cgetg(4, t_POL);
318   p[1] = evalsigne(1)|evalvarn(v);
319   gel(p,2) = gen_0;
320   gel(p,3) = gen_1; return p;
321 }
322 /* x^n, assume n >= 0 */
323 INLINE GEN
pol_xn(long n,long v)324 pol_xn(long n, long v) {
325   long i, a = n+2;
326   GEN p = cgetg(a+1, t_POL);
327   p[1] = evalsigne(1)|evalvarn(v);
328   for (i = 2; i < a; i++) gel(p,i) = gen_0;
329   gel(p,a) = gen_1; return p;
330 }
331 /* x^n, no assumption on n */
332 INLINE GEN
pol_xnall(long n,long v)333 pol_xnall(long n, long v)
334 {
335   if (n < 0) retmkrfrac(gen_1, pol_xn(-n,v));
336   return pol_xn(n, v);
337 }
338 /* x^n, assume n >= 0 */
339 INLINE GEN
polxn_Flx(long n,long sv)340 polxn_Flx(long n, long sv) {
341   long i, a = n+2;
342   GEN p = cgetg(a+1, t_VECSMALL);
343   p[1] = sv;
344   for (i = 2; i < a; i++) p[i] = 0;
345   p[a] = 1; return p;
346 }
347 INLINE GEN
pol_1(long v)348 pol_1(long v) {
349   GEN p = cgetg(3, t_POL);
350   p[1] = evalsigne(1)|evalvarn(v);
351   gel(p,2) = gen_1; return p;
352 }
353 INLINE GEN
pol_0(long v)354 pol_0(long v)
355 {
356   GEN x = cgetg(2,t_POL);
357   x[1] = evalvarn(v); return x;
358 }
359 #define retconst_vec(n,x)\
360   do { long _i, _n = (n);\
361        GEN _v = cgetg(_n+1, t_VEC), _x = (x);\
362        for (_i = 1; _i <= _n; _i++) gel(_v,_i) = _x;\
363        return _v; } while(0)
364 INLINE GEN
const_vec(long n,GEN x)365 const_vec(long n, GEN x) { retconst_vec(n, x); }
366 #define retconst_col(n,x)\
367   do { long _i, _n = (n);\
368        GEN _v = cgetg(_n+1, t_COL), _x = (x);\
369        for (_i = 1; _i <= _n; _i++) gel(_v,_i) = _x;\
370        return _v; } while(0)
371 INLINE GEN
const_col(long n,GEN x)372 const_col(long n, GEN x) { retconst_col(n, x); }
373 INLINE GEN
const_vecsmall(long n,long c)374 const_vecsmall(long n, long c)
375 {
376   long i;
377   GEN V = cgetg(n+1,t_VECSMALL);
378   for(i=1;i<=n;i++) V[i] = c;
379   return V;
380 }
381 
382 /***   ZERO   ***/
383 /* O(p^e) */
384 INLINE GEN
zeropadic(GEN p,long e)385 zeropadic(GEN p, long e)
386 {
387   GEN y = cgetg(5,t_PADIC);
388   gel(y,4) = gen_0;
389   gel(y,3) = gen_1;
390   gel(y,2) = icopy(p);
391   y[1] = evalvalp(e) | _evalprecp(0);
392   return y;
393 }
394 INLINE GEN
zeropadic_shallow(GEN p,long e)395 zeropadic_shallow(GEN p, long e)
396 {
397   GEN y = cgetg(5,t_PADIC);
398   gel(y,4) = gen_0;
399   gel(y,3) = gen_1;
400   gel(y,2) = p;
401   y[1] = evalvalp(e) | _evalprecp(0);
402   return y;
403 }
404 /* O(pol_x(v)^e) */
405 INLINE GEN
zeroser(long v,long e)406 zeroser(long v, long e)
407 {
408   GEN x = cgetg(2, t_SER);
409   x[1] = evalvalp(e) | evalvarn(v); return x;
410 }
411 INLINE int
ser_isexactzero(GEN x)412 ser_isexactzero(GEN x)
413 {
414   if (!signe(x)) switch(lg(x))
415   {
416     case 2: return 1;
417     case 3: return isexactzero(gel(x,2));
418   }
419   return 0;
420 }
421 /* 0 * pol_x(v) */
422 INLINE GEN
zeropol(long v)423 zeropol(long v) { return pol_0(v); }
424 /* vector(n) */
425 INLINE GEN
zerocol(long n)426 zerocol(long n)
427 {
428   GEN y = cgetg(n+1,t_COL);
429   long i; for (i=1; i<=n; i++) gel(y,i) = gen_0;
430   return y;
431 }
432 /* vectorv(n) */
433 INLINE GEN
zerovec(long n)434 zerovec(long n)
435 {
436   GEN y = cgetg(n+1,t_VEC);
437   long i; for (i=1; i<=n; i++) gel(y,i) = gen_0;
438   return y;
439 }
440 /* matrix(m, n) */
441 INLINE GEN
zeromat(long m,long n)442 zeromat(long m, long n)
443 {
444   GEN y = cgetg(n+1,t_MAT);
445   GEN v = zerocol(m);
446   long i; for (i=1; i<=n; i++) gel(y,i) = v;
447   return y;
448 }
449 /* = zero_zx, sv is a evalvarn()*/
450 INLINE GEN
zero_Flx(long sv)451 zero_Flx(long sv) { return pol0_Flx(sv); }
452 INLINE GEN
zero_Flv(long n)453 zero_Flv(long n)
454 {
455   GEN y = cgetg(n+1,t_VECSMALL);
456   long i; for (i=1; i<=n; i++) y[i] = 0;
457   return y;
458 }
459 /* matrix(m, n) */
460 INLINE GEN
zero_Flm(long m,long n)461 zero_Flm(long m, long n)
462 {
463   GEN y = cgetg(n+1,t_MAT);
464   GEN v = zero_Flv(m);
465   long i; for (i=1; i<=n; i++) gel(y,i) = v;
466   return y;
467 }
468 /* matrix(m, n) */
469 INLINE GEN
zero_Flm_copy(long m,long n)470 zero_Flm_copy(long m, long n)
471 {
472   GEN y = cgetg(n+1,t_MAT);
473   long i; for (i=1; i<=n; i++) gel(y,i) = zero_Flv(m);
474   return y;
475 }
476 
477 INLINE GEN
zero_F2v(long m)478 zero_F2v(long m)
479 {
480   long l = nbits2nlong(m);
481   GEN v  = zero_Flv(l+1);
482   v[1] = m;
483   return v;
484 }
485 
486 INLINE GEN
zero_F2m(long m,long n)487 zero_F2m(long m, long n)
488 {
489   long i;
490   GEN M = cgetg(n+1, t_MAT);
491   GEN v = zero_F2v(m);
492   for (i = 1; i <= n; i++)
493     gel(M,i) = v;
494   return M;
495 }
496 
497 
498 INLINE GEN
zero_F2m_copy(long m,long n)499 zero_F2m_copy(long m, long n)
500 {
501   long i;
502   GEN M = cgetg(n+1, t_MAT);
503   for (i = 1; i <= n; i++)
504     gel(M,i)= zero_F2v(m);
505   return M;
506 }
507 
508 /* matrix(m, n) */
509 INLINE GEN
zeromatcopy(long m,long n)510 zeromatcopy(long m, long n)
511 {
512   GEN y = cgetg(n+1,t_MAT);
513   long i; for (i=1; i<=n; i++) gel(y,i) = zerocol(m);
514   return y;
515 }
516 
517 INLINE GEN
zerovec_block(long len)518 zerovec_block(long len)
519 {
520   long i;
521   GEN blk = cgetg_block(len + 1, t_VEC);
522   for (i = 1; i <= len; ++i)
523     gel(blk, i) = gen_0;
524   return blk;
525 }
526 
527 /* i-th vector in the standard basis */
528 INLINE GEN
col_ei(long n,long i)529 col_ei(long n, long i) { GEN e = zerocol(n); gel(e,i) = gen_1; return e; }
530 INLINE GEN
vec_ei(long n,long i)531 vec_ei(long n, long i) { GEN e = zerovec(n); gel(e,i) = gen_1; return e; }
532 INLINE GEN
F2v_ei(long n,long i)533 F2v_ei(long n, long i) { GEN e = zero_F2v(n); F2v_set(e,i); return e; }
534 INLINE GEN
vecsmall_ei(long n,long i)535 vecsmall_ei(long n, long i) { GEN e = zero_zv(n); e[i] = 1; return e; }
536 INLINE GEN
Rg_col_ei(GEN x,long n,long i)537 Rg_col_ei(GEN x, long n, long i) { GEN e = zerocol(n); gel(e,i) = x; return e; }
538 
539 INLINE GEN
shallowcopy(GEN x)540 shallowcopy(GEN x)
541 { return typ(x) == t_MAT ? RgM_shallowcopy(x): leafcopy(x); }
542 
543 /* routines for naive growarrays */
544 INLINE GEN
vectrunc_init(long l)545 vectrunc_init(long l)
546 {
547   GEN z = new_chunk(l);
548   z[0] = evaltyp(t_VEC) | _evallg(1); return z;
549 }
550 INLINE GEN
coltrunc_init(long l)551 coltrunc_init(long l)
552 {
553   GEN z = new_chunk(l);
554   z[0] = evaltyp(t_COL) | _evallg(1); return z;
555 }
556 INLINE void
lg_increase(GEN x)557 lg_increase(GEN x) { x[0]++; }
558 INLINE void
vectrunc_append(GEN x,GEN t)559 vectrunc_append(GEN x, GEN t) { gel(x, lg(x)) = t; lg_increase(x); }
560 INLINE void
vectrunc_append_batch(GEN x,GEN y)561 vectrunc_append_batch(GEN x, GEN y)
562 {
563   long i, l = lg(x), ly = lg(y);
564   GEN z = x + l-1;
565   for (i = 1; i < ly; i++) gel(z,i) = gel(y,i);
566   setlg(x, l+ly-1);
567 }
568 INLINE GEN
vecsmalltrunc_init(long l)569 vecsmalltrunc_init(long l)
570 {
571   GEN z = new_chunk(l);
572   z[0] = evaltyp(t_VECSMALL) | _evallg(1); return z;
573 }
574 INLINE void
vecsmalltrunc_append(GEN x,long t)575 vecsmalltrunc_append(GEN x, long t) { x[ lg(x) ] = t; lg_increase(x); }
576 
577 /*******************************************************************/
578 /*                                                                 */
579 /*                    STRING HASH FUNCTIONS                        */
580 /*                                                                 */
581 /*******************************************************************/
582 INLINE ulong
hash_str(const char * str)583 hash_str(const char *str)
584 {
585   ulong hash = 5381UL, c;
586   while ( (c = (ulong)*str++) )
587     hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
588   return hash;
589 }
590 INLINE ulong
hash_str_len(const char * str,long len)591 hash_str_len(const char *str, long len)
592 {
593   ulong hash = 5381UL;
594   long i;
595   for (i = 0; i < len; i++)
596   {
597     ulong c = (ulong)*str++;
598     hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
599   }
600   return hash;
601 }
602 
603 /*******************************************************************/
604 /*                                                                 */
605 /*                        VEC / COL / VECSMALL                     */
606 /*                                                                 */
607 /*******************************************************************/
608 /* shallow*/
609 INLINE GEN
vec_shorten(GEN v,long n)610 vec_shorten(GEN v, long n)
611 {
612   long i;
613   GEN V = cgetg(n+1,t_VEC);
614   for(i=1;i<=n;i++) gel(V,i) = gel(v,i);
615   return V;
616 }
617 /* shallow*/
618 INLINE GEN
vec_lengthen(GEN v,long n)619 vec_lengthen(GEN v, long n)
620 {
621   long i;
622   long l=lg(v);
623   GEN V = cgetg(n+1,t_VEC);
624   for(i=1;i<l;i++) gel(V,i) = gel(v,i);
625   return V;
626 }
627 /* shallow*/
628 INLINE GEN
vec_append(GEN V,GEN s)629 vec_append(GEN V, GEN s)
630 {
631   long i, l2 = lg(V);
632   GEN res = cgetg(l2+1, typ(V));
633   for (i = 1; i < l2; ++i) gel(res, i) = gel(V,i);
634   gel(res,l2) = s; return res;
635 }
636 /* shallow*/
637 INLINE GEN
vec_prepend(GEN v,GEN s)638 vec_prepend(GEN v, GEN s)
639 {
640   long i, l = lg(v);
641   GEN w = cgetg(l+1, typ(v));
642   gel(w,1) = s;
643   for (i = 2; i <= l; ++i) gel(w,i) = gel(v,i-1);
644   return w;
645 }
646 /* shallow*/
647 INLINE GEN
vec_setconst(GEN v,GEN x)648 vec_setconst(GEN v, GEN x)
649 {
650   long i, l = lg(v);
651   for (i = 1; i < l; i++) gel(v,i) = x;
652   return v;
653 }
654 INLINE GEN
vecsmall_shorten(GEN v,long n)655 vecsmall_shorten(GEN v, long n)
656 {
657   long i;
658   GEN V = cgetg(n+1,t_VECSMALL);
659   for(i=1;i<=n;i++) V[i] = v[i];
660   return V;
661 }
662 INLINE GEN
vecsmall_lengthen(GEN v,long n)663 vecsmall_lengthen(GEN v, long n)
664 {
665   long i, l = lg(v);
666   GEN V = cgetg(n+1,t_VECSMALL);
667   for(i=1;i<l;i++) V[i] = v[i];
668   return V;
669 }
670 
671 INLINE GEN
vec_to_vecsmall(GEN x)672 vec_to_vecsmall(GEN x)
673 { pari_APPLY_long(itos(gel(x,i))) }
674 INLINE GEN
vecsmall_to_vec(GEN x)675 vecsmall_to_vec(GEN x)
676 { pari_APPLY_type(t_VEC, stoi(x[i])) }
677 INLINE GEN
vecsmall_to_vec_inplace(GEN z)678 vecsmall_to_vec_inplace(GEN z)
679 {
680   long i, l = lg(z);
681   for (i=1; i<l; i++) gel(z,i) = stoi(z[i]);
682   settyp(z, t_VEC); return z;
683 }
684 INLINE GEN
vecsmall_to_col(GEN x)685 vecsmall_to_col(GEN x)
686 { pari_APPLY_type(t_COL, stoi(x[i])) }
687 
688 INLINE int
vecsmall_lexcmp(GEN x,GEN y)689 vecsmall_lexcmp(GEN x, GEN y)
690 {
691   long lx,ly,l,i;
692   lx = lg(x);
693   ly = lg(y); l = minss(lx,ly);
694   for (i=1; i<l; i++)
695     if (x[i] != y[i]) return x[i]<y[i]? -1: 1;
696   if (lx == ly) return 0;
697   return (lx < ly)? -1 : 1;
698 }
699 
700 INLINE int
vecsmall_prefixcmp(GEN x,GEN y)701 vecsmall_prefixcmp(GEN x, GEN y)
702 {
703   long i, lx = lg(x), ly = lg(y), l = minss(lx,ly);
704   for (i=1; i<l; i++)
705     if (x[i] != y[i]) return x[i]<y[i]? -1: 1;
706   return 0;
707 }
708 
709 /*Can be used on t_VEC, but coeffs not gcopy-ed*/
710 INLINE GEN
vecsmall_prepend(GEN V,long s)711 vecsmall_prepend(GEN V, long s)
712 {
713   long i, l2 = lg(V);
714   GEN res = cgetg(l2+1, typ(V));
715   res[1] = s;
716   for (i = 2; i <= l2; ++i) res[i] = V[i - 1];
717   return res;
718 }
719 
720 INLINE GEN
vecsmall_append(GEN V,long s)721 vecsmall_append(GEN V, long s)
722 {
723   long i, l2 = lg(V);
724   GEN res = cgetg(l2+1, t_VECSMALL);
725   for (i = 1; i < l2; ++i) res[i] = V[i];
726   res[l2] = s; return res;
727 }
728 
729 INLINE GEN
vecsmall_concat(GEN u,GEN v)730 vecsmall_concat(GEN u, GEN v)
731 {
732   long i, l1 = lg(u)-1, l2 = lg(v)-1;
733   GEN res = cgetg(l1+l2+1, t_VECSMALL);
734   for (i = 1; i <= l1; ++i) res[i]    = u[i];
735   for (i = 1; i <= l2; ++i) res[i+l1] = v[i];
736   return res;
737 }
738 
739 /* return the number of indices where u and v are equal */
740 INLINE long
vecsmall_coincidence(GEN u,GEN v)741 vecsmall_coincidence(GEN u, GEN v)
742 {
743   long i, s = 0, l = minss(lg(u),lg(v));
744   for(i=1; i<l; i++)
745     if(u[i] == v[i]) s++;
746   return s;
747 }
748 
749 /* returns the first index i<=n such that x=v[i] if it exists, 0 otherwise */
750 INLINE long
vecsmall_isin(GEN v,long x)751 vecsmall_isin(GEN v, long x)
752 {
753   long i, l = lg(v);
754   for (i = 1; i < l; i++)
755     if (v[i] == x) return i;
756   return 0;
757 }
758 
759 INLINE long
vecsmall_pack(GEN V,long base,long mod)760 vecsmall_pack(GEN V, long base, long mod)
761 {
762   long i, s = 0;
763   for(i=1; i<lg(V); i++) s = (base*s + V[i]) % mod;
764   return s;
765 }
766 
767 INLINE long
vecsmall_indexmax(GEN x)768 vecsmall_indexmax(GEN x)
769 {
770   long i, i0 = 1, t = x[1], lx = lg(x);
771   for (i=2; i<lx; i++)
772     if (x[i] > t) t = x[i0=i];
773   return i0;
774 }
775 
776 INLINE long
vecsmall_max(GEN x)777 vecsmall_max(GEN x)
778 {
779   long i, t = x[1], lx = lg(x);
780   for (i=2; i<lx; i++)
781     if (x[i] > t) t = x[i];
782   return t;
783 }
784 
785 INLINE long
vecsmall_indexmin(GEN x)786 vecsmall_indexmin(GEN x)
787 {
788   long i, i0 = 1, t = x[1], lx =lg(x);
789   for (i=2; i<lx; i++)
790     if (x[i] < t) t = x[i0=i];
791   return i0;
792 }
793 
794 INLINE long
vecsmall_min(GEN x)795 vecsmall_min(GEN x)
796 {
797   long i, t = x[1], lx =lg(x);
798   for (i=2; i<lx; i++)
799     if (x[i] < t) t = x[i];
800   return t;
801 }
802 
803 INLINE int
ZV_isscalar(GEN x)804 ZV_isscalar(GEN x)
805 {
806   long l = lg(x);
807   while (--l > 1)
808     if (signe(gel(x, l))) return 0;
809   return 1;
810 }
811 INLINE int
QV_isscalar(GEN x)812 QV_isscalar(GEN x)
813 {
814   long lx = lg(x),i;
815   for (i=2; i<lx; i++)
816     if (!isintzero(gel(x, i))) return 0;
817   return 1;
818 }
819 INLINE int
RgV_isscalar(GEN x)820 RgV_isscalar(GEN x)
821 {
822   long lx = lg(x),i;
823   for (i=2; i<lx; i++)
824     if (!gequal0(gel(x, i))) return 0;
825   return 1;
826 }
827 INLINE int
RgX_isscalar(GEN x)828 RgX_isscalar(GEN x)
829 {
830   long i;
831   for (i=lg(x)-1; i>2; i--)
832     if (!gequal0(gel(x, i))) return 0;
833   return 1;
834 }
835 INLINE long
RgX_equal_var(GEN x,GEN y)836 RgX_equal_var(GEN x, GEN y) { return varn(x) == varn(y) && RgX_equal(x,y); }
837 
838 INLINE int
RgX_is_rational(GEN x)839 RgX_is_rational(GEN x)
840 {
841   long i;
842   for (i = lg(x)-1; i > 1; i--)
843     if (!is_rational_t(typ(gel(x,i)))) return 0;
844   return 1;
845 }
846 INLINE int
RgX_is_ZX(GEN x)847 RgX_is_ZX(GEN x)
848 {
849   long i;
850   for (i = lg(x)-1; i > 1; i--)
851     if (typ(gel(x,i)) != t_INT) return 0;
852   return 1;
853 }
854 INLINE int
RgX_is_QX(GEN x)855 RgX_is_QX(GEN x)
856 {
857   long k = lg(x)-1;
858   for ( ; k>1; k--)
859     if (!is_rational_t(typ(gel(x,k)))) return 0;
860   return 1;
861 }
862 INLINE int
RgX_is_monomial(GEN x)863 RgX_is_monomial(GEN x)
864 {
865   long i;
866   if (!signe(x)) return 0;
867   for (i=lg(x)-2; i>1; i--)
868     if (!isexactzero(gel(x,i))) return 0;
869   return 1;
870 }
871 INLINE int
RgV_is_ZV(GEN x)872 RgV_is_ZV(GEN x)
873 {
874   long i;
875   for (i = lg(x)-1; i > 0; i--)
876     if (typ(gel(x,i)) != t_INT) return 0;
877   return 1;
878 }
879 INLINE int
RgV_is_QV(GEN x)880 RgV_is_QV(GEN x)
881 {
882   long i;
883   for (i = lg(x)-1; i > 0; i--)
884     if (!is_rational_t(typ(gel(x,i)))) return 0;
885   return 1;
886 }
887 INLINE long
RgV_isin_i(GEN v,GEN x,long n)888 RgV_isin_i(GEN v, GEN x, long n)
889 {
890   long i;
891   for (i = 1; i <= n; i++)
892     if (gequal(gel(v,i), x)) return i;
893   return 0;
894 }
895 INLINE long
RgV_isin(GEN v,GEN x)896 RgV_isin(GEN v, GEN x) { return RgV_isin_i(v, x, lg(v)-1); }
897 
898 /********************************************************************/
899 /**                                                                **/
900 /**            Dynamic arrays implementation                       **/
901 /**                                                                **/
902 /********************************************************************/
903 INLINE void **
pari_stack_base(pari_stack * s)904 pari_stack_base(pari_stack *s) { return s->data; }
905 
906 INLINE void
pari_stack_init(pari_stack * s,size_t size,void ** data)907 pari_stack_init(pari_stack *s, size_t size, void **data)
908 {
909   s->data = data;
910   *data = NULL;
911   s->n = 0;
912   s->alloc = 0;
913   s->size = size;
914 }
915 
916 INLINE void
pari_stack_alloc(pari_stack * s,long nb)917 pari_stack_alloc(pari_stack *s, long nb)
918 {
919   void **sdat = pari_stack_base(s);
920   long alloc = s->alloc;
921   if (s->n+nb <= alloc) return;
922   if (!alloc)
923     alloc = nb;
924   else
925   {
926     while (s->n+nb > alloc) alloc <<= 1;
927   }
928   pari_realloc_ip(sdat,alloc*s->size);
929   s->alloc = alloc;
930 }
931 
932 INLINE long
pari_stack_new(pari_stack * s)933 pari_stack_new(pari_stack *s) { pari_stack_alloc(s, 1); return s->n++; }
934 
935 INLINE void
pari_stack_delete(pari_stack * s)936 pari_stack_delete(pari_stack *s)
937 {
938   void **sdat = pari_stack_base(s);
939   if (*sdat) pari_free(*sdat);
940 }
941 
942 INLINE void
pari_stack_pushp(pari_stack * s,void * u)943 pari_stack_pushp(pari_stack *s, void *u)
944 {
945   long n = pari_stack_new(s);
946   void **sdat =(void**) *pari_stack_base(s);
947   sdat[n] = u;
948 }
949 
950 /*******************************************************************/
951 /*                                                                 */
952 /*                            EXTRACT                              */
953 /*                                                                 */
954 /*******************************************************************/
955 INLINE GEN
vecslice(GEN A,long y1,long y2)956 vecslice(GEN A, long y1, long y2)
957 {
958   long i,lB = y2 - y1 + 2;
959   GEN B = cgetg(lB, typ(A));
960   for (i=1; i<lB; i++) B[i] = A[y1-1+i];
961   return B;
962 }
963 INLINE GEN
vecslicepermute(GEN A,GEN p,long y1,long y2)964 vecslicepermute(GEN A, GEN p, long y1, long y2)
965 {
966   long i,lB = y2 - y1 + 2;
967   GEN B = cgetg(lB, typ(A));
968   for (i=1; i<lB; i++) B[i] = A[p[y1-1+i]];
969   return B;
970 }
971 /* rowslice(rowpermute(A,p), x1, x2) */
972 INLINE GEN
rowslicepermute(GEN x,GEN p,long j1,long j2)973 rowslicepermute(GEN x, GEN p, long j1, long j2)
974 { pari_APPLY_same(vecslicepermute(gel(x,i),p,j1,j2)) }
975 
976 INLINE GEN
rowslice(GEN x,long j1,long j2)977 rowslice(GEN x, long j1, long j2)
978 { pari_APPLY_same(vecslice(gel(x,i), j1, j2)) }
979 
980 INLINE GEN
matslice(GEN A,long x1,long x2,long y1,long y2)981 matslice(GEN A, long x1, long x2, long y1, long y2)
982 { return rowslice(vecslice(A, y1, y2), x1, x2); }
983 
984 /* shallow, remove coeff of index j */
985 INLINE GEN
rowsplice(GEN x,long j)986 rowsplice(GEN x, long j)
987 { pari_APPLY_same(vecsplice(gel(x,i), j)) }
988 
989 /* shallow, remove coeff of index j */
990 INLINE GEN
vecsplice(GEN a,long j)991 vecsplice(GEN a, long j)
992 {
993   long i, k, l = lg(a);
994   GEN b;
995   if (l == 1) pari_err(e_MISC, "incorrect component in vecsplice");
996   b = cgetg(l-1, typ(a));
997   for (i = k = 1; i < l; i++)
998     if (i != j) gel(b, k++) = gel(a,i);
999   return b;
1000 }
1001 /* shallow */
1002 INLINE GEN
RgM_minor(GEN a,long i,long j)1003 RgM_minor(GEN a, long i, long j)
1004 {
1005   GEN b = vecsplice(a, j);
1006   long k, l = lg(b);
1007   for (k = 1; k < l; k++) gel(b,k) = vecsplice(gel(b,k), i);
1008   return b;
1009 }
1010 
1011 /* A[x0,] */
1012 INLINE GEN
row(GEN x,long j)1013 row(GEN x, long j)
1014 { pari_APPLY_type(t_VEC, gcoeff(x, j, i)) }
1015 INLINE GEN
Flm_row(GEN x,long j)1016 Flm_row(GEN x, long j)
1017 { pari_APPLY_ulong((ulong)coeff(x, j, i)) }
1018 /* A[x0,] */
1019 INLINE GEN
rowcopy(GEN x,long j)1020 rowcopy(GEN x, long j)
1021 { pari_APPLY_type(t_VEC, gcopy(gcoeff(x, j, i))) }
1022 /* A[x0, x1..x2] */
1023 INLINE GEN
row_i(GEN A,long x0,long x1,long x2)1024 row_i(GEN A, long x0, long x1, long x2)
1025 {
1026   long i, lB = x2 - x1 + 2;
1027   GEN B  = cgetg(lB, t_VEC);
1028   for (i=x1; i<=x2; i++) gel(B, i) = gcoeff(A, x0, i);
1029   return B;
1030 }
1031 
1032 INLINE GEN
vecreverse(GEN A)1033 vecreverse(GEN A)
1034 {
1035   long i, l;
1036   GEN B = cgetg_copy(A, &l);
1037   for (i=1; i<l; i++) gel(B, i) = gel(A, l-i);
1038   return B;
1039 }
1040 
1041 INLINE GEN
vecsmall_reverse(GEN A)1042 vecsmall_reverse(GEN A)
1043 {
1044   long i, l;
1045   GEN B = cgetg_copy(A, &l);
1046   for (i=1; i<l; i++) B[i] = A[l-i];
1047   return B;
1048 }
1049 
1050 INLINE void
vecreverse_inplace(GEN y)1051 vecreverse_inplace(GEN y)
1052 {
1053   long l = lg(y), lim = l>>1, i;
1054   for (i = 1; i <= lim; i++)
1055   {
1056     GEN z = gel(y,i);
1057     gel(y,i)    = gel(y,l-i);
1058     gel(y,l-i) = z;
1059   }
1060 }
1061 
1062 INLINE GEN
vecsmallpermute(GEN A,GEN p)1063 vecsmallpermute(GEN A, GEN p) { return perm_mul(A, p); }
1064 
1065 INLINE GEN
vecpermute(GEN A,GEN x)1066 vecpermute(GEN A, GEN x)
1067 { pari_APPLY_type(typ(A), gel(A, x[i])) }
1068 
1069 INLINE GEN
rowpermute(GEN x,GEN p)1070 rowpermute(GEN x, GEN p)
1071 { pari_APPLY_same(typ(gel(x,i)) == t_VECSMALL ? vecsmallpermute(gel(x, i), p)
1072                                               : vecpermute(gel(x, i), p))
1073 }
1074 /*******************************************************************/
1075 /*                                                                 */
1076 /*                          PERMUTATIONS                           */
1077 /*                                                                 */
1078 /*******************************************************************/
1079 INLINE GEN
identity_zv(long n)1080 identity_zv(long n)
1081 {
1082   GEN v = cgetg(n+1, t_VECSMALL);
1083   long i;
1084   for (i = 1; i <= n; i++) v[i] = i;
1085   return v;
1086 }
1087 INLINE GEN
identity_ZV(long n)1088 identity_ZV(long n)
1089 {
1090   GEN v = cgetg(n+1, t_VEC);
1091   long i;
1092   for (i = 1; i <= n; i++) gel(v,i) = utoipos(i);
1093   return v;
1094 }
1095 /* identity permutation */
1096 INLINE GEN
identity_perm(long n)1097 identity_perm(long n) { return identity_zv(n); }
1098 
1099 /* assume d <= n */
1100 INLINE GEN
cyclic_perm(long n,long d)1101 cyclic_perm(long n, long d)
1102 {
1103   GEN perm = cgetg(n+1, t_VECSMALL);
1104   long i;
1105   for (i = 1; i <= n-d; i++) perm[i] = i+d;
1106   for (     ; i <= n;   i++) perm[i] = i-n+d;
1107   return perm;
1108 }
1109 
1110 /* Multiply (compose) two permutations */
1111 INLINE GEN
perm_mul(GEN s,GEN x)1112 perm_mul(GEN s, GEN x)
1113 { pari_APPLY_long(s[x[i]]) }
1114 
1115 INLINE GEN
perm_sqr(GEN x)1116 perm_sqr(GEN x)
1117 { pari_APPLY_long(x[x[i]]) }
1118 
1119 /* Compute the inverse (reciprocal) of a permutation. */
1120 INLINE GEN
perm_inv(GEN x)1121 perm_inv(GEN x)
1122 {
1123   long i, lx;
1124   GEN y = cgetg_copy(x, &lx);
1125   for (i=1; i<lx; i++) y[ x[i] ] = i;
1126   return y;
1127 }
1128 /* Return s*t*s^-1 */
1129 INLINE GEN
perm_conj(GEN s,GEN t)1130 perm_conj(GEN s, GEN t)
1131 {
1132   long i, l;
1133   GEN v = cgetg_copy(s, &l);
1134   for (i = 1; i < l; i++) v[ s[i] ] = s[ t[i] ];
1135   return v;
1136 }
1137 
1138 INLINE void
pari_free(void * pointer)1139 pari_free(void *pointer)
1140 {
1141   BLOCK_SIGINT_START;
1142   free(pointer);
1143   BLOCK_SIGINT_END;
1144 }
1145 INLINE void*
pari_malloc(size_t size)1146 pari_malloc(size_t size)
1147 {
1148   if (size)
1149   {
1150     char *tmp;
1151     BLOCK_SIGINT_START;
1152     tmp = (char*)malloc(size);
1153     BLOCK_SIGINT_END;
1154     if (!tmp) pari_err(e_MEM);
1155     return tmp;
1156   }
1157   return NULL;
1158 }
1159 INLINE void*
pari_realloc(void * pointer,size_t size)1160 pari_realloc(void *pointer, size_t size)
1161 {
1162   char *tmp;
1163 
1164   BLOCK_SIGINT_START;
1165   if (!pointer) tmp = (char *) malloc(size);
1166   else tmp = (char *) realloc(pointer,size);
1167   BLOCK_SIGINT_END;
1168   if (!tmp) pari_err(e_MEM);
1169   return tmp;
1170 }
1171 INLINE void
pari_realloc_ip(void ** pointer,size_t size)1172 pari_realloc_ip(void **pointer, size_t size)
1173 {
1174   char *tmp;
1175   BLOCK_SIGINT_START;
1176   if (!*pointer) tmp = (char *) malloc(size);
1177   else tmp = (char *) realloc(*pointer,size);
1178   if (!tmp) pari_err(e_MEM);
1179   *pointer = tmp;
1180   BLOCK_SIGINT_END;
1181 }
1182 
1183 INLINE void*
pari_calloc(size_t size)1184 pari_calloc(size_t size)
1185 {
1186   void *t = pari_malloc(size);
1187   memset(t, 0, size); return t;
1188 }
1189 INLINE GEN
cgetalloc(long t,size_t l)1190 cgetalloc(long t, size_t l)
1191 { /* evallg may raise e_OVERFLOW, which would leak x */
1192   ulong x0 = evaltyp(t) | evallg(l);
1193   GEN x = (GEN)pari_malloc(l * sizeof(long));
1194   x[0] = x0; return x;
1195 }
1196 
1197 /*******************************************************************/
1198 /*                                                                 */
1199 /*                       GARBAGE COLLECTION                        */
1200 /*                                                                 */
1201 /*******************************************************************/
1202 /* copy integer x as if we had set_avma(av) */
1203 INLINE GEN
icopy_avma(GEN x,pari_sp av)1204 icopy_avma(GEN x, pari_sp av)
1205 {
1206   long i = lgefint(x), lx = i;
1207   GEN y = ((GEN)av) - i;
1208   while (--i > 0) y[i] = x[i];
1209   y[0] = evaltyp(t_INT)|evallg(lx);
1210   return y;
1211 }
1212 /* copy leaf x as if we had set_avma(av) */
1213 INLINE GEN
leafcopy_avma(GEN x,pari_sp av)1214 leafcopy_avma(GEN x, pari_sp av)
1215 {
1216   long i = lg(x);
1217   GEN y = ((GEN)av) - i;
1218   while (--i > 0) y[i] = x[i];
1219   y[0] = x[0] & (~CLONEBIT);
1220   return y;
1221 }
1222 INLINE GEN
gerepileuptoleaf(pari_sp av,GEN x)1223 gerepileuptoleaf(pari_sp av, GEN x)
1224 {
1225   long lx;
1226   GEN q;
1227 
1228   if (!isonstack(x) || (GEN)av<=x) return gc_const(av,x);
1229   lx = lg(x);
1230   q = ((GEN)av) - lx;
1231   set_avma((pari_sp)q);
1232   while (--lx >= 0) q[lx] = x[lx];
1233   return q;
1234 }
1235 INLINE GEN
gerepileuptoint(pari_sp av,GEN x)1236 gerepileuptoint(pari_sp av, GEN x)
1237 {
1238   if (!isonstack(x) || (GEN)av<=x) return gc_const(av,x);
1239   set_avma((pari_sp)icopy_avma(x, av));
1240   return (GEN)avma;
1241 }
1242 INLINE GEN
gerepileupto(pari_sp av,GEN x)1243 gerepileupto(pari_sp av, GEN x)
1244 {
1245   if (!isonstack(x) || (GEN)av<=x) return gc_const(av,x);
1246   switch(typ(x))
1247   { /* non-default = !is_recursive_t(tq) */
1248     case t_INT: return gerepileuptoint(av, x);
1249     case t_REAL:
1250     case t_STR:
1251     case t_VECSMALL: return gerepileuptoleaf(av,x);
1252     default:
1253       /* NB: x+i --> ((long)x) + i*sizeof(long) */
1254       return gerepile(av, (pari_sp) (x+lg(x)), x);
1255   }
1256 }
1257 
1258 /* gerepileupto(av, gcopy(x)) */
1259 INLINE GEN
gerepilecopy(pari_sp av,GEN x)1260 gerepilecopy(pari_sp av, GEN x)
1261 {
1262   if (is_recursive_t(typ(x)))
1263   {
1264     GENbin *p = copy_bin(x);
1265     set_avma(av); return bin_copy(p);
1266   }
1267   else
1268   {
1269     set_avma(av);
1270     if (x < (GEN)av) {
1271       if (x < (GEN)pari_mainstack->bot) new_chunk(lg(x));
1272       x = leafcopy_avma(x, av);
1273       set_avma((pari_sp)x);
1274     } else
1275       x = leafcopy(x);
1276     return x;
1277   }
1278 }
1279 
1280 INLINE void
guncloneNULL(GEN x)1281 guncloneNULL(GEN x) { if (x) gunclone(x); }
1282 INLINE void
guncloneNULL_deep(GEN x)1283 guncloneNULL_deep(GEN x) { if (x) gunclone_deep(x); }
1284 
1285 /* Takes an array of pointers to GENs, of length n. Copies all
1286  * objects to contiguous locations and cleans up the stack between
1287  * av and avma. */
1288 INLINE void
gerepilemany(pari_sp av,GEN * gptr[],int n)1289 gerepilemany(pari_sp av, GEN* gptr[], int n)
1290 {
1291   int i;
1292   for (i=0; i<n; i++) *gptr[i] = (GEN)copy_bin(*gptr[i]);
1293   set_avma(av);
1294   for (i=0; i<n; i++) *gptr[i] = bin_copy((GENbin*)*gptr[i]);
1295 }
1296 
1297 INLINE void
gerepileall(pari_sp av,int n,...)1298 gerepileall(pari_sp av, int n, ...)
1299 {
1300   int i;
1301   va_list a; va_start(a, n);
1302   if (n < 10)
1303   {
1304     GEN *gptr[10];
1305     for (i=0; i<n; i++)
1306     { gptr[i] = va_arg(a,GEN*); *gptr[i] = (GEN)copy_bin(*gptr[i]); }
1307     set_avma(av);
1308     for (--i; i>=0; i--) *gptr[i] = bin_copy((GENbin*)*gptr[i]);
1309 
1310   }
1311   else
1312   {
1313     GEN **gptr = (GEN**)  pari_malloc(n*sizeof(GEN*));
1314     for (i=0; i<n; i++)
1315     { gptr[i] = va_arg(a,GEN*); *gptr[i] = (GEN)copy_bin(*gptr[i]); }
1316     set_avma(av);
1317     for (--i; i>=0; i--) *gptr[i] = bin_copy((GENbin*)*gptr[i]);
1318     pari_free(gptr);
1319   }
1320   va_end(a);
1321 }
1322 
1323 INLINE void
gerepilecoeffs(pari_sp av,GEN x,int n)1324 gerepilecoeffs(pari_sp av, GEN x, int n)
1325 {
1326   int i;
1327   for (i=0; i<n; i++) gel(x,i) = (GEN)copy_bin(gel(x,i));
1328   set_avma(av);
1329   for (i=0; i<n; i++) gel(x,i) = bin_copy((GENbin*)x[i]);
1330 }
1331 
1332 /* p from copy_bin. Copy p->x back to stack, then destroy p */
1333 INLINE GEN
bin_copy(GENbin * p)1334 bin_copy(GENbin *p)
1335 {
1336   GEN x, y, base;
1337   long dx, len;
1338 
1339   x   = p->x; if (!x) { pari_free(p); return gen_0; }
1340   len = p->len;
1341   base= p->base; dx = x - base;
1342   y = (GEN)memcpy((void*)new_chunk(len), (void*)GENbinbase(p), len*sizeof(long));
1343   y += dx;
1344   p->rebase(y, ((ulong)y-(ulong)x));
1345   pari_free(p); return y;
1346 }
1347 
1348 INLINE GEN
GENbinbase(GENbin * p)1349 GENbinbase(GENbin *p) { return (GEN)(p + 1); }
1350 
1351 INLINE void
cgiv(GEN x)1352 cgiv(GEN x)
1353 {
1354   pari_sp av = (pari_sp)(x+lg(x));
1355   if (isonstack((GEN)av)) set_avma(av);
1356 }
1357 
1358 INLINE void
killblock(GEN x)1359 killblock(GEN x) { gunclone(x); }
1360 
1361 INLINE int
is_universal_constant(GEN x)1362 is_universal_constant(GEN x) { return (x >= gen_0 && x <= ghalf); }
1363 
1364 /*******************************************************************/
1365 /*                                                                 */
1366 /*                    CONVERSION / ASSIGNMENT                      */
1367 /*                                                                 */
1368 /*******************************************************************/
1369 /* z is a type which may be a t_COMPLEX component (not a t_QUAD) */
1370 INLINE GEN
cxcompotor(GEN z,long prec)1371 cxcompotor(GEN z, long prec)
1372 {
1373   switch(typ(z))
1374   {
1375     case t_INT:  return itor(z, prec);
1376     case t_FRAC: return fractor(z, prec);
1377     case t_REAL: return rtor(z, prec);
1378     default: pari_err_TYPE("cxcompotor",z);
1379              return NULL; /* LCOV_EXCL_LINE */
1380   }
1381 }
1382 INLINE GEN
cxtofp(GEN x,long prec)1383 cxtofp(GEN x, long prec)
1384 { retmkcomplex(cxcompotor(gel(x,1),prec), cxcompotor(gel(x,2),prec)); }
1385 
1386 INLINE GEN
cxtoreal(GEN q)1387 cxtoreal(GEN q)
1388 { return (typ(q) == t_COMPLEX && gequal0(gel(q,2)))? gel(q,1): q; }
1389 
1390 INLINE double
gtodouble(GEN x)1391 gtodouble(GEN x)
1392 {
1393   if (typ(x)!=t_REAL) {
1394     pari_sp av = avma;
1395     x = gtofp(x, DEFAULTPREC);
1396     if (typ(x)!=t_REAL) pari_err_TYPE("gtodouble [t_REAL expected]", x);
1397     set_avma(av);
1398   }
1399   return rtodbl(x);
1400 }
1401 
1402 INLINE int
gisdouble(GEN x,double * g)1403 gisdouble(GEN x, double *g)
1404 {
1405   if (typ(x)!=t_REAL) {
1406     pari_sp av = avma;
1407     x = gtofp(x, DEFAULTPREC);
1408     if (typ(x)!=t_REAL) pari_err_TYPE("gisdouble [t_REAL expected]", x);
1409     set_avma(av);
1410   }
1411   if (expo(x) >= 0x3ff) return 0;
1412   *g = rtodbl(x); return 1;
1413 }
1414 
1415 INLINE long
gtos(GEN x)1416 gtos(GEN x) {
1417   if (typ(x) != t_INT) pari_err_TYPE("gtos [integer expected]",x);
1418   return itos(x);
1419 }
1420 
1421 INLINE ulong
gtou(GEN x)1422 gtou(GEN x) {
1423   if (typ(x) != t_INT || signe(x)<0)
1424     pari_err_TYPE("gtou [integer >=0 expected]",x);
1425   return itou(x);
1426 }
1427 
1428 INLINE GEN
absfrac(GEN x)1429 absfrac(GEN x)
1430 {
1431   GEN y = cgetg(3, t_FRAC);
1432   gel(y,1) = absi(gel(x,1));
1433   gel(y,2) = icopy(gel(x,2)); return y;
1434 }
1435 INLINE GEN
absfrac_shallow(GEN x)1436 absfrac_shallow(GEN x)
1437 { return signe(gel(x,1))>0? x: mkfrac(negi(gel(x,1)), gel(x,2)); }
1438 INLINE GEN
Q_abs(GEN x)1439 Q_abs(GEN x) { return (typ(x) == t_INT)? absi(x): absfrac(x); }
1440 INLINE GEN
Q_abs_shallow(GEN x)1441 Q_abs_shallow(GEN x)
1442 { return (typ(x) == t_INT)? absi_shallow(x): absfrac_shallow(x); }
1443 INLINE GEN
R_abs_shallow(GEN x)1444 R_abs_shallow(GEN x)
1445 { return (typ(x) == t_FRAC)? absfrac_shallow(x): mpabs_shallow(x); }
1446 INLINE GEN
R_abs(GEN x)1447 R_abs(GEN x)
1448 { return (typ(x) == t_FRAC)? absfrac(x): mpabs(x); }
1449 
1450 /* Force z to be of type real/complex with floating point components */
1451 INLINE GEN
gtofp(GEN z,long prec)1452 gtofp(GEN z, long prec)
1453 {
1454   switch(typ(z))
1455   {
1456     case t_INT:  return itor(z, prec);
1457     case t_FRAC: return fractor(z, prec);
1458     case t_REAL: return rtor(z, prec);
1459     case t_COMPLEX: {
1460       GEN a = gel(z,1), b = gel(z,2);
1461       if (isintzero(b)) return cxcompotor(a, prec);
1462       if (isintzero(a)) {
1463         GEN y = cgetg(3, t_COMPLEX);
1464         b = cxcompotor(b, prec);
1465         gel(y,1) = real_0_bit(expo(b) - prec2nbits(prec));
1466         gel(y,2) = b; return y;
1467       }
1468       return cxtofp(z, prec);
1469     }
1470     case t_QUAD: return quadtofp(z, prec);
1471     default: pari_err_TYPE("gtofp",z);
1472              return NULL; /* LCOV_EXCL_LINE */
1473   }
1474 }
1475 /* Force z to be of type real / int */
1476 INLINE GEN
gtomp(GEN z,long prec)1477 gtomp(GEN z, long prec)
1478 {
1479   switch(typ(z))
1480   {
1481     case t_INT:  return z;
1482     case t_FRAC: return fractor(z, prec);
1483     case t_REAL: return rtor(z, prec);
1484     case t_QUAD: z = quadtofp(z, prec);
1485                  if (typ(z) == t_REAL) return z;
1486     default: pari_err_TYPE("gtomp",z);
1487              return NULL; /* LCOV_EXCL_LINE */
1488   }
1489 }
1490 
1491 INLINE GEN
RgX_gtofp(GEN x,long prec)1492 RgX_gtofp(GEN x, long prec)
1493 {
1494   long l;
1495   GEN y = cgetg_copy(x, &l);
1496   while (--l > 1) gel(y,l) = gtofp(gel(x,l), prec);
1497   y[1] = x[1]; return y;
1498 }
1499 INLINE GEN
RgC_gtofp(GEN x,long prec)1500 RgC_gtofp(GEN x, long prec)
1501 { pari_APPLY_type(t_COL, gtofp(gel(x,i), prec)) }
1502 
1503 INLINE GEN
RgV_gtofp(GEN x,long prec)1504 RgV_gtofp(GEN x, long prec)
1505 { pari_APPLY_type(t_VEC, gtofp(gel(x,i), prec)) }
1506 
1507 INLINE GEN
RgM_gtofp(GEN x,long prec)1508 RgM_gtofp(GEN x, long prec)
1509 { pari_APPLY_same(RgC_gtofp(gel(x,i), prec)) }
1510 
1511 INLINE GEN
RgC_gtomp(GEN x,long prec)1512 RgC_gtomp(GEN x, long prec)
1513 { pari_APPLY_type(t_COL, gtomp(gel(x,i), prec)) }
1514 
1515 INLINE GEN
RgM_gtomp(GEN x,long prec)1516 RgM_gtomp(GEN x, long prec)
1517 { pari_APPLY_same(RgC_gtomp(gel(x,i), prec)) }
1518 
1519 INLINE GEN
RgX_fpnorml2(GEN x,long prec)1520 RgX_fpnorml2(GEN x, long prec)
1521 {
1522   pari_sp av = avma;
1523   return gerepileupto(av, gnorml2(RgX_gtofp(x, prec)));
1524 }
1525 INLINE GEN
RgC_fpnorml2(GEN x,long prec)1526 RgC_fpnorml2(GEN x, long prec)
1527 {
1528   pari_sp av = avma;
1529   return gerepileupto(av, gnorml2(RgC_gtofp(x, prec)));
1530 }
1531 INLINE GEN
RgM_fpnorml2(GEN x,long prec)1532 RgM_fpnorml2(GEN x, long prec)
1533 {
1534   pari_sp av = avma;
1535   return gerepileupto(av, gnorml2(RgM_gtofp(x, prec)));
1536 }
1537 
1538 /* y a t_REAL */
1539 INLINE void
affgr(GEN x,GEN y)1540 affgr(GEN x, GEN y)
1541 {
1542   pari_sp av;
1543   switch(typ(x)) {
1544     case t_INT:  affir(x,y); break;
1545     case t_REAL: affrr(x,y); break;
1546     case t_FRAC: rdiviiz(gel(x,1),gel(x,2), y); break;
1547     case t_QUAD: av = avma; affgr(quadtofp(x,realprec(y)), y); set_avma(av); break;
1548     default: pari_err_TYPE2("=",x,y);
1549   }
1550 }
1551 
1552 INLINE GEN
affc_fixlg(GEN x,GEN res)1553 affc_fixlg(GEN x, GEN res)
1554 {
1555   if (typ(x) == t_COMPLEX)
1556   {
1557     affrr_fixlg(gel(x,1), gel(res,1));
1558     affrr_fixlg(gel(x,2), gel(res,2));
1559   }
1560   else
1561   {
1562     set_avma((pari_sp)(res+3));
1563     res = cgetr(realprec(gel(res,1)));
1564     affrr_fixlg(x, res);
1565   }
1566   return res;
1567 }
1568 
1569 INLINE GEN
trunc_safe(GEN x)1570 trunc_safe(GEN x) { long e; return gcvtoi(x,&e); }
1571 
1572 /*******************************************************************/
1573 /*                                                                 */
1574 /*                          LENGTH CONVERSIONS                     */
1575 /*                                                                 */
1576 /*******************************************************************/
1577 INLINE long
ndec2nlong(long x)1578 ndec2nlong(long x) { return 1 + (long)((x)*(LOG2_10/BITS_IN_LONG)); }
1579 INLINE long
ndec2prec(long x)1580 ndec2prec(long x) { return 2 + ndec2nlong(x); }
1581 INLINE long
ndec2nbits(long x)1582 ndec2nbits(long x) { return ndec2nlong(x) << TWOPOTBITS_IN_LONG; }
1583 /* Fast implementation of ceil(x / (8*sizeof(long))); typecast to (ulong)
1584  * to avoid overflow. Faster than 1 + ((x-1)>>TWOPOTBITS_IN_LONG)) :
1585  *   addl, shrl instead of subl, sarl, addl */
1586 INLINE long
nbits2nlong(long x)1587 nbits2nlong(long x) {
1588   return (long)(((ulong)x+BITS_IN_LONG-1) >> TWOPOTBITS_IN_LONG);
1589 }
1590 
1591 INLINE long
nbits2extraprec(long x)1592 nbits2extraprec(long x) {
1593   return (long)(((ulong)x+BITS_IN_LONG-1) >> TWOPOTBITS_IN_LONG);
1594 }
1595 
1596 /* Fast implementation of 2 + nbits2nlong(x) */
1597 INLINE long
nbits2prec(long x)1598 nbits2prec(long x) {
1599   return (long)(((ulong)x+3*BITS_IN_LONG-1) >> TWOPOTBITS_IN_LONG);
1600 }
1601 INLINE long
nbits2lg(long x)1602 nbits2lg(long x) {
1603   return (long)(((ulong)x+3*BITS_IN_LONG-1) >> TWOPOTBITS_IN_LONG);
1604 }
1605 /* ceil(x / sizeof(long)) */
1606 INLINE long
nchar2nlong(long x)1607 nchar2nlong(long x) {
1608   return (long)(((ulong)x+sizeof(long)-1) >> (TWOPOTBITS_IN_LONG-3L));
1609 }
1610 INLINE long
prec2nbits(long x)1611 prec2nbits(long x) { return (x-2) * BITS_IN_LONG; }
1612 INLINE double
bit_accuracy_mul(long x,double y)1613 bit_accuracy_mul(long x, double y) { return (x-2) * (BITS_IN_LONG*y); }
1614 INLINE double
prec2nbits_mul(long x,double y)1615 prec2nbits_mul(long x, double y) { return (x-2) * (BITS_IN_LONG*y); }
1616 INLINE long
bit_prec(GEN x)1617 bit_prec(GEN x) { return prec2nbits(realprec(x)); }
1618 INLINE long
bit_accuracy(long x)1619 bit_accuracy(long x) { return prec2nbits(x); }
1620 INLINE long
prec2ndec(long x)1621 prec2ndec(long x) { return (long)prec2nbits_mul(x, LOG10_2); }
1622 INLINE long
nbits2ndec(long x)1623 nbits2ndec(long x) { return (long)(x * LOG10_2); }
1624 INLINE long
precdbl(long x)1625 precdbl(long x) {return (x - 1) << 1;}
1626 INLINE long
divsBIL(long n)1627 divsBIL(long n) { return n >> TWOPOTBITS_IN_LONG; }
1628 INLINE long
remsBIL(long n)1629 remsBIL(long n) { return n & (BITS_IN_LONG-1); }
1630 
1631 /*********************************************************************/
1632 /**                                                                 **/
1633 /**                      OPERATIONS MODULO m                        **/
1634 /**                                                                 **/
1635 /*********************************************************************/
1636 /* Assume m > 0, more efficient if 0 <= a, b < m */
1637 
1638 INLINE GEN
Fp_red(GEN a,GEN m)1639 Fp_red(GEN a, GEN m) { return modii(a, m); }
1640 INLINE GEN
Fp_add(GEN a,GEN b,GEN m)1641 Fp_add(GEN a, GEN b, GEN m)
1642 {
1643   pari_sp av=avma;
1644   GEN p = addii(a,b);
1645   long s = signe(p);
1646   if (!s) return p; /* = gen_0 */
1647   if (s > 0) /* general case */
1648   {
1649     GEN t = subii(p, m);
1650     s = signe(t);
1651     if (!s) return gc_const(av, gen_0);
1652     if (s < 0) return gc_const((pari_sp)p, p);
1653     if (cmpii(t, m) < 0) return gerepileuptoint(av, t); /* general case ! */
1654     p = remii(t, m);
1655   }
1656   else
1657     p = modii(p, m);
1658   return gerepileuptoint(av, p);
1659 }
1660 INLINE GEN
Fp_sub(GEN a,GEN b,GEN m)1661 Fp_sub(GEN a, GEN b, GEN m)
1662 {
1663   pari_sp av=avma;
1664   GEN p = subii(a,b);
1665   long s = signe(p);
1666   if (!s) return p; /* = gen_0 */
1667   if (s > 0)
1668   {
1669     if (cmpii(p, m) < 0) return p; /* general case ! */
1670     p = remii(p, m);
1671   }
1672   else
1673   {
1674     GEN t = addii(p, m);
1675     if (!s) return gc_const(av, gen_0);
1676     if (s > 0) return gerepileuptoint(av, t); /* general case ! */
1677     p = modii(t, m);
1678   }
1679   return gerepileuptoint(av, p);
1680 }
1681 INLINE GEN
Fp_neg(GEN b,GEN m)1682 Fp_neg(GEN b, GEN m)
1683 {
1684   pari_sp av = avma;
1685   long s = signe(b);
1686   GEN p;
1687   if (!s) return gen_0;
1688   if (s > 0)
1689   {
1690     p = subii(m, b);
1691     if (signe(p) >= 0) return p; /* general case ! */
1692     p = modii(p, m);
1693   } else
1694     p = remii(negi(b), m);
1695   return gerepileuptoint(av, p);
1696 }
1697 
1698 INLINE GEN
Fp_halve(GEN a,GEN p)1699 Fp_halve(GEN a, GEN p)
1700 {
1701   if (mpodd(a)) a = addii(a,p);
1702   return shifti(a,-1);
1703 }
1704 
1705 /* assume 0 <= u < p and ps2 = p>>1 */
1706 INLINE GEN
Fp_center(GEN u,GEN p,GEN ps2)1707 Fp_center(GEN u, GEN p, GEN ps2)
1708 { return abscmpii(u,ps2)<=0? icopy(u): subii(u,p); }
1709 /* same without copy */
1710 INLINE GEN
Fp_center_i(GEN u,GEN p,GEN ps2)1711 Fp_center_i(GEN u, GEN p, GEN ps2)
1712 { return abscmpii(u,ps2)<=0? u: subii(u,p); }
1713 
1714 /* x + y*z mod p */
1715 INLINE GEN
Fp_addmul(GEN x,GEN y,GEN z,GEN p)1716 Fp_addmul(GEN x, GEN y, GEN z, GEN p)
1717 {
1718   pari_sp av;
1719   if (!signe(y) || !signe(z)) return Fp_red(x, p);
1720   if (!signe(x)) return Fp_mul(z,y, p);
1721   av = avma;
1722   return gerepileuptoint(av, modii(addii(x, mulii(y,z)), p));
1723 }
1724 
1725 INLINE GEN
Fp_mul(GEN a,GEN b,GEN m)1726 Fp_mul(GEN a, GEN b, GEN m)
1727 {
1728   pari_sp av=avma;
1729   GEN p; /*HACK: assume modii use <=lg(p)+(lg(m)<<1) space*/
1730   (void)new_chunk(lg(a)+lg(b)+(lg(m)<<1));
1731   p = mulii(a,b);
1732   set_avma(av); return modii(p,m);
1733 }
1734 INLINE GEN
Fp_sqr(GEN a,GEN m)1735 Fp_sqr(GEN a, GEN m)
1736 {
1737   pari_sp av=avma;
1738   GEN p; /*HACK: assume modii use <=lg(p)+(lg(m)<<1) space*/
1739   (void)new_chunk((lg(a)+lg(m))<<1);
1740   p = sqri(a);
1741   set_avma(av); return remii(p,m); /*Use remii: p >= 0 */
1742 }
1743 INLINE GEN
Fp_mulu(GEN a,ulong b,GEN m)1744 Fp_mulu(GEN a, ulong b, GEN m)
1745 {
1746   long l = lgefint(m);
1747   if (l == 3)
1748   {
1749     ulong mm = m[2];
1750     return utoi( Fl_mul(umodiu(a, mm), b, mm) );
1751   } else {
1752     pari_sp av = avma;
1753     GEN p; /*HACK: assume modii use <=lg(p)+(lg(m)<<1) space*/
1754     (void)new_chunk(lg(a)+1+(l<<1));
1755     p = muliu(a,b);
1756     set_avma(av); return modii(p,m);
1757   }
1758 }
1759 INLINE GEN
Fp_muls(GEN a,long b,GEN m)1760 Fp_muls(GEN a, long b, GEN m)
1761 {
1762   long l = lgefint(m);
1763   if (l == 3)
1764   {
1765     ulong mm = m[2];
1766     if (b < 0)
1767     {
1768       ulong t = Fl_mul(umodiu(a, mm), -b, mm);
1769       return t? utoipos(mm - t): gen_0;
1770     }
1771     else
1772       return utoi( Fl_mul(umodiu(a, mm), b, mm) );
1773   } else {
1774     pari_sp av = avma;
1775     GEN p; /*HACK: assume modii use <=lg(p)+(lg(m)<<1) space*/
1776     (void)new_chunk(lg(a)+1+(l<<1));
1777     p = mulis(a,b);
1778     set_avma(av); return modii(p,m);
1779   }
1780 }
1781 
1782 INLINE GEN
Fp_inv(GEN a,GEN m)1783 Fp_inv(GEN a, GEN m)
1784 {
1785   GEN res;
1786   if (! invmod(a,m,&res)) pari_err_INV("Fp_inv", mkintmod(res,m));
1787   return res;
1788 }
1789 INLINE GEN
Fp_invsafe(GEN a,GEN m)1790 Fp_invsafe(GEN a, GEN m)
1791 {
1792   GEN res;
1793   if (! invmod(a,m,&res)) return NULL;
1794   return res;
1795 }
1796 INLINE GEN
Fp_div(GEN a,GEN b,GEN m)1797 Fp_div(GEN a, GEN b, GEN m)
1798 {
1799   pari_sp av = avma;
1800   GEN p;
1801   if (lgefint(b) == 3)
1802   {
1803     a = Fp_divu(a, b[2], m);
1804     if (signe(b) < 0) a = Fp_neg(a, m);
1805     return a;
1806   }
1807   /*HACK: assume modii use <=lg(p)+(lg(m)<<1) space*/
1808   (void)new_chunk(lg(a)+(lg(m)<<1));
1809   p = mulii(a, Fp_inv(b,m));
1810   set_avma(av); return modii(p,m);
1811 }
1812 INLINE GEN
Fp_divu(GEN x,ulong a,GEN p)1813 Fp_divu(GEN x, ulong a, GEN p)
1814 {
1815   pari_sp av = avma;
1816   ulong b;
1817   if (lgefint(p) == 3)
1818   {
1819     ulong pp = p[2], xp = umodiu(x, pp);
1820     return xp? utoipos(Fl_div(xp, a % pp, pp)): gen_0;
1821   }
1822   x = Fp_red(x, p);
1823   b = Fl_neg(Fl_div(umodiu(x,a), umodiu(p,a), a), a); /* x + pb = 0 (mod a) */
1824   return gerepileuptoint(av, diviuexact(addmuliu(x, p, b), a));
1825 }
1826 
1827 INLINE GEN
Flx_mulu(GEN x,ulong a,ulong p)1828 Flx_mulu(GEN x, ulong a, ulong p) { return Flx_Fl_mul(x,a%p,p); }
1829 
1830 INLINE GEN
get_F2x_mod(GEN T)1831 get_F2x_mod(GEN T) { return typ(T)==t_VEC? gel(T,2): T; }
1832 
1833 INLINE long
get_F2x_var(GEN T)1834 get_F2x_var(GEN T) { return typ(T)==t_VEC? mael(T,2,1): T[1]; }
1835 
1836 INLINE long
get_F2x_degree(GEN T)1837 get_F2x_degree(GEN T) { return typ(T)==t_VEC? F2x_degree(gel(T,2)): F2x_degree(T); }
1838 
1839 INLINE GEN
get_F2xqX_mod(GEN T)1840 get_F2xqX_mod(GEN T) { return typ(T)==t_VEC? gel(T,2): T; }
1841 
1842 INLINE long
get_F2xqX_var(GEN T)1843 get_F2xqX_var(GEN T) { return typ(T)==t_VEC? varn(gel(T,2)): varn(T); }
1844 
1845 INLINE long
get_F2xqX_degree(GEN T)1846 get_F2xqX_degree(GEN T) { return typ(T)==t_VEC? degpol(gel(T,2)): degpol(T); }
1847 
1848 INLINE GEN
get_Flx_mod(GEN T)1849 get_Flx_mod(GEN T) { return typ(T)==t_VEC? gel(T,2): T; }
1850 
1851 INLINE long
get_Flx_var(GEN T)1852 get_Flx_var(GEN T) { return typ(T)==t_VEC? mael(T,2,1): T[1]; }
1853 
1854 INLINE long
get_Flx_degree(GEN T)1855 get_Flx_degree(GEN T) { return typ(T)==t_VEC? degpol(gel(T,2)): degpol(T); }
1856 
1857 INLINE GEN
get_FlxqX_mod(GEN T)1858 get_FlxqX_mod(GEN T) { return typ(T)==t_VEC? gel(T,2): T; }
1859 
1860 INLINE long
get_FlxqX_var(GEN T)1861 get_FlxqX_var(GEN T) { return typ(T)==t_VEC? varn(gel(T,2)): varn(T); }
1862 
1863 INLINE long
get_FlxqX_degree(GEN T)1864 get_FlxqX_degree(GEN T) { return typ(T)==t_VEC? degpol(gel(T,2)): degpol(T); }
1865 
1866 INLINE GEN
get_FpX_mod(GEN T)1867 get_FpX_mod(GEN T) { return typ(T)==t_VEC? gel(T,2): T; }
1868 
1869 INLINE long
get_FpX_var(GEN T)1870 get_FpX_var(GEN T) { return typ(T)==t_VEC? varn(gel(T,2)): varn(T); }
1871 
1872 INLINE long
get_FpX_degree(GEN T)1873 get_FpX_degree(GEN T) { return typ(T)==t_VEC? degpol(gel(T,2)): degpol(T); }
1874 
1875 INLINE GEN
get_FpXQX_mod(GEN T)1876 get_FpXQX_mod(GEN T) { return typ(T)==t_VEC? gel(T,2): T; }
1877 
1878 INLINE long
get_FpXQX_var(GEN T)1879 get_FpXQX_var(GEN T) { return typ(T)==t_VEC? varn(gel(T,2)): varn(T); }
1880 
1881 INLINE long
get_FpXQX_degree(GEN T)1882 get_FpXQX_degree(GEN T) { return typ(T)==t_VEC? degpol(gel(T,2)): degpol(T); }
1883 
1884 /*******************************************************************/
1885 /*                                                                 */
1886 /*                        ADDMULII / SUBMULII                      */
1887 /*                                                                 */
1888 /*******************************************************************/
1889 /* x - y*z */
1890 INLINE GEN
submulii(GEN x,GEN y,GEN z)1891 submulii(GEN x, GEN y, GEN z)
1892 {
1893   long lx = lgefint(x), ly, lz;
1894   pari_sp av;
1895   GEN t;
1896   if (lx == 2) { t = mulii(z,y); togglesign(t); return t; }
1897   ly = lgefint(y);
1898   if (ly == 2) return icopy(x);
1899   lz = lgefint(z);
1900   av = avma; (void)new_chunk(lx+ly+lz); /* HACK */
1901   t = mulii(z, y);
1902   set_avma(av); return subii(x,t);
1903 }
1904 /* y*z - x */
1905 INLINE GEN
mulsubii(GEN y,GEN z,GEN x)1906 mulsubii(GEN y, GEN z, GEN x)
1907 {
1908   long lx = lgefint(x), ly, lz;
1909   pari_sp av;
1910   GEN t;
1911   if (lx == 2) return mulii(z,y);
1912   ly = lgefint(y);
1913   if (ly == 2) return negi(x);
1914   lz = lgefint(z);
1915   av = avma; (void)new_chunk(lx+ly+lz); /* HACK */
1916   t = mulii(z, y);
1917   set_avma(av); return subii(t,x);
1918 }
1919 
1920 /* x - u*y */
1921 INLINE GEN
submuliu(GEN x,GEN y,ulong u)1922 submuliu(GEN x, GEN y, ulong u)
1923 {
1924   pari_sp av;
1925   long ly = lgefint(y);
1926   if (ly == 2) return icopy(x);
1927   av = avma;
1928   (void)new_chunk(3+ly+lgefint(x)); /* HACK */
1929   y = mului(u,y);
1930   set_avma(av); return subii(x, y);
1931 }
1932 /* x + u*y */
1933 INLINE GEN
addmuliu(GEN x,GEN y,ulong u)1934 addmuliu(GEN x, GEN y, ulong u)
1935 {
1936   pari_sp av;
1937   long ly = lgefint(y);
1938   if (ly == 2) return icopy(x);
1939   av = avma;
1940   (void)new_chunk(3+ly+lgefint(x)); /* HACK */
1941   y = mului(u,y);
1942   set_avma(av); return addii(x, y);
1943 }
1944 /* x - u*y */
1945 INLINE GEN
submuliu_inplace(GEN x,GEN y,ulong u)1946 submuliu_inplace(GEN x, GEN y, ulong u)
1947 {
1948   pari_sp av;
1949   long ly = lgefint(y);
1950   if (ly == 2) return x;
1951   av = avma;
1952   (void)new_chunk(3+ly+lgefint(x)); /* HACK */
1953   y = mului(u,y);
1954   set_avma(av); return subii(x, y);
1955 }
1956 /* x + u*y */
1957 INLINE GEN
addmuliu_inplace(GEN x,GEN y,ulong u)1958 addmuliu_inplace(GEN x, GEN y, ulong u)
1959 {
1960   pari_sp av;
1961   long ly = lgefint(y);
1962   if (ly == 2) return x;
1963   av = avma;
1964   (void)new_chunk(3+ly+lgefint(x)); /* HACK */
1965   y = mului(u,y);
1966   set_avma(av); return addii(x, y);
1967 }
1968 /* ux + vy */
1969 INLINE GEN
lincombii(GEN u,GEN v,GEN x,GEN y)1970 lincombii(GEN u, GEN v, GEN x, GEN y)
1971 {
1972   long lx = lgefint(x), ly;
1973   GEN p1, p2;
1974   pari_sp av;
1975   if (lx == 2) return mulii(v,y);
1976   ly = lgefint(y);
1977   if (ly == 2) return mulii(u,x);
1978   av = avma; (void)new_chunk(lx+ly+lgefint(u)+lgefint(v)); /* HACK */
1979   p1 = mulii(u,x);
1980   p2 = mulii(v,y);
1981   set_avma(av); return addii(p1,p2);
1982 }
1983 
1984 /*******************************************************************/
1985 /*                                                                 */
1986 /*                          GEN SUBTYPES                           */
1987 /*                                                                 */
1988 /*******************************************************************/
1989 
1990 INLINE int
is_const_t(long t)1991 is_const_t(long t) { return (t < t_POLMOD); }
1992 INLINE int
is_extscalar_t(long t)1993 is_extscalar_t(long t) { return (t <= t_POL); }
1994 INLINE int
is_intreal_t(long t)1995 is_intreal_t(long t) { return (t <= t_REAL); }
1996 INLINE int
is_matvec_t(long t)1997 is_matvec_t(long t) { return (t >= t_VEC && t <= t_MAT); }
1998 INLINE int
is_noncalc_t(long tx)1999 is_noncalc_t(long tx) { return (tx) >= t_LIST; }
2000 INLINE int
is_rational_t(long t)2001 is_rational_t(long t) { return (t == t_INT || t == t_FRAC); }
2002 INLINE int
is_qfb_t(long t)2003 is_qfb_t(long t) { return (t == t_QFI || t == t_QFR); }
2004 INLINE int
is_real_t(long t)2005 is_real_t(long t) { return (t == t_INT || t == t_REAL || t == t_FRAC); }
2006 INLINE int
is_recursive_t(long t)2007 is_recursive_t(long t) { return lontyp[t]; }
2008 INLINE int
is_scalar_t(long t)2009 is_scalar_t(long t) { return (t < t_POL); }
2010 INLINE int
is_vec_t(long t)2011 is_vec_t(long t) { return (t == t_VEC || t == t_COL); }
2012 
2013 /*******************************************************************/
2014 /*                                                                 */
2015 /*                         TRANSCENDENTAL                          */
2016 /*                                                                 */
2017 /*******************************************************************/
2018 INLINE GEN
sqrtr(GEN x)2019 sqrtr(GEN x) {
2020   long s = signe(x);
2021   if (s == 0) return real_0_bit(expo(x) >> 1);
2022   if (s >= 0) return sqrtr_abs(x);
2023   retmkcomplex(gen_0, sqrtr_abs(x));
2024 }
2025 INLINE GEN
cbrtr_abs(GEN x)2026 cbrtr_abs(GEN x) { return sqrtnr_abs(x, 3); }
2027 INLINE GEN
cbrtr(GEN x)2028 cbrtr(GEN x) {
2029   long s = signe(x);
2030   GEN r;
2031   if (s == 0) return real_0_bit(expo(x) / 3);
2032   r = cbrtr_abs(x);
2033   if (s < 0) togglesign(r);
2034   return r;
2035 }
2036 INLINE GEN
sqrtnr(GEN x,long n)2037 sqrtnr(GEN x, long n) {
2038   long s = signe(x);
2039   GEN r;
2040   if (s == 0) return real_0_bit(expo(x) / n);
2041   r = sqrtnr_abs(x, n);
2042   if (s < 0) pari_err_IMPL("sqrtnr for x < 0");
2043   return r;
2044 }
2045 INLINE long
logint(GEN B,GEN y)2046 logint(GEN B, GEN y) { return logintall(B,y,NULL); }
2047 INLINE ulong
ulogint(ulong B,ulong y)2048 ulogint(ulong B, ulong y)
2049 {
2050   ulong r;
2051   long e;
2052   if (y == 2) return expu(B);
2053   r = y;
2054   for (e=1;; e++)
2055   { /* here, r = y^e, r2 = y^(e-1) */
2056     if (r >= B) return r == B? e: e-1;
2057     r = umuluu_or_0(y, r);
2058     if (!r) return e;
2059   }
2060 }
2061 
2062 /*******************************************************************/
2063 /*                                                                 */
2064 /*                         MISCELLANEOUS                           */
2065 /*                                                                 */
2066 /*******************************************************************/
ismpzero(GEN x)2067 INLINE int ismpzero(GEN x) { return is_intreal_t(typ(x)) && !signe(x); }
isintzero(GEN x)2068 INLINE int isintzero(GEN x) { return typ(x) == t_INT && !signe(x); }
isint1(GEN x)2069 INLINE int isint1(GEN x) { return typ(x)==t_INT && equali1(x); }
isintm1(GEN x)2070 INLINE int isintm1(GEN x){ return typ(x)==t_INT && equalim1(x);}
equali1(GEN n)2071 INLINE int equali1(GEN n)
2072 { return (ulong) n[1] == (evallgefint(3UL) | evalsigne(1)) && n[2] == 1; }
equalim1(GEN n)2073 INLINE int equalim1(GEN n)
2074 { return (ulong) n[1] == (evallgefint(3UL) | evalsigne(-1)) && n[2] == 1; }
2075 /* works only for POSITIVE integers */
is_pm1(GEN n)2076 INLINE int is_pm1(GEN n)
2077 { return lgefint(n) == 3 && n[2] == 1; }
is_bigint(GEN n)2078 INLINE int is_bigint(GEN n)
2079 { long l = lgefint(n); return l > 3 || (l == 3 && (n[2] & HIGHBIT)); }
2080 
odd(long x)2081 INLINE int odd(long x) { return x & 1; }
both_odd(long x,long y)2082 INLINE int both_odd(long x, long y) { return x & y & 1; }
2083 
2084 INLINE int
isonstack(GEN x)2085 isonstack(GEN x)
2086 { return ((pari_sp)x >= pari_mainstack->bot
2087        && (pari_sp)x <  pari_mainstack->top); }
2088 
2089 /* assume x != 0 and x t_REAL, return an approximation to log2(|x|) */
2090 INLINE double
dbllog2r(GEN x)2091 dbllog2r(GEN x)
2092 { return log2((double)(ulong)x[2]) + (double)(expo(x) - (BITS_IN_LONG-1)); }
2093 
2094 INLINE GEN
mul_content(GEN cx,GEN cy)2095 mul_content(GEN cx, GEN cy)
2096 {
2097   if (!cx) return cy;
2098   if (!cy) return cx;
2099   return gmul(cx,cy);
2100 }
2101 INLINE GEN
inv_content(GEN c)2102 inv_content(GEN c) { return c? ginv(c): NULL; }
2103 INLINE GEN
div_content(GEN cx,GEN cy)2104 div_content(GEN cx, GEN cy)
2105 {
2106   if (!cy) return cx;
2107   if (!cx) return ginv(cy);
2108   return gdiv(cx,cy);
2109 }
2110 INLINE GEN
mul_denom(GEN dx,GEN dy)2111 mul_denom(GEN dx, GEN dy)
2112 {
2113   if (!dx) return dy;
2114   if (!dy) return dx;
2115   return mulii(dx,dy);
2116 }
2117 
2118 /* POLYNOMIALS */
2119 INLINE GEN
constant_coeff(GEN x)2120 constant_coeff(GEN x) { return signe(x)? gel(x,2): gen_0; }
2121 INLINE GEN
leading_coeff(GEN x)2122 leading_coeff(GEN x) { return lg(x) == 2? gen_0: gel(x,lg(x)-1); }
2123 INLINE ulong
Flx_lead(GEN x)2124 Flx_lead(GEN x) { return lg(x) == 2? 0: x[lg(x)-1]; }
2125 INLINE ulong
Flx_constant(GEN x)2126 Flx_constant(GEN x) { return lg(x) == 2? 0: x[2]; }
2127 INLINE long
degpol(GEN x)2128 degpol(GEN x) { return lg(x)-3; }
2129 INLINE long
lgpol(GEN x)2130 lgpol(GEN x) { return lg(x)-2; }
2131 INLINE long
lgcols(GEN x)2132 lgcols(GEN x) { return lg(gel(x,1)); }
2133 INLINE long
nbrows(GEN x)2134 nbrows(GEN x) { return lg(gel(x,1))-1; }
2135 INLINE GEN
truecoef(GEN x,long n)2136 truecoef(GEN x, long n) { return polcoef(x,n,-1); }
2137 
2138 INLINE GEN
ZXQ_mul(GEN y,GEN x,GEN T)2139 ZXQ_mul(GEN y, GEN x, GEN T) { return ZX_rem(ZX_mul(y, x), T); }
2140 INLINE GEN
ZXQ_sqr(GEN x,GEN T)2141 ZXQ_sqr(GEN x, GEN T) { return ZX_rem(ZX_sqr(x), T); }
2142 
2143 INLINE GEN
RgX_copy(GEN x)2144 RgX_copy(GEN x)
2145 {
2146   long lx, i;
2147   GEN y = cgetg_copy(x, &lx); y[1] = x[1];
2148   for (i = 2; i<lx; i++) gel(y,i) = gcopy(gel(x,i));
2149   return y;
2150 }
2151 /* have to use ulong to avoid silly warnings from gcc "assuming signed
2152  * overflow does not occur" */
2153 INLINE GEN
RgX_coeff(GEN x,long n)2154 RgX_coeff(GEN x, long n)
2155 {
2156   ulong l = lg(x);
2157   return (n < 0 || ((ulong)n+3) > l)? gen_0: gel(x,n+2);
2158 }
2159 INLINE GEN
RgX_renormalize(GEN x)2160 RgX_renormalize(GEN x) { return RgX_renormalize_lg(x, lg(x)); }
2161 INLINE GEN
RgX_div(GEN x,GEN y)2162 RgX_div(GEN x, GEN y) { return RgX_divrem(x,y,NULL); }
2163 INLINE GEN
RgXQX_div(GEN x,GEN y,GEN T)2164 RgXQX_div(GEN x, GEN y, GEN T) { return RgXQX_divrem(x,y,T,NULL); }
2165 INLINE GEN
RgXQX_rem(GEN x,GEN y,GEN T)2166 RgXQX_rem(GEN x, GEN y, GEN T) { return RgXQX_divrem(x,y,T,ONLY_REM); }
2167 INLINE GEN
FpX_div(GEN x,GEN y,GEN p)2168 FpX_div(GEN x, GEN y, GEN p) { return FpX_divrem(x,y,p, NULL); }
2169 INLINE GEN
Flx_div(GEN x,GEN y,ulong p)2170 Flx_div(GEN x, GEN y, ulong p) { return Flx_divrem(x,y,p, NULL); }
2171 INLINE GEN
F2x_div(GEN x,GEN y)2172 F2x_div(GEN x, GEN y) { return F2x_divrem(x,y, NULL); }
2173 INLINE GEN
FpV_FpC_mul(GEN x,GEN y,GEN p)2174 FpV_FpC_mul(GEN x, GEN y, GEN p) { return FpV_dotproduct(x,y,p); }
2175 INLINE GEN
pol0_Flx(long sv)2176 pol0_Flx(long sv) { return mkvecsmall(sv); }
2177 INLINE GEN
pol1_Flx(long sv)2178 pol1_Flx(long sv) { return mkvecsmall2(sv, 1); }
2179 INLINE GEN
polx_Flx(long sv)2180 polx_Flx(long sv) { return mkvecsmall3(sv, 0, 1); }
2181 INLINE GEN
zero_zx(long sv)2182 zero_zx(long sv) { return zero_Flx(sv); }
2183 INLINE GEN
polx_zx(long sv)2184 polx_zx(long sv) { return polx_Flx(sv); }
2185 INLINE GEN
zx_shift(GEN x,long n)2186 zx_shift(GEN x, long n) { return Flx_shift(x,n); }
2187 INLINE GEN
zx_renormalize(GEN x,long l)2188 zx_renormalize(GEN x, long l) { return Flx_renormalize(x,l); }
2189 INLINE GEN
zero_F2x(long sv)2190 zero_F2x(long sv) { return zero_Flx(sv); }
2191 INLINE GEN
pol0_F2x(long sv)2192 pol0_F2x(long sv) { return pol0_Flx(sv); }
2193 INLINE GEN
pol1_F2x(long sv)2194 pol1_F2x(long sv) { return pol1_Flx(sv); }
2195 INLINE GEN
polx_F2x(long sv)2196 polx_F2x(long sv) { return mkvecsmall2(sv, 2); }
2197 INLINE int
F2x_equal1(GEN x)2198 F2x_equal1(GEN x) { return Flx_equal1(x); }
2199 INLINE int
F2x_equal(GEN V,GEN W)2200 F2x_equal(GEN V, GEN W) { return Flx_equal(V,W); }
2201 INLINE GEN
F2x_copy(GEN x)2202 F2x_copy(GEN x) { return leafcopy(x); }
2203 INLINE GEN
F2v_copy(GEN x)2204 F2v_copy(GEN x) { return leafcopy(x); }
2205 INLINE GEN
Flv_copy(GEN x)2206 Flv_copy(GEN x) { return leafcopy(x); }
2207 INLINE GEN
Flx_copy(GEN x)2208 Flx_copy(GEN x) { return leafcopy(x); }
2209 INLINE GEN
vecsmall_copy(GEN x)2210 vecsmall_copy(GEN x) { return leafcopy(x); }
2211 INLINE int
Flx_equal1(GEN x)2212 Flx_equal1(GEN x) { return degpol(x)==0 && x[2] == 1; }
2213 INLINE int
ZX_equal1(GEN x)2214 ZX_equal1(GEN x) { return degpol(x)==0 && equali1(gel(x,2)); }
2215 INLINE int
ZX_is_monic(GEN x)2216 ZX_is_monic(GEN x) { return equali1(leading_coeff(x)); }
2217 
2218 INLINE GEN
ZX_renormalize(GEN x,long lx)2219 ZX_renormalize(GEN x, long lx)    { return ZXX_renormalize(x,lx); }
2220 INLINE GEN
FpX_renormalize(GEN x,long lx)2221 FpX_renormalize(GEN x, long lx)   { return ZXX_renormalize(x,lx); }
2222 INLINE GEN
FpXX_renormalize(GEN x,long lx)2223 FpXX_renormalize(GEN x, long lx)  { return ZXX_renormalize(x,lx); }
2224 INLINE GEN
FpXQX_renormalize(GEN x,long lx)2225 FpXQX_renormalize(GEN x, long lx) { return ZXX_renormalize(x,lx); }
2226 INLINE GEN
F2x_renormalize(GEN x,long lx)2227 F2x_renormalize(GEN x, long lx)   { return Flx_renormalize(x,lx); }
2228 INLINE GEN
F2v_to_F2x(GEN x,long sv)2229 F2v_to_F2x(GEN x, long sv) {
2230   GEN y = leafcopy(x);
2231   y[1] = sv; F2x_renormalize(y, lg(y)); return y;
2232 }
2233 
2234 INLINE long
sturm(GEN x)2235 sturm(GEN x) { return sturmpart(x, NULL, NULL); }
2236 
2237 INLINE long
gval(GEN x,long v)2238 gval(GEN x, long v)
2239 { pari_sp av = avma; return gc_long(av, gvaluation(x, pol_x(v))); }
2240 
2241 INLINE void
RgX_shift_inplace_init(long v)2242 RgX_shift_inplace_init(long v)
2243 { if (v) (void)cgetg(v, t_VECSMALL); }
2244 /* shift polynomial in place. assume v free cells have been left before x */
2245 INLINE GEN
RgX_shift_inplace(GEN x,long v)2246 RgX_shift_inplace(GEN x, long v)
2247 {
2248   long i, lx;
2249   GEN z;
2250   if (!v) return x;
2251   lx = lg(x);
2252   if (lx == 2) return x;
2253   z = x + lx;
2254   /* stackdummy's from normalizepol */
2255   while (lg(z) != v) z += lg(z);
2256   z += v;
2257   for (i = lx-1; i >= 2; i--) gel(--z,0) = gel(x,i);
2258   for (i = 0;  i < v; i++) gel(--z,0) = gen_0;
2259   z -= 2;
2260   z[1] = x[1];
2261   z[0] = evaltyp(t_POL) | evallg(lx+v);
2262   stackdummy((pari_sp)z, (pari_sp)x); return z;
2263 }
2264 
2265 
2266 /* LINEAR ALGEBRA */
2267 INLINE GEN
zv_to_ZV(GEN x)2268 zv_to_ZV(GEN x) { return vecsmall_to_vec(x); }
2269 INLINE GEN
zc_to_ZC(GEN x)2270 zc_to_ZC(GEN x) { return vecsmall_to_col(x); }
2271 INLINE GEN
ZV_to_zv(GEN x)2272 ZV_to_zv(GEN x) { return vec_to_vecsmall(x); }
2273 INLINE GEN
zx_to_zv(GEN x,long N)2274 zx_to_zv(GEN x, long N) { return Flx_to_Flv(x,N); }
2275 INLINE GEN
zv_to_zx(GEN x,long sv)2276 zv_to_zx(GEN x, long sv) { return Flv_to_Flx(x,sv); }
2277 INLINE GEN
zm_to_zxV(GEN x,long sv)2278 zm_to_zxV(GEN x, long sv) { return Flm_to_FlxV(x,sv); }
2279 INLINE GEN
zero_zm(long x,long y)2280 zero_zm(long x, long y) { return zero_Flm(x,y); }
2281 INLINE GEN
zero_zv(long x)2282 zero_zv(long x) { return zero_Flv(x); }
2283 INLINE GEN
zm_transpose(GEN x)2284 zm_transpose(GEN x) { return Flm_transpose(x); }
2285 INLINE GEN
zm_copy(GEN x)2286 zm_copy(GEN x) { return Flm_copy(x); }
2287 INLINE GEN
zv_copy(GEN x)2288 zv_copy(GEN x) { return Flv_copy(x); }
2289 INLINE GEN
zm_row(GEN x,long i)2290 zm_row(GEN x, long i) { return Flm_row(x,i); }
2291 
2292 INLINE GEN
ZC_hnfrem(GEN x,GEN y)2293 ZC_hnfrem(GEN x, GEN y) { return ZC_hnfremdiv(x,y,NULL); }
2294 INLINE GEN
ZM_hnfrem(GEN x,GEN y)2295 ZM_hnfrem(GEN x, GEN y) { return ZM_hnfdivrem(x,y,NULL); }
2296 INLINE GEN
ZM_lll(GEN x,double D,long f)2297 ZM_lll(GEN x, double D, long f) { return ZM_lll_norms(x,D,f,NULL); }
2298 INLINE void
RgM_dimensions(GEN x,long * m,long * n)2299 RgM_dimensions(GEN x, long *m, long *n) { *n = lg(x)-1; *m = *n? nbrows(x): 0; }
2300 INLINE GEN
RgM_shallowcopy(GEN x)2301 RgM_shallowcopy(GEN x)
2302 {
2303   long l;
2304   GEN y = cgetg_copy(x, &l);
2305   while (--l > 0) gel(y,l) = leafcopy(gel(x,l));
2306   return y;
2307 }
2308 INLINE GEN
F2m_copy(GEN x)2309 F2m_copy(GEN x) { return RgM_shallowcopy(x); }
2310 
2311 INLINE GEN
Flm_copy(GEN x)2312 Flm_copy(GEN x) { return RgM_shallowcopy(x); }
2313 
2314 /* divisibility: return 1 if y[i] | x[i] for all i, 0 otherwise. Assume
2315  * x,y are ZV of the same length */
2316 INLINE int
ZV_dvd(GEN x,GEN y)2317 ZV_dvd(GEN x, GEN y)
2318 {
2319   long i, l = lg(x);
2320   for (i=1; i < l; i++)
2321     if ( ! dvdii( gel(x,i), gel(y,i) ) ) return 0;
2322   return 1;
2323 }
2324 
2325 /* Fq */
2326 INLINE GEN
Fq_red(GEN x,GEN T,GEN p)2327 Fq_red(GEN x, GEN T, GEN p)
2328 { return typ(x)==t_INT? Fp_red(x,p): FpXQ_red(x,T,p); }
2329 INLINE GEN
Fq_to_FpXQ(GEN x,GEN T,GEN p)2330 Fq_to_FpXQ(GEN x, GEN T, GEN p /*unused*/)
2331 {
2332   (void) p;
2333   return typ(x)==t_INT ? scalarpol(x, get_FpX_var(T)): x;
2334 }
2335 INLINE GEN
Rg_to_Fq(GEN x,GEN T,GEN p)2336 Rg_to_Fq(GEN x, GEN T, GEN p) { return T? Rg_to_FpXQ(x,T,p): Rg_to_Fp(x,p); }
2337 
2338 INLINE GEN
gener_Fq_local(GEN T,GEN p,GEN L)2339 gener_Fq_local(GEN T, GEN p, GEN L)
2340 { return T? gener_FpXQ_local(T,p, L)
2341           : pgener_Fp_local(p, L); }
2342 
2343 /* FpXQX */
2344 INLINE GEN
FpXQX_div(GEN x,GEN y,GEN T,GEN p)2345 FpXQX_div(GEN x, GEN y, GEN T, GEN p) { return FpXQX_divrem(x, y, T, p, NULL); }
2346 INLINE GEN
FlxqX_div(GEN x,GEN y,GEN T,ulong p)2347 FlxqX_div(GEN x, GEN y, GEN T, ulong p) { return FlxqX_divrem(x, y, T, p, NULL); }
2348 INLINE GEN
F2xqX_div(GEN x,GEN y,GEN T)2349 F2xqX_div(GEN x, GEN y, GEN T) { return F2xqX_divrem(x, y, T, NULL); }
2350 
2351 INLINE GEN
FpXY_Fq_evaly(GEN Q,GEN y,GEN T,GEN p,long vx)2352 FpXY_Fq_evaly(GEN Q, GEN y, GEN T, GEN p, long vx)
2353 { return T ? FpXY_FpXQ_evaly(Q, y, T, p, vx): FpXY_evaly(Q, y, p, vx); }
2354 
2355 /* FqX */
2356 INLINE GEN
FqX_red(GEN z,GEN T,GEN p)2357 FqX_red(GEN z, GEN T, GEN p) { return T? FpXQX_red(z, T, p): FpX_red(z, p); }
2358 INLINE GEN
FqX_add(GEN x,GEN y,GEN T,GEN p)2359 FqX_add(GEN x,GEN y,GEN T,GEN p) { return T? FpXX_add(x,y,p): FpX_add(x,y,p); }
2360 INLINE GEN
FqX_neg(GEN x,GEN T,GEN p)2361 FqX_neg(GEN x,GEN T,GEN p) { return T? FpXX_neg(x,p): FpX_neg(x,p); }
2362 INLINE GEN
FqX_sub(GEN x,GEN y,GEN T,GEN p)2363 FqX_sub(GEN x,GEN y,GEN T,GEN p) { return T? FpXX_sub(x,y,p): FpX_sub(x,y,p); }
2364 INLINE GEN
FqX_Fp_mul(GEN P,GEN u,GEN T,GEN p)2365 FqX_Fp_mul(GEN P, GEN u, GEN T, GEN p)
2366 { return T? FpXX_Fp_mul(P, u, p): FpX_Fp_mul(P, u, p); }
2367 INLINE GEN
FqX_Fq_mul(GEN P,GEN U,GEN T,GEN p)2368 FqX_Fq_mul(GEN P, GEN U, GEN T, GEN p)
2369 { return typ(U)==t_INT ? FqX_Fp_mul(P, U, T, p): FpXQX_FpXQ_mul(P, U, T, p); }
2370 INLINE GEN
FqX_mul(GEN x,GEN y,GEN T,GEN p)2371 FqX_mul(GEN x, GEN y, GEN T, GEN p)
2372 { return T? FpXQX_mul(x, y, T, p): FpX_mul(x, y, p); }
2373 INLINE GEN
FqX_mulu(GEN x,ulong y,GEN T,GEN p)2374 FqX_mulu(GEN x, ulong y, GEN T, GEN p)
2375 { return T? FpXX_mulu(x, y, p): FpX_mulu(x, y, p); }
2376 INLINE GEN
FqX_sqr(GEN x,GEN T,GEN p)2377 FqX_sqr(GEN x, GEN T, GEN p)
2378 { return T? FpXQX_sqr(x, T, p): FpX_sqr(x, p); }
2379 INLINE GEN
FqX_powu(GEN x,ulong n,GEN T,GEN p)2380 FqX_powu(GEN x, ulong n, GEN T, GEN p)
2381 { return T? FpXQX_powu(x, n, T, p): FpX_powu(x, n, p); }
2382 INLINE GEN
FqX_halve(GEN x,GEN T,GEN p)2383 FqX_halve(GEN x, GEN T, GEN p)
2384 { return T? FpXX_halve(x, p): FpX_halve(x, p); }
2385 INLINE GEN
FqX_div(GEN x,GEN y,GEN T,GEN p)2386 FqX_div(GEN x, GEN y, GEN T, GEN p)
2387 { return T? FpXQX_divrem(x,y,T,p,NULL): FpX_divrem(x,y,p,NULL); }
2388 INLINE GEN
FqX_get_red(GEN S,GEN T,GEN p)2389 FqX_get_red(GEN S, GEN T, GEN p)
2390 { return T? FpXQX_get_red(S,T,p): FpX_get_red(S,p); }
2391 INLINE GEN
FqX_rem(GEN x,GEN y,GEN T,GEN p)2392 FqX_rem(GEN x, GEN y, GEN T, GEN p)
2393 { return T? FpXQX_rem(x,y,T,p): FpX_rem(x,y,p); }
2394 INLINE GEN
FqX_divrem(GEN x,GEN y,GEN T,GEN p,GEN * z)2395 FqX_divrem(GEN x, GEN y, GEN T, GEN p, GEN *z)
2396 { return T? FpXQX_divrem(x,y,T,p,z): FpX_divrem(x,y,p,z); }
2397 INLINE GEN
FqX_div_by_X_x(GEN x,GEN y,GEN T,GEN p,GEN * z)2398 FqX_div_by_X_x(GEN x, GEN y, GEN T, GEN p, GEN *z)
2399 { return T? FpXQX_div_by_X_x(x,y,T,p,z): FpX_div_by_X_x(x,y,p,z); }
2400 INLINE GEN
FqX_halfgcd(GEN P,GEN Q,GEN T,GEN p)2401 FqX_halfgcd(GEN P,GEN Q,GEN T,GEN p)
2402 {return T? FpXQX_halfgcd(P,Q,T,p): FpX_halfgcd(P,Q,p);}
2403 INLINE GEN
FqX_gcd(GEN P,GEN Q,GEN T,GEN p)2404 FqX_gcd(GEN P,GEN Q,GEN T,GEN p)
2405 {return T? FpXQX_gcd(P,Q,T,p): FpX_gcd(P,Q,p);}
2406 INLINE GEN
FqX_extgcd(GEN P,GEN Q,GEN T,GEN p,GEN * U,GEN * V)2407 FqX_extgcd(GEN P,GEN Q,GEN T,GEN p, GEN *U, GEN *V)
2408 { return T? FpXQX_extgcd(P,Q,T,p,U,V): FpX_extgcd(P,Q,p,U,V); }
2409 INLINE GEN
FqX_normalize(GEN z,GEN T,GEN p)2410 FqX_normalize(GEN z, GEN T, GEN p)
2411 { return T? FpXQX_normalize(z, T, p): FpX_normalize(z, p); }
2412 INLINE GEN
FqX_deriv(GEN f,GEN T,GEN p)2413 FqX_deriv(GEN f, GEN T, GEN p) { return T? FpXX_deriv(f, p): FpX_deriv(f, p); }
2414 INLINE GEN
FqX_integ(GEN f,GEN T,GEN p)2415 FqX_integ(GEN f, GEN T, GEN p) { return T? FpXX_integ(f, p): FpX_integ(f, p); }
2416 INLINE GEN
FqX_factor(GEN f,GEN T,GEN p)2417 FqX_factor(GEN f, GEN T, GEN p)
2418 { return T?FpXQX_factor(f, T, p): FpX_factor(f, p); }
2419 INLINE GEN
FqX_factor_squarefree(GEN f,GEN T,GEN p)2420 FqX_factor_squarefree(GEN f, GEN T, GEN p)
2421 { return T ? FpXQX_factor_squarefree(f, T, p): FpX_factor_squarefree(f, p); }
2422 INLINE GEN
FqX_ddf(GEN f,GEN T,GEN p)2423 FqX_ddf(GEN f, GEN T, GEN p)
2424 { return T ? FpXQX_ddf(f, T, p): FpX_ddf(f, p); }
2425 INLINE GEN
FqX_degfact(GEN f,GEN T,GEN p)2426 FqX_degfact(GEN f, GEN T, GEN p)
2427 { return T?FpXQX_degfact(f, T, p): FpX_degfact(f, p); }
2428 INLINE GEN
FqX_roots(GEN f,GEN T,GEN p)2429 FqX_roots(GEN f, GEN T, GEN p)
2430 { return T?FpXQX_roots(f, T, p): FpX_roots(f, p); }
2431 INLINE GEN
FqX_to_mod(GEN f,GEN T,GEN p)2432 FqX_to_mod(GEN f, GEN T, GEN p)
2433 { return T?FpXQX_to_mod(f, T, p): FpX_to_mod(f, p); }
2434 
2435 /*FqXQ*/
2436 INLINE GEN
FqXQ_add(GEN x,GEN y,GEN S,GEN T,GEN p)2437 FqXQ_add(GEN x, GEN y, GEN S/*unused*/, GEN T, GEN p)
2438 { (void)S; return T? FpXX_add(x,y,p): FpX_add(x,y,p); }
2439 INLINE GEN
FqXQ_sub(GEN x,GEN y,GEN S,GEN T,GEN p)2440 FqXQ_sub(GEN x, GEN y, GEN S/*unused*/, GEN T, GEN p)
2441 { (void)S; return T? FpXX_sub(x,y,p): FpX_sub(x,y,p); }
2442 INLINE GEN
FqXQ_div(GEN x,GEN y,GEN S,GEN T,GEN p)2443 FqXQ_div(GEN x, GEN y, GEN S, GEN T, GEN p)
2444 { return T? FpXQXQ_div(x,y,S,T,p): FpXQ_div(x,y,S,p); }
2445 INLINE GEN
FqXQ_inv(GEN x,GEN S,GEN T,GEN p)2446 FqXQ_inv(GEN x, GEN S, GEN T, GEN p)
2447 { return T? FpXQXQ_inv(x,S,T,p): FpXQ_inv(x,S,p); }
2448 INLINE GEN
FqXQ_invsafe(GEN x,GEN S,GEN T,GEN p)2449 FqXQ_invsafe(GEN x, GEN S, GEN T, GEN p)
2450 { return T? FpXQXQ_invsafe(x,S,T,p): FpXQ_inv(x,S,p); }
2451 INLINE GEN
FqXQ_mul(GEN x,GEN y,GEN S,GEN T,GEN p)2452 FqXQ_mul(GEN x, GEN y, GEN S, GEN T, GEN p)
2453 { return T? FpXQXQ_mul(x,y,S,T,p): FpXQ_mul(x,y,S,p); }
2454 INLINE GEN
FqXQ_sqr(GEN x,GEN S,GEN T,GEN p)2455 FqXQ_sqr(GEN x, GEN S, GEN T, GEN p)
2456 { return T? FpXQXQ_sqr(x,S,T,p): FpXQ_sqr(x,S,p); }
2457 INLINE GEN
FqXQ_pow(GEN x,GEN n,GEN S,GEN T,GEN p)2458 FqXQ_pow(GEN x, GEN n, GEN S, GEN T, GEN p)
2459 { return T? FpXQXQ_pow(x,n,S,T,p): FpXQ_pow(x,n,S,p); }
2460 
2461 /*FqXn*/
2462 INLINE GEN
FqXn_expint(GEN x,long n,GEN T,GEN p)2463 FqXn_expint(GEN x, long n, GEN T, GEN p)
2464 { return T? FpXQXn_expint(x,n,T,p): FpXn_expint(x,n,p); }
2465 INLINE GEN
FqXn_exp(GEN x,long n,GEN T,GEN p)2466 FqXn_exp(GEN x, long n, GEN T, GEN p)
2467 { return T? FpXQXn_exp(x,n,T,p): FpXn_exp(x,n,p); }
2468 INLINE GEN
FqXn_inv(GEN x,long n,GEN T,GEN p)2469 FqXn_inv(GEN x, long n, GEN T, GEN p)
2470 { return T? FpXQXn_inv(x,n,T,p): FpXn_inv(x,n,p); }
2471 INLINE GEN
FqXn_mul(GEN x,GEN y,long n,GEN T,GEN p)2472 FqXn_mul(GEN x, GEN y, long n, GEN T, GEN p)
2473 { return T? FpXQXn_mul(x, y, n, T, p): FpXn_mul(x, y, n, p); }
2474 INLINE GEN
FqXn_sqr(GEN x,long n,GEN T,GEN p)2475 FqXn_sqr(GEN x, long n, GEN T, GEN p)
2476 { return T? FpXQXn_sqr(x,n,T,p): FpXn_sqr(x,n,p); }
2477 
2478 /*FpXQ*/
2479 INLINE GEN
FpXQ_add(GEN x,GEN y,GEN T,GEN p)2480 FpXQ_add(GEN x,GEN y,GEN T/*unused*/,GEN p)
2481 { (void)T; return FpX_add(x,y,p); }
2482 INLINE GEN
FpXQ_sub(GEN x,GEN y,GEN T,GEN p)2483 FpXQ_sub(GEN x,GEN y,GEN T/*unused*/,GEN p)
2484 { (void)T; return FpX_sub(x,y,p); }
2485 
2486 /*Flxq*/
2487 INLINE GEN
Flxq_add(GEN x,GEN y,GEN T,ulong p)2488 Flxq_add(GEN x,GEN y,GEN T/*unused*/,ulong p)
2489 { (void)T; return Flx_add(x,y,p); }
2490 INLINE GEN
Flxq_sub(GEN x,GEN y,GEN T,ulong p)2491 Flxq_sub(GEN x,GEN y,GEN T/*unused*/,ulong p)
2492 { (void)T; return Flx_sub(x,y,p); }
2493 
2494 /* F2x */
2495 
2496 INLINE ulong
F2x_coeff(GEN x,long v)2497 F2x_coeff(GEN x,long v)
2498 {
2499    ulong u=(ulong)x[2+divsBIL(v)];
2500    return (u>>remsBIL(v))&1UL;
2501 }
2502 
2503 INLINE void
F2x_clear(GEN x,long v)2504 F2x_clear(GEN x,long v)
2505 {
2506    ulong* u=(ulong*)&x[2+divsBIL(v)];
2507    *u&=~(1UL<<remsBIL(v));
2508 }
2509 
2510 INLINE void
F2x_set(GEN x,long v)2511 F2x_set(GEN x,long v)
2512 {
2513    ulong* u=(ulong*)&x[2+divsBIL(v)];
2514    *u|=1UL<<remsBIL(v);
2515 }
2516 
2517 INLINE void
F2x_flip(GEN x,long v)2518 F2x_flip(GEN x,long v)
2519 {
2520    ulong* u=(ulong*)&x[2+divsBIL(v)];
2521    *u^=1UL<<remsBIL(v);
2522 }
2523 
2524 /* F2v */
2525 
2526 INLINE ulong
F2v_coeff(GEN x,long v)2527 F2v_coeff(GEN x,long v) { return F2x_coeff(x,v-1); }
2528 
2529 INLINE void
F2v_clear(GEN x,long v)2530 F2v_clear(GEN x,long v) { F2x_clear(x,v-1); }
2531 
2532 INLINE void
F2v_set(GEN x,long v)2533 F2v_set(GEN x,long v)   { F2x_set(x,v-1); }
2534 
2535 INLINE void
F2v_flip(GEN x,long v)2536 F2v_flip(GEN x,long v) { F2x_flip(x,v-1); }
2537 
2538 /* F2m */
2539 
2540 INLINE ulong
F2m_coeff(GEN x,long a,long b)2541 F2m_coeff(GEN x, long a, long b) { return F2v_coeff(gel(x,b), a); }
2542 
2543 INLINE void
F2m_clear(GEN x,long a,long b)2544 F2m_clear(GEN x, long a, long b) { F2v_clear(gel(x,b), a); }
2545 
2546 INLINE void
F2m_set(GEN x,long a,long b)2547 F2m_set(GEN x, long a, long b) { F2v_set(gel(x,b), a); }
2548 
2549 INLINE void
F2m_flip(GEN x,long a,long b)2550 F2m_flip(GEN x, long a, long b) { F2v_flip(gel(x,b), a); }
2551 
2552 /* ARITHMETIC */
2553 INLINE GEN
matpascal(long n)2554 matpascal(long n) { return matqpascal(n, NULL); }
2555 INLINE long
Z_issquare(GEN x)2556 Z_issquare(GEN x) { return Z_issquareall(x, NULL); }
2557 INLINE long
Z_ispower(GEN x,ulong k)2558 Z_ispower(GEN x, ulong k) { return Z_ispowerall(x, k, NULL); }
2559 INLINE GEN
sqrti(GEN x)2560 sqrti(GEN x) { return sqrtremi(x,NULL); }
2561 INLINE GEN
gaddgs(GEN y,long s)2562 gaddgs(GEN y, long s) { return gaddsg(s,y); }
2563 INLINE int
gcmpgs(GEN y,long s)2564 gcmpgs(GEN y, long s) { return -gcmpsg(s,y); }
2565 INLINE int
gequalgs(GEN y,long s)2566 gequalgs(GEN y, long s) { return gequalsg(s,y); }
2567 INLINE GEN
gmaxsg(long s,GEN y)2568 gmaxsg(long s, GEN y) { return gmaxgs(y,s); }
2569 INLINE GEN
gminsg(long s,GEN y)2570 gminsg(long s, GEN y) { return gmings(y,s); }
2571 INLINE GEN
gmulgs(GEN y,long s)2572 gmulgs(GEN y, long s) { return gmulsg(s,y); }
2573 INLINE GEN
gsubgs(GEN y,long s)2574 gsubgs(GEN y, long s) { return gaddgs(y, -s); }
2575 INLINE GEN
gdivsg(long s,GEN y)2576 gdivsg(long s, GEN y) { return gdiv(stoi(s), y); }
2577 
2578 INLINE GEN
gmax_shallow(GEN x,GEN y)2579 gmax_shallow(GEN x, GEN y) { return gcmp(x,y)<0? y: x; }
2580 INLINE GEN
gmin_shallow(GEN x,GEN y)2581 gmin_shallow(GEN x, GEN y) { return gcmp(x,y)<0? x: y; }
2582 
2583 /* x t_COMPLEX */
2584 INLINE GEN
cxnorm(GEN x)2585 cxnorm(GEN x) { return gadd(gsqr(gel(x,1)), gsqr(gel(x,2))); }
2586 /* q t_QUAD */
2587 INLINE GEN
quadnorm(GEN q)2588 quadnorm(GEN q)
2589 {
2590   GEN X = gel(q,1), b = gel(X,3), c = gel(X,2);
2591   GEN z, u = gel(q,3), v = gel(q,2);
2592   if (typ(u) == t_INT && typ(v) == t_INT) /* generic case */
2593   {
2594     z = signe(b)? mulii(v, addii(u,v)): sqri(v);
2595     return addii(z, mulii(c, sqri(u)));
2596   }
2597   else
2598   {
2599     z = signe(b)? gmul(v, gadd(u,v)): gsqr(v);
2600     return gadd(z, gmul(c, gsqr(u)));
2601   }
2602 }
2603 /* x a t_QUAD, return the attached discriminant */
2604 INLINE GEN
quad_disc(GEN x)2605 quad_disc(GEN x)
2606 {
2607   GEN Q = gel(x,1), b = gel(Q,3), c = gel(Q,2), c4 = shifti(c,2);
2608   if (is_pm1(b)) return subsi(1, c4);
2609   togglesign_safe(&c4); return c4;
2610 }
2611 INLINE GEN
qfb_disc3(GEN x,GEN y,GEN z)2612 qfb_disc3(GEN x, GEN y, GEN z) { return subii(sqri(y), shifti(mulii(x,z),2)); }
2613 INLINE GEN
qfb_disc(GEN x)2614 qfb_disc(GEN x) { return qfb_disc3(gel(x,1), gel(x,2), gel(x,3)); }
2615 
2616 INLINE GEN
sqrfrac(GEN x)2617 sqrfrac(GEN x)
2618 {
2619   GEN z = cgetg(3,t_FRAC);
2620   gel(z,1) = sqri(gel(x,1));
2621   gel(z,2) = sqri(gel(x,2)); return z;
2622 }
2623 
2624 INLINE void
normalize_frac(GEN z)2625 normalize_frac(GEN z) {
2626   if (signe(gel(z,2)) < 0) { togglesign(gel(z,1)); setabssign(gel(z,2)); }
2627 }
2628 
2629 INLINE GEN
powii(GEN x,GEN n)2630 powii(GEN x, GEN n)
2631 {
2632   long ln = lgefint(n);
2633   if (ln == 3) {
2634     GEN z;
2635     if (signe(n) > 0) return powiu(x, n[2]);
2636     z = cgetg(3, t_FRAC);
2637     gel(z,1) = gen_1;
2638     gel(z,2) = powiu(x, n[2]);
2639     return z;
2640   }
2641   if (ln == 2) return gen_1; /* rare */
2642   /* should never happen */
2643   return powgi(x, n); /* overflow unless x = 0, 1, -1 */
2644 }
2645 INLINE GEN
powIs(long n)2646 powIs(long n) {
2647   switch(n & 3)
2648   {
2649     case 1: return mkcomplex(gen_0,gen_1);
2650     case 2: return gen_m1;
2651     case 3: return mkcomplex(gen_0,gen_m1);
2652   }
2653   return gen_1;
2654 }
2655 
2656 /*******************************************************************/
2657 /*                                                                 */
2658 /*                             ASSIGNMENTS                         */
2659 /*                                                                 */
2660 /*******************************************************************/
mpexpz(GEN x,GEN z)2661 INLINE void mpexpz(GEN x, GEN z)
2662 { pari_sp av = avma; gaffect(mpexp(x), z); set_avma(av); }
mplogz(GEN x,GEN z)2663 INLINE void mplogz(GEN x, GEN z)
2664 { pari_sp av = avma; gaffect(mplog(x), z); set_avma(av); }
mpcosz(GEN x,GEN z)2665 INLINE void mpcosz(GEN x, GEN z)
2666 { pari_sp av = avma; gaffect(mpcos(x), z); set_avma(av); }
mpsinz(GEN x,GEN z)2667 INLINE void mpsinz(GEN x, GEN z)
2668 { pari_sp av = avma; gaffect(mpsin(x), z); set_avma(av); }
gnegz(GEN x,GEN z)2669 INLINE void gnegz(GEN x, GEN z)
2670 { pari_sp av = avma; gaffect(gneg(x), z); set_avma(av); }
gabsz(GEN x,long prec,GEN z)2671 INLINE void gabsz(GEN x, long prec, GEN z)
2672 { pari_sp av = avma; gaffect(gabs(x,prec), z); set_avma(av); }
gaddz(GEN x,GEN y,GEN z)2673 INLINE void gaddz(GEN x, GEN y, GEN z)
2674 { pari_sp av = avma; gaffect(gadd(x,y), z); set_avma(av); }
gsubz(GEN x,GEN y,GEN z)2675 INLINE void gsubz(GEN x, GEN y, GEN z)
2676 { pari_sp av = avma; gaffect(gsub(x,y), z); set_avma(av); }
gmulz(GEN x,GEN y,GEN z)2677 INLINE void gmulz(GEN x, GEN y, GEN z)
2678 { pari_sp av = avma; gaffect(gmul(x,y), z); set_avma(av); }
gdivz(GEN x,GEN y,GEN z)2679 INLINE void gdivz(GEN x, GEN y, GEN z)
2680 { pari_sp av = avma; gaffect(gdiv(x,y), z); set_avma(av); }
gdiventz(GEN x,GEN y,GEN z)2681 INLINE void gdiventz(GEN x, GEN y, GEN z)
2682 { pari_sp av = avma; gaffect(gdivent(x,y), z); set_avma(av); }
gmodz(GEN x,GEN y,GEN z)2683 INLINE void gmodz(GEN x, GEN y, GEN z)
2684 { pari_sp av = avma; gaffect(gmod(x,y), z); set_avma(av); }
gmul2nz(GEN x,long s,GEN z)2685 INLINE void gmul2nz(GEN x, long s, GEN z)
2686 { pari_sp av = avma; gaffect(gmul2n(x,s), z); set_avma(av); }
gshiftz(GEN x,long s,GEN z)2687 INLINE void gshiftz(GEN x, long s, GEN z)
2688 { pari_sp av = avma; gaffect(gshift(x,s), z); set_avma(av); }
2689 
2690 /*******************************************************************/
2691 /*                                                                 */
2692 /*                       ELLIPTIC CURVES                           */
2693 /*                                                                 */
2694 /*******************************************************************/
ell_get_a1(GEN e)2695 INLINE GEN ell_get_a1(GEN e) { return gel(e,1); }
ell_get_a2(GEN e)2696 INLINE GEN ell_get_a2(GEN e) { return gel(e,2); }
ell_get_a3(GEN e)2697 INLINE GEN ell_get_a3(GEN e) { return gel(e,3); }
ell_get_a4(GEN e)2698 INLINE GEN ell_get_a4(GEN e) { return gel(e,4); }
ell_get_a6(GEN e)2699 INLINE GEN ell_get_a6(GEN e) { return gel(e,5); }
ell_get_b2(GEN e)2700 INLINE GEN ell_get_b2(GEN e) { return gel(e,6); }
ell_get_b4(GEN e)2701 INLINE GEN ell_get_b4(GEN e) { return gel(e,7); }
ell_get_b6(GEN e)2702 INLINE GEN ell_get_b6(GEN e) { return gel(e,8); }
ell_get_b8(GEN e)2703 INLINE GEN ell_get_b8(GEN e) { return gel(e,9); }
ell_get_c4(GEN e)2704 INLINE GEN ell_get_c4(GEN e) { return gel(e,10); }
ell_get_c6(GEN e)2705 INLINE GEN ell_get_c6(GEN e) { return gel(e,11); }
ell_get_disc(GEN e)2706 INLINE GEN ell_get_disc(GEN e) { return gel(e,12); }
ell_get_j(GEN e)2707 INLINE GEN ell_get_j(GEN e) { return gel(e,13); }
ell_get_type(GEN e)2708 INLINE long ell_get_type(GEN e) { return mael(e,14,1); }
ellff_get_field(GEN x)2709 INLINE GEN ellff_get_field(GEN x) { return gmael(x, 15, 1); }
ellff_get_a4a6(GEN x)2710 INLINE GEN ellff_get_a4a6(GEN x)  { return gmael(x, 15, 2); }
ellQp_get_zero(GEN x)2711 INLINE GEN ellQp_get_zero(GEN x) { return gmael(x, 15, 1); }
ellQp_get_prec(GEN E)2712 INLINE long ellQp_get_prec(GEN E) { GEN z = ellQp_get_zero(E); return valp(z); }
ellQp_get_p(GEN E)2713 INLINE GEN ellQp_get_p(GEN E) { GEN z = ellQp_get_zero(E); return gel(z,2); }
ellR_get_prec(GEN x)2714 INLINE long ellR_get_prec(GEN x) { return nbits2prec(mael3(x, 15, 1, 1)); }
ellR_get_sign(GEN x)2715 INLINE long ellR_get_sign(GEN x) { return mael3(x, 15, 1, 2); }
ellnf_get_nf(GEN x)2716 INLINE GEN ellnf_get_nf(GEN x) { return checknf_i(gmael(x,15,1)); }
ellnf_get_bnf(GEN x)2717 INLINE GEN ellnf_get_bnf(GEN x) { return checkbnf_i(gmael(x,15,1)); }
2718 
checkell_i(GEN e)2719 INLINE int checkell_i(GEN e) { return typ(e) == t_VEC && lg(e) == 17; }
ell_is_inf(GEN z)2720 INLINE int ell_is_inf(GEN z) { return lg(z) == 2; }
ellinf(void)2721 INLINE GEN ellinf(void) { return mkvec(gen_0); }
2722 
2723 /*******************************************************************/
2724 /*                                                                 */
2725 /*                    ALGEBRAIC NUMBER THEORY                      */
2726 /*                                                                 */
2727 /*******************************************************************/
modpr_get_pr(GEN x)2728 INLINE GEN modpr_get_pr(GEN x)  { return gel(x,3); }
modpr_get_p(GEN x)2729 INLINE GEN modpr_get_p(GEN x)  { return pr_get_p(modpr_get_pr(x)); }
modpr_get_T(GEN x)2730 INLINE GEN modpr_get_T(GEN x)  { return lg(x) == 4? NULL: gel(x,4); }
2731 
pr_get_p(GEN pr)2732 INLINE GEN pr_get_p(GEN pr)  { return gel(pr,1); }
pr_get_gen(GEN pr)2733 INLINE GEN pr_get_gen(GEN pr){ return gel(pr,2); }
2734 /* .[2] instead of itos works: e and f are small positive integers */
pr_get_e(GEN pr)2735 INLINE long pr_get_e(GEN pr) { return gel(pr,3)[2]; }
pr_get_f(GEN pr)2736 INLINE long pr_get_f(GEN pr) { return gel(pr,4)[2]; }
pr_get_tau(GEN pr)2737 INLINE GEN pr_get_tau(GEN pr){ return gel(pr,5); }
2738 INLINE int
pr_is_inert(GEN P)2739 pr_is_inert(GEN P) { return typ(pr_get_tau(P)) == t_INT; }
2740 INLINE GEN
pr_norm(GEN pr)2741 pr_norm(GEN pr) { return powiu(pr_get_p(pr), pr_get_f(pr)); }
2742 INLINE ulong
upr_norm(GEN pr)2743 upr_norm(GEN pr) { return upowuu(pr_get_p(pr)[2], pr_get_f(pr)); }
2744 
2745 /* assume nf a genuine nf */
2746 INLINE long
nf_get_varn(GEN nf)2747 nf_get_varn(GEN nf) { return varn(gel(nf,1)); }
2748 INLINE GEN
nf_get_pol(GEN nf)2749 nf_get_pol(GEN nf) { return gel(nf,1); }
2750 INLINE long
nf_get_degree(GEN nf)2751 nf_get_degree(GEN nf) { return degpol( nf_get_pol(nf) ); }
2752 INLINE long
nf_get_r1(GEN nf)2753 nf_get_r1(GEN nf) { GEN x = gel(nf,2); return itou(gel(x,1)); }
2754 INLINE long
nf_get_r2(GEN nf)2755 nf_get_r2(GEN nf) { GEN x = gel(nf,2); return itou(gel(x,2)); }
2756 INLINE GEN
nf_get_disc(GEN nf)2757 nf_get_disc(GEN nf) { return gel(nf,3); }
2758 INLINE GEN
nf_get_index(GEN nf)2759 nf_get_index(GEN nf) { return gel(nf,4); }
2760 INLINE GEN
nf_get_M(GEN nf)2761 nf_get_M(GEN nf) { return gmael(nf,5,1); }
2762 INLINE GEN
nf_get_G(GEN nf)2763 nf_get_G(GEN nf) { return gmael(nf,5,2); }
2764 INLINE GEN
nf_get_roundG(GEN nf)2765 nf_get_roundG(GEN nf) { return gmael(nf,5,3); }
2766 INLINE GEN
nf_get_Tr(GEN nf)2767 nf_get_Tr(GEN nf) { return gmael(nf,5,4); }
2768 INLINE GEN
nf_get_diff(GEN nf)2769 nf_get_diff(GEN nf) { return gmael(nf,5,5); }
2770 INLINE GEN
nf_get_ramified_primes(GEN nf)2771 nf_get_ramified_primes(GEN nf) { return gmael(nf,5,8); }
2772 INLINE GEN
nf_get_roots(GEN nf)2773 nf_get_roots(GEN nf) { return gel(nf,6); }
2774 INLINE GEN
nf_get_zk(GEN nf)2775 nf_get_zk(GEN nf)
2776 {
2777   GEN y = gel(nf,7), D = gel(y, 1);
2778   if (typ(D) == t_POL) D = gel(D, 2);
2779   if (!equali1(D)) y = gdiv(y, D);
2780   return y;
2781 }
2782 INLINE GEN
nf_get_zkprimpart(GEN nf)2783 nf_get_zkprimpart(GEN nf)
2784 {
2785   GEN y = gel(nf,7);
2786   /* test for old format of nf.zk: non normalized */
2787   if (!equali1(gel(nf,4)) && gequal1(gel(y,1))) y = Q_remove_denom(y,NULL);
2788   return y;
2789 }
2790 INLINE GEN
nf_get_zkden(GEN nf)2791 nf_get_zkden(GEN nf)
2792 {
2793   GEN y = gel(nf,7), D = gel(y,1);
2794   if (typ(D) == t_POL) D = gel(D,2);
2795   /* test for old format of nf.zk: non normalized */
2796   if (!equali1(gel(nf,4)) && equali1(D)) D = Q_denom(y);
2797   return D;
2798 }
2799 INLINE GEN
nf_get_invzk(GEN nf)2800 nf_get_invzk(GEN nf) { return gel(nf,8); }
2801 INLINE void
nf_get_sign(GEN nf,long * r1,long * r2)2802 nf_get_sign(GEN nf, long *r1, long *r2)
2803 {
2804   GEN x = gel(nf,2);
2805   *r1 = itou(gel(x,1));
2806   *r2 = itou(gel(x,2));
2807 }
2808 
2809 INLINE GEN
cyc_get_expo(GEN c)2810 cyc_get_expo(GEN c) { return lg(c) == 1? gen_1: gel(c,1); }
2811 INLINE GEN
abgrp_get_no(GEN x)2812 abgrp_get_no(GEN x) { return gel(x,1); }
2813 INLINE GEN
abgrp_get_cyc(GEN x)2814 abgrp_get_cyc(GEN x) { return gel(x,2); }
2815 INLINE GEN
abgrp_get_gen(GEN x)2816 abgrp_get_gen(GEN x) { return gel(x,3); }
2817 INLINE GEN
bnf_get_nf(GEN bnf)2818 bnf_get_nf(GEN bnf) { return gel(bnf,7); }
2819 INLINE GEN
bnf_get_clgp(GEN bnf)2820 bnf_get_clgp(GEN bnf) { return gmael(bnf,8,1); }
2821 INLINE GEN
bnf_get_no(GEN bnf)2822 bnf_get_no(GEN bnf) { return abgrp_get_no(bnf_get_clgp(bnf)); }
2823 INLINE GEN
bnf_get_cyc(GEN bnf)2824 bnf_get_cyc(GEN bnf) { return abgrp_get_cyc(bnf_get_clgp(bnf)); }
2825 INLINE GEN
bnf_get_gen(GEN bnf)2826 bnf_get_gen(GEN bnf)  { return abgrp_get_gen(bnf_get_clgp(bnf)); }
2827 INLINE GEN
bnf_get_reg(GEN bnf)2828 bnf_get_reg(GEN bnf) { return gmael(bnf,8,2); }
2829 INLINE GEN
bnf_get_logfu(GEN bnf)2830 bnf_get_logfu(GEN bnf) { return gel(bnf,3); }
2831 INLINE GEN
bnf_get_sunits(GEN bnf)2832 bnf_get_sunits(GEN bnf)
2833 { GEN s = gmael(bnf,8,3); return typ(s) == t_INT? NULL: s; }
2834 INLINE GEN
bnf_get_tuU(GEN bnf)2835 bnf_get_tuU(GEN bnf) { return gmael3(bnf,8,4,2); }
2836 INLINE long
bnf_get_tuN(GEN bnf)2837 bnf_get_tuN(GEN bnf) { return gmael3(bnf,8,4,1)[2]; }
2838 INLINE GEN
bnf_get_fu_nocheck(GEN bnf)2839 bnf_get_fu_nocheck(GEN bnf) { return gmael(bnf,8,5); }
2840 INLINE GEN
bnf_get_fu(GEN bnf)2841 bnf_get_fu(GEN bnf) {
2842   GEN fu = bnf_build_units(bnf), nf = bnf_get_nf(bnf);
2843   long i, l;
2844   if (typ(fu) == t_MAT) pari_err(e_MISC,"missing units in bnf");
2845   l = lg(fu)-1; fu = vecslice(fu, 2, l);
2846   for (i = 1; i < l; i++) gel(fu,i) = nf_to_scalar_or_alg(nf, gel(fu,i));
2847   return fu;
2848 }
2849 
2850 INLINE GEN
bnr_get_bnf(GEN bnr)2851 bnr_get_bnf(GEN bnr) { return gel(bnr,1); }
2852 INLINE GEN
bnr_get_bid(GEN bnr)2853 bnr_get_bid(GEN bnr) { return gel(bnr,2); }
2854 INLINE GEN
bnr_get_mod(GEN bnr)2855 bnr_get_mod(GEN bnr) { return gmael(bnr,2,1); }
2856 INLINE GEN
bnr_get_nf(GEN bnr)2857 bnr_get_nf(GEN bnr) { return gmael(bnr,1,7); }
2858 INLINE GEN
bnr_get_clgp(GEN bnr)2859 bnr_get_clgp(GEN bnr) { return gel(bnr,5); }
2860 INLINE GEN
bnr_get_no(GEN bnr)2861 bnr_get_no(GEN bnr) { return abgrp_get_no(bnr_get_clgp(bnr)); }
2862 INLINE GEN
bnr_get_cyc(GEN bnr)2863 bnr_get_cyc(GEN bnr) { return abgrp_get_cyc(bnr_get_clgp(bnr)); }
2864 INLINE GEN
bnr_get_gen_nocheck(GEN bnr)2865 bnr_get_gen_nocheck(GEN bnr) { return abgrp_get_gen(bnr_get_clgp(bnr)); }
2866 INLINE GEN
bnr_get_gen(GEN bnr)2867 bnr_get_gen(GEN bnr) {
2868   GEN G = bnr_get_clgp(bnr);
2869   if (lg(G) !=  4)
2870     pari_err(e_MISC,"missing bnr generators: please use bnrinit(,,1)");
2871   return gel(G,3);
2872 }
2873 
2874 INLINE GEN
bid_get_mod(GEN bid)2875 bid_get_mod(GEN bid) { return gel(bid,1); }
2876 INLINE GEN
bid_get_ideal(GEN bid)2877 bid_get_ideal(GEN bid) { return gmael(bid,1,1); }
2878 INLINE GEN
bid_get_arch(GEN bid)2879 bid_get_arch(GEN bid) { return gmael(bid,1,2); }
2880 INLINE GEN
bid_get_grp(GEN bid)2881 bid_get_grp(GEN bid) { return gel(bid,2); }
2882 INLINE GEN
bid_get_fact(GEN bid)2883 bid_get_fact(GEN bid) { return gmael(bid,3,1); }
2884 INLINE GEN
bid_get_fact2(GEN bid)2885 bid_get_fact2(GEN bid) { return gmael(bid,3,2); }
2886 INLINE GEN
bid_get_sprk(GEN bid)2887 bid_get_sprk(GEN bid) { return gmael(bid,4,1); }
2888 INLINE GEN
bid_get_sarch(GEN bid)2889 bid_get_sarch(GEN bid) { return gmael(bid,4,2); }
2890 INLINE GEN
bid_get_archp(GEN bid)2891 bid_get_archp(GEN bid) { return gmael3(bid,4,2,2); }
2892 INLINE GEN
bid_get_U(GEN bid)2893 bid_get_U(GEN bid) { return gel(bid,5); }
2894 INLINE GEN
bid_get_no(GEN bid)2895 bid_get_no(GEN bid) { return abgrp_get_no(bid_get_grp(bid)); }
2896 INLINE GEN
bid_get_cyc(GEN bid)2897 bid_get_cyc(GEN bid) { return abgrp_get_cyc(bid_get_grp(bid)); }
2898 INLINE GEN
bid_get_gen_nocheck(GEN bid)2899 bid_get_gen_nocheck(GEN bid)  { return abgrp_get_gen(bid_get_grp(bid)); }
2900 INLINE GEN
bid_get_gen(GEN bid)2901 bid_get_gen(GEN bid) {
2902   GEN G = bid_get_grp(bid);
2903   if (lg(G) != 4) pari_err(e_MISC,"missing bid generators. Use idealstar(,,2)");
2904   return abgrp_get_gen(G);
2905 }
2906 
2907 INLINE GEN
znstar_get_N(GEN G)2908 znstar_get_N(GEN G) { return gmael(G,1,1); }
2909 INLINE GEN
znstar_get_faN(GEN G)2910 znstar_get_faN(GEN G) { return gel(G,3); }
2911 INLINE GEN
znstar_get_no(GEN G)2912 znstar_get_no(GEN G) { return abgrp_get_no(gel(G,2)); }
2913 INLINE GEN
znstar_get_cyc(GEN G)2914 znstar_get_cyc(GEN G) { return abgrp_get_cyc(gel(G,2)); }
2915 INLINE GEN
znstar_get_gen(GEN G)2916 znstar_get_gen(GEN G) { return abgrp_get_gen(gel(G,2)); }
2917 INLINE GEN
znstar_get_conreycyc(GEN G)2918 znstar_get_conreycyc(GEN G) { return gmael(G,4,5); }
2919 INLINE GEN
znstar_get_conreygen(GEN G)2920 znstar_get_conreygen(GEN G) { return gmael(G,4,4); }
2921 INLINE GEN
znstar_get_Ui(GEN G)2922 znstar_get_Ui(GEN G) { return gmael(G,4,3); }
2923 INLINE GEN
znstar_get_U(GEN G)2924 znstar_get_U(GEN G) { return gel(G,5); }
2925 INLINE GEN
znstar_get_pe(GEN G)2926 znstar_get_pe(GEN G) { return gmael(G,4,1); }
2927 INLINE GEN
gal_get_pol(GEN gal)2928 gal_get_pol(GEN gal) { return gel(gal,1); }
2929 INLINE GEN
gal_get_p(GEN gal)2930 gal_get_p(GEN gal) { return gmael(gal,2,1); }
2931 INLINE GEN
gal_get_e(GEN gal)2932 gal_get_e(GEN gal) { return gmael(gal,2,2); }
2933 INLINE GEN
gal_get_mod(GEN gal)2934 gal_get_mod(GEN gal) { return gmael(gal,2,3); }
2935 INLINE GEN
gal_get_roots(GEN gal)2936 gal_get_roots(GEN gal) { return gel(gal,3); }
2937 INLINE GEN
gal_get_invvdm(GEN gal)2938 gal_get_invvdm(GEN gal) { return gel(gal,4); }
2939 INLINE GEN
gal_get_den(GEN gal)2940 gal_get_den(GEN gal) { return gel(gal,5); }
2941 INLINE GEN
gal_get_group(GEN gal)2942 gal_get_group(GEN gal) { return gel(gal,6); }
2943 INLINE GEN
gal_get_gen(GEN gal)2944 gal_get_gen(GEN gal) { return gel(gal,7); }
2945 INLINE GEN
gal_get_orders(GEN gal)2946 gal_get_orders(GEN gal) { return gel(gal,8); }
2947 
2948 /* assume rnf a genuine rnf */
2949 INLINE long
rnf_get_degree(GEN rnf)2950 rnf_get_degree(GEN rnf) { return degpol(rnf_get_pol(rnf)); }
2951 INLINE long
rnf_get_nfdegree(GEN rnf)2952 rnf_get_nfdegree(GEN rnf) { return degpol(nf_get_pol(rnf_get_nf(rnf))); }
2953 INLINE long
rnf_get_absdegree(GEN rnf)2954 rnf_get_absdegree(GEN rnf) { return degpol(gmael(rnf,11,1)); }
2955 INLINE GEN
rnf_get_idealdisc(GEN rnf)2956 rnf_get_idealdisc(GEN rnf) { return gmael(rnf,3,1); }
2957 INLINE GEN
rnf_get_k(GEN rnf)2958 rnf_get_k(GEN rnf) { return gmael(rnf,11,3); }
2959 INLINE GEN
rnf_get_alpha(GEN rnf)2960 rnf_get_alpha(GEN rnf) { return gmael(rnf, 11, 2); }
2961 INLINE GEN
rnf_get_nf(GEN rnf)2962 rnf_get_nf(GEN rnf) { return gel(rnf,10); }
2963 INLINE GEN
rnf_get_nfzk(GEN rnf)2964 rnf_get_nfzk(GEN rnf) { return gel(rnf,2); }
2965 INLINE GEN
rnf_get_polabs(GEN rnf)2966 rnf_get_polabs(GEN rnf) { return gmael(rnf,11,1); }
2967 INLINE GEN
rnf_get_pol(GEN rnf)2968 rnf_get_pol(GEN rnf) { return gel(rnf,1); }
2969 INLINE GEN
rnf_get_disc(GEN rnf)2970 rnf_get_disc(GEN rnf) { return gel(rnf,3); }
2971 INLINE GEN
rnf_get_index(GEN rnf)2972 rnf_get_index(GEN rnf) { return gel(rnf,4); }
2973 INLINE GEN
rnf_get_ramified_primes(GEN rnf)2974 rnf_get_ramified_primes(GEN rnf) { return gel(rnf,5); }
2975 INLINE long
rnf_get_varn(GEN rnf)2976 rnf_get_varn(GEN rnf) { return varn(gel(rnf,1)); }
2977 INLINE GEN
rnf_get_nfpol(GEN rnf)2978 rnf_get_nfpol(GEN rnf) { return gmael(rnf,10,1); }
2979 INLINE long
rnf_get_nfvarn(GEN rnf)2980 rnf_get_nfvarn(GEN rnf) { return varn(gmael(rnf,10,1)); }
2981 INLINE GEN
rnf_get_zk(GEN rnf)2982 rnf_get_zk(GEN rnf) { return gel(rnf,7); }
2983 INLINE GEN
rnf_get_map(GEN rnf)2984 rnf_get_map(GEN rnf) { return gel(rnf,11); }
2985 INLINE GEN
rnf_get_invzk(GEN rnf)2986 rnf_get_invzk(GEN rnf) { return gel(rnf,8); }
2987 
2988 /* I integral ZM (not HNF), G ZM, rounded Cholesky form of a weighted
2989  * T2 matrix. Reduce I wrt G */
2990 INLINE GEN
idealpseudored(GEN I,GEN G)2991 idealpseudored(GEN I, GEN G)
2992 { return ZM_mul(I, ZM_lll(ZM_mul(G, I), 0.99, LLL_IM)); }
2993 
2994 /* Same I, G; m in I with T2(m) small */
2995 INLINE GEN
idealpseudomin(GEN I,GEN G)2996 idealpseudomin(GEN I, GEN G)
2997 {
2998   GEN u = ZM_lll(ZM_mul(G, I), 0.99, LLL_IM);
2999   return ZM_ZC_mul(I, gel(u,1));
3000 }
3001 /* Same I,G; irrational m in I with T2(m) small */
3002 INLINE GEN
idealpseudomin_nonscalar(GEN I,GEN G)3003 idealpseudomin_nonscalar(GEN I, GEN G)
3004 {
3005   GEN u = ZM_lll(ZM_mul(G, I), 0.99, LLL_IM);
3006   GEN m = ZM_ZC_mul(I, gel(u,1));
3007   if (ZV_isscalar(m) && lg(u) > 2) m = ZM_ZC_mul(I, gel(u,2));
3008   return m;
3009 }
3010 /* Same I,G; t_VEC of irrational m in I with T2(m) small */
3011 INLINE GEN
idealpseudominvec(GEN I,GEN G)3012 idealpseudominvec(GEN I, GEN G)
3013 {
3014   long i, j, k, n = lg(I)-1;
3015   GEN x, L, b = idealpseudored(I, G);
3016   L = cgetg(1 + (n*(n+1))/2, t_VEC);
3017   for (i = k = 1; i <= n; i++)
3018   {
3019     x = gel(b,i);
3020     if (!ZV_isscalar(x)) gel(L,k++) = x;
3021   }
3022   for (i = 2; i <= n; i++)
3023     for (j = 1; j < i; j++)
3024     {
3025       x = ZC_add(gel(b,i),gel(b,j));
3026       if (!ZV_isscalar(x)) gel(L,k++) = x;
3027     }
3028   setlg(L,k); return L;
3029 }
3030 
3031 INLINE GEN
idealred_elt(GEN nf,GEN I)3032 idealred_elt(GEN nf, GEN I) {
3033   pari_sp av = avma;
3034   GEN u = idealpseudomin(I, nf_get_roundG(nf));
3035   return gerepileupto(av, u);
3036 }
3037 INLINE GEN
idealred(GEN nf,GEN I)3038 idealred(GEN nf, GEN I) { return idealred0(nf, I, NULL); }
3039 
3040 INLINE GEN
idealchineseinit(GEN nf,GEN x)3041 idealchineseinit(GEN nf, GEN x)
3042 { return idealchinese(nf,x,NULL); }
3043 
3044 /*******************************************************************/
3045 /*                                                                 */
3046 /*                              CLOSURES                           */
3047 /*                                                                 */
3048 /*******************************************************************/
closure_arity(GEN C)3049 INLINE long closure_arity(GEN C)          { return ((ulong)C[1])&ARITYBITS; }
closure_is_variadic(GEN C)3050 INLINE long closure_is_variadic(GEN C) { return !!(((ulong)C[1])&VARARGBITS); }
closure_codestr(GEN C)3051 INLINE const char *closure_codestr(GEN C)  { return GSTR(gel(C,2))-1; }
closure_get_code(GEN C)3052 INLINE GEN closure_get_code(GEN C)  { return gel(C,2); }
closure_get_oper(GEN C)3053 INLINE GEN closure_get_oper(GEN C)  { return gel(C,3); }
closure_get_data(GEN C)3054 INLINE GEN closure_get_data(GEN C)  { return gel(C,4); }
closure_get_dbg(GEN C)3055 INLINE GEN closure_get_dbg(GEN C)   { return gel(C,5); }
closure_get_text(GEN C)3056 INLINE GEN closure_get_text(GEN C)  { return gel(C,6); }
closure_get_frame(GEN C)3057 INLINE GEN closure_get_frame(GEN C) { return gel(C,7); }
3058 
3059 /*******************************************************************/
3060 /*                                                                 */
3061 /*                               ERRORS                            */
3062 /*                                                                 */
3063 /*******************************************************************/
3064 INLINE long
err_get_num(GEN e)3065 err_get_num(GEN e) { return e[1]; }
3066 INLINE GEN
err_get_compo(GEN e,long i)3067 err_get_compo(GEN e, long i) { return gel(e, i+1); }
3068 
3069 INLINE void
pari_err_BUG(const char * f)3070 pari_err_BUG(const char *f) { pari_err(e_BUG,f); }
3071 INLINE void
pari_err_CONSTPOL(const char * f)3072 pari_err_CONSTPOL(const char *f) { pari_err(e_CONSTPOL, f); }
3073 INLINE void
pari_err_COPRIME(const char * f,GEN x,GEN y)3074 pari_err_COPRIME(const char *f, GEN x, GEN y) { pari_err(e_COPRIME, f,x,y); }
3075 INLINE void
pari_err_DIM(const char * f)3076 pari_err_DIM(const char *f) { pari_err(e_DIM, f); }
3077 INLINE void
pari_err_FILE(const char * f,const char * g)3078 pari_err_FILE(const char *f, const char *g) { pari_err(e_FILE, f,g); }
3079 INLINE void
pari_err_FILEDESC(const char * f,long n)3080 pari_err_FILEDESC(const char *f, long n) { pari_err(e_FILEDESC, f,n); }
3081 INLINE void
pari_err_FLAG(const char * f)3082 pari_err_FLAG(const char *f) { pari_err(e_FLAG,f); }
3083 INLINE void
pari_err_IMPL(const char * f)3084 pari_err_IMPL(const char *f) { pari_err(e_IMPL,f); }
3085 INLINE void
pari_err_INV(const char * f,GEN x)3086 pari_err_INV(const char *f, GEN x) { pari_err(e_INV,f,x); }
3087 INLINE void
pari_err_IRREDPOL(const char * f,GEN x)3088 pari_err_IRREDPOL(const char *f, GEN x) { pari_err(e_IRREDPOL, f,x); }
3089 INLINE void
pari_err_DOMAIN(const char * f,const char * v,const char * op,GEN l,GEN x)3090 pari_err_DOMAIN(const char *f, const char *v, const char *op, GEN l, GEN x) { pari_err(e_DOMAIN, f,v,op,l,x); }
3091 INLINE void
pari_err_COMPONENT(const char * f,const char * op,GEN l,GEN x)3092 pari_err_COMPONENT(const char *f, const char *op, GEN l, GEN x) { pari_err(e_COMPONENT, f,op,l,x); }
3093 INLINE void
pari_err_MAXPRIME(ulong c)3094 pari_err_MAXPRIME(ulong c) { pari_err(e_MAXPRIME, c); }
3095 INLINE void
pari_err_OP(const char * f,GEN x,GEN y)3096 pari_err_OP(const char *f, GEN x, GEN y) { pari_err(e_OP, f,x,y); }
3097 INLINE void
pari_err_OVERFLOW(const char * f)3098 pari_err_OVERFLOW(const char *f) { pari_err(e_OVERFLOW, f); }
3099 INLINE void
pari_err_PREC(const char * f)3100 pari_err_PREC(const char *f) { pari_err(e_PREC,f); }
3101 INLINE void
pari_err_PACKAGE(const char * f)3102 pari_err_PACKAGE(const char *f) { pari_err(e_PACKAGE,f); }
3103 INLINE void
pari_err_PRIME(const char * f,GEN x)3104 pari_err_PRIME(const char *f, GEN x) { pari_err(e_PRIME, f,x); }
3105 INLINE void
pari_err_MODULUS(const char * f,GEN x,GEN y)3106 pari_err_MODULUS(const char *f, GEN x, GEN y) { pari_err(e_MODULUS, f,x,y); }
3107 INLINE void
pari_err_ROOTS0(const char * f)3108 pari_err_ROOTS0(const char *f) { pari_err(e_ROOTS0, f); }
3109 INLINE void
pari_err_SQRTN(const char * f,GEN x)3110 pari_err_SQRTN(const char *f, GEN x) { pari_err(e_SQRTN, f,x); }
3111 INLINE void
pari_err_TYPE(const char * f,GEN x)3112 pari_err_TYPE(const char *f, GEN x) { pari_err(e_TYPE, f,x); }
3113 INLINE void
pari_err_TYPE2(const char * f,GEN x,GEN y)3114 pari_err_TYPE2(const char *f, GEN x, GEN y) { pari_err(e_TYPE2, f,x,y); }
3115 INLINE void
pari_err_VAR(const char * f,GEN x,GEN y)3116 pari_err_VAR(const char *f, GEN x, GEN y) { pari_err(e_VAR, f,x,y); }
3117 INLINE void
pari_err_PRIORITY(const char * f,GEN x,const char * op,long v)3118 pari_err_PRIORITY(const char *f, GEN x, const char *op, long v)
3119 { pari_err(e_PRIORITY, f,x,op,v); }
3120