Annotation of OpenXM_contrib/pari-2.2/src/basemath/gen1.c, Revision 1.1
1.1 ! noro 1: /* $Id: gen1.c,v 1.33 2001/09/27 19:39:38 karim Exp $
! 2:
! 3: Copyright (C) 2000 The PARI group.
! 4:
! 5: This file is part of the PARI/GP package.
! 6:
! 7: PARI/GP is free software; you can redistribute it and/or modify it under the
! 8: terms of the GNU General Public License as published by the Free Software
! 9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
! 10: ANY WARRANTY WHATSOEVER.
! 11:
! 12: Check the License for details. You should have received a copy of it, along
! 13: with the package; see the file 'COPYING'. If not, write to the Free Software
! 14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
! 15:
! 16: /********************************************************************/
! 17: /** **/
! 18: /** GENERIC OPERATIONS **/
! 19: /** (first part) **/
! 20: /** **/
! 21: /********************************************************************/
! 22: #include "pari.h"
! 23:
! 24: #define swapspec(x,y, nx,ny) {long _a=nx;GEN _z=x; nx=ny; ny=_a; x=y; y=_z;}
! 25: #define fix_frac(z) if (signe(z[2])<0)\
! 26: {\
! 27: setsigne(z[1],-signe(z[1]));\
! 28: setsigne(z[2],1);\
! 29: }
! 30:
! 31: /* assume z[1] was created last */
! 32: #define fix_frac_if_int(z) if (is_pm1(z[2]))\
! 33: z = gerepileupto((long)(z+3), (GEN)z[1]);
! 34:
! 35: /* assume z[1] was created last */
! 36: #define fix_frac_if_int_GC(z,tetpil) { if (is_pm1(z[2]))\
! 37: z = gerepileupto((long)(z+3), (GEN)z[1]);\
! 38: else\
! 39: gerepilemanyvec((long)z, tetpil, z+1, 2); }
! 40:
! 41: GEN quickmul(GEN a, GEN b, long na, long nb);
! 42:
! 43: #define cpifstack(x) isonstack(x)?gcopy(x):x
! 44: /* y is a polmod, f is gadd or gmul */
! 45: static GEN
! 46: op_polmod(GEN f(GEN,GEN), GEN x, GEN y, long tx)
! 47: {
! 48: GEN mod,k,l, z=cgetg(3,t_POLMOD);
! 49: long av,tetpil;
! 50:
! 51: l=(GEN)y[1];
! 52: if (tx==t_POLMOD)
! 53: {
! 54: k=(GEN)x[1];
! 55: if (gegal(k,l))
! 56: { mod=cpifstack(k); x=(GEN)x[2]; y=(GEN)y[2]; }
! 57: else
! 58: {
! 59: long vx=varn(k), vy=varn(l);
! 60: if (vx==vy) { mod=srgcd(k,l); x=(GEN)x[2]; y=(GEN)y[2]; }
! 61: else
! 62: if (vx<vy) { mod=cpifstack(k); x=(GEN)x[2]; }
! 63: else { mod=cpifstack(l); y=(GEN)y[2]; }
! 64: }
! 65: }
! 66: else
! 67: {
! 68: mod=cpifstack(l); y=(GEN)y[2];
! 69: if (is_scalar_t(tx))
! 70: {
! 71: z[2] = (long)f(x,y);
! 72: z[1] = (long)mod; return z;
! 73: }
! 74: }
! 75: av=avma; x = f(x,y); tetpil=avma;
! 76: z[2] = lpile(av,tetpil,gmod(x,mod));
! 77: z[1] = (long)mod; return z;
! 78: }
! 79: #undef cpifstack
! 80:
! 81: /*******************************************************************/
! 82: /* */
! 83: /* REDUCTION */
! 84: /* transform t_FRACN/t_RFRACN --> t_FRAC/t_RFRAC */
! 85: /* */
! 86: /* (static routines are not memory clean, but OK for gerepileupto) */
! 87: /*******************************************************************/
! 88: static GEN
! 89: gred_rfrac_copy(GEN x1, GEN x2)
! 90: {
! 91: GEN y = cgetg(3,t_RFRAC);
! 92: y[1] = lcopy(x1);
! 93: y[2] = lcopy(x2); return y;
! 94: }
! 95:
! 96: /* x[1] is scalar, non-zero */
! 97: static GEN
! 98: gred_rfrac_simple(GEN x1, GEN x2)
! 99: {
! 100: GEN y, c = content(x2);
! 101:
! 102: if (gcmp1(c)) return gred_rfrac_copy(x1,x2);
! 103: x1 = gdiv(x1, c);
! 104: x2 = gdiv(x2, c);
! 105:
! 106: c = denom(x1);
! 107: y = cgetg(3,t_RFRAC);
! 108: y[1] = (long)numer(x1);
! 109: y[2] = lmul(x2,c); return y;
! 110: }
! 111:
! 112: static GEN
! 113: gred_rfrac2_i(GEN x1, GEN x2)
! 114: {
! 115: GEN y,p1,xx1,xx2,x3;
! 116: long tx,ty;
! 117:
! 118: if (gcmp0(x1)) return gcopy(x1);
! 119:
! 120: tx=typ(x1); ty=typ(x2);
! 121: if (ty!=t_POL)
! 122: {
! 123: if (tx!=t_POL) return gred_rfrac_copy(x1,x2);
! 124: if (gvar2(x2) > varn(x1)) return gdiv(x1,x2);
! 125: err(talker,"incompatible variables in gred");
! 126: }
! 127: if (tx!=t_POL)
! 128: {
! 129: if (varn(x2) < gvar2(x1)) return gred_rfrac_simple(x1,x2);
! 130: err(talker,"incompatible variables in gred");
! 131: }
! 132: if (varn(x2) < varn(x1)) return gred_rfrac_simple(x1,x2);
! 133: if (varn(x2) > varn(x1)) return gdiv(x1,x2);
! 134:
! 135: /* now x1 and x2 are polynomials with the same variable */
! 136: xx1=content(x1); if (!gcmp1(xx1)) x1=gdiv(x1,xx1);
! 137: xx2=content(x2); if (!gcmp1(xx2)) x2=gdiv(x2,xx2);
! 138: x3=gdiv(xx1,xx2);
! 139: y = poldivres(x1,x2,&p1);
! 140: if (!signe(p1)) return gmul(x3,y);
! 141:
! 142: p1 = ggcd(x2,p1);
! 143: if (!isscalar(p1)) { x1=gdeuc(x1,p1); x2=gdeuc(x2,p1); }
! 144: if (typ(x3) == t_POL)
! 145: {
! 146: xx2 = denom(content(x3));
! 147: xx1 = gmul(x3, xx2);
! 148: }
! 149: else
! 150: {
! 151: xx1 = numer(x3);
! 152: xx2 = denom(x3);
! 153: }
! 154: p1=cgetg(3,t_RFRAC);
! 155: p1[1]=lmul(x1,xx1);
! 156: p1[2]=lmul(x2,xx2); return p1;
! 157: }
! 158:
! 159: static GEN
! 160: gred_rfrac_i(GEN x)
! 161: {
! 162: return gred_rfrac2_i((GEN)x[1], (GEN)x[2]);
! 163: }
! 164:
! 165: GEN
! 166: gred_rfrac2(GEN x1, GEN x2)
! 167: {
! 168: ulong av = avma;
! 169: return gerepileupto(av, gred_rfrac2_i(x1, x2));
! 170: }
! 171:
! 172: GEN
! 173: gred_rfrac(GEN x)
! 174: {
! 175: return gred_rfrac2((GEN)x[1], (GEN)x[2]);
! 176: }
! 177:
! 178: /* x1,x2 t_INT, return x1/x2 in reduced form */
! 179: GEN
! 180: gred_frac2(GEN x1, GEN x2)
! 181: {
! 182: GEN p1, y = dvmdii(x1,x2,&p1);
! 183: ulong av;
! 184:
! 185: if (p1 == gzero) return y; /* gzero intended */
! 186: av = avma;
! 187: p1 = mppgcd(x2,p1);
! 188: if (is_pm1(p1))
! 189: {
! 190: avma = av; y = cgetg(3,t_FRAC);
! 191: y[1] = licopy(x1);
! 192: y[2] = licopy(x2);
! 193: }
! 194: else
! 195: {
! 196: p1 = gclone(p1);
! 197: avma = av; y = cgetg(3,t_FRAC);
! 198: y[1] = (long)diviiexact(x1,p1);
! 199: y[2] = (long)diviiexact(x2,p1);
! 200: gunclone(p1);
! 201: }
! 202: fix_frac(y); return y;
! 203: }
! 204:
! 205: /* must NEVER returns a FRACN or a RFRACN */
! 206: GEN
! 207: gred(GEN x)
! 208: {
! 209: long tx = typ(x);
! 210: if (is_frac_t(tx)) return gred_frac2((GEN)x[1], (GEN)x[2]);
! 211: if (is_rfrac_t(tx)) return gred_rfrac(x);
! 212: return gcopy(x);
! 213: }
! 214:
! 215: /********************************************************************/
! 216: /** **/
! 217: /** SUBTRACTION **/
! 218: /** **/
! 219: /********************************************************************/
! 220:
! 221: GEN
! 222: gsub(GEN x, GEN y)
! 223: {
! 224: long tetpil, av = avma;
! 225: y=gneg_i(y); tetpil=avma;
! 226: return gerepile(av,tetpil,gadd(x,y));
! 227: }
! 228:
! 229: /********************************************************************/
! 230: /** **/
! 231: /** ADDITION **/
! 232: /** **/
! 233: /********************************************************************/
! 234:
! 235: static GEN
! 236: addpadic(GEN x, GEN y)
! 237: {
! 238: long c,e,r,d,r1,r2,av,tetpil;
! 239: GEN z,p1,p2, p = (GEN)x[2];
! 240:
! 241: z=cgetg(5,t_PADIC); icopyifstack(p, z[2]); av=avma;
! 242: e=valp(x); r=valp(y); d = r-e;
! 243: if (d<0) { p1=x; x=y; y=p1; e=r; d = -d; }
! 244: r1=precp(x); r2=precp(y);
! 245: if (d)
! 246: {
! 247: r = d+r2;
! 248: p1 = (d==1)? p: gclone(gpuigs(p,d));
! 249: avma=av;
! 250: if (r<r1) z[3]=lmulii(p1,(GEN)y[3]);
! 251: else
! 252: {
! 253: r=r1; z[3]=licopy((GEN)x[3]);
! 254: }
! 255: av=avma; p2=mulii(p1,(GEN)y[4]);
! 256: if (d!=1) gunclone(p1);
! 257: p1=addii(p2,(GEN)x[4]); tetpil=avma;
! 258: z[4]=lpile(av,tetpil, modii(p1,(GEN)z[3]));
! 259: z[1]=evalprecp(r) | evalvalp(e); return z;
! 260: }
! 261: if (r2<r1) { r=r2; p1=x; x=y; y=p1; } else r=r1;
! 262: p1 = addii((GEN)x[4],(GEN)y[4]);
! 263: if (!signe(p1) || (c = pvaluation(p1,p,&p2)) >=r)
! 264: {
! 265: avma=av; z[4]=zero; z[3]=un;
! 266: z[1]=evalvalp(e+r); return z;
! 267: }
! 268: if (c)
! 269: {
! 270: p2=gclone(p2); avma=av;
! 271: if (c==1)
! 272: z[3] = ldivii((GEN)x[3], p);
! 273: else
! 274: {
! 275: p1 = gpuigs(p,c); tetpil=avma;
! 276: z[3] = lpile(av,tetpil, divii((GEN)x[3], p1));
! 277: }
! 278: z[4]=lmodii(p2,(GEN)z[3]); gunclone(p2);
! 279: z[1]=evalprecp(r-c) | evalvalp(e+c); return z;
! 280: }
! 281: tetpil=avma;
! 282: z[4]=lpile(av,tetpil,modii(p1,(GEN)x[3]));
! 283: z[3]=licopy((GEN)x[3]);
! 284: z[1]=evalprecp(r) | evalvalp(e); return z;
! 285: }
! 286:
! 287: /* return x + y, where x is t_INT or t_FRAC(N), y t_PADIC */
! 288: static GEN
! 289: gaddpex(GEN x, GEN y)
! 290: {
! 291: long tx,e1,e2,e3,av,tetpil;
! 292: GEN z,p,p1,p2;
! 293:
! 294: if (gcmp0(x)) return gcopy(y);
! 295:
! 296: av=avma; p=(GEN)y[2]; tx=typ(x);
! 297: z=cgetg(5,t_PADIC); z[2]=(long)p;
! 298: e3 = (tx == t_INT)? pvaluation(x,p,&p1)
! 299: : pvaluation((GEN)x[1],p,&p1) -
! 300: pvaluation((GEN)x[2],p,&p2);
! 301: e1 = valp(y)-e3; e2 = signe(y[4])? e1+precp(y): e1;
! 302: if (e2<=0)
! 303: {
! 304: z[1] = evalprecp(0) | evalvalp(e3);
! 305: z[3] = un;
! 306: z[4] = zero;
! 307: }
! 308: else
! 309: {
! 310: if (tx != t_INT && !is_pm1(p2)) p1 = gdiv(p1,p2);
! 311: z[1] = evalprecp(e2) | evalvalp(e3);
! 312: z[3] = e1? lmul((GEN)y[3], gpuigs(p,e1)): y[3];
! 313: z[4] = lmod(p1,(GEN)z[3]);
! 314: }
! 315: tetpil=avma; return gerepile(av,tetpil,addpadic(z,y));
! 316: }
! 317:
! 318: static long
! 319: kro_quad(GEN x, GEN y)
! 320: {
! 321: long k, av=avma;
! 322:
! 323: x = subii(sqri((GEN)x[3]), shifti((GEN)x[2],2));
! 324: k = kronecker(x,y); avma=av; return k;
! 325: }
! 326:
! 327: static GEN
! 328: addfrac(GEN x, GEN y)
! 329: {
! 330: GEN x1 = (GEN)x[1], x2 = (GEN)x[2];
! 331: GEN y1 = (GEN)y[1], y2 = (GEN)y[2], p1,p2,n,d,delta,z;
! 332:
! 333: z = cgetg(3,t_FRAC);
! 334: (void)new_chunk((lgefint(x1) + lgefint(x2) + /* HACK: >= lg(num) + lg(den) */
! 335: lgefint(y1) + lgefint(y2)) << 1);
! 336: delta = mppgcd(x2,y2);
! 337: if (is_pm1(delta))
! 338: {
! 339: p1 = mulii(x1,y2);
! 340: p2 = mulii(y1,x2); avma = (long)z;
! 341: z[1] = laddii(p1,p2);
! 342: z[2] = lmulii(x2,y2); return z;
! 343: }
! 344: x2 = divii(x2,delta);
! 345: y2 = divii(y2,delta);
! 346: n = addii(mulii(x1,y2), mulii(y1,x2));
! 347: if (!signe(n)) { avma = (long)(z+3); return gzero; }
! 348: d = mulii(x2, y2);
! 349: p1 = dvmdii(n, delta, &p2);
! 350: if (p2 == gzero)
! 351: {
! 352: if (is_pm1(d)) { avma = (long)(z+3); return icopy(p1); }
! 353: avma = (long)z;
! 354: z[1] = licopy(p1);
! 355: z[2] = licopy(d); return z;
! 356: }
! 357: p1 = mppgcd(delta, p2);
! 358: if (!is_pm1(p1))
! 359: {
! 360: delta = divii(delta, p1);
! 361: n = divii(n, p1);
! 362: }
! 363: d = mulii(d,delta);
! 364: avma = (long)z;
! 365: z[1] = licopy(n);
! 366: z[2] = licopy(d); return z;
! 367: }
! 368:
! 369: static GEN
! 370: addrfrac(GEN x, GEN y)
! 371: {
! 372: GEN z = cgetg(3,t_RFRAC);
! 373: GEN x1 = (GEN)x[1], x2 = (GEN)x[2];
! 374: GEN y1 = (GEN)y[1], y2 = (GEN)y[2], p1,p2,n,d,delta;
! 375: long tetpil;
! 376:
! 377: delta = ggcd(x2,y2);
! 378: if (gcmp1(delta))
! 379: {
! 380: p1 = gmul(x1,y2);
! 381: p2 = gmul(y1,x2);
! 382: tetpil = avma; /* numerator is non-zero */
! 383: z[1] = lpile((long)z,tetpil, gadd(p1,p2));
! 384: z[2] = lmul(x2, y2); return z;
! 385: }
! 386: x2 = gdeuc(x2,delta);
! 387: y2 = gdeuc(y2,delta);
! 388: n = gadd(gmul(x1,y2), gmul(y1,x2));
! 389: if (!signe(n)) return gerepileupto((long)(z+3), n);
! 390: tetpil = avma; d = gmul(x2, y2);
! 391: p1 = poldivres(n, delta, &p2); /* we want gcd(n,delta) */
! 392: if (!signe(p2))
! 393: {
! 394: if (lgef(d) == 3) /* "constant" denominator */
! 395: {
! 396: d = (GEN)d[2];
! 397: if (gcmp_1(d)) p1 = gneg(p1);
! 398: else if (!gcmp1(d)) p1 = gdiv(p1, d);
! 399: return gerepileupto((long)(z+3), p1);
! 400: }
! 401: z[1]=(long)p1; z[2]=(long)d;
! 402: gerepilemanyvec((long)z,tetpil,z+1,2); return z;
! 403: }
! 404: p1 = ggcd(delta, p2);
! 405: if (gcmp1(p1))
! 406: {
! 407: tetpil = avma;
! 408: z[1] = lcopy(n);
! 409: }
! 410: else
! 411: {
! 412: delta = gdeuc(delta, p1);
! 413: tetpil = avma;
! 414: z[1] = ldeuc(n,p1);
! 415: }
! 416: z[2] = lmul(d,delta);
! 417: gerepilemanyvec((long)z,tetpil,z+1,2); return z;
! 418: }
! 419:
! 420: static GEN
! 421: addscalrfrac(GEN x, GEN y)
! 422: {
! 423: GEN p1,num, z = cgetg(3,t_RFRAC);
! 424: long tetpil, av;
! 425:
! 426: p1 = gmul(x,(GEN)y[2]); tetpil = avma;
! 427: num = gadd(p1,(GEN)y[1]);
! 428: av = avma;
! 429: p1 = content((GEN)y[2]);
! 430: if (!gcmp1(p1))
! 431: {
! 432: p1 = ggcd(p1, content(num));
! 433: if (!gcmp1(p1))
! 434: {
! 435: tetpil = avma;
! 436: z[1] = ldiv(num, p1);
! 437: z[2] = ldiv((GEN)y[2], p1);
! 438: gerepilemanyvec((long)z,tetpil,z+1,2); return z;
! 439: }
! 440: }
! 441: avma = av;
! 442: z[1]=lpile((long)z,tetpil, num);
! 443: z[2]=lcopy((GEN)y[2]); return z;
! 444: }
! 445:
! 446: /* assume gvar(x) = varn(mod) */
! 447: GEN
! 448: to_polmod(GEN x, GEN mod)
! 449: {
! 450: long tx = typ(x);
! 451: GEN z = cgetg(3, t_POLMOD);
! 452:
! 453: if (tx == t_RFRACN) { x = gred_rfrac_i(x); tx = t_RFRAC; }
! 454: if (tx == t_RFRAC) x = gmul((GEN)x[1], ginvmod((GEN)x[2],mod));
! 455: z[1] = (long)mod;
! 456: z[2] = (long)x;
! 457: return z;
! 458: }
! 459:
! 460: GEN
! 461: gadd(GEN x, GEN y)
! 462: {
! 463: long tx = typ(x), ty = typ(y), vx,vy,lx,ly,i,j,k,l,av,tetpil;
! 464: GEN z,p1,p2;
! 465:
! 466: if (is_const_t(tx) && is_const_t(ty))
! 467: {
! 468: if (tx>ty) { p1=x; x=y; y=p1; i=tx; tx=ty; ty=i; }
! 469: switch(tx)
! 470: {
! 471: case t_INT:
! 472: switch(ty)
! 473: {
! 474: case t_INT: return addii(x,y);
! 475: case t_REAL: return addir(x,y);
! 476:
! 477: case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)y[1];
! 478: (void)new_chunk(lgefint(p2)+1); /* HACK */
! 479: p1 = addii(modii(x,p2),(GEN)y[2]); avma = (long)z;
! 480: z[2] = (cmpii(p1,p2) >=0)? lsubii(p1,p2): licopy(p1);
! 481: icopyifstack(p2,z[1]); return z;
! 482:
! 483: case t_FRAC: case t_FRACN: z=cgetg(3,ty);
! 484: (void)new_chunk(lgefint(x)+lgefint(y[1])+lgefint(y[2])+1); /*HACK*/
! 485: p1 = mulii((GEN)y[2],x); avma = (long)z;
! 486: z[1] = laddii((GEN)y[1], p1);
! 487: z[2] = licopy((GEN)y[2]); return z;
! 488:
! 489: case t_COMPLEX: z=cgetg(3,t_COMPLEX);
! 490: z[1]=ladd(x,(GEN)y[1]);
! 491: z[2]=lcopy((GEN)y[2]); return z;
! 492:
! 493: case t_PADIC:
! 494: return gaddpex(x,y);
! 495:
! 496: case t_QUAD: z=cgetg(4,t_QUAD);
! 497: copyifstack(y[1], z[1]);
! 498: z[2]=ladd(x,(GEN)y[2]);
! 499: z[3]=lcopy((GEN)y[3]); return z;
! 500: }
! 501:
! 502: case t_REAL:
! 503: switch(ty)
! 504: {
! 505: case t_REAL: return addrr(x,y);
! 506:
! 507: case t_FRAC: case t_FRACN:
! 508: if (!signe(y[1])) return rcopy(x);
! 509: if (!signe(x))
! 510: {
! 511: lx = expi((GEN)y[1]) - expi((GEN)y[2]) - expo(x);
! 512: if (lx < 0) return rcopy(x);
! 513: lx >>= TWOPOTBITS_IN_LONG;
! 514: z=cgetr(lx+3); diviiz((GEN)y[1],(GEN)y[2],z);
! 515: return z;
! 516: }
! 517: av=avma; z=addir((GEN)y[1],mulir((GEN)y[2],x)); tetpil=avma;
! 518: return gerepile(av,tetpil,divri(z,(GEN)y[2]));
! 519:
! 520: case t_COMPLEX: z=cgetg(3,t_COMPLEX);
! 521: z[1]=ladd(x,(GEN)y[1]);
! 522: z[2]=lcopy((GEN)y[2]); return z;
! 523:
! 524: case t_QUAD:
! 525: if (gcmp0(y)) return rcopy(x);
! 526:
! 527: av=avma; i=gexpo(y)-expo(x);
! 528: if (i<=0) i=0; else i >>= TWOPOTBITS_IN_LONG;
! 529: p1=co8(y,lg(x)+i); tetpil=avma;
! 530: return gerepile(av,tetpil,gadd(p1,x));
! 531:
! 532: case t_INTMOD: case t_PADIC: err(operf,"+",tx,ty);
! 533: }
! 534:
! 535: case t_INTMOD:
! 536: switch(ty)
! 537: {
! 538: case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)x[1]; p1=(GEN)y[1];
! 539: if (p1==p2 || egalii(p1,p2))
! 540: {
! 541: icopyifstack(p2,z[1]);
! 542: if (!is_bigint(p2))
! 543: {
! 544: z[2] = lstoi(addssmod(itos((GEN)x[2]),itos((GEN)y[2]), p2[2]));
! 545: return z;
! 546: }
! 547: }
! 548: else
! 549: { p2 = mppgcd(p1,p2); z[1] = (long)p2; }
! 550: av=avma; (void)new_chunk((lgefint(p1)<<1) + lgefint(x[1]));/*HACK*/
! 551: p1=addii((GEN)x[2],(GEN)y[2]); avma=av;
! 552: z[2]=lmodii(p1,p2); return z;
! 553:
! 554: case t_FRAC: case t_FRACN: z=cgetg(3,t_INTMOD); p2=(GEN)x[1];
! 555: (void)new_chunk(lgefint(p2)<<2); /* HACK */
! 556: p1 = mulii((GEN)y[1], mpinvmod((GEN)y[2],p2));
! 557: p1 = addii(modii(p1,p2), (GEN)x[2]); avma=(long)z;
! 558: z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
! 559:
! 560: case t_COMPLEX: z=cgetg(3,t_COMPLEX);
! 561: z[1]=ladd(x,(GEN)y[1]);
! 562: z[2]=lcopy((GEN)y[2]); return z;
! 563:
! 564: case t_PADIC:
! 565: l=avma; p1=cgetg(3,t_INTMOD);
! 566: p1[1]=x[1]; p1[2]=lgeti(lgefint(x[1]));
! 567: gaffect(y,p1); tetpil=avma;
! 568: return gerepile(l,tetpil,gadd(p1,x));
! 569:
! 570: case t_QUAD: z=cgetg(4,t_QUAD);
! 571: copyifstack(y[1], z[1]);
! 572: z[2]=ladd(x,(GEN)y[2]);
! 573: z[3]=lcopy((GEN)y[3]); return z;
! 574: }
! 575:
! 576: case t_FRAC: case t_FRACN:
! 577: switch (ty)
! 578: {
! 579: case t_FRAC: return addfrac(x,y);
! 580: case t_FRACN: z=cgetg(3,t_FRACN); l=avma;
! 581: p1=mulii((GEN)x[1],(GEN)y[2]);
! 582: p2=mulii((GEN)x[2],(GEN)y[1]);
! 583: tetpil=avma; z[1]=lpile(l,tetpil,addii(p1,p2));
! 584: z[2]=lmulii((GEN)x[2],(GEN)y[2]);
! 585: return z;
! 586:
! 587: case t_COMPLEX: z=cgetg(3,t_COMPLEX);
! 588: z[1]=ladd((GEN)y[1],x);
! 589: z[2]=lcopy((GEN)y[2]); return z;
! 590:
! 591: case t_PADIC:
! 592: return gaddpex(x,y);
! 593:
! 594: case t_QUAD: z=cgetg(4,t_QUAD);
! 595: z[1]=lcopy((GEN)y[1]);
! 596: z[2]=ladd((GEN)y[2],x);
! 597: z[3]=lcopy((GEN)y[3]); return z;
! 598: }
! 599:
! 600: case t_COMPLEX:
! 601: switch(ty)
! 602: {
! 603: case t_COMPLEX: z=cgetg(3,t_COMPLEX);
! 604: z[1]=ladd((GEN)x[1],(GEN)y[1]);
! 605: z[2]=ladd((GEN)x[2],(GEN)y[2]); return z;
! 606:
! 607: case t_PADIC:
! 608: if (krosg(-1,(GEN)y[2])== -1)
! 609: {
! 610: z=cgetg(3,t_COMPLEX);
! 611: z[1]=ladd((GEN)x[1],y);
! 612: z[2]=lcopy((GEN)x[2]); return z;
! 613: }
! 614: av=avma; l = signe(y[4])? precp(y): 1;
! 615: p1=cvtop(x,(GEN)y[2], l + valp(y)); tetpil=avma;
! 616: return gerepile(av,tetpil,gadd(p1,y));
! 617:
! 618: case t_QUAD:
! 619: lx=precision(x); if (!lx) err(operi,"+",tx,ty);
! 620: if (gcmp0(y)) return gcopy(x);
! 621:
! 622: av=avma; i=gexpo(y)-gexpo(x);
! 623: if (i<=0) i=0; else i >>= TWOPOTBITS_IN_LONG;
! 624: p1=co8(y,lx+i); tetpil=avma;
! 625: return gerepile(av,tetpil,gadd(p1,x));
! 626: }
! 627:
! 628: case t_PADIC:
! 629: switch(ty)
! 630: {
! 631: case t_PADIC:
! 632: if (!egalii((GEN)x[2],(GEN)y[2])) err(operi,"+",tx,ty);
! 633: return addpadic(x,y);
! 634:
! 635: case t_QUAD:
! 636: if (kro_quad((GEN)y[1],(GEN)x[2]) == -1)
! 637: {
! 638: z=cgetg(4,t_QUAD);
! 639: copyifstack(y[1], z[1]);
! 640: z[2]=ladd((GEN)y[2],x);
! 641: z[3]=lcopy((GEN)y[3]); return z;
! 642: }
! 643: av=avma; l = signe(x[4])? precp(x): 1;
! 644: p1=cvtop(y,(GEN)x[2],valp(x)+l); tetpil=avma;
! 645: return gerepile(av,tetpil,gadd(p1,x));
! 646: }
! 647:
! 648: case t_QUAD: z=cgetg(4,t_QUAD); k=x[1]; l=y[1];
! 649: if (!gegal((GEN)k,(GEN)l)) err(operi,"+",tx,ty);
! 650: copyifstack(l, z[1]);
! 651: z[2]=ladd((GEN)x[2],(GEN)y[2]);
! 652: z[3]=ladd((GEN)x[3],(GEN)y[3]); return z;
! 653: }
! 654: err(bugparier,"gadd");
! 655: }
! 656:
! 657: vx=gvar(x); vy=gvar(y);
! 658: if (vx<vy || (vx==vy && tx>ty))
! 659: {
! 660: p1=x; x=y; y=p1;
! 661: i=tx; tx=ty; ty=i;
! 662: i=vx; vx=vy; vy=i;
! 663: }
! 664: if (ty==t_POLMOD) return op_polmod(gadd,x,y,tx);
! 665:
! 666: /* here !isscalar(y) and vx >= vy */
! 667: if ( (vx>vy && (!is_matvec_t(tx) || !is_matvec_t(ty)))
! 668: || (vx==vy && is_scalar_t(tx)) )
! 669: {
! 670: if (tx == t_POLMOD && vx == vy && ty != t_SER)
! 671: {
! 672: av = avma;
! 673: return gerepileupto(av, op_polmod(gadd, x, to_polmod(y,(GEN)x[1]), tx));
! 674: }
! 675:
! 676: switch(ty)
! 677: {
! 678: case t_POL: ly=lgef(y);
! 679: if (ly==2) return isexactzero(x)? zeropol(vy): scalarpol(x,vy);
! 680:
! 681: z = cgetg(ly,t_POL); z[1] = y[1];
! 682: z[2] = ladd(x,(GEN)y[2]);
! 683: for (i=3; i<ly; i++) z[i]=lcopy((GEN)y[i]);
! 684: return normalizepol_i(z, ly);
! 685:
! 686: case t_SER: l=valp(y); ly=lg(y);
! 687: if (l<3-ly) return gcopy(y);
! 688: if (l<0)
! 689: {
! 690: z=cgetg(ly,t_SER); z[1]=y[1];
! 691: for (i=2; i<=1-l; i++) z[i]=lcopy((GEN)y[i]);
! 692: for (i=3-l; i<ly; i++) z[i]=lcopy((GEN)y[i]);
! 693: z[2-l]=ladd(x,(GEN)y[2-l]); return z;
! 694: }
! 695: if (l>0)
! 696: {
! 697: if (gcmp0(x)) return gcopy(y);
! 698: if (gcmp0(y)) ly=2;
! 699:
! 700: ly += l; z=cgetg(ly,t_SER);
! 701: z[1]=evalsigne(1) | evalvalp(0) | evalvarn(vy);
! 702: for (i=3; i<=l+1; i++) z[i]=zero;
! 703: for ( ; i<ly; i++) z[i]=lcopy((GEN)y[i-l]);
! 704: z[2]=lcopy(x); return z;
! 705: }
! 706: av=avma; z=cgetg(ly,t_SER);
! 707: p1=signe(y)? gadd(x,(GEN)y[2]): x;
! 708: if (!isexactzero(p1))
! 709: {
! 710: z[1] = evalvalp(0) | evalvarn(vy);
! 711: if (signe(y))
! 712: {
! 713: z[1] |= evalsigne(1); z[2]=(long)p1;
! 714: for (i=3; i<ly; i++) z[i]=lcopy((GEN)y[i]);
! 715: }
! 716: return z;
! 717: }
! 718: avma=av; /* first coeff is 0 */
! 719: i=3; while (i<ly && gcmp0((GEN)y[i])) i++;
! 720: if (i==ly) return zeroser(vy,i-2);
! 721:
! 722: z=cgetg(ly-i+2,t_SER); z[1]=evalvalp(i-2)|evalvarn(vy)|evalsigne(1);
! 723: for (j=2; j<=ly-i+1; j++) z[j]=lcopy((GEN)y[j+i-2]);
! 724: return z;
! 725:
! 726: case t_RFRAC: return addscalrfrac(x,y);
! 727: case t_RFRACN: z=cgetg(3,t_RFRACN);
! 728: av=avma; p1=gmul(x,(GEN)y[2]); tetpil=avma;
! 729: z[1]=lpile(av,tetpil, gadd(p1,(GEN)y[1]));
! 730: z[2]=lcopy((GEN)y[2]); return z;
! 731:
! 732: case t_VEC: case t_COL: case t_MAT:
! 733: if (isexactzero(x)) return gcopy(y);
! 734: if (ty == t_MAT) return gaddmat(x,y);
! 735: /* fall through */
! 736: case t_QFR: case t_QFI: err(operf,"+",tx,ty);
! 737: }
! 738: err(operf,"+",tx,ty);
! 739: }
! 740:
! 741: /* here !isscalar(x) && isscalar(y) && (vx=vy || ismatvec(x and y)) */
! 742: if (tx>ty) { p1=x; x=y; y=p1; i=tx; tx=ty; ty=i; }
! 743: switch(tx)
! 744: {
! 745: case t_POL:
! 746: switch (ty)
! 747: {
! 748: case t_POL:
! 749: lx = lgef(x); ly = lgef(y); if (lx < ly) swapspec(x,y, lx,ly);
! 750: z = cgetg(lx,t_POL); z[1] = x[1];
! 751: for (i=2; i<ly; i++) z[i]=ladd((GEN)x[i],(GEN)y[i]);
! 752: for ( ; i<lx; i++) z[i]=lcopy((GEN)x[i]);
! 753: (void)normalizepol_i(z, lx);
! 754: if (lgef(z) == 2) { avma = (long)(z + lx); z = zeropol(vx); }
! 755: return z;
! 756:
! 757: case t_SER:
! 758: if (gcmp0(x)) return gcopy(y);
! 759: ly = signe(y)? lg(y): 3;
! 760: i = ly+valp(y)-gval(x,vx);
! 761: if (i<3) return gcopy(y);
! 762:
! 763: p1=greffe(x,i,0); y=gadd(p1,y);
! 764: free(p1); return y;
! 765:
! 766: case t_RFRAC: return addscalrfrac(x,y);
! 767: case t_RFRACN: z=cgetg(3,t_RFRACN);
! 768: av=avma; p1=gmul(x,(GEN)y[2]); tetpil=avma;
! 769: z[1]=lpile(av,tetpil, gadd(p1,(GEN)y[1]));
! 770: z[2]=lcopy((GEN)y[2]); return z;
! 771:
! 772: default: err(operf,"+",tx,ty);
! 773: }
! 774:
! 775: case t_SER:
! 776: switch(ty)
! 777: {
! 778: case t_SER:
! 779: l=valp(y)-valp(x);
! 780: if (l<0) { l= -l; p1=x; x=y; y=p1; }
! 781: if (gcmp0(x)) return gcopy(x);
! 782: lx = lg(x);
! 783: ly = signe(y)? lg(y): 2;
! 784: ly += l; if (lx<ly) ly=lx;
! 785: av = avma;
! 786: z=cgetg(ly,t_SER);
! 787: if (l)
! 788: {
! 789: if (l>=ly-2)
! 790: for (i=2; i<ly; i++) z[i]=lcopy((GEN)x[i]);
! 791: else
! 792: {
! 793: for (i=2; i<=l+1; i++) z[i]=lcopy((GEN)x[i]);
! 794: for ( ; i<ly; i++) z[i]=ladd((GEN)x[i],(GEN)y[i-l]);
! 795: }
! 796: z[1]=x[1]; return z;
! 797: }
! 798: if (ly>2)
! 799: {
! 800: tetpil = avma;
! 801: for (i=2; i<ly; i++)
! 802: {
! 803: p1 = gadd((GEN)x[i],(GEN)y[i]);
! 804: if (!isexactzero(p1))
! 805: {
! 806: l = i-2; stackdummy(z,l); z += l;
! 807: z[0]=evaltyp(t_SER) | evallg(ly-l);
! 808: z[1]=evalvalp(valp(x)+i-2) | evalsigne(1) | evalvarn(vx);
! 809: for (j=i+1; j<ly; j++)
! 810: z[j-l]=ladd((GEN)x[j],(GEN)y[j]);
! 811: z[2]=(long)p1; return z;
! 812: }
! 813: avma = tetpil;
! 814: }
! 815: }
! 816: avma = av;
! 817: return zeroser(vx,ly-2+valp(y));
! 818:
! 819: case t_RFRAC: case t_RFRACN:
! 820: if (gcmp0(y)) return gcopy(x);
! 821:
! 822: l = valp(x)-gval(y,vy); l += gcmp0(x)? 3: lg(x);
! 823: if (l<3) return gcopy(x);
! 824:
! 825: av=avma; ty=typ(y[2]);
! 826: p1 = is_scalar_t(ty)? (GEN)y[2]: greffe((GEN)y[2],l,1);
! 827: p1 = gdiv((GEN)y[1], p1); tetpil=avma;
! 828: return gerepile(av,tetpil,gadd(p1,x));
! 829:
! 830: default: err(operf,"+",tx,ty);
! 831: }
! 832:
! 833: case t_RFRAC:
! 834: if (!is_rfrac_t(ty)) err(operi,"+",tx,ty);
! 835: return addrfrac(x,y);
! 836: case t_RFRACN:
! 837: if (!is_rfrac_t(ty)) err(operi,"+",tx,ty);
! 838: z=cgetg(3,t_RFRACN); av=avma;
! 839: p1=gmul((GEN)x[1],(GEN)y[2]);
! 840: p2=gmul((GEN)x[2],(GEN)y[1]); tetpil=avma;
! 841: z[1]=lpile(av,tetpil, gadd(p1,p2));
! 842: z[2]=lmul((GEN)x[2],(GEN)y[2]); return z;
! 843:
! 844: case t_VEC: case t_COL: case t_MAT:
! 845: lx = lg(x); ly = lg(y);
! 846: if (lx!=ly || tx!=ty) err(operi,"+",tx,ty);
! 847: z=cgetg(ly,ty);
! 848: for (i=1; i<ly; i++)
! 849: z[i]=ladd((GEN)x[i],(GEN)y[i]);
! 850: return z;
! 851: }
! 852: err(operf,"+",tx,ty);
! 853: return NULL; /* not reached */
! 854: }
! 855:
! 856: /********************************************************************/
! 857: /** **/
! 858: /** MULTIPLICATION **/
! 859: /** **/
! 860: /********************************************************************/
! 861: GEN
! 862: fix_rfrac_if_pol(GEN x, GEN y)
! 863: {
! 864: if (gcmp1(y)) return x;
! 865: if (typ(y) != t_POL)
! 866: {
! 867: if (typ(x) != t_POL || gvar2(y) > varn(x))
! 868: return gdiv(x,y);
! 869: }
! 870: else if (varn(y) > varn(x)) return gdiv(x,y);
! 871: return NULL;
! 872: }
! 873:
! 874: static long
! 875: mingvar(GEN x, GEN y)
! 876: {
! 877: long i = gvar(x);
! 878: long j = gvar(y);
! 879: return min(i,j);
! 880: }
! 881:
! 882: static GEN
! 883: to_primitive(GEN x, GEN *cx)
! 884: {
! 885: if (typ(x) != t_POL)
! 886: { *cx = x; x = gun; }
! 887: else if (lgef(x) == 3)
! 888: { *cx = (GEN)x[2]; x = gun; }
! 889: else
! 890: { *cx = content(x); if (!gcmp1(*cx)) x = gdiv(x,*cx); }
! 891: return x;
! 892: }
! 893:
! 894: GEN
! 895: mulscalrfrac(GEN x, GEN y)
! 896: {
! 897: GEN p1,z,y1,y2,cx,cy1,cy2;
! 898: long tetpil,tx;
! 899:
! 900: if (gcmp0(x)) return gcopy(x);
! 901:
! 902: y1=(GEN)y[1]; if (gcmp0(y1)) return gcopy(y1);
! 903: y2=(GEN)y[2]; tx = typ(x);
! 904: z = cgetg(3, t_RFRAC);
! 905: if (is_const_t(tx) || varn(x) > mingvar(y1,y2)) { cx = x; x = gun; }
! 906: else
! 907: {
! 908: p1 = ggcd(x,y2); if (isnonscalar(p1)) { x=gdeuc(x,p1); y2=gdeuc(y2,p1); }
! 909: x = to_primitive(x, &cx);
! 910: }
! 911: y1 = to_primitive(y1, &cy1);
! 912: y2 = to_primitive(y2, &cy2);
! 913: if (x != gun) y1 = gmul(y1,x);
! 914: x = gdiv(gmul(cx,cy1), cy2);
! 915: if (typ(x) == t_POL)
! 916: {
! 917: cy2 = denom(content(x));
! 918: cy1 = gmul(x, cy2);
! 919: }
! 920: else
! 921: {
! 922: cy1 = numer(x);
! 923: cy2 = denom(x);
! 924: }
! 925: tetpil = avma;
! 926: z[2] = lmul(y2, cy2);
! 927: z[1] = lmul(y1, cy1);
! 928: p1 = fix_rfrac_if_pol((GEN)z[1],(GEN)z[2]);
! 929: if (p1) return gerepileupto((long)(z+3), p1);
! 930: gerepilemanyvec((long)z,tetpil,z+1,2); return z;
! 931: }
! 932:
! 933: static GEN
! 934: mulrfrac(GEN x, GEN y)
! 935: {
! 936: GEN z = cgetg(3,t_RFRAC), p1;
! 937: GEN x1 = (GEN)x[1], x2 = (GEN)x[2];
! 938: GEN y1 = (GEN)y[1], y2 = (GEN)y[2];
! 939: long tetpil;
! 940:
! 941: p1 = ggcd(x1, y2); if (!gcmp1(p1)) { x1 = gdiv(x1,p1); y2 = gdiv(y2,p1); }
! 942: p1 = ggcd(x2, y1); if (!gcmp1(p1)) { x2 = gdiv(x2,p1); y1 = gdiv(y1,p1); }
! 943: tetpil = avma;
! 944: z[2] = lmul(x2,y2);
! 945: z[1] = lmul(x1,y1);
! 946: p1 = fix_rfrac_if_pol((GEN)z[1],(GEN)z[2]);
! 947: if (p1) return gerepileupto((long)(z+3), p1);
! 948: gerepilemanyvec((long)z,tetpil,z+1,2); return z;
! 949: }
! 950:
! 951: GEN
! 952: to_Kronecker(GEN P, GEN Q)
! 953: {
! 954: /* P(X) = sum Mod(.,Q(Y)) * X^i, lift then set X := Y^(2n-1) */
! 955: long i,j,k,l, lx = lgef(P), N = (degpol(Q)<<1) + 1, vQ = varn(Q);
! 956: GEN p1, y = cgetg((N-2)*(lx-2) + 2, t_POL);
! 957: for (k=i=2; i<lx; i++)
! 958: {
! 959: p1 = (GEN)P[i];
! 960: if ((l=typ(p1)) == t_POLMOD) { p1 = (GEN)p1[2]; l = typ(p1); }
! 961: if (is_scalar_t(l) || varn(p1)<vQ) { y[k++] = (long)p1; j = 3; }
! 962: else
! 963: {
! 964: l = lgef(p1);
! 965: for (j=2; j < l; j++) y[k++] = p1[j];
! 966: }
! 967: if (i == lx-1) break;
! 968: for ( ; j < N; j++) y[k++] = zero;
! 969: }
! 970: y[1] = evalsigne(1)|evalvarn(vQ)|evallgef(k);
! 971: return y;
! 972: }
! 973:
! 974: int
! 975: ff_poltype(GEN *x, GEN *p, GEN *pol)
! 976: {
! 977: GEN Q, P = *x, pr,p1,p2,y;
! 978: long i, lx;
! 979:
! 980: if (!signe(P)) return 0;
! 981: lx = lgef(P); Q = *pol;
! 982: for (i=2; i<lx; i++)
! 983: {
! 984: p1 = (GEN)P[i]; if (typ(p1) != t_POLMOD) {Q=NULL;break;}
! 985: p2 = (GEN)p1[1];
! 986: if (Q==NULL) Q = p2;
! 987: else if (p2 != Q)
! 988: {
! 989: if (!gegal(p2, Q))
! 990: {
! 991: if (DEBUGMEM) err(warner,"different modulus in ff_poltype");
! 992: return 0;
! 993: }
! 994: if (DEBUGMEM > 2) err(warner,"different pointers in ff_poltype");
! 995: }
! 996: }
! 997: if (Q) {
! 998: *x = P = to_Kronecker(P, Q);
! 999: *pol = Q; lx = lgef(P);
! 1000: }
! 1001: pr = *p; y = cgetg(lx, t_POL);
! 1002: for (i=lx-1; i>1; i--)
! 1003: {
! 1004: p1 = (GEN)P[i];
! 1005: switch(typ(p1))
! 1006: {
! 1007: case t_INTMOD: break;
! 1008: case t_INT:
! 1009: if (*p) p1 = modii(p1, *p);
! 1010: y[i] = (long)p1; continue;
! 1011: default:
! 1012: return (Q && !pr)? 1: 0;
! 1013: }
! 1014: p2 = (GEN)p1[1];
! 1015: if (pr==NULL) pr = p2;
! 1016: else if (p2 != pr)
! 1017: {
! 1018: if (!egalii(p2, pr))
! 1019: {
! 1020: if (DEBUGMEM) err(warner,"different modulus in ff_poltype");
! 1021: return 0;
! 1022: }
! 1023: if (DEBUGMEM > 2) err(warner,"different pointers in ff_poltype");
! 1024: }
! 1025: y[i] = p1[2];
! 1026: }
! 1027: y[1] = evalsigne(1)|evalvarn(varn(P))|evallgef(lx);
! 1028: *x = y; *p = pr; return (Q || pr);
! 1029: }
! 1030:
! 1031: static GEN
! 1032: gmul_err(GEN x, GEN y, long tx, long ty)
! 1033: {
! 1034: long i,l;
! 1035: GEN z;
! 1036: if (tx==ty)
! 1037: switch(tx)
! 1038: {
! 1039: case t_QFI: return compimag(x,y);
! 1040: case t_QFR: return compreal(x,y);
! 1041: case t_VECSMALL:
! 1042: l = lg(x); z = cgetg(l, t_VECSMALL);
! 1043: if (l != lg(y)) err(operf,"*",tx,ty);
! 1044: for (i=1; i<l; i++) z[i]=x[y[i]];
! 1045: return z;
! 1046: }
! 1047: err(operf,"*",tx,ty);
! 1048: return NULL; /* not reached */
! 1049: }
! 1050:
! 1051: GEN
! 1052: gmul(GEN x, GEN y)
! 1053: {
! 1054: long tx,ty,lx,ly,vx,vy,i,j,k,l,av,tetpil;
! 1055: GEN z,p1,p2,p3,p4;
! 1056:
! 1057: if (x == y) return gsqr(x);
! 1058: if (y == gun) return gcopy(x);
! 1059:
! 1060: tx = typ(x); ty = typ(y);
! 1061: if (is_const_t(tx) && is_const_t(ty))
! 1062: {
! 1063: if (tx>ty) { p1=x; x=y; y=p1; i=tx; tx=ty; ty=i; }
! 1064: switch(tx)
! 1065: {
! 1066: case t_INT:
! 1067: switch(ty)
! 1068: {
! 1069: case t_INT: return mulii(x,y);
! 1070: case t_REAL: return mulir(x,y);
! 1071:
! 1072: case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)y[1];
! 1073: (void)new_chunk(lgefint(p2)<<2); /* HACK */
! 1074: p1=mulii(modii(x,p2),(GEN)y[2]); avma=(long)z;
! 1075: z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
! 1076:
! 1077: case t_FRAC:
! 1078: if (!signe(x)) return gzero;
! 1079: z=cgetg(3,t_FRAC);
! 1080: p1 = mppgcd(x,(GEN)y[2]);
! 1081: if (is_pm1(p1))
! 1082: {
! 1083: avma = (long)z;
! 1084: z[2] = licopy((GEN)y[2]);
! 1085: z[1] = lmulii((GEN)y[1], x);
! 1086: }
! 1087: else
! 1088: {
! 1089: x = divii(x,p1); tetpil = avma;
! 1090: z[2] = ldivii((GEN)y[2], p1);
! 1091: z[1] = lmulii((GEN)y[1], x);
! 1092: fix_frac_if_int_GC(z,tetpil);
! 1093: }
! 1094: return z;
! 1095:
! 1096: case t_FRACN: z=cgetg(3,t_FRACN);
! 1097: z[1]=lmulii(x,(GEN)y[1]);
! 1098: z[2]=licopy((GEN)y[2]); return z;
! 1099:
! 1100: case t_COMPLEX: z=cgetg(3,t_COMPLEX);
! 1101: z[1]=lmul(x,(GEN)y[1]);
! 1102: z[2]=lmul(x,(GEN)y[2]); return z;
! 1103:
! 1104: case t_PADIC:
! 1105: if (!signe(x)) return gzero;
! 1106: l=avma; p1=cgetp(y); gaffect(x,p1); tetpil=avma;
! 1107: return gerepile(l,tetpil,gmul(p1,y));
! 1108:
! 1109: case t_QUAD: z=cgetg(4,t_QUAD);
! 1110: copyifstack(y[1], z[1]);
! 1111: z[2]=lmul(x,(GEN)y[2]);
! 1112: z[3]=lmul(x,(GEN)y[3]); return z;
! 1113: }
! 1114:
! 1115: case t_REAL:
! 1116: switch(ty)
! 1117: {
! 1118: case t_REAL: return mulrr(x,y);
! 1119:
! 1120: case t_FRAC: case t_FRACN:
! 1121: l=avma; p1=cgetr(lg(x)); tetpil=avma; gaffect(y,p1);
! 1122: p2=mulrr(p1,x); return gerepile(l,tetpil,p2);
! 1123:
! 1124: case t_COMPLEX: z=cgetg(3,t_COMPLEX);
! 1125: z[1]=lmul(x,(GEN)y[1]);
! 1126: z[2]=lmul(x,(GEN)y[2]); return z;
! 1127:
! 1128: case t_QUAD:
! 1129: l=avma; p1=co8(y,lg(x)); tetpil=avma;
! 1130: return gerepile(l,tetpil,gmul(p1,x));
! 1131:
! 1132: default: err(operf,"*",tx,ty);
! 1133: }
! 1134:
! 1135: case t_INTMOD:
! 1136: switch(ty)
! 1137: {
! 1138: case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)x[1]; p1=(GEN)y[1];
! 1139: if (p1==p2 || egalii(p1,p2))
! 1140: {
! 1141: icopyifstack(p2,z[1]);
! 1142: if (!is_bigint(p2))
! 1143: {
! 1144: z[2] = lstoi(mulssmod(itos((GEN)x[2]),itos((GEN)y[2]), p2[2]));
! 1145: return z;
! 1146: }
! 1147: }
! 1148: else
! 1149: { p2 = mppgcd(p1,p2); z[1] = (long)p2; }
! 1150: av=avma;
! 1151: (void)new_chunk(lgefint(x[1]) + (lgefint(p1)<<1)); /* HACK */
! 1152: p1=mulii((GEN)x[2],(GEN)y[2]); avma=av;
! 1153: z[2]=lmodii(p1,p2); return z;
! 1154:
! 1155: case t_FRAC: case t_FRACN: z=cgetg(3,t_INTMOD); p2=(GEN)x[1];
! 1156: (void)new_chunk(lgefint(p2)<<2); /* HACK */
! 1157: p1 = mulii((GEN)y[1], mpinvmod((GEN)y[2],p2));
! 1158: p1 = mulii(modii(p1,p2),(GEN)x[2]); avma=(long)z;
! 1159: z[2] = lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
! 1160:
! 1161: case t_COMPLEX: z=cgetg(3,t_COMPLEX);
! 1162: z[1]=lmul(x,(GEN)y[1]);
! 1163: z[2]=lmul(x,(GEN)y[2]); return z;
! 1164:
! 1165: case t_PADIC:
! 1166: l=avma; p1=cgetg(3,t_INTMOD);
! 1167: p1[1]=x[1]; p1[2]=lgeti(lg(x[1]));
! 1168: gaffect(y,p1); tetpil=avma;
! 1169: return gerepile(l,tetpil,gmul(x,p1));
! 1170:
! 1171: case t_QUAD: z=cgetg(4,t_QUAD);
! 1172: copyifstack(y[1], z[1]);
! 1173: z[2]=lmul(x,(GEN)y[2]);
! 1174: z[3]=lmul(x,(GEN)y[3]); return z;
! 1175: }
! 1176:
! 1177: case t_FRAC: case t_FRACN:
! 1178: switch(ty)
! 1179: {
! 1180: case t_FRAC:
! 1181: {
! 1182: GEN x1 = (GEN)x[1], x2 = (GEN)x[2];
! 1183: GEN y1 = (GEN)y[1], y2 = (GEN)y[2];
! 1184: z=cgetg(3,t_FRAC);
! 1185: p1 = mppgcd(x1, y2);
! 1186: if (!is_pm1(p1)) { x1 = divii(x1,p1); y2 = divii(y2,p1); }
! 1187: p1 = mppgcd(x2, y1);
! 1188: if (!is_pm1(p1)) { x2 = divii(x2,p1); y1 = divii(y1,p1); }
! 1189: tetpil = avma;
! 1190: z[2] = lmulii(x2,y2);
! 1191: z[1] = lmulii(x1,y1);
! 1192: fix_frac_if_int_GC(z,tetpil); return z;
! 1193: }
! 1194: case t_FRACN: z=cgetg(3,t_FRACN);
! 1195: z[1]=lmulii((GEN)x[1],(GEN)y[1]);
! 1196: z[2]=lmulii((GEN)x[2],(GEN)y[2]); return z;
! 1197:
! 1198: case t_COMPLEX: z=cgetg(3,t_COMPLEX);
! 1199: z[1]=lmul((GEN)y[1],x);
! 1200: z[2]=lmul((GEN)y[2],x); return z;
! 1201:
! 1202: case t_PADIC:
! 1203: if (!signe(x[1])) return gzero;
! 1204: l=avma; p1=cgetp(y); gaffect(x,p1); tetpil=avma;
! 1205: return gerepile(l,tetpil,gmul(p1,y));
! 1206:
! 1207: case t_QUAD: z=cgetg(4,t_QUAD);
! 1208: copyifstack(y[1], z[1]);
! 1209: z[2]=lmul((GEN)y[2],x);
! 1210: z[3]=lmul((GEN)y[3],x); return z;
! 1211: }
! 1212:
! 1213: case t_COMPLEX:
! 1214: switch(ty)
! 1215: {
! 1216: case t_COMPLEX: z=cgetg(3,t_COMPLEX); l=avma;
! 1217: p1=gmul((GEN)x[1],(GEN)y[1]);
! 1218: p2=gmul((GEN)x[2],(GEN)y[2]);
! 1219: x=gadd((GEN)x[1],(GEN)x[2]);
! 1220: y=gadd((GEN)y[1],(GEN)y[2]);
! 1221: y=gmul(x,y); x=gadd(p1,p2);
! 1222: tetpil=avma; z[1]=lsub(p1,p2); z[2]=lsub(y,x);
! 1223: gerepilemanyvec(l,tetpil,z+1,2); return z;
! 1224:
! 1225: case t_PADIC:
! 1226: if (krosg(-1,(GEN)y[2]))
! 1227: {
! 1228: z=cgetg(3,t_COMPLEX);
! 1229: z[1]=lmul((GEN)x[1],y);
! 1230: z[2]=lmul((GEN)x[2],y); return z;
! 1231: }
! 1232: av=avma;
! 1233: if (signe(y[4])) l=precp(y);
! 1234: else
! 1235: {
! 1236: l=valp(y)+1; if (l<=0) l=1;
! 1237: }
! 1238: p1=cvtop(x,(GEN)y[2],l); tetpil=avma;
! 1239: return gerepile(av,tetpil,gmul(p1,y));
! 1240:
! 1241: case t_QUAD:
! 1242: lx=precision(x); if (!lx) err(operi,"*",tx,ty);
! 1243: l=avma; p1=co8(y,lx); tetpil=avma;
! 1244: return gerepile(l,tetpil,gmul(p1,x));
! 1245: }
! 1246:
! 1247: case t_PADIC:
! 1248: switch(ty)
! 1249: {
! 1250: case t_PADIC:
! 1251: if (!egalii((GEN)x[2],(GEN)y[2])) err(operi,"*",tx,ty);
! 1252: l = valp(x)+valp(y);
! 1253: if (!signe(x[4])) { z=gcopy(x); setvalp(z,l); return z; }
! 1254: if (!signe(y[4])) { z=gcopy(y); setvalp(z,l); return z; }
! 1255:
! 1256: p1 = (precp(x) > precp(y))? y: x;
! 1257: z=cgetp(p1); setvalp(z,l); av=avma;
! 1258: modiiz(mulii((GEN)x[4],(GEN)y[4]),(GEN)p1[3],(GEN)z[4]);
! 1259: avma=av; return z;
! 1260:
! 1261: case t_QUAD:
! 1262: if (kro_quad((GEN)y[1],(GEN)x[2])== -1)
! 1263: {
! 1264: z=cgetg(4,t_QUAD);
! 1265: copyifstack(y[1], z[1]);
! 1266: z[2]=lmul((GEN)y[2],x);
! 1267: z[3]=lmul((GEN)y[3],x); return z;
! 1268: }
! 1269: l = signe(x[4])? precp(x): valp(x)+1;
! 1270: av=avma; p1=cvtop(y,(GEN)x[2],l); tetpil=avma;
! 1271: return gerepile(av,tetpil,gmul(p1,x));
! 1272: }
! 1273:
! 1274: case t_QUAD: z=cgetg(4,t_QUAD);
! 1275: p1=(GEN)x[1]; p2=(GEN)y[1];
! 1276: if (!gegal(p1,p2)) err(operi,"*",tx,ty);
! 1277:
! 1278: copyifstack(p2, z[1]); l=avma;
! 1279: p2=gmul((GEN)x[2],(GEN)y[2]);
! 1280: p3=gmul((GEN)x[3],(GEN)y[3]);
! 1281: p4=gmul(gneg_i((GEN)p1[2]),p3);
! 1282:
! 1283: if (gcmp0((GEN)p1[3]))
! 1284: {
! 1285: tetpil=avma;
! 1286: z[2]=lpile(l,tetpil,gadd(p4,p2)); l=avma;
! 1287: p2=gmul((GEN)x[2],(GEN)y[3]);
! 1288: p3=gmul((GEN)x[3],(GEN)y[2]); tetpil=avma;
! 1289: z[3]=lpile(l,tetpil,gadd(p2,p3)); return z;
! 1290: }
! 1291:
! 1292: p1 = gadd(gmul((GEN)x[2],(GEN)y[3]), gmul((GEN)x[3],(GEN)y[2]));
! 1293: tetpil=avma;
! 1294: z[2]=ladd(p2,p4);
! 1295: z[3]=ladd(p1,p3);
! 1296: gerepilemanyvec(l,tetpil,z+2,2); return z;
! 1297: }
! 1298: err(bugparier,"multiplication");
! 1299: }
! 1300:
! 1301: vx=gvar(x); vy=gvar(y);
! 1302: if (!is_matvec_t(ty))
! 1303: if (is_matvec_t(tx) || vx<vy || (vx==vy && tx>ty))
! 1304: {
! 1305: p1=x; x=y; y=p1;
! 1306: i=tx; tx=ty; ty=i;
! 1307: i=vx; vx=vy; vy=i;
! 1308: }
! 1309: if (ty==t_POLMOD) return op_polmod(gmul,x,y,tx);
! 1310: if (is_noncalc_t(tx) || is_noncalc_t(ty)) return gmul_err(x,y,tx,ty);
! 1311:
! 1312: /* here !isscalar(y) */
! 1313: if (is_matvec_t(ty))
! 1314: {
! 1315: ly=lg(y);
! 1316: if (!is_matvec_t(tx))
! 1317: {
! 1318: z=cgetg(ly,ty);
! 1319: for (i=1; i<ly; i++) z[i]=lmul(x,(GEN)y[i]);
! 1320: return z;
! 1321: }
! 1322: lx=lg(x);
! 1323:
! 1324: switch(tx)
! 1325: {
! 1326: case t_VEC:
! 1327: switch(ty)
! 1328: {
! 1329: case t_COL:
! 1330: if (lx!=ly) err(operi,"*",tx,ty);
! 1331: z=gzero; l=avma;
! 1332: for (i=1; i<lx; i++)
! 1333: {
! 1334: p1=gmul((GEN)x[i],(GEN)y[i]);
! 1335: z=gadd(z,p1);
! 1336: }
! 1337: return gerepileupto(l,z);
! 1338:
! 1339: case t_MAT:
! 1340: if (ly==1) return cgetg(1,t_VEC);
! 1341: l=lg(y[1]); if (lx!=l) err(operi,"*",tx,ty);
! 1342:
! 1343: z=cgetg(ly,tx);
! 1344: for (i=1; i<ly; i++)
! 1345: {
! 1346: p1=gzero; av=avma;
! 1347: for (j=1; j<lx; j++)
! 1348: {
! 1349: p2=gmul((GEN)x[j],gcoeff(y,j,i));
! 1350: p1=gadd(p1,p2);
! 1351: }
! 1352: z[i]=lpileupto(av,p1);
! 1353: }
! 1354: return z;
! 1355:
! 1356: default: err(operf,"*",tx,ty);
! 1357: }
! 1358:
! 1359: case t_COL:
! 1360: switch(ty)
! 1361: {
! 1362: case t_VEC:
! 1363: z=cgetg(ly,t_MAT);
! 1364: for (i=1; i<ly; i++)
! 1365: {
! 1366: p1 = gmul((GEN)y[i],x);
! 1367: if (typ(p1) != t_COL) err(operi,"*",tx,ty);
! 1368: z[i]=(long)p1;
! 1369: }
! 1370: return z;
! 1371:
! 1372: case t_MAT:
! 1373: if (ly!=1 && lg(y[1])!=2) err(operi,"*",tx,ty);
! 1374:
! 1375: z=cgetg(ly,t_MAT);
! 1376: for (i=1; i<ly; i++) z[i]=lmul(gcoeff(y,1,i),x);
! 1377: return z;
! 1378:
! 1379: default: err(operf,"*",tx,ty);
! 1380: }
! 1381:
! 1382: case t_MAT:
! 1383: switch(ty)
! 1384: {
! 1385: case t_VEC:
! 1386: if (lx!=2) err(operi,"*",tx,ty);
! 1387: z=cgetg(ly,t_MAT);
! 1388: for (i=1; i<ly; i++) z[i]=lmul((GEN)y[i],(GEN)x[1]);
! 1389: return z;
! 1390:
! 1391: case t_COL:
! 1392: if (lx!=ly) err(operi,"*",tx,ty);
! 1393: if (lx==1) return gcopy(y);
! 1394:
! 1395: lx=lg(x[1]); z=cgetg(lx,t_COL);
! 1396: for (i=1; i<lx; i++)
! 1397: {
! 1398: p1=gzero; l=avma;
! 1399: for (j=1; j<ly; j++)
! 1400: {
! 1401: p2=gmul(gcoeff(x,i,j),(GEN)y[j]);
! 1402: p1=gadd(p1,p2);
! 1403: }
! 1404: z[i]=lpileupto(l,p1);
! 1405: }
! 1406: return z;
! 1407:
! 1408: case t_MAT:
! 1409: if (ly==1) return cgetg(ly,t_MAT);
! 1410: if (lx != lg(y[1])) err(operi,"*",tx,ty);
! 1411: z=cgetg(ly,t_MAT);
! 1412: if (lx==1)
! 1413: {
! 1414: for (i=1; i<ly; i++) z[i]=lgetg(1,t_COL);
! 1415: return z;
! 1416: }
! 1417: l=lg(x[1]);
! 1418: for (j=1; j<ly; j++)
! 1419: {
! 1420: z[j] = lgetg(l,t_COL);
! 1421: for (i=1; i<l; i++)
! 1422: {
! 1423: p1=gzero; av=avma;
! 1424: for (k=1; k<lx; k++)
! 1425: {
! 1426: p2=gmul(gcoeff(x,i,k),gcoeff(y,k,j));
! 1427: p1=gadd(p1,p2);
! 1428: }
! 1429: coeff(z,i,j)=lpileupto(av,p1);
! 1430: }
! 1431: }
! 1432: return z;
! 1433: }
! 1434: }
! 1435: err(bugparier,"multiplication");
! 1436: }
! 1437: /* now !ismatvec(x and y) */
! 1438:
! 1439: if (vx>vy || (vx==vy && is_scalar_t(tx)))
! 1440: {
! 1441: if (isexactzero(x))
! 1442: {
! 1443: if (vy == BIGINT) err(operf,"*",tx,ty);
! 1444: return zeropol(vy);
! 1445: }
! 1446: if (tx == t_INT && is_pm1(x))
! 1447: return (signe(x)>0) ? gcopy(y): gneg(y);
! 1448: if (tx == t_POLMOD && vx == vy && ty != t_SER)
! 1449: {
! 1450: av = avma;
! 1451: return gerepileupto(av, op_polmod(gmul, x, to_polmod(y,(GEN)x[1]), tx));
! 1452: }
! 1453: switch(ty)
! 1454: {
! 1455: case t_POL:
! 1456: if (isexactzero(y)) return zeropol(vy);
! 1457: ly = lgef(y); z = cgetg(ly,t_POL); z[1]=y[1];
! 1458: for (i=2; i<ly; i++) z[i]=lmul(x,(GEN)y[i]);
! 1459: return normalizepol_i(z,ly);
! 1460:
! 1461: case t_SER:
! 1462: if (!signe(y)) return gcopy(y);
! 1463: ly=lg(y); z=cgetg(ly,t_SER);
! 1464: for (i=2; i<ly; i++) z[i]=lmul(x,(GEN)y[i]);
! 1465: z[1]=y[1]; return normalize(z);
! 1466:
! 1467: case t_RFRAC: return mulscalrfrac(x,y);
! 1468: case t_RFRACN: av=avma; z=cgetg(3,t_RFRACN);
! 1469: z[1]=lmul(x,(GEN)y[1]);
! 1470: z[2]=lcopy((GEN)y[2]); return z;
! 1471: default: err(operf,"*",tx,ty);
! 1472: }
! 1473: }
! 1474:
! 1475: if (tx>ty) { p1=x; x=y; y=p1; i=tx; tx=ty; ty=i; }
! 1476: switch(tx)
! 1477: {
! 1478: case t_POL:
! 1479: switch (ty)
! 1480: {
! 1481: case t_POL:
! 1482: {
! 1483: #if 0
! 1484: /* Too dangerous / cumbersome to correct here. Don't use t_POLMODS of
! 1485: * t_INTMODs to represent elements of finite fields. Implement a finite
! 1486: * field type instead and compute with polynomials with integer coeffs in
! 1487: * Kronecker form...
! 1488: * For gsqr, it's still idiotic to let ff_poltype correct bad implementations,
! 1489: * but less dangerous.
! 1490: */
! 1491: GEN a = x,b = y
! 1492: GEN p = NULL, pol = NULL;
! 1493: long av = avma;
! 1494: if (ff_poltype(&x,&p,&pol) && ff_poltype(&y,&p,&pol))
! 1495: {
! 1496: /* fprintferr("HUM"); */
! 1497: if (pol && varn(x) != varn(y))
! 1498: x = to_Kronecker(x,pol);
! 1499: z = quickmul(x+2, y+2, lgef(x)-2, lgef(y)-2);
! 1500: if (p) z = FpX(z,p);
! 1501: if (pol) z = from_Kronecker(z,pol);
! 1502: z = gerepileupto(av, z);
! 1503: }
! 1504: else
! 1505: {
! 1506: avma = av;
! 1507: z = quickmul(a+2, b+2, lgef(a)-2, lgef(b)-2);
! 1508: }
! 1509: #else
! 1510: z = quickmul(x+2, y+2, lgef(x)-2, lgef(y)-2);
! 1511: #endif
! 1512: setvarn(z,vx); return z;
! 1513: }
! 1514: case t_SER:
! 1515: if (gcmp0(x)) return zeropol(vx);
! 1516: if (gcmp0(y)) return zeroser(vx, valp(y)+gval(x,vx));
! 1517: p1=greffe(x,lg(y),0); p2=gmul(p1,y);
! 1518: free(p1); return p2;
! 1519:
! 1520: case t_RFRAC: return mulscalrfrac(x,y);
! 1521: case t_RFRACN: av=avma; z=cgetg(3,t_RFRACN);
! 1522: z[1]=lmul(x,(GEN)y[1]);
! 1523: z[2]=lcopy((GEN)y[2]); return z;
! 1524:
! 1525: default: err(operf,"*",tx,ty);
! 1526: }
! 1527:
! 1528: case t_SER:
! 1529: switch (ty)
! 1530: {
! 1531: case t_SER:
! 1532: if (gcmp0(x) || gcmp0(y)) return zeroser(vx, valp(x)+valp(y));
! 1533: lx=lg(x); ly=lg(y);
! 1534: if (lx>ly) { k=ly; ly=lx; lx=k; p1=y; y=x; x=p1; }
! 1535: z = cgetg(lx,t_SER);
! 1536: z[1] = evalvalp(valp(x)+valp(y)) | evalvarn(vx) | evalsigne(1);
! 1537: x += 2; y += 2; z += 2; lx -= 3;
! 1538: p2 = (GEN)gpmalloc((lx+1)*sizeof(long));
! 1539: for (i=0; i<=lx; i++)
! 1540: {
! 1541: p2[i] = !isexactzero((GEN)y[i]);
! 1542: p1 = gzero; av = avma;
! 1543: for (j=0; j<=i; j++)
! 1544: if (p2[j])
! 1545: p1 = gadd(p1, gmul((GEN)y[j],(GEN)x[i-j]));
! 1546: z[i] = lpileupto(av,p1);
! 1547: }
! 1548: z -= 2; /* back to normalcy */
! 1549: free(p2); return normalize(z);
! 1550:
! 1551: case t_RFRAC: case t_RFRACN:
! 1552: if (gcmp0(y)) return zeropol(vx);
! 1553: if (gcmp0(x)) return zeroser(vx, valp(x)+gval(y,vx));
! 1554: l=avma; p1=gmul((GEN)y[1],x); tetpil=avma;
! 1555: return gerepile(l,tetpil,gdiv(p1,(GEN)y[2]));
! 1556:
! 1557: default: err(operf,"*",tx,ty);
! 1558: }
! 1559:
! 1560: /* (tx,ty) == t_RFRAC <==> ty == t_RFRAC */
! 1561: case t_RFRAC: return mulrfrac(x,y);
! 1562: case t_RFRACN:
! 1563: if (!is_rfrac_t(ty)) err(operf,"*",tx,ty);
! 1564: av=avma; z=cgetg(3,ty);
! 1565: z[1]=lmul((GEN)x[1],(GEN)y[1]);
! 1566: z[2]=lmul((GEN)x[2],(GEN)y[2]); return z;
! 1567: }
! 1568: return gmul_err(x,y,tx,ty);
! 1569: }
! 1570:
! 1571: GEN
! 1572: gsqr(GEN x)
! 1573: {
! 1574: long tx=typ(x),lx,i,j,k,l,av,tetpil;
! 1575: GEN z,p1,p2,p3,p4;
! 1576:
! 1577: if (is_scalar_t(tx))
! 1578: switch(tx)
! 1579: {
! 1580: case t_INT:
! 1581: return sqri(x);
! 1582:
! 1583: case t_REAL:
! 1584: return mulrr(x,x);
! 1585:
! 1586: case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)x[1];
! 1587: (void)new_chunk(lgefint(p2)<<2); /* HACK */
! 1588: p1=sqri((GEN)x[2]); avma=(long)z;
! 1589: z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
! 1590:
! 1591: case t_FRAC: case t_FRACN:
! 1592: z=cgetg(3,tx);
! 1593: z[1]=lsqri((GEN)x[1]);
! 1594: z[2]=lsqri((GEN)x[2]);
! 1595: return z;
! 1596:
! 1597: case t_COMPLEX:
! 1598: z=cgetg(lg(x),tx); l=avma;
! 1599: p1=gadd((GEN)x[1],(GEN)x[2]);
! 1600: p2=gadd((GEN)x[1],gneg_i((GEN)x[2]));
! 1601: p3=gmul((GEN)x[1],(GEN)x[2]);
! 1602: tetpil=avma;
! 1603: z[1]=lmul(p1,p2); z[2]=lshift(p3,1);
! 1604: gerepilemanyvec(l,tetpil,z+1,2);
! 1605: return z;
! 1606:
! 1607: case t_PADIC:
! 1608: z = cgetg(5,t_PADIC);
! 1609: i = (egalii((GEN)x[2], gdeux) && signe(x[4]))? 1: 0;
! 1610: if (i && precp(x) == 1) i = 2; /* (1 + O(2))^2 = 1 + O(2^3) */
! 1611: z[1] = evalprecp(precp(x)+i) | evalvalp(2*valp(x));
! 1612: icopyifstack(x[2], z[2]);
! 1613: z[3] = lshifti((GEN)x[3], i); av = avma;
! 1614: z[4] = (long)gerepileuptoint(av, modii(sqri((GEN)x[4]), (GEN)z[3]));
! 1615: return z;
! 1616:
! 1617: case t_QUAD:
! 1618: p1=(GEN)x[1]; z=cgetg(lg(x),tx); l=avma;
! 1619: p2=gsqr((GEN)x[2]); p3=gsqr((GEN)x[3]);
! 1620: p4=gmul(gneg_i((GEN)p1[2]),p3);
! 1621:
! 1622: if (gcmp0((GEN)p1[3]))
! 1623: {
! 1624: tetpil=avma;
! 1625: z[2]=lpile(l,tetpil,gadd(p4,p2));
! 1626: l=avma; p2=gmul((GEN)x[2],(GEN)x[3]); tetpil=avma;
! 1627: z[3]=lpile(l,tetpil,gmul2n(p2,1));
! 1628: copyifstack(p1,z[1]); return z;
! 1629: }
! 1630:
! 1631: p1=gmul((GEN)x[2],(GEN)x[3]);
! 1632: p1=gmul2n(p1,1); tetpil=avma;
! 1633: z[2]=ladd(p2,p4); z[3]=ladd(p1,p3);
! 1634: gerepilemanyvec(l,tetpil,z+2,2);
! 1635: copyifstack(x[1],z[1]); return z;
! 1636:
! 1637: case t_POLMOD:
! 1638: z=cgetg(lg(x),tx); copyifstack(x[1],z[1]);
! 1639: l=avma; p1=gsqr((GEN)x[2]); tetpil=avma;
! 1640: z[2]=lpile(l,tetpil, gres(p1,(GEN)z[1]));
! 1641: return z;
! 1642: }
! 1643:
! 1644: switch(tx)
! 1645: {
! 1646: case t_POL:
! 1647: {
! 1648: GEN a = x, p = NULL, pol = NULL;
! 1649: long vx = varn(x);
! 1650: av = avma;
! 1651: if (ff_poltype(&x,&p,&pol))
! 1652: {
! 1653: z = quicksqr(x+2, lgef(x)-2);
! 1654: if (p) z = FpX(z,p);
! 1655: if (pol) z = from_Kronecker(z,pol);
! 1656: z = gerepileupto(av, z);
! 1657: }
! 1658: else
! 1659: {
! 1660: avma = av;
! 1661: z = quicksqr(a+2, lgef(a)-2);
! 1662: }
! 1663: setvarn(z, vx); return z;
! 1664: }
! 1665:
! 1666: case t_SER:
! 1667: if (gcmp0(x)) return zeroser(varn(x), 2*valp(x));
! 1668: lx = lg(x); z = cgetg(lx,tx);
! 1669: z[1] = evalsigne(1) | evalvalp(2*valp(x)) | evalvarn(varn(x));
! 1670: x += 2; z += 2; lx -= 3;
! 1671: p2 = (GEN)gpmalloc((lx+1)*sizeof(long));
! 1672: for (i=0; i<=lx; i++)
! 1673: {
! 1674: p2[i] = !isexactzero((GEN)x[i]);
! 1675: p1=gzero; av=avma; l=(i+1)>>1;
! 1676: for (j=0; j<l; j++)
! 1677: if (p2[j] && p2[i-j])
! 1678: p1 = gadd(p1, gmul((GEN)x[j],(GEN)x[i-j]));
! 1679: p1 = gshift(p1,1);
! 1680: if ((i&1) == 0 && p2[i>>1])
! 1681: p1 = gadd(p1, gsqr((GEN)x[i>>1]));
! 1682: z[i] = lpileupto(av,p1);
! 1683: }
! 1684: z -= 2; free(p2); return normalize(z);
! 1685:
! 1686: case t_RFRAC: case t_RFRACN:
! 1687: z=cgetg(3,tx);
! 1688: z[1]=lsqr((GEN)x[1]);
! 1689: z[2]=lsqr((GEN)x[2]); return z;
! 1690:
! 1691: case t_MAT:
! 1692: lx=lg(x);
! 1693: if (lx==1) return cgetg(1,tx);
! 1694: if (lx != lg(x[1])) err(operi,"*",tx,tx);
! 1695: z=cgetg(lx,tx);
! 1696: for (j=1; j<lx; j++)
! 1697: {
! 1698: z[j]=lgetg(lx,t_COL);
! 1699: for (i=1; i<lx; i++)
! 1700: {
! 1701: p1=gzero; l=avma;
! 1702: for (k=1; k<lx; k++)
! 1703: p1 = gadd(p1, gmul(gcoeff(x,i,k),gcoeff(x,k,j)));
! 1704: coeff(z,i,j)=lpileupto(l,p1);
! 1705: }
! 1706: }
! 1707: return z;
! 1708:
! 1709: case t_QFR: return sqcompreal(x);
! 1710: case t_QFI: return sqcompimag(x);
! 1711: }
! 1712: return gmul_err(x,x,tx,tx);
! 1713: }
! 1714:
! 1715: /********************************************************************/
! 1716: /** **/
! 1717: /** DIVISION **/
! 1718: /** **/
! 1719: /********************************************************************/
! 1720:
! 1721: static
! 1722: GEN divrfracscal(GEN x, GEN y)
! 1723: {
! 1724: long Y[3]; Y[1]=un; Y[2]=(long)y;
! 1725: return mulrfrac(x,Y);
! 1726: }
! 1727:
! 1728: static
! 1729: GEN divscalrfrac(GEN x, GEN y)
! 1730: {
! 1731: long Y[3]; Y[1]=y[2]; Y[2]=y[1];
! 1732: return mulscalrfrac(x,Y);
! 1733: }
! 1734:
! 1735: static
! 1736: GEN divrfrac(GEN x, GEN y)
! 1737: {
! 1738: long Y[3]; Y[1]=y[2]; Y[2]=y[1];
! 1739: return mulrfrac(x,Y);
! 1740: }
! 1741:
! 1742: GEN
! 1743: gdiv(GEN x, GEN y)
! 1744: {
! 1745: long tx = typ(x), ty = typ(y), lx,ly,vx,vy,i,j,k,l,av,tetpil;
! 1746: GEN z,p1,p2,p3;
! 1747:
! 1748: if (y == gun) return gcopy(x);
! 1749: if (tx==t_INT && is_const_t(ty))
! 1750: {
! 1751: switch (signe(x))
! 1752: {
! 1753: case 0:
! 1754: if (gcmp0(y)) err(gdiver2);
! 1755: if (ty != t_INTMOD) return gzero;
! 1756: z = cgetg(3,t_INTMOD); icopyifstack(y[1],z[1]); z[2]=zero;
! 1757: return z;
! 1758: case 1:
! 1759: if (is_pm1(x)) return ginv(y);
! 1760: break;
! 1761: case -1:
! 1762: if (is_pm1(x)) { av = avma; return gerepileupto(av, ginv(gneg(y))); }
! 1763: }
! 1764: switch(ty)
! 1765: {
! 1766: case t_INT:
! 1767: return gred_frac2(x,y);
! 1768: case t_REAL:
! 1769: return divir(x,y);
! 1770:
! 1771: case t_INTMOD:
! 1772: z=cgetg(3,t_INTMOD); p2=(GEN)y[1];
! 1773: (void)new_chunk(lgefint(p2)<<2); /* HACK */
! 1774: p1=mulii(modii(x,p2), mpinvmod((GEN)y[2],p2)); avma=(long)z;
! 1775: z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
! 1776:
! 1777: case t_FRAC:
! 1778: z=cgetg(3,t_FRAC);
! 1779: p1 = mppgcd(x,(GEN)y[1]);
! 1780: if (is_pm1(p1))
! 1781: {
! 1782: avma = (long)z; tetpil = 0;
! 1783: z[2] = licopy((GEN)y[1]);
! 1784: }
! 1785: else
! 1786: {
! 1787: x = divii(x,p1); tetpil = avma;
! 1788: z[2] = ldivii((GEN)y[1], p1);
! 1789: }
! 1790: z[1] = lmulii((GEN)y[2], x);
! 1791: fix_frac(z);
! 1792: if (tetpil)
! 1793: { fix_frac_if_int_GC(z,tetpil); }
! 1794: else
! 1795: fix_frac_if_int(z);
! 1796: return z;
! 1797:
! 1798: case t_FRACN:
! 1799: z=cgetg(3,t_FRACN);
! 1800: z[1]=lmulii((GEN)y[2], x);
! 1801: z[2]=licopy((GEN)y[1]);
! 1802: fix_frac(z); return z;
! 1803:
! 1804: case t_PADIC:
! 1805: l=avma; p1=cgetp(y); gaffect(x,p1); tetpil=avma;
! 1806: return gerepile(l,tetpil,gdiv(p1,y));
! 1807:
! 1808: case t_COMPLEX: case t_QUAD:
! 1809: l=avma; p1=gnorm(y); p2=gmul(x,gconj(y)); tetpil=avma;
! 1810: return gerepile(l,tetpil,gdiv(p2,p1));
! 1811: }
! 1812: }
! 1813: if (gcmp0(y) && ty != t_MAT) err(gdiver2);
! 1814:
! 1815: if (is_const_t(tx) && is_const_t(ty))
! 1816: {
! 1817: switch(tx)
! 1818: {
! 1819: case t_REAL:
! 1820: switch(ty)
! 1821: {
! 1822: case t_INT:
! 1823: return divri(x,y);
! 1824:
! 1825: case t_REAL:
! 1826: return divrr(x,y);
! 1827:
! 1828: case t_FRAC: case t_FRACN:
! 1829: l=avma; p1=cgetg(lg(x),t_REAL); gaffect(y,p1);
! 1830: return gerepile(l,(long)p1,divrr(x,p1));
! 1831:
! 1832: case t_COMPLEX: z=cgetg(3,t_COMPLEX);
! 1833: l=avma; p1=gnorm(y);
! 1834: p2=gmul(x,(GEN)y[1]);
! 1835: p3=gmul(x,(GEN)y[2]);
! 1836: if (!gcmp0(p3)) p3 = gneg_i(p3);
! 1837: tetpil=avma;
! 1838: z[1]=ldiv(p2,p1);
! 1839: z[2]=ldiv(p3,p1);
! 1840: gerepilemanyvec(l,tetpil,z+1,2); return z;
! 1841:
! 1842: case t_QUAD:
! 1843: l=avma; p1=co8(y,lg(x)); tetpil=avma;
! 1844: return gerepile(l,tetpil,gdiv(x,p1));
! 1845:
! 1846: case t_INTMOD: case t_PADIC: err(operf,"/",tx,ty);
! 1847: }
! 1848:
! 1849: case t_INTMOD:
! 1850: switch(ty)
! 1851: {
! 1852: case t_INT: z=cgetg(3,t_INTMOD); p2=(GEN)x[1];
! 1853: (void)new_chunk(lgefint(p2)<<2); /* HACK */
! 1854: p1=mulii((GEN)x[2], mpinvmod(y,p2)); avma=(long)z;
! 1855: z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
! 1856:
! 1857: case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)x[1]; p1=(GEN)y[1];
! 1858: if (p1==p2 || egalii(p1,p2))
! 1859: { icopyifstack(p2,z[1]); }
! 1860: else
! 1861: { p2 = mppgcd(p1,p2); z[1] = (long)p2; }
! 1862: av=avma; (void)new_chunk(lgefint(x[1])+(lgefint(p1)<<1)); /* HACK */
! 1863: p1=mulii((GEN)x[2], mpinvmod((GEN)y[2],p2)); avma=av;
! 1864: z[2]=lmodii(p1,p2); return z;
! 1865:
! 1866: case t_FRAC: z=cgetg(3,t_INTMOD); p2=(GEN)x[1];
! 1867: (void)new_chunk(lgefint(p2)<<2); /* HACK */
! 1868: p1=mulii((GEN)y[2], mpinvmod((GEN)y[1],p2));
! 1869: p1=mulii(modii(p1,p2),(GEN)x[2]); avma=(long)z;
! 1870: z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
! 1871:
! 1872: case t_FRACN:
! 1873: l=avma; p1=gred(y); tetpil=avma;
! 1874: return gerepile(l,tetpil,gdiv(x,p1));
! 1875:
! 1876: case t_COMPLEX: case t_QUAD:
! 1877: l=avma; p1=gnorm(y); p2=gmul(x,gconj(y)); tetpil=avma;
! 1878: return gerepile(l,tetpil,gdiv(p2,p1));
! 1879:
! 1880: case t_PADIC:
! 1881: l=avma; p1=cgetg(3,t_INTMOD); p1[1]=x[1]; p1[2]=lgeti(lg(x[1]));
! 1882: gaffect(y,p1); tetpil=avma; return gerepile(l,tetpil,gdiv(x,p1));
! 1883:
! 1884: case t_REAL: err(operf,"/",tx,ty);
! 1885: }
! 1886:
! 1887: case t_FRAC: case t_FRACN:
! 1888: switch(ty)
! 1889: {
! 1890: case t_INT:
! 1891: z = cgetg(3, tx);
! 1892: if (tx == t_FRAC)
! 1893: {
! 1894: p1 = mppgcd(y,(GEN)x[1]);
! 1895: if (is_pm1(p1))
! 1896: {
! 1897: avma = (long)z; tetpil = 0;
! 1898: z[1] = licopy((GEN)x[1]);
! 1899: }
! 1900: else
! 1901: {
! 1902: y = divii(y,p1); tetpil = avma;
! 1903: z[1] = ldivii((GEN)x[1], p1);
! 1904: }
! 1905: }
! 1906: else
! 1907: {
! 1908: tetpil = 0;
! 1909: z[1] = licopy((GEN)x[1]);
! 1910: }
! 1911: z[2] = lmulii((GEN)x[2],y);
! 1912: fix_frac(z);
! 1913: if (tetpil) fix_frac_if_int_GC(z,tetpil);
! 1914: return z;
! 1915:
! 1916: case t_REAL:
! 1917: l=avma; p1=cgetg(lg(y),t_REAL); gaffect(x,p1);
! 1918: p2=divrr(p1,y); return gerepile(l,(long)p1,p2);
! 1919:
! 1920: case t_INTMOD: z=cgetg(3,t_INTMOD); p2=(GEN)y[1];
! 1921: (void)new_chunk(lgefint(p2)<<2); /* HACK */
! 1922: p1=mulii((GEN)y[2],(GEN)x[2]);
! 1923: p1=mulii(mpinvmod(p1,p2), modii((GEN)x[1],p2)); avma=(long)z;
! 1924: z[2]=lmodii(p1,p2); icopyifstack(p2,z[1]); return z;
! 1925:
! 1926: case t_FRAC: if (tx == t_FRACN) ty=t_FRACN;
! 1927: case t_FRACN:
! 1928: z = cgetg(3,ty);
! 1929: if (ty == t_FRAC)
! 1930: {
! 1931: GEN x1 = (GEN)x[1], x2 = (GEN)x[2];
! 1932: GEN y1 = (GEN)y[1], y2 = (GEN)y[2];
! 1933: p1 = mppgcd(x1, y1);
! 1934: if (!is_pm1(p1)) { x1 = divii(x1,p1); y1 = divii(y1,p1); }
! 1935: p1 = mppgcd(x2, y2);
! 1936: if (!is_pm1(p1)) { x2 = divii(x2,p1); y2 = divii(y2,p1); }
! 1937: tetpil = avma;
! 1938: z[2] = lmulii(x2,y1);
! 1939: z[1] = lmulii(x1,y2);
! 1940: fix_frac(z);
! 1941: fix_frac_if_int_GC(z,tetpil);
! 1942: }
! 1943: else
! 1944: {
! 1945: z[1]=lmulii((GEN)x[1],(GEN)y[2]);
! 1946: z[2]=lmulii((GEN)x[2],(GEN)y[1]);
! 1947: fix_frac(z);
! 1948: }
! 1949: return z;
! 1950:
! 1951: case t_COMPLEX: z=cgetg(3,t_COMPLEX);
! 1952: l=avma; p1=gnorm(y);
! 1953: p2=gmul(x,(GEN)y[1]);
! 1954: p3=gmul(x,(GEN)y[2]);
! 1955: if(!gcmp0(p3)) p3 = gneg_i(p3);
! 1956: tetpil=avma;
! 1957: z[1]=ldiv(p2,p1); z[2]=ldiv(p3,p1);
! 1958: gerepilemanyvec(l,tetpil,z+1,2); return z;
! 1959:
! 1960: case t_PADIC:
! 1961: if (!signe(x[1])) return gzero;
! 1962:
! 1963: l=avma; p1=cgetp(y); gaffect(x,p1);
! 1964: tetpil=avma; return gerepile(l,tetpil,gdiv(p1,y));
! 1965:
! 1966: case t_QUAD:
! 1967: l=avma; p1=gnorm(y); p2=gmul(x,gconj(y)); tetpil=avma;
! 1968: return gerepile(l,tetpil,gdiv(p2,p1));
! 1969: }
! 1970:
! 1971: case t_COMPLEX:
! 1972: switch(ty)
! 1973: {
! 1974: case t_INT: case t_REAL: case t_INTMOD: case t_FRAC: case t_FRACN:
! 1975: z=cgetg(3,t_COMPLEX);
! 1976: z[1]=ldiv((GEN)x[1],y);
! 1977: z[2]=ldiv((GEN)x[2],y); return z;
! 1978:
! 1979: case t_COMPLEX:
! 1980: l=avma; p1=gnorm(y); p2=gconj(y); p2=gmul(x,p2); tetpil=avma;
! 1981: return gerepile(l,tetpil, gdiv(p2,p1));
! 1982:
! 1983: case t_PADIC:
! 1984: if (krosg(-1,(GEN)y[2])== -1)
! 1985: {
! 1986: z=cgetg(3,t_COMPLEX);
! 1987: z[1]=ldiv((GEN)x[1],y);
! 1988: z[2]=ldiv((GEN)x[2],y); return z;
! 1989: }
! 1990: av=avma; p1=cvtop(x,(GEN)y[2],precp(y)); tetpil=avma;
! 1991: return gerepile(av,tetpil,gdiv(p1,y));
! 1992:
! 1993: case t_QUAD:
! 1994: lx=precision(x); if (!lx) err(operi,"/",tx,ty);
! 1995: l=avma; p1=co8(y,lx); tetpil=avma;
! 1996: return gerepile(l,tetpil,gdiv(x,p1));
! 1997: }
! 1998:
! 1999: case t_PADIC:
! 2000: switch(ty)
! 2001: {
! 2002: case t_INT: case t_FRAC: case t_FRACN:
! 2003: l=avma;
! 2004: if (signe(x[4])) { p1=cgetp(x); gaffect(y,p1); }
! 2005: else p1=cvtop(y,(GEN)x[2],(valp(x)>0)?valp(x):1);
! 2006: tetpil=avma; return gerepile(l,tetpil,gdiv(x,p1));
! 2007:
! 2008: case t_INTMOD:
! 2009: l=avma; p1=cgetg(3,t_INTMOD);
! 2010: p1[1]=y[1]; p1[2]=lgeti(lg(y[1]));
! 2011: gaffect(x,p1); tetpil=avma;
! 2012: return gerepile(l,tetpil,gdiv(p1,y));
! 2013:
! 2014: case t_PADIC:
! 2015: if (!egalii((GEN)x[2],(GEN)y[2])) err(operi,"/",tx,ty);
! 2016: if (!signe(x[4]))
! 2017: {
! 2018: z=gcopy(x); setvalp(z,valp(x)-valp(y));
! 2019: return z;
! 2020: }
! 2021:
! 2022: p1=(precp(x)>precp(y)) ? y : x;
! 2023: z=cgetp(p1); l=avma;
! 2024: setvalp(z,valp(x)-valp(y));
! 2025: p2=mpinvmod((GEN)y[4],(GEN)p1[3]);
! 2026: modiiz(mulii((GEN)x[4],p2),(GEN)p1[3],(GEN)z[4]);
! 2027: avma=l; return z;
! 2028:
! 2029: case t_COMPLEX: case t_QUAD:
! 2030: l=avma; p1=gmul(x,gconj(y)); p2=gnorm(y); tetpil=avma;
! 2031: return gerepile(l,tetpil,gdiv(p1,p2));
! 2032:
! 2033: case t_REAL:
! 2034: err(operf,"/",tx,ty);
! 2035: }
! 2036:
! 2037: case t_QUAD:
! 2038: switch (ty)
! 2039: {
! 2040: case t_INT: case t_INTMOD: case t_FRAC: case t_FRACN:
! 2041: z=cgetg(4,t_QUAD);
! 2042: copyifstack(x[1], z[1]);
! 2043: for (i=2; i<4; i++) z[i]=ldiv((GEN)x[i],y);
! 2044: return z;
! 2045:
! 2046: case t_REAL:
! 2047: l=avma; p1=co8(x,lg(y)); tetpil=avma;
! 2048: return gerepile(l,tetpil,gdiv(p1,y));
! 2049:
! 2050: case t_PADIC:
! 2051: l=avma; p1=cvtop(x,(GEN)y[2],precp(y));
! 2052: tetpil=avma; return gerepile(l,tetpil,gdiv(p1,y));
! 2053:
! 2054: case t_COMPLEX:
! 2055: ly=precision(y); if (!ly) err(operi,"/",tx,ty);
! 2056: l=avma; p1=co8(x,ly); tetpil=avma;
! 2057: return gerepile(l,tetpil,gdiv(p1,y));
! 2058:
! 2059: case t_QUAD:
! 2060: k=x[1]; l=y[1];
! 2061: if (!gegal((GEN)k,(GEN)l)) err(operi,"/",tx,ty);
! 2062: l=avma; p1=gnorm(y); p2=gmul(x,gconj(y)); tetpil=avma;
! 2063: return gerepile(l,tetpil,gdiv(p2,p1));
! 2064: }
! 2065: }
! 2066: err(bugparier,"division");
! 2067: }
! 2068:
! 2069: vx=gvar(x); vy=gvar(y);
! 2070: if (ty == t_POLMOD || ty == t_INTMOD)
! 2071: {
! 2072: av = avma;
! 2073: return gerepileupto(av, gmul(x, ginv(y)));
! 2074: }
! 2075: if (tx == t_POLMOD && vx<=vy)
! 2076: {
! 2077: av = avma;
! 2078: if (vx == vy)
! 2079: y = gmul(y, gmodulsg(1, (GEN)x[1]));
! 2080: else if (is_extscalar_t(ty))
! 2081: {
! 2082: z=cgetg(3,t_POLMOD);
! 2083: copyifstack(x[1],z[1]);
! 2084: z[2]=ldiv((GEN)x[2],y); return z;
! 2085: }
! 2086: return gerepileupto(av, gmul(x, ginv(y)));
! 2087: }
! 2088: if (is_noncalc_t(tx) || is_noncalc_t(ty)) err(operf,"/",tx, ty);
! 2089: /* now x and y are not both is_scalar_t */
! 2090:
! 2091: lx = lg(x);
! 2092: if ((vx<vy && (!is_matvec_t(tx) || !is_matvec_t(ty)))
! 2093: || (vx==vy && is_scalar_t(ty)) || (is_matvec_t(tx) && !is_matvec_t(ty)))
! 2094: {
! 2095: if (tx == t_RFRAC) return divrfracscal(x,y);
! 2096: z = cgetg(lx,tx);
! 2097: if (tx == t_RFRACN)
! 2098: {
! 2099: z[2]=lmul((GEN)x[2],y);
! 2100: z[1]=lcopy((GEN)x[1]); return z;
! 2101: }
! 2102: switch(tx)
! 2103: {
! 2104: case t_POL: lx = lgef(x);
! 2105: case t_SER: z[1] = x[1];
! 2106: case t_VEC: case t_COL: case t_MAT:
! 2107: for (i=lontyp[tx]; i<lx; i++) z[i]=ldiv((GEN)x[i],y);
! 2108: return z;
! 2109: }
! 2110: err(operf,"/",tx,ty);
! 2111: }
! 2112:
! 2113: ly=lg(y);
! 2114: if (vy<vx || (vy==vx && is_scalar_t(tx)))
! 2115: {
! 2116: switch(ty)
! 2117: {
! 2118: case t_POL:
! 2119: if (lgef(y)==3) return gdiv(x,(GEN)y[2]);
! 2120: if (isexactzero(x)) return zeropol(vy);
! 2121: return gred_rfrac2(x,y);
! 2122:
! 2123: case t_SER:
! 2124: if (gcmp0(x))
! 2125: {
! 2126: l=avma; p1=ginv(y); tetpil=avma; /* a ameliorer !!!! */
! 2127: return gerepile(l,tetpil,gmul(x,p1));
! 2128: }
! 2129: p1 = (GEN)gpmalloc(ly*sizeof(long));
! 2130: p1[0] = evaltyp(t_SER) | evallg(ly);
! 2131: p1[1] = evalsigne(1) | evalvalp(0) | evalvarn(vy);
! 2132: p1[2] = (long)x; for (i=3; i<ly; i++) p1[i]=zero;
! 2133: y = gdiv(p1,y); free(p1); return y;
! 2134:
! 2135: case t_RFRAC: return divscalrfrac(x,y);
! 2136: case t_RFRACN: z=cgetg(ly,t_RFRACN);
! 2137: z[1]=lmul(x,(GEN)y[2]);
! 2138: z[2]=lcopy((GEN)y[1]); return z;
! 2139:
! 2140: case t_MAT:
! 2141: l=avma; p1=invmat(y); tetpil=avma;
! 2142: return gerepile(l,tetpil,gmul(x,p1));
! 2143:
! 2144: case t_VEC: case t_COL: err(operf,"/",tx,ty);
! 2145: }
! 2146: err(operf,"/",tx,ty);
! 2147: }
! 2148:
! 2149: /* ici vx=vy et tx>=10 et ty>=10*/
! 2150: switch(tx)
! 2151: {
! 2152: case t_POL:
! 2153: switch(ty)
! 2154: {
! 2155: case t_POL:
! 2156: if (lgef(y)==3) return gdiv(x,(GEN)y[2]);
! 2157: if (isexactzero(x)) return zeropol(vy);
! 2158: return gred_rfrac2(x,y);
! 2159:
! 2160: case t_SER:
! 2161: if (gcmp0(x)) return zeropol(vx);
! 2162: p1=greffe(x,ly,0); p2=gdiv(p1,y);
! 2163: free(p1); return p2;
! 2164:
! 2165: case t_RFRAC: return divscalrfrac(x,y);
! 2166: case t_RFRACN: z=cgetg(ly,t_RFRACN);
! 2167: z[1]=lmul(x,(GEN)y[2]);
! 2168: z[2]=lcopy((GEN)y[1]); return z;
! 2169:
! 2170: default: err(operf,"/",tx,ty);
! 2171: }
! 2172:
! 2173: case t_SER:
! 2174: switch(ty)
! 2175: {
! 2176: case t_POL:
! 2177: p1=greffe(y,lg(x),0); p2=gdiv(x,p1);
! 2178: free(p1); return p2;
! 2179:
! 2180: case t_SER:
! 2181: {
! 2182: GEN y_lead;
! 2183:
! 2184: l = valp(x) - valp(y);
! 2185: if (gcmp0(x)) return zeroser(vx,l);
! 2186: y_lead = (GEN)y[2];
! 2187: if (gcmp0(y_lead)) /* normalize denominator if leading term is 0 */
! 2188: {
! 2189: err(warner,"normalizing a series with 0 leading term");
! 2190: for (i=3,y++; i<ly; i++,y++)
! 2191: {
! 2192: y_lead = (GEN)y[2]; ly--; l--;
! 2193: if (!gcmp0(y_lead)) break;
! 2194: }
! 2195: if (i>=ly) err(gdiver2);
! 2196: }
! 2197: if (ly < lx) lx = ly;
! 2198: p2 = (GEN)gpmalloc(lx*sizeof(long));
! 2199: for (i=3; i<lx; i++)
! 2200: {
! 2201: p1 = (GEN)y[i];
! 2202: if (isexactzero(p1)) p2[i] = 0;
! 2203: else
! 2204: {
! 2205: av = avma; p2[i] = lclone(gneg_i(p1));
! 2206: avma = av;
! 2207: }
! 2208: }
! 2209: z = cgetg(lx,t_SER);
! 2210: z[1] = evalvalp(l) | evalvarn(vx) | evalsigne(1);
! 2211: z[2] = ldiv((GEN)x[2], y_lead);
! 2212: for (i=3; i<lx; i++)
! 2213: {
! 2214: av=avma; p1 = (GEN)x[i];
! 2215: for (j=2; j<i; j++)
! 2216: {
! 2217: l = i-j+2;
! 2218: if (p2[l])
! 2219: p1 = gadd(p1, gmul((GEN)z[j], (GEN)p2[l]));
! 2220: }
! 2221: p1 = gdiv(p1, y_lead);
! 2222: tetpil=avma; z[i]=lpile(av,tetpil, forcecopy(p1));
! 2223: }
! 2224: for (i=3; i<lx; i++)
! 2225: if (p2[i]) gunclone((GEN)p2[i]);
! 2226: free(p2); return z;
! 2227: }
! 2228:
! 2229: case t_RFRAC: case t_RFRACN:
! 2230: l=avma; p2=gmul(x,(GEN)y[2]); tetpil=avma;
! 2231: return gerepile(l,tetpil,gdiv(p2,(GEN)y[1]));
! 2232:
! 2233: default: err(operf,"/",tx,ty);
! 2234: }
! 2235:
! 2236: case t_RFRAC: case t_RFRACN:
! 2237: switch(ty)
! 2238: {
! 2239: case t_POL:
! 2240: if (tx==t_RFRAC) return divrfracscal(x,y);
! 2241: z=cgetg(3,t_RFRACN);
! 2242: z[2]=lmul((GEN)x[2],y);
! 2243: z[1]=lcopy((GEN)x[1]); return z;
! 2244:
! 2245: case t_SER:
! 2246: l=avma; p2=gmul((GEN)x[2],y); tetpil=avma;
! 2247: return gerepile(l,tetpil, gdiv((GEN)x[1],p2));
! 2248:
! 2249: case t_RFRAC: case t_RFRACN:
! 2250: if (tx == t_RFRACN) ty=t_RFRACN;
! 2251: if (ty != t_RFRACN) return divrfrac(x,y);
! 2252: z=cgetg(3,t_RFRACN);
! 2253: z[1]=lmul((GEN)x[1],(GEN)y[2]);
! 2254: z[2]=lmul((GEN)x[2],(GEN)y[1]); return z;
! 2255:
! 2256: default: err(operf,"/",tx,ty);
! 2257: }
! 2258:
! 2259: case t_VEC: case t_COL: case t_MAT:
! 2260: if (!is_matvec_t(ty))
! 2261: {
! 2262: z=cgetg(lx,tx);
! 2263: for (i=1; i<lx; i++) z[i]=ldiv((GEN)x[i],y);
! 2264: return z;
! 2265: }
! 2266: if (ty!=t_MAT || ly==1 || lg(y[1])!=ly) err(operi,"/",tx,ty);
! 2267: l=avma; p1=invmat(y); tetpil=avma;
! 2268: return gerepile(l,tetpil,gmul(x,p1));
! 2269: case t_QFI:case t_QFR:
! 2270: break;
! 2271: default: err(operf,"/",tx,ty);
! 2272: }
! 2273: /*Here tx==t_QFI || tx==t_QFR*/
! 2274: if (tx==ty)
! 2275: {
! 2276: l=signe(y[2]); setsigne(y[2],-l);
! 2277: switch(tx)
! 2278: {
! 2279: case t_QFI: z = compimag(x,y);
! 2280: setsigne(y[2],l); return z;
! 2281: case t_QFR:
! 2282: k=signe(y[4]); setsigne(y[4],-k); z=compreal(x,y);
! 2283: setsigne(y[2],l); setsigne(y[4],k); return z;
! 2284: }
! 2285: }
! 2286: err(operf,"/",tx,ty);
! 2287: return NULL; /* not reached */
! 2288: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>