Annotation of OpenXM_contrib2/asir2000/engine/E.c, Revision 1.1
1.1 ! noro 1: /* $OpenXM: OpenXM/src/asir99/engine/E.c,v 1.1.1.1 1999/11/10 08:12:26 noro Exp $ */
! 2: #include "ca.h"
! 3:
! 4: void henmv(vl,vn,f,g0,h0,a0,b0,lg,lh,lg0,lh0,q,k,gp,hp)
! 5: VL vl;
! 6: VN vn;
! 7: P f,g0,h0,a0,b0,lg,lh,lg0,lh0;
! 8: Q q;
! 9: int k;
! 10: P *gp,*hp;
! 11: {
! 12: P g1,h1,a1,b1;
! 13: N qn;
! 14: Q q2;
! 15:
! 16: divin((NM(q)),2,&qn); NTOQ(qn,1,q2);
! 17: adjc(vl,g0,a0,lg0,q,&g1,&a1); adjc(vl,h0,b0,lh0,q,&h1,&b1);
! 18: henmvmain(vl,vn,f,g1,h1,b1,a1,lg,lh,q,q2,k,gp,hp);
! 19: }
! 20:
! 21: void henmvmain(vl,vn,f,fi0,fi1,gi0,gi1,l0,l1,mod,mod2,k,fr0,fr1)
! 22: VL vl;
! 23: VN vn;
! 24: P f,fi0,fi1,gi0,gi1,l0,l1;
! 25: Q mod,mod2;
! 26: int k;
! 27: P *fr0,*fr1;
! 28: {
! 29: V v;
! 30: int n,i,j;
! 31: int *md;
! 32: P x,m,m1,c,q,r,a,s,u,ff,f0,f1;
! 33: P w0,w1,cf,cfi,t,q1,dvr;
! 34: P *c0,*c1;
! 35: P *f0h,*f1h;
! 36:
! 37: v = VR(f); n = deg(v,f); MKV(v,x);
! 38: c0 = (P *)ALLOCA((n+1)*sizeof(P));
! 39: c1 = (P *)ALLOCA((n+1)*sizeof(P));
! 40: invl((Q)LC(fi1),mod,(Q *)&c); mulp(vl,fi1,c,&t); cmp(mod,t,&dvr);
! 41: cm2p(mod,mod2,gi0,&c0[0]); cm2p(mod,mod2,gi1,&c1[0]);
! 42: for ( i = 1; i <= n; i++ ) {
! 43: mulp(vl,x,c1[i-1],&m); divsrp(vl,m,dvr,&q,&r); mulp(vl,q,c,&q1);
! 44: cm2p(mod,mod2,r,&c1[i]);
! 45: mulp(vl,x,c0[i-1],&m); mulp(vl,q1,fi0,&m1); addp(vl,m,m1,&a);
! 46: cm2p(mod,mod2,a,&c0[i]);
! 47: }
! 48: affine(vl,f,vn,&t); cm2p(mod,mod2,t,&ff);
! 49: for ( i = 0; vn[i].v; i++ );
! 50: md = ( int *) ALLOCA((i+1)*sizeof(int));
! 51: for ( i = 0; vn[i].v; i++ )
! 52: md[i] = getdeg(vn[i].v,ff);
! 53: cm2p(mod,mod2,fi0,&f0); affine(vl,l0,vn,&t);
! 54: if ( NUM(f0) )
! 55: cm2p(mod,mod2,t,&f0);
! 56: else
! 57: cm2p(mod,mod2,t,&COEF(DC(f0)));
! 58: cm2p(mod,mod2,fi1,&f1); affine(vl,l1,vn,&t);
! 59: if ( NUM(f1) )
! 60: cm2p(mod,mod2,t,&f1);
! 61: else
! 62: cm2p(mod,mod2,t,&COEF(DC(f1)));
! 63: W_CALLOC(k,P,f0h); W_CALLOC(k,P,f1h);
! 64: for ( i = 0; i <= k; i++ ) {
! 65: exthpc(vl,v,f0,i,&f0h[i]); exthpc(vl,v,f1,i,&f1h[i]);
! 66: }
! 67: for ( j = 1; j <= k; j++ ) {
! 68: for ( i = 0; vn[i].v; i++ )
! 69: if ( getdeg(vn[i].v,f0)+getdeg(vn[i].v,f1) > md[i] )
! 70: goto END;
! 71: for ( i = 0, s = 0; i <= j; i++ ) {
! 72: mulp(vl,f0h[i],f1h[j-i],&t); addp(vl,s,t,&u); s = u;
! 73: }
! 74: cm2p(mod,mod2,s,&t);
! 75: exthpc(vl,v,ff,j,&u); subm2p(vl,mod,mod2,u,t,&cf);
! 76: for ( i = 0, w0 = 0, w1 = 0; i <= n; i++ ) {
! 77: if ( !cf )
! 78: cfi = 0;
! 79: else if ( VR(cf) == v )
! 80: coefp(cf,i,&cfi);
! 81: else if ( i == 0 )
! 82: cfi = cf;
! 83: else
! 84: cfi = 0;
! 85: if ( cfi ) {
! 86: mulp(vl,cfi,c0[i],&m); addp(vl,w0,m,&a); w0 = a;
! 87: mulp(vl,cfi,c1[i],&m); addp(vl,w1,m,&a); w1 = a;
! 88: }
! 89: }
! 90: cm2p(mod,mod2,w0,&t); addm2p(vl,mod,mod2,f0,t,&a);
! 91: addm2p(vl,mod,mod2,f0h[j],t,&s); f0h[j] = s; f0 = a;
! 92: cm2p(mod,mod2,w1,&u); addm2p(vl,mod,mod2,f1,u,&a);
! 93: addm2p(vl,mod,mod2,f1h[j],u,&s); f1h[j] = s; f1 = a;
! 94: if ( !t ) {
! 95: restore(vl,f0,vn,&s); cm2p(mod,mod2,s,&t);
! 96: if ( divtpz(vl,f,t,&s) ) {
! 97: *fr0 = t; *fr1 = s;
! 98: return;
! 99: }
! 100: }
! 101: if ( !u ) {
! 102: restore(vl,f1,vn,&s); cm2p(mod,mod2,s,&t);
! 103: if ( divtpz(vl,f,t,&s) ) {
! 104: *fr0 = s; *fr1 = t;
! 105: return;
! 106: }
! 107: }
! 108: }
! 109: END:
! 110: restore(vl,f0,vn,&t); cm2p(mod,mod2,t,fr0);
! 111: restore(vl,f1,vn,&t); cm2p(mod,mod2,t,fr1);
! 112: }
! 113:
! 114: /*
! 115: input : f, fi0, fi1, p, k; f = fi0 * fi1 mod p; ( p, k : integer )
! 116: output : gr1 * fr0 + gr0 * fr1 = 1 mod qr; ( qr = p^(2^(k-1)) )
! 117: */
! 118:
! 119: void henzq(f,i0,fi0,i1,fi1,p,k,fr0p,fr1p,gr0p,gr1p,qrp)
! 120: P f;
! 121: UM fi0,fi1;
! 122: int p,k;
! 123: P i0,i1;
! 124: P *fr0p,*fr1p,*gr0p,*gr1p;
! 125: Q *qrp;
! 126: {
! 127: N qn;
! 128: Q q,qq,q2;
! 129: int n,i;
! 130: UM wg0,wg1,wf0,wf1;
! 131: P f0,f1,g0,g1,m,m1,s,c,d,q1,r1,rm,rm1,a,a1,a2;
! 132:
! 133: n = UDEG(f);
! 134: wf0 = W_UMALLOC(n); wf1 = W_UMALLOC(n);
! 135: wg0 = W_UMALLOC(n); wg1 = W_UMALLOC(n);
! 136: cpyum(fi0,wf0); cpyum(fi1,wf1);
! 137: eucum(p,wf0,wf1,wg1,wg0);
! 138: umtop(VR(f),fi0,&f0); umtop(VR(f),fi1,&f1);
! 139: umtop(VR(f),wg0,&g0); umtop(VR(f),wg1,&g1);
! 140:
! 141: STOQ(p,q); divin(NM(q),2,&qn); NTOQ(qn,1,q2);
! 142: for ( i = 1; i < k; i++ ) {
! 143: #if 0
! 144: mulp(CO,i1,g0,&m); mulp(CO,i0,g1,&m1); addp(CO,m,m1,&a);
! 145: if ( NUM(a) ) {
! 146: for ( STOQ(p,q), j = 1; j < k; j++ ) {
! 147: mulq(q,q,&qq); q = qq;
! 148: }
! 149: f0 = i0; f1 = i1;
! 150: invl(a,q,&qq);
! 151: mulp(CO,g0,qq,&s); g0 = s; mulp(CO,g1,qq,&s); g1 = s;
! 152: break;
! 153: }
! 154: #endif
! 155: /* c = ((f - f0*f1)/q) mod q;
! 156: q1 = (c*g1) / f1;
! 157: r1 = (c*g1) mod f1;
! 158: f1 += (r1 mod q)*q;
! 159: f0 += ((c*g0 + q1*f0) mod q)*q;
! 160:
! 161: d = ((1 - (f1*g0 + f0*g1))/q) mod q;
! 162: q1 = (d*g0) / f1;
! 163: r1 = (d*g0) mod f1;
! 164: g1 += (r1 mod q)*q;
! 165: g0 += ((c*g0 + q1*f0) mod q)*q;
! 166: q = q^2;
! 167: */
! 168:
! 169: /* c = ((f - f0*f1)/q) mod q */
! 170: mulp(CO,f0,f1,&m); subp(CO,f,m,&s);
! 171: divcp(s,q,&m); cm2p(q,q2,m,&c);
! 172:
! 173: /* q1 = (c*g1) / f1; r1 = (c*g1) mod f1; */
! 174: mulp(CO,c,g1,&m); cm2p(q,q2,m,&s);
! 175: udivpwm(q,s,f1,&q1,&r1);
! 176:
! 177: /* f1 = f1 + (r1 mod q)*q; */
! 178: cm2p(q,q2,r1,&rm);
! 179: mulpq(rm,(P)q,&rm1); addp(CO,f1,rm1,&a);
! 180: f1 = a;
! 181:
! 182: /* a1 = (c*g0 + q1*f0) mod q; */
! 183: mulp(CO,c,g0,&m); mulp(CO,q1,f0,&m1); addp(CO,m,m1,&a);
! 184: cm2p(q,q2,a,&a1);
! 185:
! 186: /* f0 = f0 + a1*q; */
! 187: mulpq(a1,(P)q,&a2);
! 188: addp(CO,f0,a2,&a);
! 189: f0 = a;
! 190:
! 191: /* d = ((1 - (f1*g0 + f0*g1))/q) mod q; */
! 192: mulp(CO,f1,g0,&m); mulp(CO,f0,g1,&m1); addp(CO,m,m1,&a);
! 193: subp(CO,(P)ONE,a,&s);
! 194: divcp(s,q,&m); cm2p(q,q2,m,&d);
! 195:
! 196: /* q1 = (d*g0) / f1; r1 = (d*g0) mod f1; */
! 197: mulp(CO,d,g1,&m); udivpwm(q,m,f1,&q1,&r1);
! 198:
! 199: /* g1 = g1 + (r1 mod q )*q; */
! 200: cm2p(q,q2,r1,&rm);
! 201: mulpq(rm,(P)q,&rm1); addp(CO,g1,rm1,&a);
! 202: g1 = a;
! 203:
! 204: /* g0 = g0 + (c*g0 + q1*f0 mod q)*q; */
! 205: mulp(CO,d,g0,&m); mulp(CO,q1,f0,&m1); addp(CO,m,m1,&a);
! 206: cm2p(q,q2,a,&a1); mulpq(a1,(P)q,&a2);
! 207: addp(CO,g0,a2,&a);
! 208: g0 = a;
! 209:
! 210: /* q = q^2; */
! 211: mulq(q,q,&qq);
! 212: q = qq;
! 213: divin(NM(q),2,&qn); NTOQ(qn,1,q2);
! 214: }
! 215: *fr0p = f0; *fr1p = f1; *gr0p = g0; *gr1p = g1; *qrp = q;
! 216: }
! 217:
! 218: void henzq1(g,h,bound,gcp,hcp,qp)
! 219: P g,h;
! 220: Q bound;
! 221: P *gcp,*hcp;
! 222: Q *qp;
! 223: {
! 224: V v;
! 225: Q f,q,q1;
! 226: Q u,t,a,b,s;
! 227: P c,c1;
! 228: P tg,th,tr;
! 229: UM wg,wh,ws,wt,wm;
! 230: int n,m,modres,mod,index,i;
! 231: P gc0,hc0;
! 232: P z,zz,zzz;
! 233:
! 234:
! 235: v = VR(g); n=deg(v,g); m=deg(v,h);
! 236: norm(g,&a); norm(h,&b);
! 237: STOQ(m,u); pwrq(a,u,&t);
! 238: STOQ(n,u); pwrq(b,u,&s);
! 239: mulq(t,s,&u);
! 240:
! 241: factorial(n+m,&t); mulq(u,t,&s);
! 242: addq(s,s,&f);
! 243:
! 244: wg = W_UMALLOC(m+n); wh = W_UMALLOC(m+n);
! 245: wt = W_UMALLOC(m+n); ws = W_UMALLOC(m+n);
! 246: wm = W_UMALLOC(m+n);
! 247:
! 248: for ( q = ONE, t = 0, c = 0, index = 0; ; ) {
! 249: mod = lprime[index++];
! 250: if ( !mod )
! 251: error("henzq1 : lprime[] exhausted.");
! 252: if ( !rem(NM((Q)LC(g)),mod) || !rem(NM((Q)LC(h)),mod) )
! 253: continue;
! 254: ptomp(mod,g,&tg); ptomp(mod,h,&th);
! 255: srchump(mod,tg,th,&tr);
! 256: if ( !tr )
! 257: continue;
! 258: else
! 259: modres = CONT((MQ)tr);
! 260:
! 261: mptoum(tg,wg); mptoum(th,wh);
! 262: eucum(mod,wg,wh,ws,wt); /* wg * ws + wh * wt = 1 */
! 263: DEG(wm) = 0; COEF(wm)[0] = modres;
! 264: mulum(mod,ws,wm,wt);
! 265: for ( i = DEG(wt); i >= 0; i-- )
! 266: if ( ( COEF(wt)[i] * 2 ) > mod )
! 267: COEF(wt)[i] -= mod;
! 268: chnrem(mod,v,c,q,wt,&c1,&q1);
! 269: if ( !ucmpp(c,c1) ) {
! 270: mulp(CO,c,g,&z); divsrp(CO,z,h,&zz,&zzz);
! 271: if ( NUM(zzz) ) {
! 272: q = q1; c = c1;
! 273: break;
! 274: }
! 275: }
! 276: q = q1; c = c1;
! 277:
! 278: if ( cmpq(f,q) < 0 )
! 279: break;
! 280: }
! 281: ptozp(c,1,&s,&gc0);
! 282: /* gc0*g = zz*h + zzz -> c*g + (-zz)*h = zzz */
! 283: mulp(CO,gc0,g,&z);
! 284: divsrp(CO,z,h,&zz,&zzz);
! 285: ptozp(zz,1,&s,(P *)&t);
! 286: if ( INT((Q)s) )
! 287: chsgnp(zz,&hc0);
! 288: else {
! 289: NTOQ(DN((Q)s),1,q); mulq(q,(Q)zzz,&q1); zzz = (P)q1;
! 290: mulp(CO,gc0,(P)q,&c); gc0 = c; mulp(CO,zz,(P)q,&c); chsgnp(c,&hc0);
! 291: }
! 292: if ( !INT((Q)zzz) ) {
! 293: NTOQ(DN((Q)zzz),1,q); NTOQ(NM((Q)zzz),1,q1); zzz = (P)q1;
! 294: mulp(CO,gc0,(P)q,&c); gc0 = c; mulp(CO,hc0,(P)q,&c); hc0 = c;
! 295: }
! 296: for ( index = 0; ; ) {
! 297: mod = lprime[index++];
! 298: if ( !mod )
! 299: error("henzq1 : lprime[] exhausted.");
! 300: if ( !rem(NM((Q)zzz),mod) ||
! 301: !rem(NM((Q)LC(g)),mod) ||
! 302: !rem(NM((Q)LC(h)),mod) )
! 303: continue;
! 304: for ( STOQ(mod,q); cmpq(q,bound) < 0; ) {
! 305: mulq(q,q,&q1); q = q1;
! 306: }
! 307: *qp = q;
! 308: invl((Q)zzz,q,&q1);
! 309: mulp(CO,gc0,(P)q1,hcp); mulp(CO,hc0,(P)q1,gcp);
! 310: return;
! 311: }
! 312: }
! 313:
! 314: void addm2p(vl,mod,mod2,n1,n2,nr)
! 315: VL vl;
! 316: Q mod,mod2;
! 317: P n1,n2,*nr;
! 318: {
! 319: P t;
! 320:
! 321: addp(vl,n1,n2,&t);
! 322: if ( !t )
! 323: *nr = 0;
! 324: else
! 325: cm2p(mod,mod2,t,nr);
! 326: }
! 327:
! 328: void subm2p(vl,mod,mod2,n1,n2,nr)
! 329: VL vl;
! 330: Q mod,mod2;
! 331: P n1,n2,*nr;
! 332: {
! 333: P t;
! 334:
! 335: subp(vl,n1,n2,&t);
! 336: if ( !t )
! 337: *nr = 0;
! 338: else
! 339: cm2p(mod,mod2,t,nr);
! 340: }
! 341:
! 342: void mulm2p(vl,mod,mod2,n1,n2,nr)
! 343: VL vl;
! 344: Q mod,mod2;
! 345: P n1,n2,*nr;
! 346: {
! 347: P t;
! 348:
! 349: mulp(vl,n1,n2,&t);
! 350: if ( !t )
! 351: *nr = 0;
! 352: else
! 353: cm2p(mod,mod2,t,nr);
! 354: }
! 355:
! 356: void cmp(mod,p,pr)
! 357: Q mod;
! 358: P p,*pr;
! 359: {
! 360: P t;
! 361: DCP dc,dcr,dcr0;
! 362:
! 363: if ( !p )
! 364: *pr = 0;
! 365: else if ( NUM(p) )
! 366: remq((Q)p,mod,(Q *)pr);
! 367: else {
! 368: for ( dc = DC(p), dcr0 = 0; dc; dc = NEXT(dc) ) {
! 369: cmp(mod,COEF(dc),&t);
! 370: if ( t ) {
! 371: NEXTDC(dcr0,dcr);
! 372: DEG(dcr) = DEG(dc);
! 373: COEF(dcr) = t;
! 374: }
! 375: }
! 376: if ( !dcr0 )
! 377: *pr = 0;
! 378: else {
! 379: NEXT(dcr) = 0;
! 380: MKP(VR(p),dcr0,*pr);
! 381: }
! 382: }
! 383: }
! 384:
! 385: void cm2p(mod,m,p,pr)
! 386: Q mod,m;
! 387: P p,*pr;
! 388: {
! 389: P t;
! 390: DCP dc,dcr,dcr0;
! 391:
! 392: if ( !p )
! 393: *pr = 0;
! 394: else if ( NUM(p) )
! 395: rem2q((Q)p,mod,m,(Q *)pr);
! 396: else {
! 397: for ( dc = DC(p), dcr0 = 0; dc; dc = NEXT(dc) ) {
! 398: cm2p(mod,m,COEF(dc),&t);
! 399: if ( t ) {
! 400: NEXTDC(dcr0,dcr);
! 401: DEG(dcr) = DEG(dc);
! 402: COEF(dcr) = t;
! 403: }
! 404: }
! 405: if ( !dcr0 )
! 406: *pr = 0;
! 407: else {
! 408: NEXT(dcr) = 0;
! 409: MKP(VR(p),dcr0,*pr);
! 410: }
! 411: }
! 412: }
! 413:
! 414: void addm2q(mod,mod2,n1,n2,nr)
! 415: Q mod,mod2;
! 416: Q n1,n2,*nr;
! 417: {
! 418: Q t;
! 419:
! 420: addq(n1,n2,&t);
! 421: if ( !t )
! 422: *nr = 0;
! 423: else
! 424: rem2q(t,mod,mod2,nr);
! 425: }
! 426:
! 427: void subm2q(mod,mod2,n1,n2,nr)
! 428: Q mod,mod2;
! 429: Q n1,n2,*nr;
! 430: {
! 431: Q t;
! 432:
! 433: subq(n1,n2,&t);
! 434: if ( !t )
! 435: *nr = 0;
! 436: else
! 437: rem2q(t,mod,mod2,nr);
! 438: }
! 439:
! 440: void mulm2q(mod,mod2,n1,n2,nr)
! 441: Q mod,mod2;
! 442: Q n1,n2,*nr;
! 443: {
! 444: Q t;
! 445:
! 446: mulq(n1,n2,&t);
! 447: if ( !t )
! 448: *nr = 0;
! 449: else
! 450: rem2q(t,mod,mod2,nr);
! 451: }
! 452:
! 453: void rem2q(n,m,m2,nr)
! 454: Q n,m,m2,*nr;
! 455: {
! 456: N q,r,s;
! 457: int sgn;
! 458:
! 459: divn(NM(n),NM(m),&q,&r);
! 460: if ( !r )
! 461: *nr = 0;
! 462: else {
! 463: sgn = cmpn(r,NM(m2));
! 464: if ( sgn > 0 ) {
! 465: subn(NM(m),r,&s); NTOQ(s,-1*SGN(n),*nr);
! 466: } else
! 467: NTOQ(r,SGN(n),*nr);
! 468: }
! 469: }
! 470:
! 471: void exthp(vl,p,d,pr)
! 472: VL vl;
! 473: P p;
! 474: int d;
! 475: P *pr;
! 476: {
! 477: P t,t1,a,w,x,xd;
! 478: DCP dc;
! 479:
! 480: if ( d < 0 )
! 481: *pr = 0;
! 482: else if ( NUM(p) )
! 483: if ( d == 0 )
! 484: *pr = p;
! 485: else
! 486: *pr = 0;
! 487: else {
! 488: for ( MKV(VR(p),x), dc = DC(p), w = 0; dc; dc = NEXT(dc) ) {
! 489: exthp(vl,COEF(dc),d - QTOS(DEG(dc)),&t);
! 490: pwrp(vl,x,DEG(dc),&xd);
! 491: mulp(vl,xd,t,&t1); addp(vl,w,t1,&a); w = a;
! 492: }
! 493: *pr = w;
! 494: }
! 495: }
! 496:
! 497: void exthpc(vl,v,p,d,pr)
! 498: VL vl;
! 499: V v;
! 500: P p;
! 501: int d;
! 502: P *pr;
! 503: {
! 504: P t,t1,a,w,x,xd;
! 505: DCP dc;
! 506:
! 507: if ( v != VR(p) )
! 508: exthp(vl,p,d,pr);
! 509: else if ( d < 0 )
! 510: *pr = 0;
! 511: else {
! 512: for ( MKV(v,x), dc = DC(p), w = 0; dc; dc = NEXT(dc) ) {
! 513: exthp(vl,COEF(dc),d,&t);
! 514: pwrp(vl,x,DEG(dc),&xd);
! 515: mulp(vl,xd,t,&t1); addp(vl,w,t1,&a); w = a;
! 516: }
! 517: *pr = w;
! 518: }
! 519: }
! 520:
! 521: void cbound(vl,p,b)
! 522: VL vl;
! 523: P p;
! 524: Q *b;
! 525: {
! 526: Q n,e,t,m;
! 527: int k;
! 528:
! 529: cmax(p,&n);
! 530: addq(n,n,&m);
! 531:
! 532: k = geldb(vl,p);
! 533: STOQ(3,t); STOQ(k,e);
! 534:
! 535: pwrq(t,e,&n);
! 536: mulq(m,n,b);
! 537: }
! 538:
! 539: int geldb(vl,p)
! 540: VL vl;
! 541: P p;
! 542: {
! 543: int m;
! 544:
! 545: for ( m = 0; vl; vl = NEXT(vl) )
! 546: m += getdeg(vl->v,p);
! 547: return ( m );
! 548: }
! 549:
! 550: int getdeg(v,p)
! 551: V v;
! 552: P p;
! 553: {
! 554: int m;
! 555: DCP dc;
! 556:
! 557: if ( !p || NUM(p) )
! 558: return ( 0 );
! 559: else if ( v == VR(p) )
! 560: return ( deg(v,p) );
! 561: else {
! 562: for ( dc = DC(p), m = 0; dc; dc = NEXT(dc) )
! 563: m = MAX(m,getdeg(v,COEF(dc)));
! 564: return ( m );
! 565: }
! 566: }
! 567:
! 568: void cmax(p,b)
! 569: P p;
! 570: Q *b;
! 571: {
! 572: DCP dc;
! 573: Q m,m1;
! 574: N tn;
! 575:
! 576: if ( NUM(p) ) {
! 577: tn = NM((Q)p);
! 578: NTOQ(tn,1,*b);
! 579: } else {
! 580: for ( dc = DC(p), m = 0; dc; dc = NEXT(dc) ) {
! 581: cmax(COEF(dc),&m1);
! 582: if ( cmpq(m1,m) > 0 )
! 583: m = m1;
! 584: }
! 585: *b = m;
! 586: }
! 587: }
! 588:
! 589: int nextbin(vn,n)
! 590: VN vn;
! 591: int n;
! 592: {
! 593: int tmp,i,carry;
! 594:
! 595: if ( n == 0 )
! 596: return ( 1 );
! 597:
! 598: for ( i = n - 1, carry = 1; i >= 0; i-- ) {
! 599: tmp = vn[i].n + carry;
! 600: vn[i].n = tmp % 2;
! 601: carry = tmp / 2;
! 602: }
! 603: return ( carry );
! 604: }
! 605:
! 606: void mulsgn(vn,vnt,n,vn1)
! 607: VN vn,vnt,vn1;
! 608: int n;
! 609: {
! 610: int i;
! 611:
! 612: for ( i = 0; vn[i].v; i++ )
! 613: vn1[i].n = vn[i].n;
! 614: for ( i = 0; i < n; i++ )
! 615: if ( vnt[i].n )
! 616: vn1[(int)vnt[i].v].n *= -1;
! 617: }
! 618:
! 619: void next(vn)
! 620: VN vn;
! 621: {
! 622: int i,m,n,tmp,carry;
! 623:
! 624: for ( m = 0, i = 0; vn[i].v; i++ )
! 625: m = MAX(m,ABS(vn[i].n));
! 626: if ( m == 0 ) {
! 627: vn[--i].n = 1;
! 628: return;
! 629: }
! 630: for ( carry = 1, m++, i--; ( i >= 0 ) && carry; i-- ) {
! 631: tmp = vn[i].n + carry;
! 632: vn[i].n = tmp % m;
! 633: carry = tmp / m;
! 634: }
! 635: if ( ( i == -1 ) && carry ) {
! 636: for ( i = 0; vn[i].v; i++ )
! 637: vn[i].n = 0;
! 638: vn[--i].n = m;
! 639: } else {
! 640: for ( n = 0, i = 0; vn[i].v; i++ )
! 641: n = MAX(n,ABS(vn[i].n));
! 642: if ( n < m - 1 )
! 643: vn[--i].n = m - 1;
! 644: }
! 645: }
! 646:
! 647: void clctv(vl,p,nvlp)
! 648: VL vl;
! 649: P p;
! 650: VL *nvlp;
! 651: {
! 652: int i,n;
! 653: VL tvl;
! 654: VN tvn;
! 655:
! 656: if ( !p || NUM(p) ) {
! 657: *nvlp = 0;
! 658: return;
! 659: }
! 660:
! 661: for ( n = 0, tvl = vl; tvl; tvl = NEXT(tvl), n++ );
! 662: tvn = (VN) ALLOCA((n+1)*sizeof(struct oVN));
! 663: for ( i = 0, tvl = vl; tvl; tvl = NEXT(tvl), i++ ) {
! 664: tvn[i].v = tvl->v;
! 665: tvn[i].n = 0;
! 666: }
! 667:
! 668: markv(tvn,n,p);
! 669: vntovl(tvn,n,nvlp);
! 670: }
! 671:
! 672: void markv(vn,n,p)
! 673: VN vn;
! 674: int n;
! 675: P p;
! 676: {
! 677: V v;
! 678: DCP dc;
! 679: int i;
! 680:
! 681: if ( NUM(p) )
! 682: return;
! 683: v = VR(p);
! 684: for ( i = 0, v = VR(p); i < n; i++ )
! 685: if ( v == vn[i].v ) {
! 686: vn[i].n = 1;
! 687: break;
! 688: }
! 689: for ( dc = DC(p); dc; dc = NEXT(dc) )
! 690: markv(vn,n,COEF(dc));
! 691: }
! 692:
! 693: void vntovl(vn,n,vlp)
! 694: VN vn;
! 695: int n;
! 696: VL *vlp;
! 697: {
! 698: int i;
! 699: VL tvl,tvl0;
! 700:
! 701: for ( i = 0, tvl0 = 0; ; ) {
! 702: while ( ( i < n ) && ( vn[i].n == 0 ) ) i++;
! 703: if ( i == n )
! 704: break;
! 705: else {
! 706: if ( !tvl0 ) {
! 707: NEWVL(tvl0);
! 708: tvl = tvl0;
! 709: } else {
! 710: NEWVL(NEXT(tvl));
! 711: tvl = NEXT(tvl);
! 712: }
! 713: tvl->v = vn[i++].v;
! 714: }
! 715: }
! 716: if ( tvl0 )
! 717: NEXT(tvl) = 0;
! 718: *vlp = tvl0;
! 719: }
! 720:
! 721: int dbound(v,f)
! 722: V v;
! 723: P f;
! 724: {
! 725: int m;
! 726: DCP dc;
! 727:
! 728: if ( !f )
! 729: return ( -1 );
! 730: else if ( v != VR(f) )
! 731: return homdeg(f);
! 732: else {
! 733: for ( dc = DC(f), m = 0; dc; dc = NEXT(dc) )
! 734: m = MAX(m,homdeg(COEF(dc)));
! 735: return ( m );
! 736: }
! 737: }
! 738:
! 739: int homdeg(f)
! 740: P f;
! 741: {
! 742: int m;
! 743: DCP dc;
! 744:
! 745: if ( !f )
! 746: return ( -1 );
! 747: else if ( NUM(f) )
! 748: return( 0 );
! 749: else {
! 750: for ( dc = DC(f), m = 0; dc; dc = NEXT(dc) )
! 751: m = MAX(m,QTOS(DEG(dc))+homdeg(COEF(dc)));
! 752: return ( m );
! 753: }
! 754: }
! 755:
! 756: int minhomdeg(f)
! 757: P f;
! 758: {
! 759: int m;
! 760: DCP dc;
! 761:
! 762: if ( !f )
! 763: return ( -1 );
! 764: else if ( NUM(f) )
! 765: return( 0 );
! 766: else {
! 767: for ( dc = DC(f), m = homdeg(f); dc; dc = NEXT(dc) )
! 768: m = MIN(m,QTOS(DEG(dc))+minhomdeg(COEF(dc)));
! 769: return ( m );
! 770: }
! 771: }
! 772:
! 773: void adjc(vl,f,a,lc0,q,fr,ar)
! 774: VL vl;
! 775: P f,a,lc0;
! 776: Q q;
! 777: P *fr,*ar;
! 778: {
! 779: P m,m1;
! 780: Q t;
! 781:
! 782: invl((Q)LC(f),q,&t);
! 783: mulq((Q)lc0,t,(Q *)&m);
! 784: mulpq(f,m,&m1); cmp(q,m1,fr);
! 785: invl((Q)m,q,&t);
! 786: mulpq(a,(P)t,&m1);
! 787: cmp(q,m1,ar);
! 788: }
! 789:
! 790: #if 1
! 791: void affinemain(vl,p,v0,n,pl,pr)
! 792: VL vl;
! 793: V v0;
! 794: int n;
! 795: P *pl;
! 796: P p;
! 797: P *pr;
! 798: {
! 799: P x,t,m,c,s,a;
! 800: DCP dc;
! 801: Q d;
! 802:
! 803: if ( !p )
! 804: *pr = 0;
! 805: else if ( NUM(p) )
! 806: *pr = p;
! 807: else if ( VR(p) != v0 ) {
! 808: MKV(VR(p),x);
! 809: for ( c = 0, dc = DC(p); dc; dc = NEXT(dc) ) {
! 810: affinemain(vl,COEF(dc),v0,n,pl,&t);
! 811: if ( DEG(dc) ) {
! 812: pwrp(vl,x,DEG(dc),&s); mulp(vl,s,t,&m);
! 813: addp(vl,m,c,&a); c = a;
! 814: } else {
! 815: addp(vl,t,c,&a); c = a;
! 816: }
! 817: }
! 818: *pr = c;
! 819: } else {
! 820: dc = DC(p);
! 821: c = COEF(dc);
! 822: for ( d = DEG(dc), dc = NEXT(dc);
! 823: dc; d = DEG(dc), dc = NEXT(dc) ) {
! 824: mulp(vl,pl[QTOS(d)-QTOS(DEG(dc))],c,&m);
! 825: addp(vl,m,COEF(dc),&c);
! 826: }
! 827: if ( d ) {
! 828: mulp(vl,pl[QTOS(d)],c,&m); c = m;
! 829: }
! 830: *pr = c;
! 831: }
! 832: }
! 833: #endif
! 834:
! 835: #if 0
! 836: affine(vl,p,vn,r)
! 837: VL vl;
! 838: P p;
! 839: VN vn;
! 840: P *r;
! 841: {
! 842: int n,d,d1,i;
! 843: Q *q;
! 844: Q **bc;
! 845:
! 846: if ( !p || NUM(p) )
! 847: *r = p;
! 848: else {
! 849: for ( i = 0, d = 0; vn[i].v; i++ )
! 850: d1 = getdeg(vn[i].v,p), d = MAX(d,d1);
! 851: W_CALLOC(d+1,Q *,bc);
! 852: for ( i = 0; i <= d; i++ )
! 853: W_CALLOC(i+1,Q,q), mkbc(i,q), bc[i] = q;
! 854: afmain(vl,bc,p,vn,r);
! 855: }
! 856: }
! 857:
! 858: afmain(vl,bc,p,vn,r)
! 859: VL vl;
! 860: Q **bc;
! 861: P p;
! 862: VN vn;
! 863: P *r;
! 864: {
! 865: P t,s,u;
! 866: P *c,*rc;
! 867: Q *q;
! 868: DCP dc;
! 869: int n,i,j;
! 870:
! 871: if ( !p || NUM(p) || !vn[0].v )
! 872: *r = p;
! 873: else if ( vn[0].v != VR(p) ) {
! 874: for ( i = 0; vn[i].v && (vn[i].v != VR(p)); i++ );
! 875: if ( vn[i].v )
! 876: afmain(vl,bc,p,vn+i,r);
! 877: else {
! 878: n = QTOS(DEG(DC(p))); W_CALLOC(n+1,P,c);
! 879: for ( dc = DC(p); dc; dc = NEXT(dc) )
! 880: afmain(vl,bc,COEF(dc),vn,&c[QTOS(DEG(dc))]);
! 881: plisttop(c,VR(p),n,r);
! 882: }
! 883: } else {
! 884: n = QTOS(DEG(DC(p))); W_CALLOC(n+1,P,c);
! 885: W_CALLOC(n+1,P,rc); W_CALLOC(n+1,Q,q);
! 886: for ( dc = DC(p); dc; dc = NEXT(dc) )
! 887: afmain(vl,bc,COEF(dc),vn+1,&c[QTOS(DEG(dc))]);
! 888: if ( !vn[0].n )
! 889: bcopy(c,rc,sizeof(P)*(n+1));
! 890: else {
! 891: for ( q[0] = ONE, STOQ(vn[0].n,q[1]), i = 2; i <= n; i++ )
! 892: mulq(q[i-1],q[1],&q[i]);
! 893: for ( j = 0; j <= n; rc[j] = t, j++ )
! 894: for ( i = j, t = 0; i <= n; i++ )
! 895: if ( c[i] )
! 896: mulq(bc[i][j],q[i-j],&s), mulp(vl,s,c[i],&u),
! 897: addp(CO,u,t,&s), t = s;
! 898: }
! 899: plisttop(rc,VR(p),n,r);
! 900: }
! 901: }
! 902: #endif
! 903:
! 904: void restore(vl,f,vn,fr)
! 905: VL vl;
! 906: P f;
! 907: VN vn;
! 908: P *fr;
! 909: {
! 910: int i;
! 911: P vv,g,g1,t;
! 912: Q s;
! 913:
! 914: g = f;
! 915: for ( i = 0; vn[i].v; i++ ) {
! 916: MKV(vn[i].v,t);
! 917: if ( vn[i].n ) {
! 918: STOQ(-vn[i].n,s);
! 919: addp(vl,t,(P)s,&vv);
! 920: } else
! 921: vv = t;
! 922:
! 923: substp(vl,g,vn[i].v,vv,&g1); g = g1;
! 924: }
! 925: *fr = g;
! 926: }
! 927:
! 928: void mergev(vl,vl1,vl2,nvlp)
! 929: VL vl,vl1,vl2,*nvlp;
! 930: {
! 931: int i,n;
! 932: VL tvl;
! 933: VN vn;
! 934:
! 935: if ( !vl1 ) {
! 936: *nvlp = vl2; return;
! 937: } else if ( !vl2 ) {
! 938: *nvlp = vl1; return;
! 939: }
! 940: for ( i = 0, tvl = vl; tvl; i++, tvl = NEXT(tvl) );
! 941: n = i;
! 942: W_CALLOC(n,struct oVN,vn);
! 943: for ( i = 0, tvl = vl; tvl; tvl = NEXT(tvl), i++ )
! 944: vn[i].v = tvl->v;
! 945: for ( i = 0, tvl = vl1; (i < n) && tvl; i++, tvl = NEXT(tvl)) {
! 946: while ( ( i < n ) && ( vn[i].v != tvl->v ) )
! 947: i++;
! 948: if ( i == n )
! 949: break;
! 950: else
! 951: vn[i].n = 1;
! 952: }
! 953: for ( i = 0, tvl = vl2; (i < n) && tvl; i++, tvl = NEXT(tvl) ) {
! 954: while ( ( i < n ) && ( vn[i].v != tvl->v ) )
! 955: i++;
! 956: if ( i == n )
! 957: break;
! 958: else
! 959: vn[i].n = 1;
! 960: }
! 961: vntovl(vn,n,nvlp);
! 962: }
! 963:
! 964: #if 0
! 965: void substvp(vl,f,vn,g)
! 966: VL vl;
! 967: P f;
! 968: VN vn;
! 969: P *g;
! 970: {
! 971: V v;
! 972: int i;
! 973: P h,h1;
! 974: Q t;
! 975:
! 976: h = f;
! 977: for ( i = 0; v = vn[i].v; i++ ) {
! 978: STOQ(vn[i].n,t);
! 979: substp(vl,h,v,(P)t,&h1); h = h1;
! 980: }
! 981: *g = h;
! 982: }
! 983:
! 984: void affine(vl,f,vn,fr)
! 985: VL vl;
! 986: P f;
! 987: VN vn;
! 988: P *fr;
! 989: {
! 990: int i,j,n;
! 991: P vv,g,g1,t,u;
! 992: Q s;
! 993: int *dlist;
! 994: P **plist;
! 995:
! 996: for ( n = 0; vn[n].v; n++);
! 997: dlist = (int *)ALLOCA((n+1)*sizeof(int));
! 998: plist = (P **)ALLOCA((n+1)*sizeof(P *));
! 999: for ( i = 0; vn[i].v; i++ ) {
! 1000: if ( !vn[i].n )
! 1001: continue;
! 1002: dlist[i] = getdeg(vn[i].v,f);
! 1003: plist[i] = (P *)ALLOCA((dlist[i]+1)*sizeof(P));
! 1004:
! 1005: MKV(vn[i].v,t);
! 1006: if ( vn[i].n ) {
! 1007: STOQ(vn[i].n,s); addp(vl,t,(P)s,&vv);
! 1008: } else
! 1009: vv = t;
! 1010:
! 1011: for ( j = 0, t = (P)ONE; j < dlist[i]; j++ ) {
! 1012: plist[i][j] = t;
! 1013: mulp(vl,t,vv,&u);
! 1014: t = u;
! 1015: }
! 1016: plist[i][j] = t;
! 1017: }
! 1018:
! 1019: g = f;
! 1020: for ( i = 0; vn[i].v; i++ ) {
! 1021: if ( !vn[i].n )
! 1022: continue;
! 1023: affinemain(vl,g,vn[i].v,dlist[i],plist[i],&g1); g = g1;
! 1024: }
! 1025: *fr = g;
! 1026: }
! 1027: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>