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