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