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