Annotation of OpenXM_contrib/pari-2.2/src/basemath/gen2.c, Revision 1.1.1.1
1.1 noro 1: /* $Id: gen2.c,v 1.33 2001/10/01 12:11:30 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: /** (second part) **/
20: /** **/
21: /********************************************************************/
22: #include "pari.h"
23:
24: /*******************************************************************/
25: /* */
26: /* OPERATIONS BY VALUE */
27: /* f is a pointer to the function called. */
28: /* result is gaffect-ed to last parameter */
29: /* */
30: /*******************************************************************/
31:
32: void
33: gop1z(GEN (*f)(GEN), GEN x, GEN y)
34: {
35: long av=avma; gaffect(f(x),y); avma=av;
36: }
37:
38: void
39: gop2z(GEN (*f)(GEN, GEN), GEN x, GEN y, GEN z)
40: {
41: long av=avma; gaffect(f(x,y),z); avma=av;
42: }
43:
44: void
45: gops2gsz(GEN (*f)(GEN, long), GEN x, long s, GEN z)
46: {
47: long av=avma; gaffect(f(x,s),z); avma=av;
48: }
49:
50: void
51: gops2sgz(GEN (*f)(long, GEN), long s, GEN y, GEN z)
52: {
53: long av=avma; gaffect(f(s,y),z); avma=av;
54: }
55:
56: void
57: gops2ssz(GEN (*f)(long, long), long s, long y, GEN z)
58: {
59: long av=avma; gaffect(f(s,y),z); avma=av;
60: }
61:
62: /*******************************************************************/
63: /* */
64: /* OPERATIONS USING SMALL INTEGERS */
65: /* */
66: /*******************************************************************/
67:
68: /* small int prototype */
69: static long court_p[] = { evaltyp(t_INT) | m_evallg(3),0,0 };
70:
71: GEN
72: gopsg2(GEN (*f)(GEN, GEN), long s, GEN y)
73: {
74: affsi(s,court_p); return f(court_p,y);
75: }
76:
77: GEN
78: gopgs2(GEN (*f)(GEN, GEN), GEN y, long s)
79: {
80: affsi(s,court_p); return f(y,court_p);
81: }
82:
83: long
84: opgs2(int (*f)(GEN, GEN), GEN y, long s)
85: {
86: affsi(s,court_p); return f(y,court_p);
87: }
88:
89: void
90: gopsg2z(GEN (*f)(GEN, GEN), long s, GEN y, GEN z)
91: {
92: long av=avma;
93: affsi(s,court_p); gaffect(f(court_p,y),z); avma=av;
94: }
95:
96: void
97: gopgs2z(GEN (*f)(GEN, GEN), GEN y, long s, GEN z)
98: {
99: long av=avma;
100: affsi(s,court_p); gaffect(f(y,court_p),z); avma=av;
101: }
102:
103: /*******************************************************************/
104: /* */
105: /* CREATION OF A P-ADIC GEN */
106: /* */
107: /*******************************************************************/
108:
109: /* y[4] not filled */
110: static GEN
111: cgetp2(GEN x, long v)
112: {
113: GEN y = cgetg(5,t_PADIC);
114: y[1] = evalprecp(precp(x)) | evalvalp(v);
115: icopyifstack(x[2], y[2]);
116: y[3] = licopy((GEN)x[3]); return y;
117: }
118:
119: GEN
120: cgetp(GEN x)
121: {
122: GEN y = cgetp2(x, 0);
123: y[4] = lgeti(lgefint(x[3])); return y;
124: }
125:
126: GEN
127: pureimag(GEN x)
128: {
129: GEN y = cgetg(3,t_COMPLEX);
130: y[1] = zero;
131: y[2] = (long)x; return y;
132: }
133:
134: /*******************************************************************/
135: /* */
136: /* SIZES */
137: /* */
138: /*******************************************************************/
139:
140: long
141: glength(GEN x)
142: {
143: switch(typ(x))
144: {
145: case t_INT: return lgefint(x)-2;
146: case t_POL: case t_LIST: return lgef(x)-2;
147: case t_REAL: return signe(x)? lg(x)-2: 0;
148: case t_STR: return strlen(GSTR(x));
149: }
150: return lg(x)-lontyp[typ(x)];
151: }
152:
153: GEN
154: matsize(GEN x)
155: {
156: GEN y=cgetg(3,t_VEC);
157:
158: switch(typ(x))
159: {
160: case t_VEC:
161: y[1]=un; y[2]=lstoi(lg(x)-1); break;
162: case t_COL:
163: y[1]=lstoi(lg(x)-1); y[2]=un; break;
164: case t_MAT:
165: y[2]=lstoi(lg(x)-1);
166: y[1]=(lg(x)==1)? zero: lstoi(lg(x[1])-1); break;
167: default: err(typeer,"matsize");
168: }
169: return y;
170: }
171:
172: long
173: taille(GEN x)
174: {
175: long i,n,lx, tx = typ(x);
176: n = lg(x);
177: if (is_recursive_t(tx))
178: {
179: lx = (tx==t_POL || tx==t_LIST)? lgef(x): n;
180: for (i=lontyp[tx]; i<lx; i++) n += taille((GEN)x[i]);
181: }
182: return n;
183: }
184:
185: long
186: taille2(GEN x) { return taille(x)<<TWOPOTBYTES_IN_LONG; }
187:
188: /*******************************************************************/
189: /* */
190: /* GREFFE */
191: /* Greffe d'une serie sur un polynome */
192: /* */
193: /*******************************************************************/
194:
195: GEN
196: greffe(GEN x, long l, long use_stack)
197: {
198: long i,e,k,vx;
199: GEN y;
200:
201: if (typ(x)!=t_POL) err(notpoler,"greffe");
202: if (use_stack) y = cgetg(l,t_SER);
203: else
204: {
205: y = (GEN) gpmalloc(l*sizeof(long));
206: y[0] = evaltyp(t_SER) | evallg(l);
207: }
208: if (gcmp0(x))
209: {
210: y[1]=evalvalp(l-2) | evalvarn(varn(x));
211: i=2; while(i<l) { y[i]=x[2]; i++; }
212: return y;
213: }
214: vx=varn(x); e=gval(x,vx);
215: y[1]=evalsigne(1) | evalvalp(e) | evalvarn(vx);
216: k=lgef(x)-e-1; i=l-1;
217: if (k<l)
218: while (i>k) { y[i]=zero; i--; }
219: while (i>=2) { y[i]=x[i+e]; i--; }
220: return y;
221: }
222:
223: /*******************************************************************/
224: /* */
225: /* CONVERSION GEN --> long */
226: /* */
227: /*******************************************************************/
228:
229: long
230: gtolong(GEN x)
231: {
232: long y,tx=typ(x),av=avma;
233:
234: switch(tx)
235: {
236: case t_INT:
237: return itos(x);
238: case t_REAL: case t_FRAC: case t_FRACN:
239: y=itos(ground(x)); avma=av; return y;
240: case t_COMPLEX:
241: if (gcmp0((GEN)x[2])) return gtolong((GEN)x[1]); break;
242: case t_QUAD:
243: if (gcmp0((GEN)x[3])) return gtolong((GEN)x[2]); break;
244: }
245: err(typeer,"gtolong");
246: return 0; /* not reached */
247: }
248:
249: /*******************************************************************/
250: /* */
251: /* COMPARISONS */
252: /* */
253: /*******************************************************************/
254:
255: /* returns 1 whenever x = 0, and 0 otherwise */
256: int
257: gcmp0(GEN x)
258: {
259: switch(typ(x))
260: {
261: case t_INT: case t_REAL: case t_POL: case t_SER:
262: return !signe(x);
263:
264: case t_INTMOD: case t_POLMOD:
265: return gcmp0((GEN)x[2]);
266:
267: case t_FRAC: case t_FRACN:
268: return !signe(x[1]);
269:
270: case t_COMPLEX:
271: /* is 0 iff norm(x) would be 0 (can happen with Re(x) and Im(x) != 0
272: * only if Re(x) and Im(x) are of type t_REAL). See mp.c:addrr().
273: */
274: if (gcmp0((GEN)x[1]))
275: {
276: if (gcmp0((GEN)x[2])) return 1;
277: if (typ(x[1])!=t_REAL || typ(x[2])!=t_REAL) return 0;
278: return (expo(x[1])>expo(x[2]));
279: }
280: if (gcmp0((GEN)x[2]))
281: {
282: if (typ(x[1])!=t_REAL || typ(x[2])!=t_REAL) return 0;
283: return (expo(x[2])>expo(x[1]));
284: }
285: return 0;
286:
287: case t_PADIC:
288: return !signe(x[4]);
289:
290: case t_QUAD:
291: return gcmp0((GEN)x[2]) && gcmp0((GEN)x[3]);
292:
293: case t_RFRAC: case t_RFRACN:
294: return gcmp0((GEN)x[1]);
295:
296: case t_VEC: case t_COL: case t_MAT:
297: {
298: long i;
299: for (i=lg(x)-1; i; i--)
300: if (!gcmp0((GEN)x[i])) return 0;
301: return 1;
302: }
303: }
304: return 0;
305: }
306:
307: /* returns 1 whenever x = 1, 0 otherwise */
308: int
309: gcmp1(GEN x)
310: {
311: switch(typ(x))
312: {
313: case t_INT:
314: return is_pm1(x) && signe(x)==1;
315:
316: case t_REAL:
317: if (signe(x) > 0 && expo(x)==0 && (ulong)x[2]==HIGHBIT)
318: {
319: long i,lx = lg(x);
320: for (i=3; i<lx; i++)
321: if (x[i]) return 0;
322: return 1;
323: }
324: return 0;
325:
326: case t_INTMOD: case t_POLMOD:
327: return gcmp1((GEN)x[2]);
328:
329: case t_FRAC:
330: return gcmp1((GEN)x[1]) && gcmp1((GEN)x[2]);
331:
332: case t_FRACN:
333: return egalii((GEN)x[1],(GEN)x[2]);
334:
335: case t_COMPLEX:
336: return gcmp1((GEN)x[1]) && gcmp0((GEN)x[2]);
337:
338: case t_PADIC:
339: return !valp(x) && gcmp1((GEN)x[4]);
340:
341: case t_QUAD:
342: return gcmp1((GEN)x[2]) && gcmp0((GEN)x[3]);
343:
344: case t_POL:
345: return lgef(x)==3 && gcmp1((GEN)x[2]);
346: }
347: return 0;
348: }
349:
350: /* returns 1 whenever the x = -1, 0 otherwise */
351: int
352: gcmp_1(GEN x)
353: {
354: long l,y;
355: GEN p1;
356:
357: switch(typ(x))
358: {
359: case t_INT:
360: return is_pm1(x) && signe(x)== -1;
361:
362: case t_REAL:
363: if (signe(x) < 0 && expo(x)==0 && (ulong)x[2]==HIGHBIT)
364: {
365: long i,lx = lg(x);
366: for (i=3; i<lx; i++)
367: if (x[i]) return 0;
368: return 1;
369: }
370: return 0;
371:
372: case t_INTMOD:
373: l=avma; y=egalii(addsi(1,(GEN)x[2]), (GEN)x[1]); avma=l; return y;
374:
375: case t_FRAC: case t_FRACN:
376: l = signe(x[1]);
377: return l && l == -signe(x[2]) && !absi_cmp((GEN)x[1],(GEN)x[2]);
378:
379: case t_COMPLEX:
380: return gcmp_1((GEN)x[1]) && gcmp0((GEN)x[2]);
381:
382: case t_QUAD:
383: return gcmp_1((GEN)x[2]) && gcmp0((GEN)x[3]);
384:
385: case t_PADIC:
386: l=avma; y=gegal(addsi(1,(GEN)x[4]), (GEN)x[3]); avma=l; return y;
387:
388: case t_POLMOD:
389: l=avma; p1=gadd(gun,(GEN)x[2]);
390: y = signe(p1) && !gegal(p1,(GEN)x[1]); avma=l; return !y;
391:
392: case t_POL:
393: return lgef(x)==3 && gcmp_1((GEN)x[2]);
394: }
395: return 0;
396: }
397:
398: /* returns the sign of x - y when it makes sense. 0 otherwise */
399: int
400: gcmp(GEN x, GEN y)
401: {
402: long tx,ty,f,av;
403:
404: tx=typ(x); ty=typ(y);
405: if (is_intreal_t(tx))
406: { if (is_intreal_t(ty)) return mpcmp(x,y); }
407: else
408: {
409: if (tx==t_STR)
410: {
411: if (ty != t_STR) return 1;
412: return strcmp(GSTR(x),GSTR(y));
413: }
414: if (!is_frac_t(tx)) err(typeer,"comparison");
415: }
416: if (ty == t_STR) return -1;
417: if (!is_intreal_t(ty) && !is_frac_t(ty)) err(typeer,"comparison");
418: av=avma; y=gneg_i(y); f=gsigne(gadd(x,y)); avma=av; return f;
419: }
420:
421: /* as gcmp for vector/matrices, using lexicographic ordering on components */
422: int
423: lexcmp(GEN x, GEN y)
424: {
425: const long tx=typ(x), ty=typ(y);
426: long lx,ly,l,fl,i;
427:
428: ly=lg(y);
429: if (!is_matvec_t(tx))
430: {
431: if (!is_matvec_t(ty)) return gcmp(x,y);
432: if (ly==1) return 1;
433: fl = lexcmp(x,(GEN)y[1]);
434: if (fl) return fl;
435: return (ly>2)? -1:0;
436: }
437:
438: lx=lg(x);
439: if (!is_matvec_t(ty))
440: {
441: if (lx==1) return -1;
442: fl = lexcmp(y,(GEN)x[1]);
443: if (fl) return -fl;
444: return (lx>2)? 1:0;
445: }
446:
447: /* x and y are matvec_t */
448: if (ly==1) return (lx==1)?0:1;
449: if (lx==1) return -1;
450: if (ty==t_MAT)
451: {
452: if (tx != t_MAT)
453: {
454: fl = lexcmp(x,(GEN)y[1]);
455: if (fl) return fl;
456: return (ly>2)?-1:0;
457: }
458: }
459: else if (tx==t_MAT)
460: {
461: fl = lexcmp(y,(GEN)x[1]);
462: if (fl) return -fl;
463: return (ly>2)?1:0;
464: }
465:
466: /* tx = ty = t_MAT, or x and y are both vect_t */
467: l=min(lx,ly);
468: for (i=1; i<l; i++)
469: {
470: fl = lexcmp((GEN)x[i],(GEN)y[i]);
471: if (fl) return fl;
472: }
473: return (ly != lx)? -1 : 0;
474: }
475:
476: /*****************************************************************/
477: /* */
478: /* EQUALITY */
479: /* returns 1 if x == y, 0 otherwise */
480: /* */
481: /*****************************************************************/
482:
483: /* x,y t_POL */
484: static int
485: polegal(GEN x, GEN y)
486: {
487: long i, lx = lgef(x);
488:
489: if (x[1] != y[1] && (lgef(y) != lx || lx > 3)) return 0;
490: for (i = 2; i < lx; i++)
491: if (!gegal((GEN)x[i],(GEN)y[i])) return 0;
492: return 1;
493: }
494:
495: #define MASK(x) (((ulong)(x)) & (TYPBITS | LGBITS))
496: /* typ(x) = typ(y) = t_VEC/COL/MAT */
497: static int
498: vecegal(GEN x, GEN y)
499: {
500: long i;
501:
502: if (MASK(x[0]) != MASK(y[0])) return 0;
503:
504: i = lg(x)-1;
505: if (typ(x) != t_MAT)
506: {
507: for ( ; i; i--)
508: if (! gegal((GEN)x[i],(GEN)y[i]) ) return 0;
509: return 1;
510: }
511: for ( ; i; i--)
512: if (! vecegal((GEN)x[i],(GEN)y[i]) ) return 0;
513: return 1;
514: }
515:
516: int
517: gegal(GEN x, GEN y)
518: {
519: ulong av,tx;
520: long i;
521:
522: if (x == y) return 1;
523: tx = typ(x);
524: if (tx==typ(y))
525: switch(tx)
526: {
527: case t_INT:
528: return egalii(x,y);
529:
530: case t_POL:
531: return polegal(x,y);
532:
533: case t_COMPLEX:
534: return gegal((GEN)x[1],(GEN)y[1]) && gegal((GEN)x[2],(GEN)y[2]);
535:
536: case t_INTMOD: case t_POLMOD:
537: return gegal((GEN)x[2],(GEN)y[2])
538: && (x[1]==y[1] || gegal((GEN)x[1],(GEN)y[1]));
539:
540: case t_QFR:
541: if (!gegal((GEN)x[4],(GEN)y[4])) return 0; /* fall through */
542: case t_QUAD: case t_QFI:
543: return gegal((GEN)x[1],(GEN)y[1])
544: && gegal((GEN)x[2],(GEN)y[2])
545: && gegal((GEN)x[3],(GEN)y[3]);
546:
547: case t_FRAC:
548: return gegal((GEN)x[1], (GEN)y[1])
549: && gegal((GEN)x[2], (GEN)y[2]);
550:
551: case t_FRACN: case t_RFRAC: case t_RFRACN:
552: av=avma; i=gegal(gmul((GEN)x[1],(GEN)y[2]),gmul((GEN)x[2],(GEN)y[1]));
553: avma=av; return i;
554:
555: case t_STR:
556: return !strcmp(GSTR(x),GSTR(y));
557:
558: case t_VEC: case t_COL: case t_MAT:
559: return vecegal(x,y);
560: case t_VECSMALL:
561: if (MASK(x[0]) != MASK(y[0])) return 0;
562: for (i = lg(x)-1; i; i--)
563: if (x[i] != y[i]) return 0;
564: return 1;
565: }
566: {
567: jmp_buf env;
568: VOLATILE long av = avma;
569: void *c;
570: if (setjmp(env)) i = 0;
571: else
572: {
573: c = err_catch(-1, env, NULL);
574: i = gcmp0(gadd(x, gneg_i(y)));
575: }
576: err_leave(&c);
577: avma = av;
578: }
579: return i;
580: }
581: #undef MASK
582:
583: /*******************************************************************/
584: /* */
585: /* VALUATION */
586: /* p is either an int or a polynomial. */
587: /* returns the largest exponent of p dividing x when this makes */
588: /* sense : error for types real, integermod and polymod if p does */
589: /* not divide the modulus, q-adic if q!=p. */
590: /* */
591: /*******************************************************************/
592:
593: static long
594: minval(GEN x, GEN p, long first, long lx)
595: {
596: long i,k, val = VERYBIGINT;
597: for (i=first; i<lx; i++)
598: {
599: k = ggval((GEN)x[i],p);
600: if (k < val) val = k;
601: }
602: return val;
603: }
604:
605: long
606: ggval(GEN x, GEN p)
607: {
608: long tx=typ(x), tp=typ(p), av, limit,vx,v,i,val;
609: GEN p1,p2;
610:
611: if (isexactzero(x)) return VERYBIGINT;
612: if (is_const_t(tx) && tp==t_POL) return 0;
613: switch(tx)
614: {
615: case t_INT:
616: if (tp != t_INT) break;
617: av=avma; val = pvaluation(x,p, &p1);
618: avma=av; return val;
619:
620: case t_INTMOD:
621: av=avma;
622: p1=cgeti(lgefint(x[1]));
623: p2=cgeti(lgefint(x[2]));
624: if (tp!=t_INT || !mpdivis((GEN)x[1],p,p1)) break;
625: if (!mpdivis((GEN)x[2],p,p2)) { avma=av; return 0; }
626: val=1; while (mpdivis(p1,p,p1) && mpdivis(p2,p,p2)) val++;
627: avma=av; return val;
628:
629: case t_PADIC:
630: if (tp!=t_INT || !gegal(p,(GEN)x[2])) break;
631: return valp(x);
632:
633: case t_POLMOD:
634: if (tp==t_INT) return ggval((GEN)x[2],p);
635: av = avma;
636: if (tp!=t_POL || !poldivis((GEN)x[1],p,&p1)) break;
637: if (!poldivis((GEN)x[2],p,&p2)) { avma=av; return 0; }
638: val=1; while (poldivis(p1,p,&p1)&&poldivis(p2,p,&p2)) val++;
639: avma = av; return val;
640:
641: case t_POL:
642: if (tp==t_POL)
643: {
644: v=varn(p); vx=varn(x);
645: if (vx == v)
646: {
647: if ((p>=(GEN)polx && p <= (GEN)(polx+MAXVARN)) || ismonome(p))
648: {
649: i=2; while (isexactzero((GEN)x[i])) i++;
650: return i-2;
651: }
652: av = avma; limit=stack_lim(av,1);
653: for (val=0; ; val++)
654: {
655: if (!poldivis(x,p,&x)) break;
656: if (low_stack(limit, stack_lim(av,1)))
657: {
658: if(DEBUGMEM>1) err(warnmem,"ggval");
659: x = gerepilecopy(av, x);
660: }
661: }
662: avma = av; return val;
663: }
664: if (vx > v) return 0;
665: }
666: else if (tp!=t_INT) break;
667: i=2; while (isexactzero((GEN)x[i])) i++;
668: return minval(x,p,i,lgef(x));
669:
670: case t_SER:
671: if (tp!=t_POL && tp!=t_SER && tp!=t_INT) break;
672: v=gvar(p); vx=varn(x);
673: if (vx==v) return (long)(valp(x)/ggval(p,polx[v]));
674: if (vx>v) return 0;
675: return minval(x,p,2,lg(x));
676:
677: case t_FRAC: case t_FRACN: case t_RFRAC: case t_RFRACN:
678: return ggval((GEN)x[1],p) - ggval((GEN)x[2],p);
679:
680: case t_COMPLEX: case t_QUAD: case t_VEC: case t_COL: case t_MAT:
681: return minval(x,p,1,lg(x));
682: }
683: err(talker,"forbidden or conflicting type in gval");
684: return 0; /* not reached */
685: }
686:
687: /* x is non-zero */
688: long
689: svaluation(ulong x, ulong p, long *py)
690: {
691: ulong v = 0;
692: for(;;)
693: {
694: if (x%p) { *py = x; return v; }
695: v++; x/=p;
696: }
697: }
698:
699: /* x is a non-zero integer */
700: long
701: pvaluation(GEN x, GEN p, GEN *py)
702: {
703: long av,v;
704: GEN p1,p2;
705:
706: if (egalii(p,gdeux))
707: {
708: v = vali(x);
709: if (py) *py = shifti(x, -v);
710: return v;
711: }
712: if (is_pm1(p))
713: {
714: v = (signe(p) < 0 && signe(x) < 0);
715: if (py) { *py = v? negi(x): icopy(x); }
716: return v;
717: }
718: if (!is_bigint(x))
719: {
720: long y;
721: if (!is_bigint(p))
722: {
723: v = svaluation(x[2],p[2], &y);
724: if (signe(x) < 0) y = -y;
725: if (py) *py = stoi(y);
726: }
727: else
728: {
729: v = 0;
730: if (py) *py = icopy(x);
731: }
732: return v;
733: }
734: av = avma; v = 0; (void)new_chunk(lgefint(x));
735: for(;;)
736: {
737: p1 = dvmdii(x,p,&p2);
738: if (p2 != gzero) { avma=av; if (py) *py = icopy(x); return v; }
739: v++; x = p1;
740: }
741: }
742:
743: /*******************************************************************/
744: /* */
745: /* NEGATION: Create -x */
746: /* */
747: /*******************************************************************/
748:
749: GEN
750: gneg(GEN x)
751: {
752: long tx=typ(x),lx,i;
753: GEN y;
754:
755: if (gcmp0(x)) return gcopy(x);
756: switch(tx)
757: {
758: case t_INT: case t_REAL:
759: return mpneg(x);
760:
761: case t_INTMOD: y=cgetg(3,t_INTMOD);
762: icopyifstack(x[1],y[1]);
763: y[2] = lsubii((GEN)y[1],(GEN)x[2]);
764: break;
765:
766: case t_POLMOD: y=cgetg(3,t_POLMOD);
767: copyifstack(x[1],y[1]);
768: y[2]=lneg((GEN)x[2]); break;
769:
770: case t_FRAC: case t_FRACN: case t_RFRAC: case t_RFRACN:
771: y=cgetg(3,tx);
772: y[1]=lneg((GEN)x[1]);
773: y[2]=lcopy((GEN)x[2]); break;
774:
775: case t_PADIC:
776: y=cgetp2(x,valp(x));
777: y[4]=lsubii((GEN)x[3],(GEN)x[4]);
778: break;
779:
780: case t_QUAD:
781: y=cgetg(4,t_QUAD); copyifstack(x[1],y[1]);
782: y[2]=lneg((GEN)x[2]);
783: y[3]=lneg((GEN)x[3]); break;
784:
785: case t_COMPLEX: case t_VEC: case t_COL: case t_MAT:
786: lx=lg(x); y=cgetg(lx,tx);
787: for (i=1; i<lx; i++) y[i]=lneg((GEN)x[i]);
788: break;
789:
790: case t_POL:
791: lx=lgef(x); y=cgetg(lx,tx); y[1]=x[1];
792: for (i=2; i<lx; i++) y[i]=lneg((GEN)x[i]);
793: break;
794:
795: case t_SER:
796: lx=lg(x); y=cgetg(lx,tx); y[1]=x[1];
797: for (i=2; i<lx; i++) y[i]=lneg((GEN)x[i]);
798: break;
799:
800: default:
801: err(typeer,"negation");
802: return NULL; /* not reached */
803: }
804: return y;
805: }
806:
807: GEN
808: gneg_i(GEN x)
809: {
810: long tx=typ(x),lx,i;
811: GEN y;
812:
813: if (gcmp0(x)) return x;
814: switch(tx)
815: {
816: case t_INT: case t_REAL:
817: return mpneg(x);
818:
819: case t_INTMOD: y=cgetg(3,t_INTMOD); y[1]=x[1];
820: y[2] = lsubii((GEN)y[1],(GEN)x[2]);
821: break;
822:
823: case t_FRAC: case t_FRACN: case t_RFRAC: case t_RFRACN:
824: y=cgetg(3,tx); y[2]=x[2];
825: y[1]=(long)gneg_i((GEN)x[1]); break;
826:
827: case t_PADIC: y = cgetg(5,t_PADIC); y[2]=x[2]; y[3]=x[3];
828: y[1] = evalprecp(precp(x)) | evalvalp(valp(x));
829: y[4]=lsubii((GEN)x[3],(GEN)x[4]); break;
830:
831: case t_POLMOD: y=cgetg(3,t_POLMOD); y[1]=x[1];
832: y[2]=(long)gneg_i((GEN)x[2]); break;
833:
834: case t_QUAD: y=cgetg(4,t_QUAD); y[1]=x[1];
835: y[2]=(long)gneg_i((GEN)x[2]);
836: y[3]=(long)gneg_i((GEN)x[3]); break;
837:
838: case t_COMPLEX: case t_VEC: case t_COL: case t_MAT:
839: lx=lg(x); y=cgetg(lx,tx);
840: for (i=1; i<lx; i++) y[i]=(long)gneg_i((GEN)x[i]);
841: break;
842:
843: case t_POL: lx=lgef(x); y=cgetg(lx,tx); y[1]=x[1];
844: for (i=2; i<lx; i++) y[i]=(long)gneg_i((GEN)x[i]);
845: break;
846:
847: case t_SER: lx=lg(x); y=cgetg(lx,tx); y[1]=x[1];
848: for (i=2; i<lx; i++) y[i]=(long)gneg_i((GEN)x[i]);
849: break;
850:
851: default:
852: err(typeer,"negation");
853: return NULL; /* not reached */
854: }
855: return y;
856: }
857:
858: /******************************************************************/
859: /* */
860: /* ABSOLUTE VALUE */
861: /* Create abs(x) if x is integer, real, fraction or complex. */
862: /* Error otherwise. */
863: /* */
864: /******************************************************************/
865:
866: GEN
867: gabs(GEN x, long prec)
868: {
869: long tx=typ(x),lx,i,l,tetpil;
870: GEN y,p1;
871:
872: switch(tx)
873: {
874: case t_INT: case t_REAL:
875: return mpabs(x);
876:
877: case t_FRAC: case t_FRACN: y=cgetg(lg(x),tx);
878: y[1]=labsi((GEN)x[1]);
879: y[2]=labsi((GEN)x[2]); return y;
880:
881: case t_COMPLEX:
882: l=avma; p1=gnorm(x);
883: switch(typ(p1))
884: {
885: case t_INT:
886: if (!carrecomplet(p1, &y)) break;
887: return gerepileupto(l, y);
888: case t_FRAC:
889: case t_FRACN:
890: {
891: GEN a,b;
892: if (!carrecomplet((GEN)p1[1], &a)) break;
893: if (!carrecomplet((GEN)p1[2], &b)) break;
894: return gerepileupto(l, gdiv(a,b));
895: }
896: }
897: tetpil=avma;
898: return gerepile(l,tetpil,gsqrt(p1,prec));
899:
900: case t_QUAD:
901: l=avma; p1=gmul(x, realun(prec)); tetpil=avma;
902: return gerepile(l,tetpil,gabs(p1,prec));
903:
904: case t_POL:
905: lx=lgef(x); if (lx<=2) return gcopy(x);
906: p1=(GEN)x[lx-1];
907: switch(typ(p1))
908: {
909: case t_INT: case t_REAL: case t_FRAC: case t_FRACN:
910: if (gsigne(p1)<0) return gneg(x);
911: }
912: return gcopy(x);
913:
914: case t_SER:
915: if (valp(x) || !signe(x) || lg(x)<3)
916: err(talker,"abs is not analytic at 0");
917: if (gsigne((GEN) x[2])<0) return gneg(x);
918: return gcopy(x);
919:
920: case t_VEC: case t_COL: case t_MAT:
921: lx=lg(x); y=cgetg(lx,tx);
922: for (i=1; i<lx; i++)
923: y[i]=(long)gabs((GEN)x[i],prec);
924: return y;
925: }
926: err(typeer,"gabs");
927: return NULL; /* not reached */
928: }
929:
930: GEN
931: gmax(GEN x, GEN y)
932: {
933: if (gcmp(x,y)>0) y=x; return gcopy(y);
934: }
935:
936: GEN
937: gmin(GEN x, GEN y)
938: {
939: if (gcmp(x,y)<0) y=x; return gcopy(y);
940: }
941:
942: GEN
943: vecmax(GEN x)
944: {
945: long tx=typ(x),lx,lx2,i,j;
946: GEN *p1,s;
947:
948: if (!is_matvec_t(tx)) return gcopy(x);
949: lx=lg(x); if (lx==1) return stoi(-VERYBIGINT);
950: if (tx!=t_MAT)
951: {
952: s=(GEN)x[1];
953: for (i=2; i<lx; i++)
954: if (gcmp((GEN)x[i],s) > 0) s=(GEN)x[i];
955: }
956: else
957: {
958: lx2 = lg(x[1]);
959: if (lx2==1) return stoi(-VERYBIGINT);
960: s=gmael(x,1,1); i=2;
961: for (j=1; j<lx; j++)
962: {
963: p1 = (GEN *) x[j];
964: for (; i<lx2; i++)
965: if (gcmp(p1[i],s) > 0) s=p1[i];
966: i=1;
967: }
968: }
969: return gcopy(s);
970: }
971:
972: GEN
973: vecmin(GEN x)
974: {
975: long tx=typ(x),lx,lx2,i,j;
976: GEN *p1,s;
977:
978: if (!is_matvec_t(tx)) return gcopy(x);
979: lx=lg(x); if (lx==1) return stoi(VERYBIGINT);
980: if (tx!=t_MAT)
981: {
982: s=(GEN)x[1];
983: for (i=2; i<lx; i++)
984: if (gcmp((GEN)x[i],s) < 0) s=(GEN)x[i];
985: }
986: else
987: {
988: lx2 = lg(x[1]);
989: if (lx2==1) return stoi(VERYBIGINT);
990: s=gmael(x,1,1); i=2;
991: for (j=1; j<lx; j++)
992: {
993: p1 = (GEN *) x[j];
994: for (; i<lx2; i++)
995: if (gcmp(p1[i],s) < 0) s=p1[i];
996: i=1;
997: }
998: }
999: return gcopy(s);
1000: }
1001:
1002: /*******************************************************************/
1003: /* */
1004: /* AFFECT long --> GEN */
1005: /* affect long s to GEN x. Useful for initialization. */
1006: /* */
1007: /*******************************************************************/
1008:
1009: static void
1010: padicaff0(GEN x)
1011: {
1012: if (signe(x[4]))
1013: {
1014: setvalp(x, valp(x)|precp(x));
1015: affsi(0,(GEN)x[4]);
1016: }
1017: }
1018:
1019: void
1020: gaffsg(long s, GEN x)
1021: {
1022: long l,i,v;
1023: GEN p;
1024:
1025: switch(typ(x))
1026: {
1027: case t_INT:
1028: affsi(s,x); break;
1029:
1030: case t_REAL:
1031: affsr(s,x); break;
1032:
1033: case t_INTMOD:
1034: modsiz(s,(GEN)x[1],(GEN)x[2]); break;
1035:
1036: case t_FRAC: case t_FRACN:
1037: affsi(s,(GEN)x[1]); affsi(1,(GEN)x[2]); break;
1038:
1039: case t_COMPLEX:
1040: gaffsg(s,(GEN)x[1]); gaffsg(0,(GEN)x[2]); break;
1041:
1042: case t_PADIC:
1043: if (!s) { padicaff0(x); break; }
1044: p = (GEN)x[2];
1045: v = (is_bigint(p))? 0: svaluation(s,p[2], &i);
1046: setvalp(x,v); modsiz(i,(GEN)x[3],(GEN)x[4]);
1047: break;
1048:
1049: case t_QUAD:
1050: gaffsg(s,(GEN)x[2]); gaffsg(0,(GEN)x[3]); break;
1051:
1052: case t_POLMOD:
1053: gaffsg(s,(GEN)x[2]); break;
1054:
1055: case t_POL:
1056: v=varn(x);
1057: if (!s) x[1]=evallgef(2) | evalvarn(v);
1058: else
1059: {
1060: x[1]=evalsigne(1) | evallgef(3) | evalvarn(v);
1061: gaffsg(s,(GEN)x[2]);
1062: }
1063: break;
1064:
1065: case t_SER:
1066: v=varn(x); gaffsg(s,(GEN)x[2]); l=lg(x);
1067: if (!s)
1068: x[1] = evalvalp(l-2) | evalvarn(v);
1069: else
1070: x[1] = evalsigne(1) | evalvalp(0) | evalvarn(v);
1071: for (i=3; i<l; i++) gaffsg(0,(GEN)x[i]);
1072: break;
1073:
1074: case t_RFRAC: case t_RFRACN:
1075: gaffsg(s,(GEN)x[1]); gaffsg(1,(GEN)x[2]); break;
1076:
1077: case t_VEC: case t_COL: case t_MAT:
1078: if (lg(x)!=2) err(operi,"",t_INT,typ(x));
1079: gaffsg(s,(GEN)x[1]); break;
1080:
1081: default: err(operf,"",t_INT,typ(x));
1082: }
1083: }
1084:
1085: /*******************************************************************/
1086: /* */
1087: /* GENERIC AFFECTATION */
1088: /* Affect the content of x to y, whenever possible */
1089: /* */
1090: /*******************************************************************/
1091: void
1092: gaffect(GEN x, GEN y)
1093: {
1094: long i,j,k,l,v,vy,lx,ly,tx,ty,av;
1095: GEN p1,num,den;
1096:
1097:
1098: tx=typ(x); ty=typ(y); lx=lg(x); ly=lg(y);
1099: if (is_scalar_t(tx))
1100: {
1101: if (is_scalar_t(ty))
1102: {
1103: switch(tx)
1104: {
1105: case t_INT:
1106: switch(ty)
1107: {
1108: case t_INT:
1109: /* y = gzero, gnil, gun or gdeux */
1110: if (is_universal_constant(y))
1111: {
1112: if (y==gzero) err(overwriter,"gaffect (gzero)");
1113: if (y==gun) err(overwriter,"gaffect (gun)");
1114: if (y==gdeux) err(overwriter,"gaffect (gdeux)");
1115: err(overwriter,"gaffect (gnil)");
1116: }
1117: affii(x,y); break;
1118:
1119: case t_REAL:
1120: if (y == gpi) err(overwriter,"gaffect (gpi)");
1121: if (y==geuler) err(overwriter,"gaffect (geuler)");
1122: affir(x,y); break;
1123:
1124: case t_INTMOD:
1125: modiiz(x,(GEN)y[1],(GEN)y[2]); break;
1126:
1127: case t_FRAC:
1128: if (y == ghalf) err(overwriter,"gaffect (ghalf)");
1129: case t_FRACN:
1130: affii(x,(GEN)y[1]); affsi(1,(GEN)y[2]); break;
1131:
1132: case t_COMPLEX:
1133: if (y == gi) err(overwriter,"gaffect (gi)");
1134: gaffect(x,(GEN)y[1]); gaffsg(0,(GEN)y[2]); break;
1135:
1136: case t_PADIC:
1137: if (!signe(x)) { padicaff0(y); break; }
1138: l=avma;
1139: setvalp(y, pvaluation(x,(GEN)y[2],&p1));
1140: modiiz(p1,(GEN)y[3],(GEN)y[4]);
1141: avma=l; break;
1142:
1143: case t_QUAD:
1144: gaffect(x,(GEN)y[2]); gaffsg(0,(GEN)y[3]); break;
1145:
1146: case t_POLMOD:
1147: gaffect(x,(GEN)y[2]); break;
1148:
1149: default: err(operf,"",tx,ty);
1150: }
1151: break;
1152:
1153: case t_REAL:
1154: switch(ty)
1155: {
1156: case t_REAL:
1157: affrr(x,y); break;
1158:
1159: case t_COMPLEX:
1160: gaffect(x,(GEN)y[1]); gaffsg(0,(GEN)y[2]); break;
1161:
1162: case t_POLMOD:
1163: gaffect(x,(GEN)y[2]); break;
1164:
1165: case t_INT: case t_INTMOD: case t_FRAC:
1166: case t_FRACN: case t_PADIC: case t_QUAD:
1167: err(operf,"",tx,ty);
1168:
1169: default: err(operf,"",tx,ty);
1170: }
1171: break;
1172:
1173: case t_INTMOD:
1174: switch(ty)
1175: {
1176: case t_INTMOD:
1177: if (!divise((GEN)x[1],(GEN)y[1]))
1178: err(operi,"",tx,ty);
1179: modiiz((GEN)x[2],(GEN)y[1],(GEN)y[2]); break;
1180:
1181: case t_POLMOD:
1182: gaffect(x,(GEN)y[2]); break;
1183:
1184: default: err(operf,"",tx,ty);
1185: }
1186: break;
1187:
1188: case t_FRAC:
1189: switch(ty)
1190: {
1191: case t_INT:
1192: if (! mpdivis((GEN)x[1],(GEN)x[2],y))
1193: err(operi,"",tx,ty);
1194: break;
1195:
1196: case t_REAL:
1197: diviiz((GEN)x[1],(GEN)x[2],y); break;
1198:
1199: case t_INTMOD:
1200: av=avma; p1=mpinvmod((GEN)x[2],(GEN)y[1]);
1201: modiiz(mulii((GEN)x[1],p1),(GEN)y[1],(GEN)y[2]);
1202: avma=av; break;
1203:
1204: case t_FRAC: case t_FRACN:
1205: affii((GEN)x[1],(GEN)y[1]);
1206: affii((GEN)x[2],(GEN)y[2]);
1207: break;
1208:
1209: case t_COMPLEX:
1210: gaffect(x,(GEN)y[1]); gaffsg(0,(GEN)y[2]); break;
1211:
1212: case t_PADIC:
1213: if (!signe(x[1])) { padicaff0(y); break; }
1214: av=avma; num=(GEN)x[1]; den=(GEN)x[2];
1215: v = pvaluation(num, (GEN) y[2], &num);
1216: if (!v) v = -pvaluation(den,(GEN)y[2],&den);
1217: p1=mulii(num,mpinvmod(den,(GEN)y[3]));
1218: modiiz(p1,(GEN)y[3],(GEN)y[4]); avma=av;
1219: setvalp(y,v); break;
1220:
1221: case t_QUAD:
1222: gaffect(x,(GEN)y[2]); gaffsg(0,(GEN)y[3]); break;
1223: case t_POLMOD:
1224: gaffect(x,(GEN)y[2]); break;
1225: default: err(operf,"",tx,ty);
1226: }
1227: break;
1228:
1229: case t_FRACN:
1230: switch(ty)
1231: {
1232: case t_INT:
1233: if (! mpdivis((GEN)x[1],(GEN)x[2],y)) err(operi,"",tx,ty);
1234: break;
1235:
1236: case t_REAL:
1237: diviiz((GEN)x[1],(GEN)x[2],y); break;
1238: case t_INTMOD:
1239: av=avma; gaffect(gred(x),y); avma=av; break;
1240: case t_FRAC:
1241: gredz(x,y); break;
1242: case t_FRACN:
1243: affii((GEN)x[1],(GEN)y[1]);
1244: affii((GEN)x[2],(GEN)y[2]); break;
1245: case t_COMPLEX:
1246: gaffect(x,(GEN)y[1]); gaffsg(0,(GEN)y[2]); break;
1247: case t_PADIC:
1248: if (!signe(x[1])) { padicaff0(y); break; }
1249: av=avma; num=(GEN)x[1]; den=(GEN)x[2];
1250: v = pvaluation(num,(GEN)y[2],&num)
1251: - pvaluation(den,(GEN)y[2],&den);
1252: p1=mulii(num,mpinvmod(den,(GEN)y[3]));
1253: modiiz(p1,(GEN)y[3],(GEN)y[4]); avma=av;
1254: setvalp(y,v); break;
1255:
1256: case t_QUAD:
1257: gaffect(x,(GEN)y[2]); gaffsg(0,(GEN)y[3]); break;
1258: case t_POLMOD:
1259: gaffect(x,(GEN)y[2]); break;
1260: default: err(operf,"",tx,ty);
1261: }
1262: break;
1263:
1264: case t_COMPLEX:
1265: switch(ty)
1266: {
1267: case t_INT: case t_REAL: case t_INTMOD:
1268: case t_FRAC: case t_FRACN: case t_PADIC: case t_QUAD:
1269: if (!gcmp0((GEN)x[2])) err(operi,"",tx,ty);
1270: gaffect((GEN)x[1],y); break;
1271:
1272: case t_COMPLEX:
1273: gaffect((GEN)x[1],(GEN)y[1]);
1274: gaffect((GEN)x[2],(GEN)y[2]);
1275: break;
1276:
1277: case t_POLMOD:
1278: gaffect(x,(GEN)y[2]); break;
1279:
1280: default: err(operf,"",tx,ty);
1281: }
1282: break;
1283:
1284: case t_PADIC:
1285: switch(ty)
1286: {
1287: case t_INTMOD:
1288: if (valp(x)<0) err(operi,"",tx,ty);
1289: av=avma;
1290: v = pvaluation((GEN)y[1],(GEN)x[2],&p1);
1291: k = signe(x[4])? (precp(x)+valp(x)): valp(x)+1;
1292: if (!gcmp1(p1) || v > k) err(operi,"",tx,ty);
1293: modiiz(gtrunc(x),(GEN)y[1],(GEN)y[2]); avma=av; break;
1294:
1295: case t_PADIC:
1296: if (!egalii((GEN)x[2],(GEN)y[2])) err(operi,"",tx,ty);
1297: modiiz((GEN)x[4],(GEN)y[3],(GEN)y[4]);
1298: setvalp(y,valp(x)); break;
1299:
1300: case t_POLMOD:
1301: gaffect(x,(GEN)y[2]); break;
1302:
1303: default: err(operf,"",tx,ty);
1304: }
1305: break;
1306:
1307: case t_QUAD:
1308: switch(ty)
1309: {
1310: case t_INT: case t_INTMOD: case t_FRAC:
1311: case t_FRACN: case t_PADIC:
1312: if (!gcmp0((GEN)x[3])) err(operi,"",tx,ty);
1313: gaffect((GEN)x[2],y); break;
1314:
1315: case t_REAL:
1316: av=avma; p1=co8(x,ly); gaffect(p1,y); avma=av; break;
1317: case t_COMPLEX:
1318: ly=precision(y);
1319: if (ly)
1320: {
1321: av=avma; p1=co8(x,ly); gaffect(p1,y); avma=av;
1322: }
1323: else
1324: {
1325: if (!gcmp0((GEN)x[3])) err(operi,"",tx,ty);
1326: gaffect((GEN)x[2],y);
1327: }
1328: break;
1329:
1330: case t_QUAD:
1331: if (! gegal((GEN)x[1],(GEN)y[1])) err(operi,"",tx,ty);
1332: affii((GEN)x[2],(GEN)y[2]);
1333: affii((GEN)x[3],(GEN)y[3]);
1334: break;
1335: case t_POLMOD:
1336: gaffect(x,(GEN)y[2]); break;
1337: default: err(operf,"",tx,ty);
1338: }
1339: break;
1340:
1341: case t_POLMOD:
1342: if (ty!=t_POLMOD) err(operf,"",tx,ty);
1343: if (! gdivise((GEN)x[1],(GEN)y[1])) err(operi,"",tx,ty);
1344: gmodz((GEN)x[2],(GEN)y[1],(GEN)y[2]); break;
1345:
1346: default: err(operf,"",tx,ty);
1347: }
1348: return;
1349: }
1350:
1351: /* here y is not scalar */
1352: switch(ty)
1353: {
1354: case t_POL:
1355: v=varn(y);
1356: if (y==polun[v] || y==polx[v])
1357: err(talker,"trying to overwrite a universal polynomial");
1358: gaffect(x,(GEN)y[2]);
1359: for (i=3; i<ly; i++) gaffsg(0,(GEN)y[i]);
1360: if (gcmp0(x)) y[1]=evallgef(2)+evalvarn(v);
1361: else y[1]=evalsigne(1)+evallgef(3)+evalvarn(v);
1362: break;
1363:
1364: case t_SER:
1365: v=varn(y); gaffect(x,(GEN)y[2]);
1366: if (gcmp0(x))
1367: y[1] = evalvalp(ly-2) | evalvarn(v);
1368: else
1369: y[1] = evalsigne(1) | evalvalp(0) | evalvarn(v);
1370: for (i=3; i<ly; i++) gaffsg(0,(GEN)y[i]);
1371: break;
1372:
1373: case t_RFRAC: case t_RFRACN:
1374: gaffect(x,(GEN)y[1]); gaffsg(1,(GEN)y[2]); break;
1375:
1376: default: err(operf,"",tx,ty);
1377: }
1378: return;
1379: }
1380:
1381: if (is_const_t(ty)) {
1382: #define initial_value(ep) ((ep)+1)
1383: if (tx == t_POL) {
1384: entree *var = varentries[ordvar[varn(x)]];
1385: /* Is a bound expression, thus should not loop: */
1386: if (var && var->value != (void*)initial_value(var)) {
1387: gaffect(geval(x),y);
1388: return;
1389: }
1390: } else if (is_rfrac_t(tx)) {
1391: GEN num = (GEN)x[1], den = (GEN)x[2];
1392: entree *varnum = varentries[ordvar[varn(num)]];
1393: entree *varden = varentries[ordvar[varn(den)]];
1394:
1395: /* Are bound expressions, thus should not loop: */
1396: if (varnum && varnum->value != (void*)initial_value(varnum)
1397: && varden && varden->value != (void*)initial_value(varden)) {
1398: gaffect(geval(x),y);
1399: return;
1400: }
1401: }
1402: #undef initial_value
1403: err(operf,"",tx,ty);
1404: }
1405:
1406: switch(tx)
1407: {
1408: case t_POL:
1409: v=varn(x);
1410: switch(ty)
1411: {
1412: case t_POL:
1413: vy=varn(y); if (vy>v) err(operf,"",tx,ty);
1414: if (vy==v)
1415: {
1416: l=lgef(x); if (l>ly) err(operi,"",tx,ty);
1417: y[1]=x[1]; for (i=2; i<l; i++) gaffect((GEN)x[i],(GEN)y[i]);
1418: }
1419: else
1420: {
1421: gaffect(x,(GEN)y[2]);
1422: for (i=3; i<ly; i++) gaffsg(0,(GEN)y[i]);
1423: if (signe(x)) y[1]=evalsigne(1)+evallgef(3)+evalvarn(vy);
1424: else y[1]=evallgef(2)+evalvarn(vy);
1425: }
1426: break;
1427:
1428: case t_SER:
1429: vy=varn(y); if (vy>v) err(operf,"",tx,ty);
1430: if (!signe(x)) { gaffsg(0,y); return; }
1431: if (vy==v)
1432: {
1433: i=gval(x,v); y[1]=evalvarn(v) | evalvalp(i) | evalsigne(1);
1434: k=lgef(x)-i; if (k>ly) k=ly;
1435: for (j=2; j<k; j++) gaffect((GEN)x[i+j],(GEN)y[j]);
1436: for ( ; j<ly; j++) gaffsg(0,(GEN)y[j]);
1437: }
1438: else
1439: {
1440: gaffect(x,(GEN)y[2]);
1441: if (!signe(x))
1442: y[1] = evalvalp(ly-2) | evalvarn(vy);
1443: else
1444: y[1] = evalsigne(1) | evalvalp(0) | evalvarn(vy);
1445: for (i=3; i<ly; i++) gaffsg(0,(GEN)y[i]);
1446: }
1447: break;
1448:
1449: case t_POLMOD:
1450: gmodz(x,(GEN)y[1],(GEN)y[2]); break;
1451:
1452: case t_RFRAC: case t_RFRACN:
1453: gaffect(x,(GEN)y[1]); gaffsg(1,(GEN)y[2]); break;
1454:
1455: default: err(operf,"",tx,ty);
1456: }
1457: break;
1458:
1459: case t_SER:
1460: if (ty!=t_SER) err(operf,"",tx,ty);
1461: v=varn(x); vy=varn(y); if (vy>v) err(operf,"",tx,ty);
1462: if (vy==v)
1463: {
1464: y[1]=x[1]; k=lx; if (k>ly) k=ly;
1465: for (i=2; i< k; i++) gaffect((GEN)x[i],(GEN)y[i]);
1466: for ( ; i<ly; i++) gaffsg(0,(GEN)y[i]);
1467: }
1468: else
1469: {
1470: gaffect(x,(GEN)y[2]);
1471: if (!signe(x))
1472: y[1] = evalvalp(ly-2) | evalvarn(vy);
1473: else
1474: y[1] = evalsigne(1) | evalvalp(0) | evalvarn(vy);
1475: for (i=3; i<ly; i++) gaffsg(0,(GEN)y[i]);
1476: }
1477: break;
1478:
1479: case t_RFRAC: case t_RFRACN:
1480: switch(ty)
1481: {
1482: case t_POL: case t_VEC: case t_COL: case t_MAT:
1483: err(operf,"",tx,ty);
1484:
1485: case t_POLMOD:
1486: av=avma; p1=ginvmod((GEN)x[2],(GEN)y[1]);
1487: gmodz(gmul((GEN)x[1],p1),(GEN)y[1],(GEN)y[2]);
1488: avma=av; break;
1489:
1490: case t_SER:
1491: gdivz((GEN)x[1],(GEN)x[2],y); break;
1492:
1493: case t_RFRAC:
1494: if (tx==t_RFRACN) gredz(x,y);
1495: else
1496: {
1497: gaffect((GEN)x[1],(GEN)y[1]);
1498: gaffect((GEN)x[2],(GEN)y[2]);
1499: }
1500: break;
1501:
1502: case t_RFRACN:
1503: gaffect((GEN)x[1],(GEN)y[1]);
1504: gaffect((GEN)x[2],(GEN)y[2]); break;
1505:
1506: default: err(operf,"",tx,ty);
1507: }
1508: break;
1509:
1510: case t_QFR: case t_QFI: case t_VEC: case t_COL: case t_MAT:
1511: if (ty != tx || ly != lx) err(operi,"",tx,ty);
1512: for (i=1; i<lx; i++) gaffect((GEN)x[i],(GEN)y[i]);
1513: break;
1514:
1515: default: err(operf,"",tx,ty);
1516: }
1517: }
1518:
1519: /*******************************************************************/
1520: /* */
1521: /* CONVERSION QUAD --> REAL, COMPLEX OR P-ADIC */
1522: /* */
1523: /*******************************************************************/
1524:
1525: GEN
1526: co8(GEN x, long prec)
1527: {
1528: long av=avma,tetpil;
1529: GEN p1, p = (GEN) x[1];
1530:
1531: p1 = subii(sqri((GEN)p[3]), shifti((GEN)p[2],2));
1532: if (signe(p1) > 0)
1533: {
1534: p1 = subri(gsqrt(p1,prec), (GEN)p[3]);
1535: setexpo(p1, expo(p1)-1);
1536: }
1537: else
1538: {
1539: p1 = gsub(gsqrt(p1,prec), (GEN)p[3]);
1540: p1[1] = lmul2n((GEN)p1[1],-1);
1541: setexpo(p1[2], expo(p1[2])-1);
1542: }/* p1 = (-b + sqrt(D)) / 2 */
1543: p1 = gmul((GEN)x[3],p1); tetpil=avma;
1544: return gerepile(av,tetpil,gadd((GEN)x[2],p1));
1545: }
1546:
1547: GEN
1548: cvtop(GEN x, GEN p, long l)
1549: {
1550: GEN p1,p2,p3;
1551: long av,tetpil,n;
1552:
1553: if (typ(p)!=t_INT)
1554: err(talker,"not an integer modulus in cvtop or gcvtop");
1555: if (gcmp0(x)) return ggrandocp(p,l);
1556: switch(typ(x))
1557: {
1558: case t_INT:
1559: return gadd(x,ggrandocp(p,ggval(x,p)+l));
1560:
1561: case t_INTMOD:
1562: n=ggval((GEN)x[1],p); if (n>l) n=l;
1563: return gadd((GEN)x[2],ggrandocp(p,n));
1564:
1565: case t_FRAC: case t_FRACN:
1566: n = ggval((GEN)x[1],p) - ggval((GEN)x[2],p);
1567: return gadd(x,ggrandocp(p,n+l));
1568:
1569: case t_COMPLEX:
1570: av=avma; p1=gsqrt(gaddgs(ggrandocp(p,l),-1),0);
1571: p1=gmul(p1,(GEN)x[2]); tetpil=avma;
1572: return gerepile(av,tetpil,gadd(p1,(GEN)x[1]));
1573:
1574: case t_PADIC:
1575: return gprec(x,l);
1576:
1577: case t_QUAD:
1578: av=avma; p1=(GEN)x[1]; p3=gmul2n((GEN)p1[3],-1);
1579: p2=gsub(gsqr(p3),(GEN)p1[2]);
1580: switch(typ(p2))
1581: {
1582: case t_INT:
1583: n=ggval(p2,p); p2=gadd(p2,ggrandocp(p,n+l)); break;
1584:
1585: case t_INTMOD: case t_PADIC:
1586: break;
1587:
1588: case t_FRAC: case t_FRACN:
1589: n = ggval((GEN)p2[1],p) - ggval((GEN)p2[2],p);
1590: p2=gadd(p2,ggrandocp(p,n+l)); break;
1591:
1592: default: err(operi,"",t_QUAD,t_QUAD);
1593: }
1594: p2=gsqrt(p2,0); p1=gmul((GEN)x[3],gsub(p2,p3)); tetpil=avma;
1595: return gerepile(av,tetpil,gadd((GEN)x[2],p1));
1596:
1597: }
1598: err(typeer,"cvtop");
1599: return NULL; /* not reached */
1600: }
1601:
1602: GEN
1603: gcvtop(GEN x, GEN p, long r)
1604: {
1605: long i,lx, tx=typ(x);
1606: GEN y;
1607:
1608: if (is_const_t(tx)) return cvtop(x,p,r);
1609: switch(tx)
1610: {
1611: case t_POL:
1612: lx=lgef(x); y=cgetg(lx,t_POL); y[1]=x[1];
1613: for (i=2; i<lx; i++)
1614: y[i]=(long)gcvtop((GEN)x[i],p,r);
1615: break;
1616:
1617: case t_SER:
1618: lx=lg(x); y=cgetg(lx,t_SER); y[1]=x[1];
1619: for (i=2; i<lx; i++)
1620: y[i]=(long)gcvtop((GEN)x[i],p,r);
1621: break;
1622:
1623: case t_POLMOD: case t_RFRAC: case t_RFRACN:
1624: case t_VEC: case t_COL: case t_MAT:
1625: lx=lg(x); y=cgetg(lx,tx);
1626: for (i=1; i<lx; i++)
1627: y[i]=(long)gcvtop((GEN)x[i],p,r);
1628: break;
1629:
1630: default: err(typeer,"gcvtop");
1631: return NULL; /* not reached */
1632: }
1633: return y;
1634: }
1635:
1636: long
1637: gexpo(GEN x)
1638: {
1639: long tx=typ(x),lx,e,i,y,av;
1640:
1641: switch(tx)
1642: {
1643: case t_INT:
1644: return expi(x);
1645:
1646: case t_FRAC: case t_FRACN:
1647: if (!signe(x[1])) return -HIGHEXPOBIT;
1648: return expi((GEN)x[1]) - expi((GEN)x[2]);
1649:
1650: case t_REAL:
1651: return expo(x);
1652:
1653: case t_COMPLEX:
1654: e = gexpo((GEN)x[1]);
1655: y = gexpo((GEN)x[2]); return max(e,y);
1656:
1657: case t_QUAD:
1658: av=avma; e = gexpo(co8(x,3)); avma=av; return e;
1659:
1660: case t_POL: case t_SER: case t_VEC: case t_COL: case t_MAT:
1661: lx=(tx==t_POL)? lgef(x): lg(x);
1662: y = -HIGHEXPOBIT;
1663: for (i=lontyp[tx]; i<lx; i++) { e=gexpo((GEN)x[i]); if (e>y) y=e; }
1664: return y;
1665: }
1666: err(typeer,"gexpo");
1667: return 0; /* not reached */
1668: }
1669:
1670: long
1671: sizedigit(GEN x)
1672: {
1673: return gcmp0(x)? 0: (long) ((gexpo(x)+1) * L2SL10) + 1;
1674: }
1675:
1676: /* Normalize series x in place.
1677: * Assumption: x,x[2],...,x[lg(x)-1] have been created in that order.
1678: * All intermediate objects will be destroyed.
1679: */
1680: GEN
1681: normalize(GEN x)
1682: {
1683: long i,j, lx = lg(x);
1684:
1685: if (typ(x)!=t_SER) err(typeer,"normalize");
1686: if (lx==2) { setsigne(x,0); avma = (long) x; return x; }
1687: if (! isexactzero((GEN)x[2])) { setsigne(x,1); return x; }
1688:
1689: for (i=3; i<lx; i++)
1690: if (! isexactzero((GEN)x[i]))
1691: {
1692: long tetpil = avma;
1693: GEN p1 = cgetg(lx-i+2,t_SER);
1694: p1[1] = evalsigne(1) | evalvalp(valp(x)+i-2) | evalvarn(varn(x));
1695: j=i; i=2; while (j<lx) p1[i++] = lcopy((GEN)x[j++]);
1696: return gerepile((long) (x+lx),tetpil,p1);
1697: }
1698: avma = (long) (x+lx); return zeroser(varn(x),lx-2);
1699: }
1700:
1701: GEN
1702: normalizepol_i(GEN x, long lx)
1703: {
1704: long i;
1705: for (i=lx-1; i>1; i--)
1706: if (! isexactzero((GEN)x[i])) break;
1707: setlgef(x,i+1);
1708: for (; i>1; i--)
1709: if (! gcmp0((GEN)x[i]) ) { setsigne(x,1); return x; }
1710: setsigne(x,0); return x;
1711: }
1712:
1713: /* Normalize polynomial x in place. See preceding comment */
1714: GEN
1715: normalizepol(GEN x)
1716: {
1717: if (typ(x)!=t_POL) err(typeer,"normalizepol");
1718: return normalizepol_i(x, lgef(x));
1719: }
1720:
1721: int
1722: gsigne(GEN x)
1723: {
1724: switch(typ(x))
1725: {
1726: case t_INT: case t_REAL:
1727: return signe(x);
1728:
1729: case t_FRAC: case t_FRACN:
1730: return (signe(x[2])>0) ? signe(x[1]) : -signe(x[1]);
1731: }
1732: err(typeer,"gsigne");
1733: return 0; /* not reached */
1734: }
1735:
1736: /*******************************************************************/
1737: /* */
1738: /* LISTS */
1739: /* */
1740: /*******************************************************************/
1741:
1742: GEN
1743: listcreate(long n)
1744: {
1745: GEN list;
1746:
1747: if (n<0) err(talker,"negative length in listcreate");
1748: n += 2;
1749: if (n & ~LGEFBITS) err(talker,"list too long (max = %ld)",LGEFBITS-2);
1750: list=cgetg(n,t_LIST); list[1]=evallgef(2);
1751: return list;
1752: }
1753:
1754: static void
1755: listaffect(GEN list, long index, GEN object)
1756: {
1757: if (index<lgef(list) && isclone(list[index]))
1758: gunclone((GEN)list[index]);
1759: list[index]=lclone(object);
1760: }
1761:
1762: void
1763: listkill(GEN list)
1764: {
1765: long lx,i;
1766:
1767: if (typ(list)!=t_LIST) err(typeer,"listkill");
1768: lx=lgef(list);
1769: for (i=2; i<lx; i++)
1770: if (isclone(list[i])) gunclone((GEN)list[i]);
1771: list[1]=evallgef(2); return;
1772: }
1773:
1774: GEN
1775: listput(GEN list, GEN object, long index)
1776: {
1777: long lx=lgef(list);
1778:
1779: if (typ(list)!=t_LIST) err(typeer,"listput");
1780: if (index < 0) err(talker,"negative index (%ld) in listput", index);
1781: if (!index || index >= lx-1)
1782: {
1783: index = lx-1; lx++;
1784: if (lx > lg(list))
1785: err(talker,"no more room in this list (size %ld)", lg(list)-2);
1786: }
1787: listaffect(list,index+1,object);
1788: list[1]=evallgef(lx);
1789: return (GEN)list[index+1];
1790: }
1791:
1792: GEN
1793: listinsert(GEN list, GEN object, long index)
1794: {
1795: long lx = lgef(list), i;
1796:
1797: if (typ(list)!=t_LIST) err(typeer,"listinsert");
1798: if (index <= 0 || index > lx-1) err(talker,"bad index in listinsert");
1799: lx++; if (lx > lg(list)) err(talker,"no more room in this list");
1800:
1801: for (i=lx-2; i > index; i--) list[i+1]=list[i];
1802: list[index+1] = lclone(object);
1803: list[1] = evallgef(lx); return (GEN)list[index+1];
1804: }
1805:
1806: GEN
1807: gtolist(GEN x)
1808: {
1809: long tx,lx,i;
1810: GEN list;
1811:
1812: if (!x) { list = cgetg(2, t_LIST); list[1] = evallgef(2); return list; }
1813:
1814: tx = typ(x);
1815: lx = (tx==t_LIST)? lgef(x): lg(x);
1816: switch(tx)
1817: {
1818: case t_VEC: case t_COL:
1819: lx++; x--; /* fall through */
1820: case t_LIST:
1821: list = cgetg(lx,t_LIST);
1822: for (i=2; i<lx; i++) list[i] = lclone((GEN)x[i]);
1823: break;
1824: default: err(typeer,"gtolist");
1825: return NULL; /* not reached */
1826: }
1827: list[1] = evallgef(lx); return list;
1828: }
1829:
1830: GEN
1831: listconcat(GEN list1, GEN list2)
1832: {
1833: long i,l1,lx;
1834: GEN list;
1835:
1836: if (typ(list1)!=t_LIST || typ(list2)!=t_LIST)
1837: err(typeer,"listconcat");
1838: l1=lgef(list1)-2; lx=l1+lgef(list2);
1839: list = listcreate(lx-2);
1840: for (i=2; i<=l1+1; i++) listaffect(list,i,(GEN)list1[i]);
1841: for ( ; i<lx; i++) listaffect(list,i,(GEN)list2[i-l1]);
1842: list[1]=evallgef(lx); return list;
1843: }
1844:
1845: GEN
1846: listsort(GEN list, long flag)
1847: {
1848: long i,av=avma, c=list[1], lx = lgef(list)-1;
1849: GEN perm,vec,l;
1850:
1851: if (typ(list) != t_LIST) err(typeer,"listsort");
1852: vec = list+1;
1853: vec[0] = evaltyp(t_VEC) | evallg(lx);
1854: perm = sindexsort(vec);
1855: list[1] = c; l = cgetg(lx,t_VEC);
1856: for (i=1; i<lx; i++) l[i] = vec[perm[i]];
1857: if (flag)
1858: {
1859: c=1; vec[1] = l[1];
1860: for (i=2; i<lx; i++)
1861: if (!gegal((GEN)l[i], (GEN)vec[c]))
1862: vec[++c] = l[i];
1863: else
1864: if (isclone(l[i])) gunclone((GEN)l[i]);
1865: setlgef(list,c+2);
1866: }
1867: else
1868: for (i=1; i<lx; i++) vec[i] = l[i];
1869:
1870: avma=av; return list;
1871: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>