Annotation of OpenXM_contrib/pari-2.2/src/basemath/gen3.c, Revision 1.1.1.1
1.1 noro 1: /* $Id: gen3.c,v 1.39 2001/10/01 12:11:31 karim Exp $
2:
3: Copyright (C) 2000 The PARI group.
4:
5: This file is part of the PARI/GP package.
6:
7: PARI/GP is free software; you can redistribute it and/or modify it under the
8: terms of the GNU General Public License as published by the Free Software
9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
10: ANY WARRANTY WHATSOEVER.
11:
12: Check the License for details. You should have received a copy of it, along
13: with the package; see the file 'COPYING'. If not, write to the Free Software
14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
15:
16: /********************************************************************/
17: /** **/
18: /** GENERIC OPERATIONS **/
19: /** (third part) **/
20: /** **/
21: /********************************************************************/
22: #include "pari.h"
23:
24: /********************************************************************/
25: /** **/
26: /** PRINCIPAL VARIABLE NUMBER **/
27: /** **/
28: /********************************************************************/
29:
30: int
31: gvar(GEN x)
32: {
33: long tx=typ(x),i,v,w;
34:
35: if (is_polser_t(tx)) return varn(x);
36: if (tx==t_POLMOD) return varn(x[1]);
37: if (is_const_t(tx) || is_qf_t(tx) || is_noncalc_t(tx)) return BIGINT;
38: v=BIGINT;
39: for (i=1; i < lg(x); i++) { w=gvar((GEN)x[i]); if (w<v) v=w; }
40: return v;
41: }
42:
43: /* assume x POLMOD */
44: static int
45: _varPOLMOD(GEN x)
46: {
47: long v = gvar2((GEN)x[1]);
48: long w = gvar2((GEN)x[2]); if (w<v) v=w;
49: return v;
50:
51: }
52:
53: int
54: gvar2(GEN x)
55: {
56: long tx=typ(x),i,v,w;
57:
58: if (is_const_t(tx) || is_qf_t(tx) || is_noncalc_t(tx)) return BIGINT;
59: v = BIGINT;
60: switch(tx)
61: {
62: case t_POLMOD:
63: return _varPOLMOD(x);
64:
65: case t_SER:
66: for (i=2; i < lg(x); i++) { w=gvar((GEN)x[i]); if (w<v) v=w; }
67: return v;
68:
69: case t_POL:
70: for (i=2; i<lgef(x); i++) { w=gvar((GEN)x[i]); if (w<v) v=w; }
71: return v;
72: }
73: for (i=1; i<lg(x); i++) { w=gvar2((GEN)x[i]); if (w<v) v=w; }
74: return v;
75: }
76:
77: int
78: gvar9(GEN x)
79: {
80: return (typ(x) == t_POLMOD)? _varPOLMOD(x): gvar(x);
81: }
82:
83: GEN
84: gpolvar(GEN x)
85: {
86: if (typ(x)==t_PADIC) x = (GEN)x[2];
87: else
88: {
89: long v=gvar(x);
90: if (v==BIGINT) err(typeer,"polvar");
91: x = polx[v];
92: }
93: return gcopy(x);
94: }
95:
96: /*******************************************************************/
97: /* */
98: /* PRECISION OF SCALAR OBJECTS */
99: /* */
100: /*******************************************************************/
101:
102: long
103: precision(GEN x)
104: {
105: long tx=typ(x),k,l;
106:
107: if (tx==t_REAL)
108: {
109: k=2-(expo(x)>>TWOPOTBITS_IN_LONG);
110: l=lg(x); if (l>k) k=l;
111: return k;
112: }
113: if (tx==t_COMPLEX)
114: {
115: k=precision((GEN)x[1]);
116: l=precision((GEN)x[2]); if (l && (!k || l<k)) k=l;
117: return k;
118: }
119: return 0;
120: }
121:
122: long
123: gprecision(GEN x)
124: {
125: long tx=typ(x),lx=lg(x),i,k,l;
126:
127: if (is_scalar_t(tx)) return precision(x);
128: switch(tx)
129: {
130: case t_POL: lx=lgef(x);
131: case t_VEC: case t_COL: case t_MAT:
132: k=VERYBIGINT;
133: for (i=lontyp[tx]; i<lx; i++)
134: {
135: l = gprecision((GEN)x[i]);
136: if (l && l<k) k = l;
137: }
138: return (k==VERYBIGINT)? 0: k;
139:
140: case t_RFRAC: case t_RFRACN:
141: {
142: k=gprecision((GEN)x[1]);
143: l=gprecision((GEN)x[2]); if (l && (!k || l<k)) k=l;
144: return k;
145: }
146: case t_QFR:
147: return gprecision((GEN)x[4]);
148: }
149: return 0;
150: }
151:
152: GEN
153: ggprecision(GEN x)
154: {
155: long a=gprecision(x);
156: return stoi(a ? (long) ((a-2)*pariK): VERYBIGINT);
157: }
158:
159: GEN
160: precision0(GEN x, long n)
161: {
162: if (n) return gprec(x,n);
163: return ggprecision(x);
164: }
165:
166: /* attention: precision p-adique absolue */
167: long
168: padicprec(GEN x, GEN p)
169: {
170: long i,s,t,lx=lg(x),tx=typ(x);
171:
172: switch(tx)
173: {
174: case t_INT: case t_FRAC: case t_FRACN:
175: return VERYBIGINT;
176:
177: case t_INTMOD:
178: return ggval((GEN)x[1],p);
179:
180: case t_PADIC:
181: if (!gegal((GEN)x[2],p))
182: err(talker,"not the same prime in padicprec");
183: return precp(x)+valp(x);
184:
185: case t_POL:
186: lx=lgef(x);
187:
188: case t_COMPLEX: case t_QUAD: case t_POLMOD: case t_SER: case t_RFRAC:
189: case t_RFRACN: case t_VEC: case t_COL: case t_MAT:
190: for (s=VERYBIGINT, i=lontyp[tx]; i<lx; i++)
191: {
192: t = padicprec((GEN)x[i],p); if (t<s) s = t;
193: }
194: return s;
195: }
196: err(typeer,"padicprec");
197: return 0; /* not reached */
198: }
199:
200: /* Degre de x par rapport a la variable v si v>=0, par rapport a la variable
201: * principale si v<0. On suppose x fraction rationnelle ou polynome.
202: * Convention deg(0)=-1.
203: */
204: long
205: poldegree(GEN x, long v)
206: {
207: long tx=typ(x), av, w, d;
208:
209: if (is_scalar_t(tx)) return gcmp0(x)? -1: 0;
210: switch(tx)
211: {
212: case t_POL:
213: w = varn(x);
214: if (v < 0 || v == w) return degpol(x);
215: if (v < w) return signe(x)? 0: -1;
216: av = avma; x = gsubst(gsubst(x,w,polx[MAXVARN]),v,polx[0]);
217: if (gvar(x)) { d = gcmp0(x)? -1: 0; } else d = degpol(x);
218: avma = av; return d;
219:
220: case t_RFRAC: case t_RFRACN:
221: if (gcmp0((GEN)x[1])) return -1;
222: return poldegree((GEN)x[1],v) - poldegree((GEN)x[2],v);
223: }
224: err(typeer,"degree");
225: return 0; /* not reached */
226: }
227:
228: long
229: degree(GEN x)
230: {
231: return poldegree(x,-1);
232: }
233:
234: /* si v<0, par rapport a la variable principale, sinon par rapport a v.
235: * On suppose que x est un polynome ou une serie.
236: */
237: GEN
238: pollead(GEN x, long v)
239: {
240: long l,tx = typ(x),av,tetpil,w;
241: GEN xinit;
242:
243: if (is_scalar_t(tx)) return gcopy(x);
244: w = varn(x);
245: switch(tx)
246: {
247: case t_POL:
248: if (v < 0 || v == w)
249: {
250: l=lgef(x);
251: return (l==2)? gzero: gcopy((GEN)x[l-1]);
252: }
253: if (v < w) return gcopy(x);
254: av = avma; xinit = x;
255: x = gsubst(gsubst(x,w,polx[MAXVARN]),v,polx[0]);
256: if (gvar(x)) { avma = av; return gcopy(xinit); }
257: l = lgef(x); if (l == 2) { avma = av; return gzero; }
258: tetpil = avma; x = gsubst((GEN)x[l-1],MAXVARN,polx[w]);
259: return gerepile(av,tetpil,x);
260:
261: case t_SER:
262: if (v < 0 || v == w) return (!signe(x))? gzero: gcopy((GEN)x[2]);
263: if (v < w) return gcopy(x);
264: av = avma; xinit = x;
265: x = gsubst(gsubst(x,w,polx[MAXVARN]),v,polx[0]);
266: if (gvar(x)) { avma = av; return gcopy(xinit);}
267: if (!signe(x)) { avma = av; return gzero;}
268: tetpil = avma; x = gsubst((GEN)x[2],MAXVARN,polx[w]);
269: return gerepile(av,tetpil,x);
270: }
271: err(typeer,"pollead");
272: return NULL; /* not reached */
273: }
274:
275: /* returns 1 if there's a real component in the structure, 0 otherwise */
276: int
277: isinexactreal(GEN x)
278: {
279: long tx=typ(x),lx,i;
280:
281: if (is_scalar_t(tx))
282: {
283: switch(tx)
284: {
285: case t_REAL:
286: return 1;
287:
288: case t_COMPLEX: case t_QUAD:
289: return (typ(x[1])==t_REAL || typ(x[2])==t_REAL);
290: }
291: return 0;
292: }
293: switch(tx)
294: {
295: case t_QFR: case t_QFI:
296: return 0;
297:
298: case t_RFRAC: case t_RFRACN:
299: return isinexactreal((GEN)x[1]) || isinexactreal((GEN)x[2]);
300: }
301: if (is_noncalc_t(tx)) return 0;
302: lx = (tx==t_POL)? lgef(x): lg(x);
303: for (i=lontyp[tx]; i<lx; i++)
304: if (isinexactreal((GEN)x[i])) return 1;
305: return 0;
306: }
307:
308: int
309: isexactzero(GEN g)
310: {
311: long i;
312: switch (typ(g))
313: {
314: case t_INT:
315: return !signe(g);
316: case t_REAL: case t_PADIC: case t_SER:
317: return 0;
318: case t_INTMOD: case t_POLMOD:
319: return isexactzero((GEN)g[2]);
320: case t_FRAC: case t_FRACN: case t_RFRAC: case t_RFRACN:
321: return isexactzero((GEN)g[1]);
322: case t_COMPLEX:
323: return isexactzero((GEN)g[1]) && isexactzero((GEN)g[2]);
324: case t_QUAD:
325: return isexactzero((GEN)g[2]) && isexactzero((GEN)g[3]);
326:
327: case t_POL:
328: for (i=lgef(g)-1; i>1; i--)
329: if (!isexactzero((GEN)g[i])) return 0;
330: return 1;
331: case t_VEC: case t_COL: case t_MAT:
332: for (i=lg(g)-1; i; i--)
333: if (!isexactzero((GEN)g[i])) return 0;
334: return 1;
335: }
336: return 0;
337: }
338:
339: int
340: iscomplex(GEN x)
341: {
342: switch(typ(x))
343: {
344: case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
345: return 0;
346: case t_COMPLEX:
347: return !gcmp0((GEN)x[2]);
348: case t_QUAD:
349: return signe(mael(x,1,2)) > 0;
350: }
351: err(typeer,"iscomplex");
352: return 0; /* not reached */
353: }
354:
355: int
356: ismonome(GEN x)
357: {
358: long i;
359: if (typ(x)!=t_POL || !signe(x)) return 0;
360: for (i=lgef(x)-2; i>1; i--)
361: if (!isexactzero((GEN)x[i])) return 0;
362: return 1;
363: }
364:
365: /********************************************************************/
366: /** **/
367: /** MULTIPLICATION SIMPLE **/
368: /** **/
369: /********************************************************************/
370: #define fix_frac(z) if (signe(z[2])<0)\
371: {\
372: setsigne(z[1],-signe(z[1]));\
373: setsigne(z[2],1);\
374: }
375:
376: /* assume z[1] was created last */
377: #define fix_frac_if_int(z) if (is_pm1(z[2]))\
378: z = gerepileuptoint((long)(z+3), (GEN)z[1]);
379:
380: GEN
381: gmulsg(long s, GEN y)
382: {
383: long ty=typ(y),ly=lg(y),i,av,tetpil;
384: GEN z,p1,p2;
385:
386: switch(ty)
387: {
388: case t_INT:
389: return mulsi(s,y);
390:
391: case t_REAL:
392: return mulsr(s,y);
393:
394: case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)y[1];
395: (void)new_chunk(lgefint(p2)<<2); /* HACK */
396: p1=mulsi(s,(GEN)y[2]); avma=(long)z;
397: z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
398:
399: case t_FRAC:
400: if (!s) return gzero;
401: z = cgetg(3,t_FRAC);
402: i = cgcd(s, smodis((GEN)y[2], s));
403: if (i == 1)
404: {
405: z[2] = licopy((GEN)y[2]);
406: z[1] = lmulis((GEN)y[1], s);
407: }
408: else
409: {
410: z[2] = ldivis((GEN)y[2], i);
411: z[1] = lmulis((GEN)y[1], s/i);
412: fix_frac_if_int(z);
413: }
414: return z;
415:
416: case t_FRACN: z=cgetg(3,ty);
417: z[1]=lmulsi(s,(GEN)y[1]);
418: z[2]=licopy((GEN)y[2]);
419: return z;
420:
421: case t_COMPLEX: z=cgetg(ly,ty);
422: z[1]=lmulsg(s,(GEN)y[1]);
423: z[2]=lmulsg(s,(GEN)y[2]); return z;
424:
425: case t_PADIC:
426: if (!s) return gzero;
427: av=avma; p1=cgetp(y); gaffsg(s,p1); tetpil=avma;
428: return gerepile(av,tetpil,gmul(p1,y));
429:
430: case t_QUAD: z=cgetg(ly,ty);
431: copyifstack(y[1],z[1]);
432: z[2]=lmulsg(s,(GEN)y[2]);
433: z[3]=lmulsg(s,(GEN)y[3]); return z;
434:
435: case t_POLMOD: z=cgetg(ly,ty);
436: z[2]=lmulsg(s,(GEN)y[2]);
437: copyifstack(y[1],z[1]); return z;
438:
439: case t_POL:
440: if (!s || !signe(y)) return zeropol(varn(y));
441: ly=lgef(y); z=cgetg(ly,t_POL); z[1]=y[1];
442: for (i=2; i<ly; i++) z[i]=lmulsg(s,(GEN)y[i]);
443: return normalizepol_i(z, ly);
444:
445: case t_SER:
446: if (!s) return zeropol(varn(y));
447: if (gcmp0(y)) return gcopy(y);
448: z=cgetg(ly,ty);
449: for (i=2; i<ly; i++) z[i]=lmulsg(s,(GEN)y[i]);
450: z[1]=y[1]; return normalize(z);
451:
452: case t_RFRAC:
453: if (!s) return zeropol(gvar(y));
454: z = cgetg(3, t_RFRAC);
455: i = ggcd(stoi(s),(GEN)y[2])[2];
456: avma = (long)z;
457: if (i == 1)
458: {
459: z[1]=lmulgs((GEN)y[1], s);
460: z[2]= lcopy((GEN)y[2]);
461: }
462: else
463: {
464: z[1] = lmulgs((GEN)y[1], s/i);
465: z[2] = ldivgs((GEN)y[2], i);
466: }
467: return z;
468:
469: case t_RFRACN:
470: if (!s) return zeropol(gvar(y));
471: z=cgetg(ly,t_RFRACN);
472: z[1]=lmulsg(s,(GEN)y[1]);
473: z[2]=lcopy((GEN)y[2]); return z;
474:
475: case t_VEC: case t_COL: case t_MAT:
476: z=cgetg(ly,ty);
477: for (i=1; i<ly; i++) z[i]=lmulsg(s,(GEN)y[i]);
478: return z;
479: }
480: err(typeer,"gmulsg");
481: return NULL; /* not reached */
482: }
483:
484: /********************************************************************/
485: /** **/
486: /** DIVISION SIMPLE **/
487: /** **/
488: /********************************************************************/
489:
490: GEN
491: gdivgs(GEN x, long s)
492: {
493: static long court[] = { evaltyp(t_INT) | m_evallg(3),0,0 };
494: long tx=typ(x),lx=lg(x),i,av;
495: GEN z,p1;
496:
497: if (!s) err(gdiver2);
498: switch(tx)
499: {
500: case t_INT:
501: av=avma; z=dvmdis(x,s,&p1);
502: if (p1==gzero) return z;
503:
504: i = cgcd(s, smodis(x,s));
505: avma=av; z=cgetg(3,t_FRAC);
506: if (i == 1)
507: x = icopy(x);
508: else
509: {
510: s /= i;
511: x = divis(x, i);
512: }
513: z[1]=(long)x; z[2]=lstoi(s);
514: fix_frac(z); return z;
515:
516: case t_REAL:
517: return divrs(x,s);
518:
519: case t_FRAC: z=cgetg(3,tx);
520: i = cgcd(s, smodis((GEN)x[1], s));
521: if (i == 1)
522: {
523: z[2] = lmulsi(s, (GEN)x[2]);
524: z[1] = licopy((GEN)x[1]);
525: }
526: else
527: {
528: z[2] = lmulsi(s/i, (GEN)x[2]);
529: z[1] = ldivis((GEN)x[1], i);
530: }
531: fix_frac(z);
532: fix_frac_if_int(z); return z;
533:
534: case t_FRACN: z = cgetg(3,tx);
535: z[1]=licopy((GEN)x[1]);
536: z[2]=lmulsi(s,(GEN)x[2]);
537: fix_frac(z); return z;
538:
539: case t_COMPLEX: z=cgetg(lx,tx);
540: z[1]=ldivgs((GEN)x[1],s);
541: z[2]=ldivgs((GEN)x[2],s);
542: return z;
543:
544: case t_QUAD: z=cgetg(lx,tx);
545: copyifstack(x[1],z[1]);
546: for (i=2; i<4; i++) z[i]=ldivgs((GEN)x[i],s);
547: return z;
548:
549: case t_POLMOD: z=cgetg(lx,tx);
550: copyifstack(x[1],z[1]);
551: z[2]=ldivgs((GEN)x[2],s);
552: return z;
553:
554: case t_POL: lx=lgef(x); z=cgetg(lx,tx);
555: for (i=2; i<lx; i++) z[i]=ldivgs((GEN)x[i],s);
556: z[1]=x[1]; return z;
557:
558: case t_SER: z=cgetg(lx,tx);
559: for (i=2; i<lx; i++) z[i]=ldivgs((GEN)x[i],s);
560: z[1]=x[1]; return z;
561:
562: case t_RFRAC:
563: z = cgetg(3, t_RFRAC);
564: i = ggcd(stoi(s),(GEN)x[1])[2];
565: avma = (long)z;
566: if (i == 1)
567: {
568: z[2]=lmulsg(s,(GEN)x[2]);
569: z[1]=lcopy((GEN)x[1]); return z;
570: }
571: z[1] = ldivgs((GEN)x[1], i);
572: z[2] = lmulgs((GEN)x[2], s/i); return z;
573:
574: case t_RFRACN: z=cgetg(3,t_RFRACN);
575: z[2]=lmulsg(s,(GEN)x[2]);
576: z[1]=lcopy((GEN)x[1]); return z;
577:
578: case t_VEC: case t_COL: case t_MAT: z=cgetg(lx,tx);
579: for (i=1; i<lx; i++) z[i]=ldivgs((GEN)x[i],s);
580: return z;
581: }
582: affsi(s,court); return gdiv(x,court);
583: }
584:
585: /*******************************************************************/
586: /* */
587: /* MODULO GENERAL */
588: /* */
589: /*******************************************************************/
590:
591: GEN
592: gmod(GEN x, GEN y)
593: {
594: long av,tetpil,i, tx=typ(x), ty = typ(y);
595: GEN z,p1;
596:
597: if (is_matvec_t(tx))
598: {
599: i=lg(x); z=cgetg(i,tx);
600: for (i--; i; i--) z[i]=lmod((GEN)x[i],y);
601: return z;
602: }
603: switch(ty)
604: {
605: case t_INT:
606: switch(tx)
607: {
608: case t_INT:
609: return modii(x,y);
610:
611: case t_INTMOD: z=cgetg(3,tx);
612: z[1]=lmppgcd((GEN)x[1],y);
613: z[2]=lmodii((GEN)x[2],(GEN)z[1]); return z;
614:
615: case t_FRAC: case t_FRACN:
616: av=avma; if (tx==t_FRACN) x=gred(x);
617: p1=mulii((GEN)x[1],mpinvmod((GEN)x[2],y));
618: tetpil=avma; return gerepile(av,tetpil,modii(p1,y));
619:
620: case t_QUAD: z=cgetg(4,tx);
621: copyifstack(x[1],z[1]);
622: z[2]=lmod((GEN)x[2],y);
623: z[3]=lmod((GEN)x[3],y); return z;
624:
625: case t_PADIC:
626: {
627: long p1[] = {evaltyp(t_INTMOD)|m_evallg(3),0,0};
628: p1[1] = (long)y;
629: p1[2] = lgeti(lgefint(y));
630: gaffect(x,p1); return (GEN)p1[2];
631: }
632: case t_POLMOD: case t_POL:
633: return gzero;
634:
635: default: err(operf,"%",tx,ty);
636: }
637:
638: case t_REAL: case t_FRAC: case t_FRACN:
639: switch(tx)
640: {
641: case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
642: av=avma; p1 = gfloor(gdiv(x,y)); p1 = gneg_i(gmul(p1,y));
643: tetpil=avma; return gerepile(av,tetpil,gadd(x,p1));
644:
645: case t_POLMOD: case t_POL:
646: return gzero;
647:
648: default: err(operf,"%",tx,ty);
649: }
650:
651: case t_POL:
652: if (is_scalar_t(tx))
653: {
654: if (tx!=t_POLMOD || varn(x[1]) > varn(y))
655: return (lgef(y) < 4)? gzero: gcopy(x);
656: if (varn(x[1])!=varn(y)) return gzero;
657: z=cgetg(3,t_POLMOD);
658: z[1]=lgcd((GEN)x[1],y);
659: z[2]=lres((GEN)x[2],(GEN)z[1]); return z;
660: }
661: switch(tx)
662: {
663: case t_POL:
664: return gres(x,y);
665:
666: case t_RFRAC: case t_RFRACN:
667: av=avma; if (tx==t_RFRACN) x=gred_rfrac(x);
668: p1=gmul((GEN)x[1],ginvmod((GEN)x[2],y)); tetpil=avma;
669: return gerepile(av,tetpil,gres(p1,y));
670:
671: case t_SER:
672: if (ismonome(y) && varn(x) == varn(y))
673: {
674: long d = degpol(y);
675: if (lg(x)-2 + valp(x) < d) err(operi,"%",tx,ty);
676: av = avma;
677: return gerepileupto(av, gmod(gtrunc(x), y));
678: }
679: default: err(operf,"%",tx,ty);
680: }
681: }
682: err(operf,"%",tx,ty);
683: return NULL; /* not reached */
684: }
685:
686: GEN
687: gmodulsg(long x, GEN y)
688: {
689: GEN z;
690:
691: switch(typ(y))
692: {
693: case t_INT: z=cgetg(3,t_INTMOD);
694: z[1]=labsi(y); z[2]=lmodsi(x,y); return z;
695:
696: case t_POL: z=cgetg(3,t_POLMOD);
697: z[1]=lcopy(y); z[2]=lstoi(x); return z;
698: }
699: err(operf,"%",t_INT,typ(y)); return NULL; /* not reached */
700: }
701:
702: GEN
703: gmodulss(long x, long y)
704: {
705: GEN z=cgetg(3,t_INTMOD);
706:
707: y=labs(y); z[1]=lstoi(y); z[2]=lstoi(x % y); return z;
708: }
709:
710: static GEN
711: specialmod(GEN x, GEN y)
712: {
713: GEN z = gmod(x,y);
714: if (gvar(z) < varn(y)) z = gzero;
715: return z;
716: }
717:
718: GEN
719: gmodulo(GEN x,GEN y)
720: {
721: long tx=typ(x),l,i;
722: GEN z;
723:
724: if (is_matvec_t(tx))
725: {
726: l=lg(x); z=cgetg(l,tx);
727: for (i=1; i<l; i++) z[i] = lmodulo((GEN)x[i],y);
728: return z;
729: }
730: switch(typ(y))
731: {
732: case t_INT:
733: if (tx!=t_INT && !is_frac_t(tx) && tx!=t_PADIC) break;
734: z=cgetg(3,t_INTMOD);
735: if (!signe(y)) err(talker,"zero modulus in gmodulo");
736: y = gclone(y); setsigne(y,1);
737: z[1]=(long)y;
738: z[2]=lmod(x,y); return z;
739:
740: case t_POL: z=cgetg(3,t_POLMOD);
741: z[1] = lclone(y);
742: if (is_scalar_t(tx)) { z[2]=lcopy(x); return z; }
743: if (tx!=t_POL && !is_rfrac_t(tx) && tx!=t_SER) break;
744: z[2]=(long)specialmod(x,y); return z;
745: }
746: err(operf,"%",tx,typ(y)); return NULL; /* not reached */
747: }
748:
749: GEN
750: gmodulcp(GEN x,GEN y)
751: {
752: long tx=typ(x),l,i;
753: GEN z;
754:
755: if (is_matvec_t(tx))
756: {
757: l=lg(x); z=cgetg(l,tx);
758: for (i=1; i<l; i++) z[i] = lmodulcp((GEN)x[i],y);
759: return z;
760: }
761: switch(typ(y))
762: {
763: case t_INT:
764: if (tx!=t_INT && !is_frac_t(tx) && tx!=t_PADIC) break;
765: z=cgetg(3,t_INTMOD);
766: z[1]=labsi(y);
767: z[2]=lmod(x,y); return z;
768:
769: case t_POL: z=cgetg(3,t_POLMOD);
770: z[1]=lcopy(y);
771: if (is_scalar_t(tx))
772: {
773: z[2] = (lgef(y) > 3)? lcopy(x): lmod(x,y);
774: return z;
775: }
776: if (tx!=t_POL && !is_rfrac_t(tx) && tx!=t_SER) break;
777: z[2]=(long)specialmod(x,y); return z;
778: }
779: err(operf,"%",tx,typ(y)); return NULL; /* not reached */
780: }
781:
782: GEN
783: Mod0(GEN x,GEN y,long flag)
784: {
785: switch(flag)
786: {
787: case 0: return gmodulcp(x,y);
788: case 1: return gmodulo(x,y);
789: default: err(flagerr,"Mod");
790: }
791: return NULL; /* not reached */
792: }
793:
794: /*******************************************************************/
795: /* */
796: /* DIVISION ENTIERE GENERALE */
797: /* DIVISION ENTIERE AVEC RESTE GENERALE */
798: /* */
799: /*******************************************************************/
800:
801: GEN
802: gdivent(GEN x, GEN y)
803: {
804: long tx=typ(x),ty=typ(y);
805:
806: if (tx == t_INT)
807: {
808: if (ty == t_INT) return truedvmdii(x,y,NULL);
809: if (ty!=t_POL) err(typeer,"gdivent");
810: return gzero;
811: }
812: if (ty != t_POL) err(typeer,"gdivent");
813: if (tx == t_POL) return gdeuc(x,y);
814: if (! is_scalar_t(tx)) err(typeer,"gdivent");
815: return gzero;
816: }
817:
818: GEN
819: gdiventres(GEN x, GEN y)
820: {
821: long tx=typ(x),ty=typ(y);
822: GEN z = cgetg(3,t_COL);
823:
824: if (tx==t_INT)
825: {
826: if (ty==t_INT)
827: {
828: z[1]=(long)truedvmdii(x,y,(GEN*)(z+2));
829: return z;
830: }
831: if (ty!=t_POL) err(typeer,"gdiventres");
832: z[1]=zero; z[2]=licopy(x); return z;
833: }
834: if (ty != t_POL) err(typeer,"gdiventres");
835: if (tx == t_POL)
836: {
837: z[1]=ldivres(x,y,(GEN *)(z+2));
838: return z;
839: }
840: if (! is_scalar_t(tx)) err(typeer,"gdiventres");
841: z[1]=zero; z[2]=lcopy(x); return z;
842: }
843:
844: GEN
845: gdivmod(GEN x, GEN y, GEN *pr)
846: {
847: long ty,tx=typ(x);
848:
849: if (tx==t_INT)
850: {
851: ty=typ(y);
852: if (ty==t_INT) return dvmdii(x,y,pr);
853: if (ty==t_POL) { *pr=gcopy(x); return gzero; }
854: err(typeer,"gdivmod");
855: }
856: if (tx!=t_POL) err(typeer,"gdivmod");
857: return poldivres(x,y,pr);
858: }
859:
860: /* When x and y are integers, compute the quotient x/y, rounded to the
861: * nearest integer. If there is a tie, the quotient is rounded towards zero.
862: * If x and y are not both integers, same as gdivent.
863: */
864: GEN
865: gdivround(GEN x, GEN y)
866: {
867: long tx=typ(x),ty=typ(y);
868:
869: if (tx==t_INT)
870: {
871: if (ty==t_INT)
872: {
873: long av = avma, av1,fl;
874: GEN r, q=dvmdii(x,y,&r); /* q = x/y rounded towards 0, sqn(r)=sgn(x) */
875:
876: if (r==gzero) return q;
877: av1 = avma;
878: fl = absi_cmp(shifti(r,1),y);
879: avma = av1; cgiv(r);
880: if (fl >= 0) /* If 2*|r| >= |y| */
881: {
882: long sz = signe(x)*signe(y);
883: if (fl || sz > 0)
884: { av1=avma; q = gerepile(av,av1,addis(q,sz)); }
885: }
886: return q;
887: }
888: if (ty!=t_POL) err(typeer,"gdivround");
889: return gzero;
890: }
891: if (ty != t_POL) err(typeer,"gdivround");
892: if (tx == t_POL) return gdeuc(x,y);
893: if (! is_scalar_t(tx)) err(typeer,"gdivround");
894: return gzero;
895: }
896:
897: /*******************************************************************/
898: /* */
899: /* SHIFT D'UN GEN */
900: /* */
901: /*******************************************************************/
902:
903: /* Shift tronque si n<0 (multiplication tronquee par 2^n) */
904: GEN
905: gshift(GEN x, long n)
906: {
907: long i,l,lx, tx = typ(x);
908: GEN y;
909:
910: switch(tx)
911: {
912: case t_INT:
913: return shifti(x,n);
914: case t_REAL:
915: return shiftr(x,n);
916:
917: case t_VEC: case t_COL: case t_MAT:
918: lx=lg(x); y=cgetg(lx,tx); l=lontyp[tx];
919: for (i=1; i<l ; i++) y[i]=x[i];
920: for ( ; i<lx; i++) y[i]=lshift((GEN)x[i],n);
921: return y;
922: }
923: return gmul2n(x,n);
924: }
925:
926: extern GEN mulscalrfrac(GEN x, GEN y);
927:
928: /* Shift vrai (multiplication exacte par 2^n) */
929: GEN
930: gmul2n(GEN x, long n)
931: {
932: long tx,lx,i,k,l,av,tetpil;
933: GEN p2,p1,y;
934:
935: tx=typ(x);
936: switch(tx)
937: {
938: case t_INT:
939: if (n>=0) return shifti(x,n);
940: if (!signe(x)) return gzero;
941: l = vali(x); n = -n;
942: if (n<=l) return shifti(x,-n);
943: y=cgetg(3,t_FRAC);
944: y[1]=lshifti(x,-l);
945: y[2]=lshifti(gun,n-l); return y;
946:
947: case t_REAL:
948: return shiftr(x,n);
949:
950: case t_INTMOD:
951: if (n > 0)
952: {
953: y=cgetg(3,t_INTMOD); p2=(GEN)x[1];
954: av=avma; new_chunk(2 * lgefint(p2) + n); /* HACK */
955: p1 = shifti((GEN)x[2],n); avma=av;
956: y[2]=lmodii(p1,p2); icopyifstack(p2,y[1]); return y;
957: }
958: l=avma; y=gmul2n(gun,n); tetpil=avma;
959: return gerepile(l,tetpil,gmul(y,x));
960:
961: case t_FRAC: case t_FRACN:
962: l = vali((GEN)x[1]);
963: k = vali((GEN)x[2]);
964: if (n+l-k>=0)
965: {
966: if (expi((GEN)x[2]) == k) /* x[2] power of 2 */
967: return shifti((GEN)x[1],n-k);
968: l = n-k; k = -k;
969: }
970: else
971: {
972: k = -l-n; l = -l;
973: }
974: y=cgetg(3,t_FRAC);
975: y[1]=lshifti((GEN)x[1],l);
976: y[2]=lshifti((GEN)x[2],k); return y;
977:
978: case t_QUAD: y=cgetg(4,t_QUAD);
979: copyifstack(x[1],y[1]);
980: for (i=2; i<4; i++) y[i]=lmul2n((GEN)x[i],n);
981: return y;
982:
983: case t_POLMOD: y=cgetg(3,t_POLMOD);
984: copyifstack(x[1],y[1]);
985: y[2]=lmul2n((GEN)x[2],n); return y;
986:
987: case t_POL: case t_COMPLEX: case t_SER:
988: case t_VEC: case t_COL: case t_MAT:
989: lx = (tx==t_POL)? lgef(x): lg(x);
990: y=cgetg(lx,tx); l=lontyp[tx];
991: for (i=1; i<l ; i++) y[i]=x[i];
992: for ( ; i<lx; i++) y[i]=lmul2n((GEN)x[i],n);
993: return y;
994:
995: case t_RFRAC: av=avma; p1 = gmul2n(gun,n); tetpil = avma;
996: return gerepile(av,tetpil, mulscalrfrac(p1,x));
997:
998: case t_RFRACN: y=cgetg(3,tx);
999: if (n>=0)
1000: {
1001: y[1]=lmul2n((GEN)x[1],n); y[2]=lcopy((GEN)x[2]);
1002: }
1003: else
1004: {
1005: y[2]=lmul2n((GEN)x[2],-n); y[1]=lcopy((GEN)x[1]);
1006: }
1007: return y;
1008:
1009: case t_PADIC:
1010: l=avma; y=gmul2n(gun,n); tetpil=avma;
1011: return gerepile(l,tetpil,gmul(y,x));
1012: }
1013: err(typeer,"gmul2n");
1014: return NULL; /* not reached */
1015: }
1016:
1017: /*******************************************************************/
1018: /* */
1019: /* INVERSE D'UN GEN */
1020: /* */
1021: /*******************************************************************/
1022: extern GEN fix_rfrac_if_pol(GEN x, GEN y);
1023:
1024: GEN
1025: ginv(GEN x)
1026: {
1027: long tx=typ(x),av,tetpil,s;
1028: GEN z,y,p1,p2;
1029:
1030: switch(tx)
1031: {
1032: case t_INT:
1033: if (is_pm1(x)) return icopy(x);
1034: if (!signe(x)) err(gdiver2);
1035: z=cgetg(3,t_FRAC);
1036: z[1] = (signe(x)<0)? lnegi(gun): un;
1037: z[2]=labsi(x); return z;
1038:
1039: case t_REAL:
1040: return divsr(1,x);
1041:
1042: case t_INTMOD: z=cgetg(3,t_INTMOD);
1043: icopyifstack(x[1],z[1]);
1044: z[2]=lmpinvmod((GEN)x[2],(GEN)x[1]); return z;
1045:
1046: case t_FRAC: case t_FRACN:
1047: s = signe(x[1]);
1048: if (!s) err(gdiver2);
1049: if (is_pm1(x[1]))
1050: return s>0? icopy((GEN)x[2]): negi((GEN)x[2]);
1051: z = cgetg(3,tx);
1052: z[1] = licopy((GEN)x[2]);
1053: z[2] = licopy((GEN)x[1]);
1054: if (s < 0)
1055: {
1056: setsigne(z[1],-signe(z[1]));
1057: setsigne(z[2],1);
1058: }
1059: return z;
1060:
1061: case t_COMPLEX: case t_QUAD:
1062: av=avma; p1=gnorm(x); p2=gconj(x); tetpil=avma;
1063: return gerepile(av,tetpil,gdiv(p2,p1));
1064:
1065: case t_PADIC: z = cgetg(5,t_PADIC);
1066: if (!signe(x[4])) err(gdiver2);
1067: z[1] = evalprecp(precp(x)) | evalvalp(-valp(x));
1068: icopyifstack(x[2], z[2]);
1069: z[3] = licopy((GEN)x[3]);
1070: z[4] = lmpinvmod((GEN)x[4],(GEN)z[3]); return z;
1071:
1072: case t_POLMOD: z=cgetg(3,t_POLMOD);
1073: copyifstack(x[1],z[1]);
1074: z[2]=linvmod((GEN)x[2],(GEN)x[1]); return z;
1075:
1076: case t_POL: case t_SER:
1077: return gdiv(gun,x);
1078:
1079: case t_RFRAC: case t_RFRACN:
1080: if (gcmp0((GEN) x[1])) err(gdiver2);
1081: p1 = fix_rfrac_if_pol((GEN)x[2],(GEN)x[1]);
1082: if (p1) return p1;
1083: z=cgetg(3,tx);
1084: z[1]=lcopy((GEN)x[2]);
1085: z[2]=lcopy((GEN)x[1]); return z;
1086:
1087: case t_QFR:
1088: {
1089: long k,l;
1090: l=signe(x[2]); setsigne(x[2],-l);
1091: k=signe(x[4]); setsigne(x[4],-k); z=redreal(x);
1092: setsigne(x[2],l); setsigne(x[4],k); return z;
1093: }
1094: case t_QFI:
1095: y=gcopy(x);
1096: if (!egalii((GEN)x[1],(GEN)x[2]) && !egalii((GEN)x[1],(GEN)x[3]))
1097: setsigne(y[2],-signe(y[2]));
1098: return y;
1099: case t_MAT:
1100: return (lg(x)==1)? cgetg(1,t_MAT): invmat(x);
1101: }
1102: err(typeer,"inverse");
1103: return NULL; /* not reached */
1104: }
1105:
1106: /*******************************************************************/
1107: /* */
1108: /* SUBSTITUTION DANS UN POLYNOME OU UNE SERIE */
1109: /* */
1110: /*******************************************************************/
1111:
1112: /* Convert t_SER --> t_POL / t_RFRAC */
1113: static GEN
1114: gconvsp(GEN x, int flpile)
1115: {
1116: long v = varn(x), av,tetpil,i;
1117: GEN p1,y;
1118:
1119: if (gcmp0(x)) return zeropol(v);
1120: av=avma; y=dummycopy(x); settyp(y,t_POL);
1121: i=lg(x)-1; while (i>1 && gcmp0((GEN)y[i])) i--;
1122: setlgef(y,i+1);
1123: p1=gpuigs(polx[v],valp(x));
1124: tetpil=avma; p1=gmul(p1,y);
1125: return flpile? gerepile(av,tetpil,p1): p1;
1126: }
1127:
1128: GEN
1129: gsubst0(GEN x, GEN T, GEN y)
1130: {
1131: ulong av;
1132: long d, v;
1133: if (typ(T) != t_POL || !ismonome(T) || !gcmp1(leading_term(T)))
1134: err(talker,"variable number expected in subst");
1135: d = degpol(T); v = varn(T);
1136: if (d == 1) return gsubst(x, v, y);
1137: av = avma;
1138: return gerepilecopy(av, gsubst(gdeflate(x, v, d), v, y));
1139: }
1140:
1141: GEN
1142: gsubst(GEN x, long v, GEN y)
1143: {
1144: long tx = typ(x), ty = typ(y), lx = lg(x), ly = lg(y);
1145: long l,vx,vy,e,ex,ey,tetpil,av,i,j,k,jb,limite;
1146: GEN t,p1,p2,z;
1147:
1148: if (ty==t_MAT)
1149: {
1150: if (ly==1) return cgetg(1,t_MAT);
1151: if (ly != lg(y[1]))
1152: err(talker,"forbidden substitution by a non square matrix");
1153: } else if (is_graphicvec_t(ty))
1154: err(talker,"forbidden substitution by a vector");
1155:
1156: if (is_scalar_t(tx))
1157: {
1158: if (tx!=t_POLMOD || v <= varn(x[1]))
1159: {
1160: if (ty==t_MAT) return gscalmat(x,ly-1);
1161: return gcopy(x);
1162: }
1163: av=avma;
1164: p1=gsubst((GEN)x[1],v,y); vx=varn(p1);
1165: p2=gsubst((GEN)x[2],v,y); vy=gvar(p2);
1166: if (typ(p1)!=t_POL)
1167: err(talker,"forbidden substitution in a scalar type");
1168: if (vy>=vx)
1169: {
1170: tetpil=avma;
1171: return gerepile(av,tetpil,gmodulcp(p2,p1));
1172: }
1173: lx=lgef(p2); tetpil=avma; z=cgetg(lx,t_POL); z[1]=p2[1];
1174: for (i=2; i<lx; i++) z[i]=lmodulcp((GEN)p2[i],p1);
1175: return gerepile(av,tetpil, normalizepol_i(z,lx));
1176: }
1177:
1178: switch(tx)
1179: {
1180: case t_POL:
1181: l=lgef(x);
1182: if (l==2)
1183: return (ty==t_MAT)? gscalmat(gzero,ly-1): gzero;
1184:
1185: vx=varn(x);
1186: if (vx<v)
1187: {
1188: av=avma; p1=polx[vx]; z= gsubst((GEN)x[l-1],v,y);
1189: for (i=l-1; i>2; i--) z=gadd(gmul(z,p1),gsubst((GEN)x[i-1],v,y));
1190: return gerepileupto(av,z);
1191: }
1192: if (ty!=t_MAT)
1193: return (vx>v)? gcopy(x): poleval(x,y);
1194:
1195: if (vx>v) return gscalmat(x,ly-1);
1196: if (l==3) return gscalmat((GEN)x[2],ly-1);
1197: av=avma; z=(GEN)x[l-1];
1198: for (i=l-1; i>2; i--) z=gaddmat((GEN)x[i-1],gmul(z,y));
1199: return gerepileupto(av,z);
1200:
1201: case t_SER:
1202: vx=varn(x);
1203: if (vx > v)
1204: return (ty==t_MAT)? gscalmat(x,ly-1): gcopy(x);
1205: ex = valp(x);
1206: if (vx < v)
1207: {
1208: if (!signe(x)) return gcopy(x);
1209: /* a ameliorer */
1210: av=avma; setvalp(x,0); p1=gconvsp(x,0); setvalp(x,ex);
1211: p2=gsubst(p1,v,y); tetpil=avma; z=tayl(p2,vx,lx-2);
1212: if (ex)
1213: {
1214: p1=gpuigs(polx[vx],ex); tetpil=avma; z=gmul(z,p1);
1215: }
1216: return gerepile(av,tetpil,z);
1217: }
1218: switch(ty) /* here vx == v */
1219: {
1220: case t_SER:
1221: ey=valp(y); vy=varn(y);
1222: if (ey<1) return zeroser(vy,ey*(ex+lx-2));
1223: l=(lx-2)*ey+2;
1224: if (ex) { if (l>ly) l=ly; }
1225: else
1226: {
1227: if (gcmp0(y)) l=ey+2;
1228: else { if (l>ly) l=ey+ly; }
1229: }
1230: if (vy!=vx)
1231: {
1232: av=avma; z = zeroser(vy,0);
1233: for (i=lx-1; i>=2; i--)
1234: z = gadd((GEN)x[i], gmul(y,z));
1235: if (ex) z = gmul(z, gpuigs(y,ex));
1236: return gerepileupto(av,z);
1237: }
1238:
1239: av=avma; limite=stack_lim(av,1);
1240: t=cgetg(ly,t_SER);
1241: z = scalarser((GEN)x[2],varn(y),l-2);
1242: for (i=2; i<ly; i++) t[i]=y[i];
1243:
1244: for (i=3,jb=ey; jb<=l-2; i++,jb+=ey)
1245: {
1246: for (j=jb+2; j<l; j++)
1247: {
1248: p1=gmul((GEN)x[i],(GEN)t[j-jb]);
1249: z[j]=ladd((GEN)z[j],p1);
1250: }
1251: for (j=l-1-jb-ey; j>1; j--)
1252: {
1253: p1=gzero;
1254: for (k=2; k<j; k++)
1255: p1=gadd(p1,gmul((GEN)t[j-k+2],(GEN)y[k]));
1256: p2=gmul((GEN)t[2],(GEN)y[j]);
1257: t[j]=ladd(p1,p2);
1258: }
1259: if (low_stack(limite, stack_lim(av,1)))
1260: {
1261: GEN *gptr[2];
1262: if(DEBUGMEM>1) err(warnmem,"gsubst");
1263: gptr[0]=&z; gptr[1]=&t; gerepilemany(av,gptr,2);
1264: }
1265: }
1266: if (!ex) return gerepilecopy(av,z);
1267:
1268: if (l<ly) { setlg(y,l); p1=gpuigs(y,ex); setlg(y,ly); }
1269: else p1=gpuigs(y,ex);
1270: tetpil=avma; return gerepile(av,tetpil,gmul(z,p1));
1271:
1272: case t_POL: case t_RFRAC: case t_RFRACN:
1273: if (isexactzero(y)) return scalarser((GEN)x[2],v,lx-2);
1274: vy=gvar(y); e=gval(y,vy);
1275: if (e<=0)
1276: err(talker,"non positive valuation in a series substitution");
1277: av=avma; p1=gconvsp(x,0); p2=gsubst(p1,v,y); tetpil=avma;
1278: return gerepile(av,tetpil,tayl(p2,vy,e*(lx-2+ex)));
1279:
1280: default:
1281: err(talker,"non polynomial or series type substituted in a series");
1282: }
1283: break;
1284:
1285: case t_RFRAC: case t_RFRACN: av=avma;
1286: p1=gsubst((GEN)x[1],v,y);
1287: p2=gsubst((GEN)x[2],v,y); tetpil=avma;
1288: return gerepile(av,tetpil,gdiv(p1,p2));
1289:
1290: case t_VEC: case t_COL: case t_MAT: z=cgetg(lx,tx);
1291: for (i=1; i<lx; i++) z[i]=lsubst((GEN)x[i],v,y);
1292: }
1293: return z;
1294: }
1295:
1296: /*******************************************************************/
1297: /* */
1298: /* SERIE RECIPROQUE D'UNE SERIE */
1299: /* */
1300: /*******************************************************************/
1301:
1302: GEN
1303: recip(GEN x)
1304: {
1305: long tetpil, av=avma, v=varn(x);
1306: GEN p1,p2,a,y,u;
1307:
1308: if (typ(x)!=t_SER) err(talker,"not a series in serreverse");
1309: if (valp(x)!=1) err(talker,"valuation not equal to 1 in serreverse");
1310:
1311: a=(GEN)x[2];
1312: if (gcmp1(a))
1313: {
1314: long i,j,k, lx=lg(x), lim=stack_lim(av,2);
1315:
1316: u=cgetg(lx,t_SER); y=cgetg(lx,t_SER);
1317: u[1]=y[1]=evalsigne(1) | evalvalp(1) | evalvarn(v);
1318: u[2]=un; u[3]=lmulsg(-2,(GEN)x[3]);
1319: y[2]=un; y[3]=lneg((GEN)x[3]);
1320: for (i=3; i<lx-1; )
1321: {
1322: for (j=3; j<i+1; j++)
1323: {
1324: p1=(GEN)u[j];
1325: for (k=j-1; k>2; k--)
1326: p1=gsub(p1,gmul((GEN)u[k],(GEN)x[j-k+2]));
1327: u[j]=lsub(p1,(GEN)x[j]);
1328: }
1329: p1=gmulsg(i,(GEN)x[i+1]);
1330: for (k=2; k<i; k++)
1331: {
1332: p2=gmul((GEN)x[k+1],(GEN)u[i-k+2]);
1333: p1=gadd(p1,gmulsg(k,p2));
1334: }
1335: i++; u[i]=lneg(p1); y[i]=ldivgs((GEN)u[i],i-1);
1336: if (low_stack(lim, stack_lim(av,2)))
1337: {
1338: GEN *gptr[2];
1339: if(DEBUGMEM>1) err(warnmem,"recip");
1340: for(k=i+1; k<lx; k++) u[k]=y[k]=zero; /* dummy */
1341: gptr[0]=&u; gptr[1]=&y; gerepilemany(av,gptr,2);
1342: }
1343: }
1344: return gerepilecopy(av,y);
1345: }
1346: y=gdiv(x,a); y[2]=un; y=recip(y);
1347: a=gdiv(polx[v],a); tetpil=avma;
1348: return gerepile(av,tetpil,gsubst(y,v,a));
1349: }
1350:
1351: /*******************************************************************/
1352: /* */
1353: /* DERIVATION ET INTEGRATION */
1354: /* */
1355: /*******************************************************************/
1356: GEN
1357: derivpol(GEN x)
1358: {
1359: long i,lx = lgef(x)-1;
1360: GEN y;
1361:
1362: if (lx<3) return gzero;
1363: y = cgetg(lx,t_POL);
1364: for (i=2; i<lx ; i++) y[i] = lmulsg(i-1,(GEN)x[i+1]);
1365: y[1] = x[1]; return normalizepol_i(y,i);
1366: }
1367:
1368: GEN
1369: derivser(GEN x)
1370: {
1371: long i,j,vx = varn(x), e = valp(x), lx = lg(x);
1372: GEN y;
1373: if (gcmp0(x)) return zeroser(vx,e-1);
1374: if (e)
1375: {
1376: y=cgetg(lx,t_SER); y[1] = evalsigne(1) | evalvalp(e-1) | evalvarn(vx);
1377: for (i=2; i<lx; i++) y[i]=lmulsg(i+e-2,(GEN)x[i]);
1378: return y;
1379: }
1380: i=3; while (i<lx && gcmp0((GEN)x[i])) i++;
1381: if (i==lx) return zeroser(vx,lx-3);
1382: lx--; if (lx<3) lx=3;
1383: lx = lx-i+3; y=cgetg(lx,t_SER);
1384: y[1]=evalsigne(1) | evalvalp(i-3) | evalvarn(vx);
1385: for (j=2; j<lx; j++) y[j]=lmulsg(j+i-4,(GEN)x[i+j-2]);
1386: return y;
1387: }
1388:
1389: GEN
1390: deriv(GEN x, long v)
1391: {
1392: long lx,vx,tx,e,i,j,l,av,tetpil;
1393: GEN y,p1,p2;
1394:
1395: tx=typ(x); if (is_const_t(tx)) return gzero;
1396: if (v < 0) v = gvar(x);
1397: switch(tx)
1398: {
1399: case t_POLMOD:
1400: if (v<=varn(x[1])) return gzero;
1401: y=cgetg(3,t_POLMOD); copyifstack(x[1],y[1]);
1402: y[2]=lderiv((GEN)x[2],v); return y;
1403:
1404: case t_POL:
1405: vx=varn(x); if (vx>v) return gzero;
1406: if (vx<v)
1407: {
1408: lx = lgef(x);
1409: y = cgetg(lx,t_POL);
1410: for (i=2; i<lx; i++) y[i] = lderiv((GEN)x[i],v);
1411: y[1] = evalvarn(vx);
1412: return normalizepol_i(y,i);
1413: }
1414: return derivpol(x);
1415:
1416: case t_SER:
1417: vx=varn(x); if (vx>v) return gzero;
1418: if (vx<v)
1419: {
1420: if (!signe(x)) return gcopy(x);
1421: lx=lg(x); e=valp(x);
1422: l=avma;
1423: for (i=2; i<lx; i++)
1424: {
1425: if (!gcmp0(deriv((GEN)x[i],v))) break;
1426: avma=l;
1427: }
1428: if (i==lx) return ggrando(polx[vx],e+lx-2);
1429: y=cgetg(lx-i+2,t_SER);
1430: y[1] = evalsigne(1) | evalvalp(e+i-2) | evalvarn(vx);
1431: for (j=2; i<lx; j++,i++) y[j]=lderiv((GEN)x[i],v);
1432: return y;
1433: }
1434: return derivser(x);
1435:
1436: case t_RFRAC: case t_RFRACN: av=avma; y=cgetg(3,tx);
1437: y[2]=lsqr((GEN)x[2]); l=avma;
1438: p1=gmul((GEN)x[2],deriv((GEN)x[1],v));
1439: p2=gmul(gneg_i((GEN)x[1]),deriv((GEN)x[2],v));
1440: tetpil=avma; p1=gadd(p1,p2);
1441: if (tx==t_RFRACN) { y[1]=lpile(l,tetpil,p1); return y; }
1442: y[1]=(long)p1; return gerepileupto(av,gred_rfrac(y));
1443:
1444: case t_VEC: case t_COL: case t_MAT: lx=lg(x); y=cgetg(lx,tx);
1445: for (i=1; i<lx; i++) y[i]=lderiv((GEN)x[i],v);
1446: return y;
1447: }
1448: err(typeer,"deriv");
1449: return NULL; /* not reached */
1450: }
1451:
1452: /*******************************************************************/
1453: /* */
1454: /* INTEGRATION FORMELLE */
1455: /* */
1456: /*******************************************************************/
1457:
1458: static GEN
1459: triv_integ(GEN x, long v, long tx, long lx)
1460: {
1461: GEN y=cgetg(lx,tx);
1462: long i;
1463:
1464: y[1]=x[1];
1465: for (i=2; i<lx; i++) y[i]=linteg((GEN)x[i],v);
1466: return y;
1467: }
1468:
1469: GEN
1470: integ(GEN x, long v)
1471: {
1472: long lx,tx,e,i,j,vx,n,av=avma,tetpil;
1473: GEN y,p1;
1474:
1475: tx = typ(x);
1476: if (v < 0) v = gvar(x);
1477: if (is_scalar_t(tx))
1478: {
1479: if (tx == t_POLMOD && v>varn(x[1]))
1480: {
1481: y=cgetg(3,t_POLMOD); copyifstack(x[1],y[1]);
1482: y[2]=linteg((GEN)x[2],v); return y;
1483: }
1484: if (gcmp0(x)) return gzero;
1485:
1486: y=cgetg(4,t_POL); y[1] = evalsigne(1) | evallgef(4) | evalvarn(v);
1487: y[2]=zero; y[3]=lcopy(x); return y;
1488: }
1489:
1490: switch(tx)
1491: {
1492: case t_POL:
1493: vx=varn(x); lx=lgef(x);
1494: if (lx==2) return zeropol(min(v,vx));
1495: if (vx>v)
1496: {
1497: y=cgetg(4,t_POL);
1498: y[1] = signe(x)? evallgef(4) | evalvarn(v) | evalsigne(1)
1499: : evallgef(4) | evalvarn(v);
1500: y[2]=zero; y[3]=lcopy(x); return y;
1501: }
1502: if (vx<v) return triv_integ(x,v,tx,lx);
1503: y=cgetg(lx+1,tx); y[2]=zero;
1504: for (i=3; i<=lx; i++)
1505: y[i]=ldivgs((GEN)x[i-1],i-2);
1506: y[1] = signe(x)? evallgef(lx+1) | evalvarn(v) | evalsigne(1)
1507: : evallgef(lx+1) | evalvarn(v);
1508: return y;
1509:
1510: case t_SER:
1511: lx=lg(x); e=valp(x); vx=varn(x);
1512: if (!signe(x))
1513: {
1514: if (vx == v) e++; else if (vx < v) v = vx;
1515: return zeroser(v,e);
1516: }
1517: if (vx>v)
1518: {
1519: y=cgetg(4,t_POL);
1520: y[1] = evallgef(4) | evalvarn(v) | evalsigne(1);
1521: y[2]=zero; y[3]=lcopy(x); return y;
1522: }
1523: if (vx<v) return triv_integ(x,v,tx,lx);
1524: y=cgetg(lx,tx);
1525: for (i=2; i<lx; i++)
1526: {
1527: j=i+e-1;
1528: if (!j)
1529: {
1530: if (!gcmp0((GEN)x[i])) err(inter2);
1531: y[i]=zero;
1532: }
1533: else y[i] = ldivgs((GEN)x[i],j);
1534: }
1535: y[1]=x[1]+1; return y;
1536:
1537: case t_RFRAC: case t_RFRACN:
1538: vx = gvar(x);
1539: if (vx>v)
1540: {
1541: y=cgetg(4,t_POL);
1542: y[1] = signe(x[1])? evallgef(4) | evalvarn(v) | evalsigne(1)
1543: : evallgef(4) | evalvarn(v);
1544: y[2]=zero; y[3]=lcopy(x); return y;
1545: }
1546: if (vx<v)
1547: {
1548: p1=cgetg(v+2,t_VEC);
1549: for (i=0; i<vx; i++) p1[i+1] = lpolx[i];
1550: for (i=vx+1; i<v; i++) p1[i+1] = lpolx[i];
1551: p1[v+1] = lpolx[vx]; p1[vx+1] = lpolx[v];
1552: y=integ(changevar(x,p1),vx); tetpil=avma;
1553: return gerepile(av,tetpil,changevar(y,p1));
1554: }
1555:
1556: tx = typ(x[1]); i = is_scalar_t(tx)? 0: degpol(x[1]);
1557: tx = typ(x[2]); j = is_scalar_t(tx)? 0: degpol(x[2]);
1558: n = i+j + 2;
1559: y = gdiv(gtrunc(gmul((GEN)x[2], integ(tayl(x,v,n),v))), (GEN)x[2]);
1560: if (!gegal(deriv(y,v),x)) err(inter2);
1561: if (typ(y)==t_RFRAC && lgef(y[1]) == lgef(y[2]))
1562: {
1563: GEN p2;
1564: tx=typ(y[1]); p1=is_scalar_t(tx)? (GEN)y[1]: leading_term(y[1]);
1565: tx=typ(y[2]); p2=is_scalar_t(tx)? (GEN)y[2]: leading_term(y[2]);
1566: y=gsub(y, gdiv(p1,p2));
1567: }
1568: return gerepileupto(av,y);
1569:
1570: case t_VEC: case t_COL: case t_MAT:
1571: lx=lg(x); y=cgetg(lx,tx);
1572: for (i=1; i<lg(x); i++) y[i]=linteg((GEN)x[i],v);
1573: return y;
1574: }
1575: err(typeer,"integ");
1576: return NULL; /* not reached */
1577: }
1578:
1579: /*******************************************************************/
1580: /* */
1581: /* PARTIES ENTIERES */
1582: /* */
1583: /*******************************************************************/
1584:
1585: GEN
1586: gfloor(GEN x)
1587: {
1588: GEN y;
1589: long i,lx, tx = typ(x);
1590:
1591: switch(tx)
1592: {
1593: case t_INT: case t_POL:
1594: return gcopy(x);
1595:
1596: case t_REAL:
1597: return mpent(x);
1598:
1599: case t_FRAC: case t_FRACN:
1600: return truedvmdii((GEN)x[1],(GEN)x[2],NULL);
1601:
1602: case t_RFRAC: case t_RFRACN:
1603: return gdeuc((GEN)x[1],(GEN)x[2]);
1604:
1605: case t_VEC: case t_COL: case t_MAT:
1606: lx=lg(x); y=cgetg(lx,tx);
1607: for (i=1; i<lx; i++) y[i]=lfloor((GEN)x[i]);
1608: return y;
1609: }
1610: err(typeer,"gfloor");
1611: return NULL; /* not reached */
1612: }
1613:
1614: GEN
1615: gfrac(GEN x)
1616: {
1617: long av = avma,tetpil;
1618: GEN p1 = gneg_i(gfloor(x));
1619:
1620: tetpil=avma; return gerepile(av,tetpil,gadd(x,p1));
1621: }
1622:
1623: GEN
1624: gceil(GEN x)
1625: {
1626: GEN y,p1;
1627: long i,lx,tx=typ(x),av,tetpil;
1628:
1629: switch(tx)
1630: {
1631: case t_INT: case t_POL:
1632: return gcopy(x);
1633:
1634: case t_REAL:
1635: av=avma; y=mpent(x);
1636: if (!gegal(x,y))
1637: {
1638: tetpil=avma; return gerepile(av,tetpil,addsi(1,y));
1639: }
1640: return y;
1641:
1642: case t_FRAC: case t_FRACN:
1643: av=avma; y=dvmdii((GEN)x[1],(GEN)x[2],&p1);
1644: if (p1 != gzero && gsigne(x)>0)
1645: {
1646: cgiv(p1); tetpil=avma;
1647: return gerepile(av,tetpil,addsi(1,y));
1648: }
1649: return y;
1650:
1651: case t_RFRAC: case t_RFRACN:
1652: return gdeuc((GEN)x[1],(GEN)x[2]);
1653:
1654: case t_VEC: case t_COL: case t_MAT:
1655: lx=lg(x); y=cgetg(lx,tx);
1656: for (i=1; i<lx; i++) y[i]=lceil((GEN)x[i]);
1657: return y;
1658: }
1659: err(typeer,"gceil");
1660: return NULL; /* not reached */
1661: }
1662:
1663: GEN
1664: round0(GEN x, GEN *pte)
1665: {
1666: if (pte) { long e; x = grndtoi(x,&e); *pte = stoi(e); }
1667: return ground(x);
1668: }
1669:
1670: GEN
1671: ground(GEN x)
1672: {
1673: GEN y,p1;
1674: long i,lx,tx=typ(x),av,tetpil;
1675:
1676: switch(tx)
1677: {
1678: case t_INT: case t_INTMOD: case t_QUAD:
1679: return gcopy(x);
1680:
1681: case t_REAL:
1682: {
1683: long ex, s = signe(x);
1684: if (s==0 || (ex=expo(x)) < -1) return gzero;
1685: if (ex < 0) return s>0? gun: negi(gun);
1686: av=avma; p1 = realun(3 + (ex>>TWOPOTBITS_IN_LONG));
1687: setexpo(p1,-1); /* p1 = 0.5 */
1688: p1 = addrr(x,p1); tetpil = avma;
1689: return gerepile(av,tetpil,mpent(p1));
1690: }
1691: case t_FRAC: case t_FRACN:
1692: av=avma; p1 = addii(shifti((GEN)x[2], -1), (GEN)x[1]);
1693: return gerepileuptoint(av, truedvmdii(p1, (GEN)x[2], NULL));
1694:
1695: case t_POLMOD: y=cgetg(3,t_POLMOD);
1696: copyifstack(x[1],y[1]);
1697: y[2]=lround((GEN)x[2]); return y;
1698:
1699: case t_COMPLEX: case t_POL: case t_SER: case t_RFRAC: case t_RFRACN:
1700: case t_VEC: case t_COL: case t_MAT:
1701: lx = (tx==t_POL)? lgef(x): lg(x);
1702: y=cgetg(lx,tx);
1703: for (i=1; i<lontyp[tx]; i++) y[i]=x[i];
1704: for ( ; i<lx; i++) y[i]=lround((GEN)x[i]);
1705: if (tx==t_POL) return normalizepol_i(y, lx);
1706: if (tx==t_SER) return normalize(y);
1707: return y;
1708: }
1709: err(typeer,"ground");
1710: return NULL; /* not reached */
1711: }
1712:
1713: /* e = number of error bits on integral part */
1714: GEN
1715: grndtoi(GEN x, long *e)
1716: {
1717: GEN y,p1;
1718: long i,tx=typ(x), lx,av,ex,e1;
1719:
1720: *e = -HIGHEXPOBIT;
1721: switch(tx)
1722: {
1723: case t_INT: case t_INTMOD: case t_QUAD:
1724: case t_FRAC: case t_FRACN:
1725: return ground(x);
1726:
1727: case t_REAL:
1728: av=avma; p1=gadd(ghalf,x); ex=expo(p1);
1729: if (ex<0)
1730: {
1731: if (signe(p1)>=0) { *e=expo(x); avma=av; return gzero; }
1732: *e=expo(addsr(1,x)); avma=av; return negi(gun);
1733: }
1734: lx=lg(x); e1 = ex - bit_accuracy(lx) + 1;
1735: settyp(p1,t_INT); setlgefint(p1,lx);
1736: y=shifti(p1,e1); if (signe(x)<0) y=addsi(-1,y);
1737: y = gerepileupto(av,y);
1738:
1739: if (e1<=0) { av=avma; e1=expo(subri(x,y)); avma=av; }
1740: *e=e1; return y;
1741:
1742: case t_POLMOD: y=cgetg(3,t_POLMOD);
1743: copyifstack(x[1],y[1]);
1744: y[2]=lrndtoi((GEN)x[2],e); return y;
1745:
1746: case t_COMPLEX: case t_POL: case t_SER: case t_RFRAC: case t_RFRACN:
1747: case t_VEC: case t_COL: case t_MAT:
1748: lx=(tx==t_POL)? lgef(x): lg(x);
1749: y=cgetg(lx,tx);
1750: for (i=1; i<lontyp[tx]; i++) y[i]=x[i];
1751: for ( ; i<lx; i++)
1752: {
1753: y[i]=lrndtoi((GEN)x[i],&e1);
1754: if (e1>*e) *e=e1;
1755: }
1756: return y;
1757: }
1758: err(typeer,"grndtoi");
1759: return NULL; /* not reached */
1760: }
1761:
1762: /* e = number of error bits on integral part */
1763: GEN
1764: gcvtoi(GEN x, long *e)
1765: {
1766: long tx=typ(x), lx,i,ex,av,e1;
1767: GEN y;
1768:
1769: *e = -HIGHEXPOBIT;
1770: if (tx == t_REAL)
1771: {
1772: long x0,x1;
1773: ex=expo(x); if (ex<0) { *e=ex; return gzero; }
1774: lx=lg(x); e1 = ex - bit_accuracy(lx) + 1;
1775: x0=x[0]; x1=x[1]; settyp(x,t_INT); setlgefint(x,lx);
1776: y=shifti(x,e1); x[0]=x0; x[1]=x1;
1777: if (e1<=0) { av=avma; e1=expo(subri(x,y)); avma=av; }
1778: *e=e1; return y;
1779: }
1780: if (is_matvec_t(tx))
1781: {
1782: lx=lg(x); y=cgetg(lx,tx);
1783: for (i=1; i<lx; i++)
1784: {
1785: y[i]=lcvtoi((GEN)x[i],&e1);
1786: if (e1>*e) *e=e1;
1787: }
1788: return y;
1789: }
1790: return gtrunc(x);
1791: }
1792:
1793: /* smallest integer greater than any incarnations of the real x
1794: * [avoid mpent() and "precision loss in truncation"] */
1795: GEN
1796: ceil_safe(GEN x)
1797: {
1798: ulong av = avma;
1799: long e;
1800: GEN y = gcvtoi(x,&e);
1801: if (e < 0) e = 0;
1802: y = addii(y, shifti(gun,e));
1803: return gerepileuptoint(av, y);
1804: }
1805:
1806: GEN
1807: gtrunc(GEN x)
1808: {
1809: long tx=typ(x),av,tetpil,i,v;
1810: GEN y;
1811:
1812: switch(tx)
1813: {
1814: case t_INT: case t_POL:
1815: return gcopy(x);
1816:
1817: case t_REAL:
1818: return mptrunc(x);
1819:
1820: case t_FRAC: case t_FRACN:
1821: return divii((GEN)x[1],(GEN)x[2]);
1822:
1823: case t_PADIC:
1824: if (!signe(x[4])) return gzero;
1825: v = valp(x);
1826: if (!v) return gcopy((GEN)x[4]);
1827: if (v>0)
1828: { /* here p^v is an integer */
1829: av=avma; y=gpuigs((GEN)x[2],v); tetpil=avma;
1830: return gerepile(av,tetpil, mulii(y,(GEN)x[4]));
1831: }
1832: y=cgetg(3,t_FRAC);
1833: y[1]=licopy((GEN)x[4]);
1834: y[2]=lpuigs((GEN)x[2],-v);
1835: return y;
1836:
1837: case t_RFRAC: case t_RFRACN:
1838: return gdeuc((GEN)x[1],(GEN)x[2]);
1839:
1840: case t_SER:
1841: return gconvsp(x,1);
1842:
1843: case t_VEC: case t_COL: case t_MAT:
1844: {
1845: long lx=lg(x);
1846:
1847: y=cgetg(lx,tx);
1848: for (i=1; i<lx; i++) y[i]=ltrunc((GEN)x[i]);
1849: return y;
1850: }
1851: }
1852: err(typeer,"gtrunc");
1853: return NULL; /* not reached */
1854: }
1855:
1856: GEN
1857: trunc0(GEN x, GEN *pte)
1858: {
1859: if (pte) { long e; x = gcvtoi(x,&e); *pte = stoi(e); }
1860: return gtrunc(x);
1861: }
1862:
1863: /*******************************************************************/
1864: /* */
1865: /* CONVERSIONS --> INT, POL & SER */
1866: /* */
1867: /*******************************************************************/
1868:
1869: /* return a_n B^n + ... + a_0, where B = 2^BIL. Assume n even if BIL=64 and
1870: * the a_i are 32bits integers, one of which is non-zero */
1871: GEN
1872: coefs_to_int(long n, ...)
1873: {
1874: va_list ap;
1875: GEN x, y;
1876: long i;
1877: va_start(ap,n);
1878: #ifdef LONG_IS_64BIT
1879: n >>= 1;
1880: #endif
1881: x = cgetg(n+2, t_INT); y = x + 2;
1882: x[1] = evallgefint(n+2) | evalsigne(1);
1883: for (i=0; i <n; i++)
1884: {
1885: #ifdef LONG_IS_64BIT
1886: ulong a = va_arg(ap, long);
1887: ulong b = va_arg(ap, long);
1888: y[i] = (a << 32) | b;
1889: #else
1890: y[i] = va_arg(ap, long);
1891: #endif
1892: }
1893: return x;
1894: }
1895:
1896: /* 2^32 a + b */
1897: GEN
1898: u2toi(ulong a, ulong b)
1899: {
1900: GEN x;
1901: if (!a && !b) return gzero;
1902: #ifdef LONG_IS_64BIT
1903: x = cgetg(3, t_INT);
1904: x[1] = evallgefint(3)|evalsigne(1);
1905: x[2] = (a << 32) | b;
1906: #else
1907: x = cgetg(4, t_INT);
1908: x[1] = evallgefint(4)|evalsigne(1);
1909: x[2] = a;
1910: x[3] = b;
1911: #endif
1912: return x;
1913: }
1914:
1915: /* return a_(n-1) x^(n-1) + ... + a_0 */
1916: GEN
1917: coefs_to_pol(long n, ...)
1918: {
1919: va_list ap;
1920: GEN x, y;
1921: long i;
1922: va_start(ap,n);
1923: x = cgetg(n+2, t_POL); y = x + 2;
1924: x[1] = evallgef(n+2) | evalvarn(0);
1925: for (i=n-1; i >= 0; i--) y[i] = (long) va_arg(ap, GEN);
1926: return normalizepol(x);
1927: }
1928:
1929: GEN
1930: zeropol(long v)
1931: {
1932: GEN x = cgetg(2,t_POL);
1933: x[1] = evallgef(2) | evalvarn(v); return x;
1934: }
1935:
1936: GEN
1937: scalarpol(GEN x, long v)
1938: {
1939: GEN y=cgetg(3,t_POL);
1940: y[1] = gcmp0(x)? evallgef(3) | evalvarn(v)
1941: : evallgef(3) | evalvarn(v) | evalsigne(1);
1942: y[2]=lcopy(x); return y;
1943: }
1944:
1945: /* deg1pol(a,b,x)=a*x+b*/
1946: GEN
1947: deg1pol(GEN x1, GEN x0,long v)
1948: {
1949: GEN x = cgetg(4,t_POL);
1950: x[1] = evalsigne(1) | evalvarn(v) | evallgef(4);
1951: x[2] = lcopy(x0); x[3] = lcopy(x1); return normalizepol_i(x,4);
1952: }
1953:
1954: /* same, no copy */
1955: GEN
1956: deg1pol_i(GEN x1, GEN x0,long v)
1957: {
1958: GEN x = cgetg(4,t_POL);
1959: x[1] = evalsigne(1) | evalvarn(v) | evallgef(4);
1960: x[2] = (long)x0; x[3] = (long)x1; return normalizepol_i(x,4);
1961: }
1962:
1963: static GEN
1964: gtopoly0(GEN x, long v, int reverse)
1965: {
1966: long tx=typ(x),lx,i,j;
1967: GEN y;
1968:
1969: if (v<0) v = 0;
1970: if (isexactzero(x)) return zeropol(v);
1971: if (is_scalar_t(tx)) return scalarpol(x,v);
1972:
1973: switch(tx)
1974: {
1975: case t_POL:
1976: y=gcopy(x); break;
1977: case t_SER:
1978: y=gconvsp(x,1);
1979: if (typ(y) != t_POL)
1980: err(talker,"t_SER with negative valuation in gtopoly");
1981: break;
1982: case t_RFRAC: case t_RFRACN:
1983: y=gdeuc((GEN)x[1],(GEN)x[2]); break;
1984: case t_QFR: case t_QFI: case t_VEC: case t_COL: case t_MAT:
1985: lx=lg(x);
1986: if (reverse)
1987: {
1988: while (lx-- && isexactzero((GEN)x[lx]));
1989: i=lx+2; y=cgetg(i,t_POL);
1990: y[1]=evallgef(i); if (!gcmp0(x)) y[1] |= evalsigne(1);
1991: for (j=2; j<i; j++) y[j]=lcopy((GEN)x[j-1]);
1992: }
1993: else
1994: {
1995: i=1; j=lx; while (lx-- && isexactzero((GEN)x[i++]));
1996: i=lx+2; y=cgetg(i,t_POL);
1997: y[1]=evallgef(i); if (!gcmp0(x)) y[1] |= evalsigne(1);
1998: lx = j-1;
1999: for (j=2; j<i; j++) y[j]=lcopy((GEN)x[lx--]);
2000: }
2001: break;
2002: default: err(typeer,"gtopoly");
2003: return NULL; /* not reached */
2004: }
2005: setvarn(y,v); return y;
2006: }
2007:
2008: GEN
2009: gtopolyrev(GEN x, long v) { return gtopoly0(x,v,1); }
2010:
2011: GEN
2012: gtopoly(GEN x, long v) { return gtopoly0(x,v,0); }
2013:
2014: GEN
2015: zeroser(long v, long val)
2016: {
2017: GEN x = cgetg(2,t_SER);
2018: x[1]=evalvalp(val) | evalvarn(v); return x;
2019: }
2020:
2021: GEN
2022: scalarser(GEN x, long v, long prec)
2023: {
2024: GEN y=cgetg(prec+2,t_SER);
2025: long i;
2026:
2027: y[1]=evalsigne(1) | evalvalp(0) | evalvarn(v);
2028: y[2]=lcopy(x); for (i=3; i<=prec+1; i++) y[i]=zero;
2029: return y;
2030: }
2031:
2032: GEN
2033: gtoser(GEN x, long v)
2034: {
2035: long tx=typ(x),lx,i,j,l,av,tetpil;
2036: GEN y,p1,p2;
2037:
2038: if (v<0) v = 0;
2039: if (tx==t_SER) { y=gcopy(x); setvarn(y,v); return y; }
2040: if (isexactzero(x)) return zeroser(v,precdl);
2041: if (is_scalar_t(tx)) return scalarser(x,v,precdl);
2042:
2043: switch(tx)
2044: {
2045: case t_POL:
2046: lx=lgef(x); i=2; while (i<lx && gcmp0((GEN)x[i])) i++;
2047: l=lx-i; if (precdl>l) l=precdl;
2048: y=cgetg(l+2,t_SER);
2049: y[1] = evalsigne(1) | evalvalp(i-2) | evalvarn(v);
2050: for (j=2; j<=lx-i+1; j++) y[j]=lcopy((GEN)x[j+i-2]);
2051: for ( ; j<=l+1; j++) y[j]=zero;
2052: break;
2053:
2054: case t_RFRAC: case t_RFRACN:
2055: av=avma; p1=gtoser((GEN)x[1],v); p2=gtoser((GEN)x[2],v);
2056: tetpil=avma; return gerepile(av,tetpil,gdiv(p1,p2));
2057:
2058: case t_QFR: case t_QFI: case t_VEC: case t_COL: case t_MAT:
2059: lx=lg(x); i=1; while (i<lx && isexactzero((GEN)x[i])) i++;
2060: y = cgetg(lx-i+2,t_SER);
2061: y[1] = evalsigne(1) | evalvalp(i-1) | evalvarn(v);
2062: for (j=2; j<=lx-i+1; j++) y[j]=lcopy((GEN)x[j+i-2]);
2063: break;
2064:
2065: default: err(typeer,"gtoser");
2066: return NULL; /* not reached */
2067: }
2068: return y;
2069: }
2070:
2071: GEN
2072: gtovec(GEN x)
2073: {
2074: long tx,lx,i;
2075: GEN y;
2076:
2077: if (!x) return cgetg(1,t_VEC);
2078: tx = typ(x);
2079: if (is_scalar_t(tx) || is_rfrac_t(tx))
2080: {
2081: y=cgetg(2,t_VEC); y[1]=lcopy(x);
2082: return y;
2083: }
2084: if (tx == t_STR)
2085: {
2086: char *s = GSTR(x);
2087: char t[2];
2088: lx = strlen(s); t[1] = 0;
2089: y = cgetg(lx+1, t_VEC);
2090: for (i=0; i<lx; i++)
2091: {
2092: t[0] = s[i];
2093: y[i+1] = (long)strtoGENstr(t,0);
2094: }
2095: return y;
2096: }
2097: if (is_graphicvec_t(tx))
2098: {
2099: lx=lg(x); y=cgetg(lx,t_VEC);
2100: for (i=1; i<lx; i++) y[i]=lcopy((GEN)x[i]);
2101: return y;
2102: }
2103: if (tx==t_POL)
2104: {
2105: lx=lgef(x); y=cgetg(lx-1,t_VEC);
2106: for (i=1; i<=lx-2; i++) y[i]=lcopy((GEN)x[lx-i]);
2107: return y;
2108: }
2109: if (tx==t_LIST)
2110: {
2111: lx=lgef(x); y=cgetg(lx-1,t_VEC); x++;
2112: for (i=1; i<=lx-2; i++) y[i]=lcopy((GEN)x[i]);
2113: return y;
2114: }
2115: if (tx == t_VECSMALL)
2116: {
2117: lx=lg(x); y=cgetg(lx,t_VEC);
2118: for (i=1; i<lx; i++) y[i]=lstoi(x[i]);
2119: return y;
2120: }
2121: if (!signe(x)) { y=cgetg(2,t_VEC); y[1]=zero; return y; }
2122: lx=lg(x); y=cgetg(lx-1,t_VEC); x++;
2123: for (i=1; i<=lx-2; i++) y[i]=lcopy((GEN)x[i]);
2124: return y;
2125: }
2126:
2127: GEN
2128: gtovecsmall(GEN x)
2129: {
2130: GEN V;
2131: long tx, l,i;
2132:
2133: if (!x) return cgetg(1,t_VECSMALL);
2134: tx = typ(x);
2135: if (tx == t_VECSMALL) return gcopy(x);
2136: if (tx == t_INT)
2137: {
2138: GEN u = cgetg(2, t_VECSMALL);
2139: u[1] = itos(x); return u;
2140: }
2141: if (!is_vec_t(tx)) err(typeer,"vectosmall");
2142: l = lg(x);
2143: V = cgetg(l,t_VECSMALL);
2144: for(i=1;i<l;i++) V[i] = itos((GEN)x[i]);
2145: return V;
2146: }
2147:
2148: GEN
2149: compo(GEN x, long n)
2150: {
2151: long l,tx=typ(x);
2152:
2153: if (tx==t_POL && n+1 >= lgef(x)) return gzero;
2154: if (tx==t_SER && !signe(x)) return gzero;
2155: if (!is_recursive_t(tx))
2156: err(talker, "this object doesn't have components (is a leaf)");
2157: l=lontyp[tx]+n-1;
2158: if (n<1 || l>=lg(x))
2159: err(talker,"nonexistent component");
2160: return gcopy((GEN)x[l]);
2161: }
2162:
2163: /* with respect to the main variable if v<0, with respect to the variable v
2164: otherwise. v ignored if x is not a polynomial/series. */
2165:
2166: GEN
2167: polcoeff0(GEN x, long n, long v)
2168: {
2169: long tx=typ(x),lx,ex,w,av,tetpil;
2170: GEN xinit;
2171:
2172: if (is_scalar_t(tx)) return n? gzero: gcopy(x);
2173:
2174: switch(tx)
2175: {
2176: case t_QFR: case t_QFI: case t_VEC: case t_COL: case t_MAT:
2177: if (n<1 || n>=lg(x)) break;
2178: return gcopy((GEN)x[n]);
2179:
2180: case t_POL:
2181: if (n<0) return gzero;
2182: w=varn(x);
2183: if (v < 0 || v == w)
2184: return (n>=lgef(x)-2)? gzero: gcopy((GEN)x[n+2]);
2185: if (v < w) return n? gzero: gcopy(x);
2186: av=avma; xinit=x;
2187: x=gsubst(gsubst(x,w,polx[MAXVARN]),v,polx[0]);
2188: if (gvar(x)) { avma=av; return n? gzero: gcopy(xinit); }
2189: if (typ(x) == t_POL)
2190: {
2191: if (n>=lgef(x)-2) { avma=av; return gzero; }
2192: x = (GEN)x[n+2];
2193: }
2194: else
2195: x = polcoeff0(x, n, 0);
2196: tetpil=avma; return gerepile(av,tetpil,gsubst(x,MAXVARN,polx[w]));
2197:
2198: case t_SER:
2199: w=varn(x);
2200: if (v < 0 || v == w)
2201: {
2202: if (!signe(x)) return gzero;
2203: lx=lg(x); ex=valp(x); if (n<ex) return gzero;
2204: if (n>=ex+lx-2) break;
2205: return gcopy((GEN)x[n-ex+2]);
2206: }
2207: if (v < w) return n? gzero: gcopy(x);
2208: av=avma; xinit=x;
2209: x=gsubst(gsubst(x,w,polx[MAXVARN]),v,polx[0]);
2210: if (gvar(x)) { avma=av; return n? gzero: gcopy(xinit); }
2211: if (gcmp0(x)) { avma=av; return gzero; }
2212: if (typ(x) == t_SER)
2213: {
2214: lx=lg(x); ex=valp(x); if (n<ex) return gzero;
2215: if (n>=ex+lx-2) break;
2216: x = (GEN)x[n-ex+2];
2217: }
2218: else
2219: x = polcoeff0(x, n, 0);
2220: tetpil=avma; return gerepile(av,tetpil,gsubst(x,MAXVARN,polx[w]));
2221:
2222: case t_RFRAC: case t_RFRACN:
2223: w = precdl; av = avma;
2224: if (v<0) v = gvar(x);
2225: ex = ggval((GEN)x[2], polx[v]);
2226: precdl = n + ex + 1; x = gtoser(x, v); precdl = w;
2227: return gerepileupto(av, polcoeff0(x, n, v));
2228: }
2229: err(talker,"nonexistent component in truecoeff");
2230: return NULL; /* not reached */
2231: }
2232:
2233: GEN
2234: truecoeff(GEN x, long n)
2235: {
2236: return polcoeff0(x,n,-1);
2237: }
2238:
2239: GEN
2240: denom(GEN x)
2241: {
2242: long lx,i,av,tetpil;
2243: GEN s,t;
2244:
2245: switch(typ(x))
2246: {
2247: case t_INT: case t_REAL: case t_INTMOD: case t_PADIC: case t_SER:
2248: return gun;
2249:
2250: case t_FRAC: case t_FRACN:
2251: return absi((GEN)x[2]);
2252:
2253: case t_COMPLEX:
2254: av=avma; t=denom((GEN)x[1]); s=denom((GEN)x[2]); tetpil=avma;
2255: return gerepile(av,tetpil,glcm(s,t));
2256:
2257: case t_QUAD:
2258: av=avma; t=denom((GEN)x[2]); s=denom((GEN)x[3]); tetpil=avma;
2259: return gerepile(av,tetpil,glcm(s,t));
2260:
2261: case t_POLMOD:
2262: return denom((GEN)x[2]);
2263:
2264: case t_RFRAC: case t_RFRACN:
2265: return gcopy((GEN)x[2]);
2266:
2267: case t_POL:
2268: return polun[varn(x)];
2269:
2270: case t_VEC: case t_COL: case t_MAT:
2271: lx=lg(x); if (lx==1) return gun;
2272: av = tetpil = avma; s = denom((GEN)x[1]);
2273: for (i=2; i<lx; i++)
2274: {
2275: t = denom((GEN)x[i]);
2276: /* t != gun est volontaire */
2277: if (t != gun) { tetpil=avma; s=glcm(s,t); }
2278: }
2279: return gerepile(av,tetpil,s);
2280: }
2281: err(typeer,"denom");
2282: return NULL; /* not reached */
2283: }
2284:
2285: GEN
2286: numer(GEN x)
2287: {
2288: long av,tetpil;
2289: GEN s;
2290:
2291: switch(typ(x))
2292: {
2293: case t_INT: case t_REAL: case t_INTMOD:
2294: case t_PADIC: case t_POL: case t_SER:
2295: return gcopy(x);
2296:
2297: case t_FRAC: case t_FRACN:
2298: return (signe(x[2])>0)? gcopy((GEN)x[1]): gneg((GEN)x[1]);
2299:
2300: case t_POLMOD:
2301: av=avma; s=numer((GEN)x[2]); tetpil=avma;
2302: return gerepile(av,tetpil,gmodulcp(s,(GEN)x[1]));
2303:
2304: case t_RFRAC: case t_RFRACN:
2305: return gcopy((GEN)x[1]);
2306:
2307: case t_COMPLEX: case t_QUAD: case t_VEC: case t_COL: case t_MAT:
2308: av=avma; s=denom(x); tetpil=avma;
2309: return gerepile(av,tetpil,gmul(s,x));
2310: }
2311: err(typeer,"numer");
2312: return NULL; /* not reached */
2313: }
2314:
2315: /* Lift only intmods if v does not occur in x, lift with respect to main
2316: * variable of x if v < 0, with respect to variable v otherwise.
2317: */
2318: GEN
2319: lift0(GEN x, long v)
2320: {
2321: long lx,tx=typ(x),i;
2322: GEN y;
2323:
2324: switch(tx)
2325: {
2326: case t_INT: case t_REAL:
2327: return gcopy(x);
2328:
2329: case t_INTMOD:
2330: return gcopy((GEN)x[2]);
2331:
2332: case t_POLMOD:
2333: if (v < 0 || v == varn((GEN)x[1])) return gcopy((GEN)x[2]);
2334: y = cgetg(3,tx);
2335: y[1] = (long)lift0((GEN)x[1],v);
2336: y[2] = (long)lift0((GEN)x[2],v); return y;
2337:
2338: case t_SER:
2339: if (!signe(x)) return gcopy(x);
2340: lx=lg(x); y=cgetg(lx,tx); y[1]=x[1];
2341: for (i=2; i<lx; i++) y[i]=(long)lift0((GEN)x[i],v);
2342: return y;
2343:
2344: case t_PADIC:
2345: return gtrunc(x);
2346:
2347: case t_FRAC: case t_FRACN: case t_COMPLEX: case t_RFRAC:
2348: case t_RFRACN: case t_VEC: case t_COL: case t_MAT:
2349: lx=lg(x); y=cgetg(lx,tx);
2350: for (i=1; i<lx; i++) y[i]=(long)lift0((GEN)x[i],v);
2351: return y;
2352:
2353: case t_POL:
2354: y=cgetg(lx=lgef(x),tx); y[1]=x[1];
2355: for (i=2; i<lx; i++) y[i]=(long)lift0((GEN)x[i],v);
2356: return y;
2357:
2358: case t_QUAD:
2359: y=cgetg(4,tx); copyifstack(x[1],y[1]);
2360: for (i=2; i<4; i++) y[i]=(long)lift0((GEN)x[i],v);
2361: return y;
2362: }
2363: err(typeer,"lift");
2364: return NULL; /* not reached */
2365: }
2366:
2367: GEN
2368: lift(GEN x)
2369: {
2370: return lift0(x,-1);
2371: }
2372:
2373: /* same as lift, without copy. May DESTROY x. For internal use only.
2374: Conventions on v as for lift. */
2375: GEN
2376: lift_intern0(GEN x, long v)
2377: {
2378: long i,lx,tx=typ(x);
2379:
2380: switch(tx)
2381: {
2382: case t_INT: case t_REAL:
2383: return x;
2384:
2385: case t_INTMOD:
2386: return (GEN)x[2];
2387:
2388: case t_POLMOD:
2389: if (v < 0 || v == varn((GEN)x[1])) return (GEN)x[2];
2390: x[1]=(long)lift_intern0((GEN)x[1],v);
2391: x[2]=(long)lift_intern0((GEN)x[2],v);
2392: return x;
2393:
2394: case t_SER: if (!signe(x)) return x; /* fall through */
2395: case t_FRAC: case t_FRACN: case t_COMPLEX: case t_QUAD: case t_POL:
2396: case t_RFRAC: case t_RFRACN: case t_VEC: case t_COL: case t_MAT:
2397: lx = (tx==t_POL)? lgef(x): lg(x);
2398: for (i = lx-1; i>=lontyp[tx]; i--)
2399: x[i] = (long) lift_intern0((GEN)x[i],v);
2400: return x;
2401: }
2402: err(typeer,"lift_intern");
2403: return NULL; /* not reached */
2404: }
2405:
2406: /* memes conventions pour v que lift */
2407: GEN
2408: centerlift0(GEN x, long v)
2409: {
2410: long lx,tx=typ(x),i,av;
2411: GEN y;
2412:
2413: switch(tx)
2414: {
2415: case t_INT:
2416: return icopy(x);
2417:
2418: case t_INTMOD:
2419: av=avma; i=cmpii(shifti((GEN)x[2],1),(GEN)x[1]); avma=av;
2420: return (i>0)? subii((GEN)x[2],(GEN)x[1]): icopy((GEN)x[2]);
2421:
2422: case t_POLMOD:
2423: if (v < 0 || v == varn((GEN)x[1])) return gcopy((GEN)x[2]);
2424: y=cgetg(3,tx);
2425: y[1]=(long)centerlift0((GEN)x[1],v); y[2]=(long)centerlift0((GEN)x[2],v);
2426: return y;
2427:
2428: case t_SER:
2429: if (!signe(x)) return gcopy(x);
2430: lx=lg(x); y=cgetg(lx,tx); y[1]=x[1];
2431: for (i=2; i<lx; i++) y[i]=(long)centerlift0((GEN)x[i],v);
2432: return y;
2433:
2434: case t_POL:
2435: case t_FRAC: case t_FRACN: case t_COMPLEX: case t_RFRAC:
2436: case t_RFRACN: case t_VEC: case t_COL: case t_MAT:
2437: lx = (tx==t_POL)? lgef(x): lg(x);
2438: y=cgetg(lx,tx); y[1]=x[1];
2439: for (i=lontyp[tx]; i<lx; i++) y[i]=(long)centerlift0((GEN)x[i],v);
2440: return y;
2441:
2442: case t_QUAD:
2443: y=cgetg(4,tx); copyifstack(x[1],y[1]);
2444: for (i=2; i<4; i++) y[i]=(long)centerlift0((GEN)x[i],v);
2445: return y;
2446: }
2447: err(typeer,"centerlift");
2448: return NULL; /* not reached */
2449: }
2450:
2451: GEN
2452: centerlift(GEN x)
2453: {
2454: return centerlift0(x,-1);
2455: }
2456:
2457: /*******************************************************************/
2458: /* */
2459: /* PARTIES REELLE ET IMAGINAIRES */
2460: /* */
2461: /*******************************************************************/
2462:
2463: static GEN
2464: op_ReIm(GEN f(GEN), GEN x)
2465: {
2466: long lx,i,j,av, tx = typ(x);
2467: GEN z;
2468:
2469: switch(tx)
2470: {
2471: case t_POL:
2472: lx=lgef(x); av=avma;
2473: for (i=lx-1; i>=2; i--)
2474: if (!gcmp0(f((GEN)x[i]))) break;
2475: avma=av; if (i==1) return zeropol(varn(x));
2476:
2477: z=cgetg(i+1,t_POL); z[1]=evalsigne(1)|evallgef(1+i)|evalvarn(varn(x));
2478: for (j=2; j<=i; j++) z[j] = (long)f((GEN)x[j]);
2479: return z;
2480:
2481: case t_SER:
2482: if (gcmp0(x)) { z=cgetg(2,t_SER); z[1]=x[1]; return z; }
2483: lx=lg(x); av=avma;
2484: for (i=2; i<lx; i++)
2485: if (!gcmp0(f((GEN)x[i]))) break;
2486: avma=av; if (i==lx) return zeroser(varn(x),lx-2+valp(x));
2487:
2488: z=cgetg(lx-i+2,t_SER); z[1]=x[1]; setvalp(z, valp(x)+i-2);
2489: for (j=2; i<lx; j++,i++) z[j] = (long) f((GEN)x[i]);
2490: return z;
2491:
2492: case t_RFRAC: case t_RFRACN:
2493: {
2494: GEN dxb, n, d;
2495: av = avma; dxb = gconj((GEN)x[2]);
2496: n = gmul((GEN)x[1], dxb);
2497: d = gmul((GEN)x[2], dxb);
2498: return gerepileupto(av, gdiv(f(n), d));
2499: }
2500:
2501: case t_VEC: case t_COL: case t_MAT:
2502: lx=lg(x); z=cgetg(lx,tx);
2503: for (i=1; i<lx; i++) z[i] = (long) f((GEN)x[i]);
2504: return z;
2505: }
2506: err(typeer,"greal/gimag");
2507: return NULL; /* not reached */
2508: }
2509:
2510: GEN
2511: greal(GEN x)
2512: {
2513: switch(typ(x))
2514: {
2515: case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
2516: return gcopy(x);
2517:
2518: case t_COMPLEX:
2519: return gcopy((GEN)x[1]);
2520:
2521: case t_QUAD:
2522: return gcopy((GEN)x[2]);
2523: }
2524: return op_ReIm(greal,x);
2525: }
2526:
2527: GEN
2528: gimag(GEN x)
2529: {
2530: switch(typ(x))
2531: {
2532: case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
2533: return gzero;
2534:
2535: case t_COMPLEX:
2536: return gcopy((GEN)x[2]);
2537:
2538: case t_QUAD:
2539: return gcopy((GEN)x[3]);
2540: }
2541: return op_ReIm(gimag,x);
2542: }
2543:
2544: /*******************************************************************/
2545: /* */
2546: /* LOGICAL OPERATIONS */
2547: /* */
2548: /*******************************************************************/
2549: static long
2550: _egal(GEN x, GEN y)
2551: {
2552: long av = avma;
2553: long r = gegal(simplify_i(x), simplify_i(y));
2554: avma = av; return r;
2555: }
2556:
2557: GEN
2558: glt(GEN x, GEN y) { return gcmp(x,y)<0? gun: gzero; }
2559:
2560: GEN
2561: gle(GEN x, GEN y) { return gcmp(x,y)<=0? gun: gzero; }
2562:
2563: GEN
2564: gge(GEN x, GEN y) { return gcmp(x,y)>=0? gun: gzero; }
2565:
2566: GEN
2567: ggt(GEN x, GEN y) { return gcmp(x,y)>0? gun: gzero; }
2568:
2569: GEN
2570: geq(GEN x, GEN y) { return _egal(x,y)? gun: gzero; }
2571:
2572: GEN
2573: gne(GEN x, GEN y) { return _egal(x,y)? gzero: gun; }
2574:
2575: GEN
2576: gand(GEN x, GEN y) { return gcmp0(x)? gzero: (gcmp0(y)? gzero: gun); }
2577:
2578: GEN
2579: gor(GEN x, GEN y) { return gcmp0(x)? (gcmp0(y)? gzero: gun): gun; }
2580:
2581: GEN
2582: gnot(GEN x) { return gcmp0(x)? gun: gzero; }
2583:
2584: /*******************************************************************/
2585: /* */
2586: /* FORMAL SIMPLIFICATIONS */
2587: /* */
2588: /*******************************************************************/
2589:
2590: GEN
2591: geval(GEN x)
2592: {
2593: long av,tetpil,lx,i, tx = typ(x);
2594: GEN y,z;
2595:
2596: if (is_const_t(tx)) return gcopy(x);
2597: if (is_graphicvec_t(tx) || tx == t_RFRACN)
2598: {
2599: lx=lg(x); y=cgetg(lx, tx);
2600: for (i=1; i<lx; i++) y[i] = (long)geval((GEN)x[i]);
2601: return y;
2602: }
2603:
2604: switch(tx)
2605: {
2606: case t_STR:
2607: return flisseq(GSTR(x));
2608:
2609: case t_POLMOD: y=cgetg(3,tx);
2610: y[1]=(long)geval((GEN)x[1]);
2611: av=avma; z=geval((GEN)x[2]); tetpil=avma;
2612: y[2]=lpile(av,tetpil,gmod(z,(GEN)y[1]));
2613: return y;
2614:
2615: case t_POL:
2616: lx=lgef(x); if (lx==2) return gzero;
2617: {
2618: #define initial_value(ep) (GEN)((ep)+1) /* cf anal.h */
2619: entree *ep = varentries[varn(x)];
2620: if (!ep) return gcopy(x);
2621: z = (GEN)ep->value;
2622: if (gegal(x, initial_value(ep))) return gcopy(z);
2623: #undef initial_value
2624: }
2625: y=gzero; av=avma;
2626: for (i=lx-1; i>1; i--)
2627: y = gadd(geval((GEN)x[i]), gmul(z,y));
2628: return gerepileupto(av, y);
2629:
2630: case t_SER:
2631: err(impl, "evaluation of a power series");
2632:
2633: case t_RFRAC:
2634: return gdiv(geval((GEN)x[1]),geval((GEN)x[2]));
2635: }
2636: err(typeer,"geval");
2637: return NULL; /* not reached */
2638: }
2639:
2640: GEN
2641: simplify_i(GEN x)
2642: {
2643: long tx=typ(x),i,lx;
2644: GEN y;
2645:
2646: switch(tx)
2647: {
2648: case t_INT: case t_REAL: case t_FRAC:
2649: case t_INTMOD: case t_PADIC: case t_QFR: case t_QFI:
2650: case t_LIST: case t_STR: case t_VECSMALL:
2651: return x;
2652:
2653: case t_FRACN:
2654: return gred(x);
2655:
2656: case t_COMPLEX:
2657: if (isexactzero((GEN)x[2])) return simplify_i((GEN)x[1]);
2658: y=cgetg(3,t_COMPLEX);
2659: y[1]=(long)simplify_i((GEN)x[1]);
2660: y[2]=(long)simplify_i((GEN)x[2]); return y;
2661:
2662: case t_QUAD:
2663: if (isexactzero((GEN)x[3])) return simplify_i((GEN)x[2]);
2664: y=cgetg(4,t_QUAD);
2665: y[1]=x[1];
2666: y[2]=(long)simplify_i((GEN)x[2]);
2667: y[3]=(long)simplify_i((GEN)x[3]); return y;
2668:
2669: case t_POLMOD: y=cgetg(3,t_POLMOD);
2670: y[1]=(long)simplify_i((GEN)x[1]);
2671: i = typ(y[1]);
2672: if (i != t_POL)
2673: {
2674: if (i == t_INT) settyp(y, t_INTMOD);
2675: else y[1] = x[1]; /* invalid object otherwise */
2676: }
2677: y[2]=lmod(simplify_i((GEN)x[2]),(GEN)y[1]); return y;
2678:
2679: case t_POL:
2680: lx=lgef(x); if (lx==2) return gzero;
2681: if (lx==3) return simplify_i((GEN)x[2]);
2682: y=cgetg(lx,t_POL); y[1]=x[1];
2683: for (i=2; i<lx; i++) y[i]=(long)simplify_i((GEN)x[i]);
2684: return y;
2685:
2686: case t_SER:
2687: if (!signe(x)) return gcopy(x);
2688: lx=lg(x);
2689: y=cgetg(lx,t_SER); y[1]=x[1];
2690: for (i=2; i<lx; i++) y[i]=(long)simplify_i((GEN)x[i]);
2691: return y;
2692:
2693: case t_RFRAC: y=cgetg(3,t_RFRAC);
2694: y[1]=(long)simplify_i((GEN)x[1]);
2695: y[2]=(long)simplify_i((GEN)x[2]); return y;
2696:
2697: case t_RFRACN: y=cgetg(3,t_RFRAC);
2698: y[1]=(long)simplify_i((GEN)x[1]);
2699: y[2]=(long)simplify_i((GEN)x[2]); return gred_rfrac(y);
2700:
2701: case t_VEC: case t_COL: case t_MAT:
2702: lx=lg(x); y=cgetg(lx,tx);
2703: for (i=1; i<lx; i++) y[i]=(long)simplify_i((GEN)x[i]);
2704: return y;
2705: }
2706: err(typeer,"simplify_i");
2707: return NULL; /* not reached */
2708: }
2709:
2710: GEN
2711: simplify(GEN x)
2712: {
2713: ulong av = avma;
2714: return gerepilecopy(av, simplify_i(x));
2715: }
2716:
2717: /*******************************************************************/
2718: /* */
2719: /* EVALUATION OF SOME SIMPLE OBJECTS */
2720: /* */
2721: /*******************************************************************/
2722: static GEN
2723: qfeval0_i(GEN q, GEN x, long n)
2724: {
2725: long i,j,av=avma;
2726: GEN res=gzero;
2727:
2728: for (i=2;i<n;i++)
2729: for (j=1;j<i;j++)
2730: res = gadd(res, gmul(gcoeff(q,i,j), mulii((GEN)x[i],(GEN)x[j])) );
2731: res=gshift(res,1);
2732: for (i=1;i<n;i++)
2733: res = gadd(res, gmul(gcoeff(q,i,i), sqri((GEN)x[i])) );
2734: return gerepileupto(av,res);
2735: }
2736:
2737: #if 0
2738: static GEN
2739: qfeval0(GEN q, GEN x, long n)
2740: {
2741: long i,j,av=avma;
2742: GEN res=gzero;
2743:
2744: for (i=2;i<n;i++)
2745: for (j=1;j<i;j++)
2746: res = gadd(res, gmul(gcoeff(q,i,j), gmul((GEN)x[i],(GEN)x[j])) );
2747: res=gshift(res,1);
2748: for (i=1;i<n;i++)
2749: res = gadd(res, gmul(gcoeff(q,i,i), gsqr((GEN)x[i])) );
2750: return gerepileupto(av,res);
2751: }
2752: #else
2753: static GEN
2754: qfeval0(GEN q, GEN x, long n)
2755: {
2756: long i,j,av=avma;
2757: GEN res = gmul(gcoeff(q,1,1), gsqr((GEN)x[1]));
2758:
2759: for (i=2; i<n; i++)
2760: {
2761: GEN l = (GEN)q[i];
2762: GEN sx = gmul((GEN)l[1], (GEN)x[1]);
2763: for (j=2; j<i; j++)
2764: sx = gadd(sx, gmul((GEN)l[j],(GEN)x[j]));
2765: sx = gadd(gshift(sx,1), gmul((GEN)l[i],(GEN)x[i]));
2766:
2767: res = gadd(res, gmul((GEN)x[i], sx));
2768: }
2769: return gerepileupto(av,res);
2770: }
2771: #endif
2772:
2773: /* We assume q is a real symetric matrix */
2774: GEN
2775: qfeval(GEN q, GEN x)
2776: {
2777: long n=lg(q);
2778:
2779: if (n==1)
2780: {
2781: if (typ(q) != t_MAT || lg(x) != 1)
2782: err(talker,"invalid data in qfeval");
2783: return gzero;
2784: }
2785: if (typ(q) != t_MAT || lg(q[1]) != n)
2786: err(talker,"invalid quadratic form in qfeval");
2787: if (typ(x) != t_COL || lg(x) != n)
2788: err(talker,"invalid vector in qfeval");
2789:
2790: return qfeval0(q,x,n);
2791: }
2792:
2793: /* the Horner-type evaluation (mul x 2/3) would force us to use gmul and not
2794: * mulii (more than 4 x slower for small entries). Not worth it.
2795: */
2796: static GEN
2797: qfbeval0_i(GEN q, GEN x, GEN y, long n)
2798: {
2799: long i,j,av=avma;
2800: GEN res = gmul(gcoeff(q,1,1), mulii((GEN)x[1],(GEN)y[1]));
2801:
2802: for (i=2;i<n;i++)
2803: {
2804: for (j=1;j<i;j++)
2805: {
2806: GEN p1 = addii(mulii((GEN)x[i],(GEN)y[j]), mulii((GEN)x[j],(GEN)y[i]));
2807: res = gadd(res, gmul(gcoeff(q,i,j),p1));
2808: }
2809: res = gadd(res, gmul(gcoeff(q,i,i), mulii((GEN)x[i],(GEN)y[i])));
2810: }
2811: return gerepileupto(av,res);
2812: }
2813:
2814: #if 0
2815: static GEN
2816: qfbeval0(GEN q, GEN x, GEN y, long n)
2817: {
2818: long i,j,av=avma;
2819: GEN res = gmul(gcoeff(q,1,1), gmul((GEN)x[1],(GEN)y[1]));
2820:
2821: for (i=2;i<n;i++)
2822: {
2823: for (j=1;j<i;j++)
2824: {
2825: GEN p1 = gadd(gmul((GEN)x[i],(GEN)y[j]), gmul((GEN)x[j],(GEN)y[i]));
2826: res = gadd(res, gmul(gcoeff(q,i,j),p1));
2827: }
2828: res = gadd(res, gmul(gcoeff(q,i,i), gmul((GEN)x[i],(GEN)y[i])));
2829: }
2830: return gerepileupto(av,res);
2831: }
2832: #else
2833: static GEN
2834: qfbeval0(GEN q, GEN x, GEN y, long n)
2835: {
2836: long i,j,av=avma;
2837: GEN res = gmul(gcoeff(q,1,1), gmul((GEN)x[1], (GEN)y[1]));
2838:
2839: for (i=2; i<n; i++)
2840: {
2841: GEN l = (GEN)q[i];
2842: GEN sx = gmul((GEN)l[1], (GEN)y[1]);
2843: GEN sy = gmul((GEN)l[1], (GEN)x[1]);
2844: for (j=2; j<i; j++)
2845: {
2846: sx = gadd(sx, gmul((GEN)l[j],(GEN)y[j]));
2847: sy = gadd(sy, gmul((GEN)l[j],(GEN)x[j]));
2848: }
2849: sx = gadd(sx, gmul((GEN)l[i],(GEN)y[i]));
2850:
2851: sx = gmul((GEN)x[i], sx);
2852: sy = gmul((GEN)y[i], sy);
2853: res = gadd(res, gadd(sx,sy));
2854: }
2855: return gerepileupto(av,res);
2856: }
2857: #endif
2858:
2859: /* We assume q is a real symetric matrix */
2860: GEN
2861: qfbeval(GEN q, GEN x, GEN y)
2862: {
2863: long n=lg(q);
2864:
2865: if (n==1)
2866: {
2867: if (typ(q) != t_MAT || lg(x) != 1 || lg(y) != 1)
2868: err(talker,"invalid data in qfbeval");
2869: return gzero;
2870: }
2871: if (typ(q) != t_MAT || lg(q[1]) != n)
2872: err(talker,"invalid quadratic form in qfbeval");
2873: if (typ(x) != t_COL || lg(x) != n || typ(y) != t_COL || lg(y) != n)
2874: err(talker,"invalid vector in qfbeval");
2875:
2876: return qfbeval0(q,x,y,n);
2877: }
2878:
2879: /* yield X = M'.q.M, assuming q is symetric.
2880: * X_ij are X_ji identical, not copies
2881: * if flag is set, M has integer entries
2882: */
2883: GEN
2884: qf_base_change(GEN q, GEN M, int flag)
2885: {
2886: long i,j, k = lg(M), n=lg(q);
2887: GEN res = cgetg(k,t_MAT);
2888: GEN (*qf)(GEN,GEN,long) = flag? qfeval0_i: qfeval0;
2889: GEN (*qfb)(GEN,GEN,GEN,long) = flag? qfbeval0_i: qfbeval0;
2890:
2891: if (n==1)
2892: {
2893: if (typ(q) != t_MAT || k != 1)
2894: err(talker,"invalid data in qf_base_change");
2895: return res;
2896: }
2897: if (typ(M) != t_MAT || k == 1 || lg(M[1]) != n)
2898: err(talker,"invalid base change matrix in qf_base_change");
2899:
2900: for (i=1;i<k;i++)
2901: {
2902: res[i] = lgetg(k,t_COL);
2903: coeff(res,i,i) = (long) qf(q,(GEN)M[i],n);
2904: }
2905: for (i=2;i<k;i++)
2906: for (j=1;j<i;j++)
2907: coeff(res,i,j)=coeff(res,j,i) = (long) qfb(q,(GEN)M[i],(GEN)M[j],n);
2908: return res;
2909: }
2910:
2911: /* compute M'.M */
2912: GEN
2913: gram_matrix(GEN M)
2914: {
2915: long n=lg(M),i,j,k, av;
2916: GEN res = cgetg(n,t_MAT),p1;
2917:
2918: if (n==1)
2919: {
2920: if (typ(M) != t_MAT)
2921: err(talker,"invalid data in gram_matrix");
2922: return res;
2923: }
2924: if (typ(M) != t_MAT || lg(M[1]) != n)
2925: err(talker,"not a square matrix in gram_matrix");
2926:
2927: for (i=1;i<n;i++) res[i]=lgetg(n,t_COL);
2928: av=avma;
2929: for (i=1;i<n;i++)
2930: {
2931: p1 = gzero;
2932: for (k=1;k<n;k++)
2933: p1 = gadd(p1, gsqr(gcoeff(M,k,i)));
2934: coeff(res,i,i) = (long) gerepileupto(av,p1);
2935: av=avma;
2936: }
2937: for (i=2;i<n;i++)
2938: for (j=1;j<i;j++)
2939: {
2940: p1=gzero;
2941: for (k=1;k<n;k++)
2942: p1 = gadd(p1, gmul(gcoeff(M,k,i),gcoeff(M,k,j)));
2943: coeff(res,i,j)=coeff(res,j,i) = lpileupto(av,p1);
2944: av=avma;
2945: }
2946: return res;
2947: }
2948:
2949: /* return Re(x * y), x and y scalars */
2950: GEN
2951: mul_real(GEN x, GEN y)
2952: {
2953: if (typ(x) == t_COMPLEX)
2954: {
2955: if (typ(y) == t_COMPLEX)
2956: {
2957: long av=avma, tetpil;
2958: GEN p1 = gmul((GEN)x[1], (GEN) y[1]);
2959: GEN p2 = gneg(gmul((GEN)x[2], (GEN) y[2]));
2960: tetpil=avma; return gerepile(av,tetpil,gadd(p1,p2));
2961: }
2962: x = (GEN)x[1];
2963: }
2964: else if (typ(y) == t_COMPLEX) y = (GEN)y[1];
2965: return gmul(x,y);
2966: }
2967:
2968: /* Compute Re(x * y), x and y matrices of compatible dimensions
2969: * assume lx, ly > 1, and scalar entries */
2970: GEN
2971: mulmat_real(GEN x, GEN y)
2972: {
2973: long av,i,j,k, lx = lg(x), ly = lg(y), l = lg(x[1]);
2974: GEN p1, z = cgetg(ly,t_MAT);
2975:
2976: for (j=1; j<ly; j++)
2977: {
2978: z[j] = lgetg(l,t_COL);
2979: for (i=1; i<l; i++)
2980: {
2981: p1 = gzero; av=avma;
2982: for (k=1; k<lx; k++)
2983: p1 = gadd(p1, mul_real(gcoeff(x,i,k),gcoeff(y,k,j)));
2984: coeff(z,i,j)=lpileupto(av, p1);
2985: }
2986: }
2987: return z;
2988: }
2989:
2990: static GEN
2991: hqfeval0(GEN q, GEN x, long n)
2992: {
2993: long i,j, av=avma;
2994: GEN res=gzero;
2995:
2996: for (i=2;i<n;i++)
2997: for (j=1;j<i;j++)
2998: {
2999: GEN p1 = gmul((GEN)x[i],gconj((GEN)x[j]));
3000: res = gadd(res, mul_real(gcoeff(q,i,j),p1));
3001: }
3002: res=gshift(res,1);
3003: for (i=1;i<n;i++)
3004: res = gadd(res, gmul(gcoeff(q,i,i), gnorm((GEN)x[i])) );
3005: return gerepileupto(av,res);
3006: }
3007:
3008: /* We assume q is a hermitian complex matrix */
3009: GEN
3010: hqfeval(GEN q, GEN x)
3011: {
3012: long n=lg(q);
3013:
3014: if (n==1)
3015: {
3016: if (typ(q) != t_MAT || lg(x) != 1)
3017: err(talker,"invalid data in hqfeval");
3018: return gzero;
3019: }
3020: if (typ(q) != t_MAT || lg(q[1]) != n)
3021: err(talker,"invalid quadratic form in hqfeval");
3022: if (typ(x) != t_COL || lg(x) != n)
3023: err(talker,"invalid vector in hqfeval");
3024:
3025: return hqfeval0(q,x,n);
3026: }
3027:
3028: GEN
3029: poleval(GEN x, GEN y)
3030: {
3031: long av,tetpil,i,j,imin,tx=typ(x);
3032: GEN p1,p2,p3,r,s;
3033:
3034: if (is_scalar_t(tx)) return gcopy(x);
3035: switch(tx)
3036: {
3037: case t_POL:
3038: i=lgef(x)-1; imin=2; break;
3039:
3040: case t_RFRAC: case t_RFRACN: av=avma;
3041: p1=poleval((GEN)x[1],y);
3042: p2=poleval((GEN)x[2],y); tetpil=avma;
3043: return gerepile(av,tetpil,gdiv(p1,p2));
3044:
3045: case t_VEC: case t_COL:
3046: i=lg(x)-1; imin=1; break;
3047: default: err(typeer,"poleval");
3048: return NULL; /* not reached */
3049: }
3050: if (i<=imin)
3051: return (i==imin)? gcopy((GEN)x[imin]): gzero;
3052:
3053: av=avma; p1=(GEN)x[i]; i--;
3054: if (typ(y)!=t_COMPLEX)
3055: {
3056: #if 0 /* standard Horner's rule */
3057: for ( ; i>=imin; i--)
3058: p1 = gadd(gmul(p1,y),(GEN)x[i]);
3059: #endif
3060: /* specific attention to sparse polynomials */
3061: for ( ; i>=imin; i=j-1)
3062: {
3063: for (j=i; gcmp0((GEN)x[j]); j--)
3064: if (j==imin)
3065: {
3066: if (i!=j) y = gpuigs(y,i-j+1);
3067: tetpil=avma; return gerepile(av,tetpil,gmul(p1,y));
3068: }
3069: r = (i==j)? y: gpuigs(y,i-j+1);
3070: p1 = gadd(gmul(p1,r), (GEN)x[j]);
3071: }
3072: return gerepileupto(av,p1);
3073: }
3074:
3075: p2=(GEN)x[i]; i--; r=gtrace(y); s=gneg_i(gnorm(y));
3076: for ( ; i>=imin; i--)
3077: {
3078: p3=gadd(p2,gmul(r,p1));
3079: p2=gadd((GEN)x[i],gmul(s,p1)); p1=p3;
3080: }
3081: p1=gmul(y,p1); tetpil=avma;
3082: return gerepile(av,tetpil,gadd(p1,p2));
3083: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>