Annotation of OpenXM_contrib2/asir2000/engine/_distm.c, Revision 1.1
1.1 ! noro 1: /* $OpenXM$ */
! 2: #include "ca.h"
! 3: #include "inline.h"
! 4:
! 5: #define NV(p) ((p)->nv)
! 6: #define C(p) ((p)->c)
! 7: #if 0
! 8: #define ITOS(p) (((unsigned int)(p))>>1)
! 9: #define STOI(i) ((P)((((unsigned int)(i))<<1)|1))
! 10: #else
! 11: #define ITOS(p) (((unsigned int)(p))&0x7fffffff)
! 12: #define STOI(i) ((P)((unsigned int)(i)|0x80000000))
! 13: #endif
! 14:
! 15: extern int (*cmpdl)();
! 16: extern int do_weyl;
! 17:
! 18: void _dptodp();
! 19: void adddl_dup();
! 20: void _mulmdm_dup();
! 21: void _free_dp();
! 22: void _comm_mulmd_dup();
! 23: void _weyl_mulmd_dup();
! 24: void _weyl_mulmmm_dup();
! 25: void _weyl_mulmdm_dup();
! 26:
! 27: MP _mp_free_list;
! 28: DP _dp_free_list;
! 29: DL _dl_free_list;
! 30: int current_dl_length;
! 31:
! 32: #define _NEWDL_NOINIT(d,n) if ((n)!= current_dl_length){_dl_free_list=0; current_dl_length=(n);} if(!_dl_free_list)_DL_alloc(); (d)=_dl_free_list; _dl_free_list = *((DL *)_dl_free_list)
! 33: #define _NEWDL(d,n) if ((n)!= current_dl_length){_dl_free_list=0; current_dl_length=(n);} if(!_dl_free_list)_DL_alloc(); (d)=_dl_free_list; _dl_free_list = *((DL *)_dl_free_list); bzero((d),(((n)+1)*sizeof(int)))
! 34: #define _NEWMP(m) if(!_mp_free_list)_MP_alloc(); (m)=_mp_free_list; _mp_free_list = NEXT(_mp_free_list)
! 35: #define _MKDP(n,m,d) if(!_dp_free_list)_DP_alloc(); (d)=_dp_free_list; _dp_free_list = (DP)BDY(_dp_free_list); (d)->nv=(n); BDY(d)=(m)
! 36:
! 37: #define _NEXTMP(r,c) \
! 38: if(!(r)){_NEWMP(r);(c)=(r);}else{_NEWMP(NEXT(c));(c)=NEXT(c);}
! 39:
! 40: #define _NEXTMP2(r,c,s) \
! 41: if(!(r)){(c)=(r)=(s);}else{NEXT(c)=(s);(c)=(s);}
! 42:
! 43: #define FREEDL(m) *((DL *)m)=_dl_free_list; _dl_free_list=(m)
! 44: #define FREEMP(m) NEXT(m)=_mp_free_list; _mp_free_list=(m)
! 45: #define FREEDP(m) BDY(m)=(MP)_dp_free_list; _dp_free_list=(m)
! 46:
! 47:
! 48: void _DL_alloc()
! 49: {
! 50: int *p;
! 51: int i,dl_len;
! 52: static int DL_alloc_count;
! 53:
! 54: /* fprintf(stderr,"DL_alloc : %d \n",++DL_alloc_count); */
! 55: dl_len = (current_dl_length+1);
! 56: p = (int *)GC_malloc(128*dl_len*sizeof(int));
! 57: for ( i = 0; i < 128; i++, p += dl_len ) {
! 58: *(DL *)p = _dl_free_list;
! 59: _dl_free_list = (DL)p;
! 60: }
! 61: }
! 62:
! 63: void _MP_alloc()
! 64: {
! 65: MP p;
! 66: int i;
! 67: static int MP_alloc_count;
! 68:
! 69: /* fprintf(stderr,"MP_alloc : %d \n",++MP_alloc_count); */
! 70: p = (MP)GC_malloc(1024*sizeof(struct oMP));
! 71: for ( i = 0; i < 1024; i++ ) {
! 72: p[i].next = _mp_free_list; _mp_free_list = &p[i];
! 73: }
! 74: }
! 75:
! 76: void _DP_alloc()
! 77: {
! 78: DP p;
! 79: int i;
! 80: static int DP_alloc_count;
! 81:
! 82: /* fprintf(stderr,"DP_alloc : %d \n",++DP_alloc_count); */
! 83: p = (DP)GC_malloc(1024*sizeof(struct oDP));
! 84: for ( i = 0; i < 1024; i++ ) {
! 85: p[i].body = (MP)_dp_free_list; _dp_free_list = &p[i];
! 86: }
! 87: }
! 88:
! 89: /* merge p1 and p2 into pr */
! 90:
! 91: void _addmd_destructive(mod,p1,p2,pr)
! 92: int mod;
! 93: DP p1,p2,*pr;
! 94: {
! 95: int n;
! 96: MP m1,m2,mr,mr0,s;
! 97: int t;
! 98:
! 99: if ( !p1 )
! 100: *pr = p2;
! 101: else if ( !p2 )
! 102: *pr = p1;
! 103: else {
! 104: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; )
! 105: switch ( (*cmpdl)(n,m1->dl,m2->dl) ) {
! 106: case 0:
! 107: t = (ITOS(C(m1))+ITOS(C(m2))) - mod;
! 108: if ( t < 0 )
! 109: t += mod;
! 110: s = m1; m1 = NEXT(m1);
! 111: if ( t ) {
! 112: _NEXTMP2(mr0,mr,s); C(mr) = STOI(t);
! 113: } else {
! 114: FREEDL(s->dl); FREEMP(s);
! 115: }
! 116: s = m2; m2 = NEXT(m2); FREEDL(s->dl); FREEMP(s);
! 117: break;
! 118: case 1:
! 119: s = m1; m1 = NEXT(m1); _NEXTMP2(mr0,mr,s);
! 120: break;
! 121: case -1:
! 122: s = m2; m2 = NEXT(m2); _NEXTMP2(mr0,mr,s);
! 123: break;
! 124: }
! 125: if ( !mr0 )
! 126: if ( m1 )
! 127: mr0 = m1;
! 128: else if ( m2 )
! 129: mr0 = m2;
! 130: else {
! 131: *pr = 0;
! 132: return;
! 133: }
! 134: else if ( m1 )
! 135: NEXT(mr) = m1;
! 136: else if ( m2 )
! 137: NEXT(mr) = m2;
! 138: else
! 139: NEXT(mr) = 0;
! 140: _MKDP(NV(p1),mr0,*pr);
! 141: if ( *pr )
! 142: (*pr)->sugar = MAX(p1->sugar,p2->sugar);
! 143: FREEDP(p1); FREEDP(p2);
! 144: }
! 145: }
! 146:
! 147: void _mulmd_dup(mod,p1,p2,pr)
! 148: int mod;
! 149: DP p1,p2,*pr;
! 150: {
! 151: if ( !do_weyl )
! 152: _comm_mulmd_dup(mod,p1,p2,pr);
! 153: else
! 154: _weyl_mulmd_dup(mod,p1,p2,pr);
! 155: }
! 156:
! 157: void _comm_mulmd_dup(mod,p1,p2,pr)
! 158: int mod;
! 159: DP p1,p2,*pr;
! 160: {
! 161: MP m;
! 162: DP s,t,u;
! 163: int i,l,l1;
! 164: static MP *w;
! 165: static int wlen;
! 166:
! 167: if ( !p1 || !p2 )
! 168: *pr = 0;
! 169: else {
! 170: for ( m = BDY(p1), l1 = 0; m; m = NEXT(m), l1++ );
! 171: for ( m = BDY(p2), l = 0; m; m = NEXT(m), l++ );
! 172: if ( l1 < l ) {
! 173: t = p1; p1 = p2; p2 = t;
! 174: l = l1;
! 175: }
! 176: if ( l > wlen ) {
! 177: if ( w ) GC_free(w);
! 178: w = (MP *)MALLOC(l*sizeof(MP));
! 179: wlen = l;
! 180: }
! 181: for ( m = BDY(p2), i = 0; i < l; m = NEXT(m), i++ )
! 182: w[i] = m;
! 183: for ( s = 0, i = l-1; i >= 0; i-- ) {
! 184: _mulmdm_dup(mod,p1,w[i],&t); _addmd_destructive(mod,s,t,&u); s = u;
! 185: }
! 186: bzero(w,l*sizeof(MP));
! 187: *pr = s;
! 188: }
! 189: }
! 190:
! 191: void _weyl_mulmd_dup(mod,p1,p2,pr)
! 192: int mod;
! 193: DP p1,p2,*pr;
! 194: {
! 195: MP m;
! 196: DP s,t,u;
! 197: int i,l,l1;
! 198: static MP *w;
! 199: static int wlen;
! 200:
! 201: if ( !p1 || !p2 )
! 202: *pr = 0;
! 203: else {
! 204: for ( m = BDY(p2), l = 0; m; m = NEXT(m), l++ );
! 205: if ( l > wlen ) {
! 206: if ( w ) GC_free(w);
! 207: w = (MP *)MALLOC(l*sizeof(MP));
! 208: wlen = l;
! 209: }
! 210: for ( m = BDY(p2), i = 0; i < l; m = NEXT(m), i++ )
! 211: w[i] = m;
! 212: for ( s = 0, i = l-1; i >= 0; i-- ) {
! 213: _weyl_mulmdm_dup(mod,p1,w[i],&t); _addmd_destructive(mod,s,t,&u); s = u;
! 214: }
! 215: bzero(w,l*sizeof(MP));
! 216: *pr = s;
! 217: }
! 218: }
! 219:
! 220: void _mulmdm_dup(mod,p,m0,pr)
! 221: int mod;
! 222: DP p;
! 223: MP m0;
! 224: DP *pr;
! 225: {
! 226: MP m,mr,mr0;
! 227: DL d,dt,dm;
! 228: int c,n,r,i;
! 229: int *pt,*p1,*p2;
! 230:
! 231: if ( !p )
! 232: *pr = 0;
! 233: else {
! 234: for ( mr0 = 0, m = BDY(p), c = ITOS(C(m0)), d = m0->dl, n = NV(p);
! 235: m; m = NEXT(m) ) {
! 236: _NEXTMP(mr0,mr);
! 237: C(mr) = STOI(dmar(ITOS(C(m)),c,0,mod));
! 238: _NEWDL_NOINIT(dt,n); mr->dl = dt;
! 239: dm = m->dl;
! 240: dt->td = d->td + dm->td;
! 241: for ( i = 0, pt = dt->d, p1=d->d, p2 = dm->d; i < n; i++ )
! 242: *pt++ = *p1++ + *p2++;
! 243: }
! 244: NEXT(mr) = 0; _MKDP(NV(p),mr0,*pr);
! 245: if ( *pr )
! 246: (*pr)->sugar = p->sugar + m0->dl->td;
! 247: }
! 248: }
! 249:
! 250: void _weyl_mulmdm_dup(mod,p,m0,pr)
! 251: int mod;
! 252: DP p;
! 253: MP m0;
! 254: DP *pr;
! 255: {
! 256: DP r,t,t1;
! 257: MP m;
! 258: int n,l,i;
! 259: static MP *w;
! 260: static int wlen;
! 261:
! 262: if ( !p )
! 263: *pr = 0;
! 264: else {
! 265: for ( m = BDY(p), l = 0; m; m = NEXT(m), l++ );
! 266: if ( l > wlen ) {
! 267: if ( w ) GC_free(w);
! 268: w = (MP *)MALLOC(l*sizeof(MP));
! 269: wlen = l;
! 270: }
! 271: for ( m = BDY(p), i = 0; i < l; m = NEXT(m), i++ )
! 272: w[i] = m;
! 273: for ( r = 0, i = l-1, n = NV(p); i >= 0; i-- ) {
! 274: _weyl_mulmmm_dup(mod,w[i],m0,n,&t);
! 275: _addmd_destructive(mod,r,t,&t1); r = t1;
! 276: }
! 277: bzero(w,l*sizeof(MP));
! 278: if ( r )
! 279: r->sugar = p->sugar + m0->dl->td;
! 280: *pr = r;
! 281: }
! 282: }
! 283: /* m0 = x0^d0*x1^d1*... * dx0^d(n/2)*dx1^d(n/2+1)*... */
! 284:
! 285: void _weyl_mulmmm_dup(mod,m0,m1,n,pr)
! 286: int mod;
! 287: MP m0,m1;
! 288: int n;
! 289: DP *pr;
! 290: {
! 291: MP m,mr,mr0;
! 292: DP r,t,t1;
! 293: int c,c0,c1,cc;
! 294: DL d,d0,d1;
! 295: int i,j,a,b,k,l,n2,s,min,h;
! 296: static int *tab;
! 297: static int tablen;
! 298:
! 299: if ( !m0 || !m1 )
! 300: *pr = 0;
! 301: else {
! 302: c0 = ITOS(C(m0)); c1 = ITOS(C(m1));
! 303: c = dmar(c0,c1,0,mod);
! 304: d0 = m0->dl; d1 = m1->dl;
! 305: n2 = n>>1;
! 306:
! 307: _NEWDL(d,n);
! 308: if ( n & 1 )
! 309: /* offset of h-degree */
! 310: d->td = d->d[n-1] = d0->d[n-1]+d1->d[n-1];
! 311: else
! 312: d->td = 0;
! 313: _NEWMP(mr); mr->c = STOI(c); mr->dl = d; NEXT(mr) = 0;
! 314: _MKDP(n,mr,r); r->sugar = d->td;
! 315:
! 316: /* homogenized computation; dx-xd=h^2 */
! 317: for ( i = 0; i < n2; i++ ) {
! 318: a = d0->d[i]; b = d1->d[n2+i];
! 319: k = d0->d[n2+i]; l = d1->d[i];
! 320: /* degree of xi^a*(Di^k*xi^l)*Di^b */
! 321: s = a+k+l+b;
! 322: /* compute xi^a*(Di^k*xi^l)*Di^b */
! 323: min = MIN(k,l);
! 324:
! 325: if ( min+1 > tablen ) {
! 326: if ( tab ) GC_free(tab);
! 327: tab = (int *)MALLOC((min+1)*sizeof(int));
! 328: tablen = min+1;
! 329: }
! 330: mkwcm(k,l,mod,tab);
! 331: if ( n & 1 )
! 332: for ( mr0 = 0, j = 0; j <= min; j++ ) {
! 333: _NEXTMP(mr0,mr); _NEWDL(d,n);
! 334: d->d[i] = l-j+a; d->d[n2+i] = k-j+b;
! 335: d->td = s;
! 336: d->d[n-1] = s-(d->d[i]+d->d[n2+i]);
! 337: mr->c = STOI(tab[j]); mr->dl = d;
! 338: }
! 339: else
! 340: for ( mr0 = 0, s = 0, j = 0; j <= min; j++ ) {
! 341: _NEXTMP(mr0,mr); _NEWDL(d,n);
! 342: d->d[i] = l-j+a; d->d[n2+i] = k-j+b;
! 343: d->td = d->d[i]+d->d[n2+i]; /* XXX */
! 344: s = MAX(s,d->td); /* XXX */
! 345: mr->c = STOI(tab[j]); mr->dl = d;
! 346: }
! 347: bzero(tab,(min+1)*sizeof(int));
! 348: if ( mr0 )
! 349: NEXT(mr) = 0;
! 350: _MKDP(n,mr0,t);
! 351: if ( t )
! 352: t->sugar = s;
! 353: _comm_mulmd_dup(mod,r,t,&t1);
! 354: _free_dp(r); _free_dp(t);
! 355: r = t1;
! 356: }
! 357: *pr = r;
! 358: }
! 359: }
! 360:
! 361: void _dp_red_mod_destructive(p1,p2,mod,rp)
! 362: DP p1,p2;
! 363: int mod;
! 364: DP *rp;
! 365: {
! 366: int i,n;
! 367: DL d1,d2,d;
! 368: MP m;
! 369: DP t,s;
! 370: int c,c1;
! 371:
! 372: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 373: _NEWDL(d,n); d->td = d1->td - d2->td;
! 374: for ( i = 0; i < n; i++ )
! 375: d->d[i] = d1->d[i]-d2->d[i];
! 376: c = invm(ITOS(BDY(p2)->c),mod); c1 = dmar(c,ITOS(BDY(p1)->c),0,mod);
! 377: _NEWMP(m); m->dl = d; m->c = STOI(mod-c1); NEXT(m) = 0;
! 378: _MKDP(n,m,s); s->sugar = d->td;
! 379: _mulmd_dup(mod,s,p2,&t); _free_dp(s);
! 380: _addmd_destructive(mod,p1,t,rp);
! 381: }
! 382:
! 383: void _dp_sp_mod_dup(p1,p2,mod,rp)
! 384: DP p1,p2;
! 385: int mod;
! 386: DP *rp;
! 387: {
! 388: int i,n,td;
! 389: int *w;
! 390: DL d1,d2,d;
! 391: MP m;
! 392: DP t,s,u;
! 393:
! 394: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 395: w = (int *)ALLOCA(n*sizeof(int));
! 396: for ( i = 0, td = 0; i < n; i++ ) {
! 397: w[i] = MAX(d1->d[i],d2->d[i]); td += w[i];
! 398: }
! 399: _NEWDL(d,n); d->td = td - d1->td;
! 400: for ( i = 0; i < n; i++ )
! 401: d->d[i] = w[i] - d1->d[i];
! 402: _NEWMP(m); m->dl = d; m->c = BDY(p2)->c; NEXT(m) = 0;
! 403: _MKDP(n,m,s); s->sugar = d->td; _mulmd_dup(mod,s,p1,&t); _free_dp(s);
! 404: _NEWDL(d,n); d->td = td - d2->td;
! 405: for ( i = 0; i < n; i++ )
! 406: d->d[i] = w[i] - d2->d[i];
! 407: _NEWMP(m); m->dl = d; m->c = STOI(mod - ITOS(BDY(p1)->c)); NEXT(m) = 0;
! 408: _MKDP(n,m,s); s->sugar = d->td; _mulmd_dup(mod,s,p2,&u); _free_dp(s);
! 409: _addmd_destructive(mod,t,u,rp);
! 410: }
! 411:
! 412: void _dltodl(d,dr)
! 413: DL d;
! 414: DL *dr;
! 415: {
! 416: int i,n;
! 417: DL t;
! 418:
! 419: n = current_dl_length;
! 420: NEWDL(t,n); *dr = t;
! 421: t->td = d->td;
! 422: for ( i = 0; i < n; i++ )
! 423: t->d[i] = d->d[i];
! 424: }
! 425:
! 426: void adddl_dup(n,d1,d2,dr)
! 427: int n;
! 428: DL d1,d2;
! 429: DL *dr;
! 430: {
! 431: DL dt;
! 432: int i;
! 433:
! 434: _NEWDL(dt,n); *dr = dt;
! 435: dt->td = d1->td + d2->td;
! 436: for ( i = 0; i < n; i++ )
! 437: dt->d[i] = d1->d[i]+d2->d[i];
! 438: }
! 439:
! 440: void _free_dp(f)
! 441: DP f;
! 442: {
! 443: MP m,s;
! 444:
! 445: if ( !f )
! 446: return;
! 447: m = f->body;
! 448: while ( m ) {
! 449: s = m; m = NEXT(m); FREEDL(s->dl); FREEMP(s);
! 450: }
! 451: FREEDP(f);
! 452: }
! 453:
! 454: void _dptodp(p,r)
! 455: DP p;
! 456: DP *r;
! 457: {
! 458: MP m,mr0,mr;
! 459:
! 460: if ( !p )
! 461: *r = 0;
! 462: else {
! 463: for ( m = BDY(p), mr0 = 0; m; m = NEXT(m) ) {
! 464: NEXTMP(mr0,mr);
! 465: _dltodl(m->dl,&mr->dl);
! 466: mr->c = m->c;
! 467: }
! 468: NEXT(mr) = 0;
! 469: MKDP(p->nv,mr0,*r);
! 470: (*r)->sugar = p->sugar;
! 471: }
! 472: }
! 473:
! 474: void _dp_nf_mod_destructive(b,g,ps,mod,full,rp)
! 475: NODE b;
! 476: DP g;
! 477: DP *ps;
! 478: int mod,full;
! 479: DP *rp;
! 480: {
! 481: DP u,p,d,s,t;
! 482: NODE l;
! 483: MP m,mr,mrd;
! 484: int sugar,psugar,n,h_reducible,i;
! 485:
! 486: if ( !g ) {
! 487: *rp = 0; return;
! 488: }
! 489: sugar = g->sugar;
! 490: n = g->nv;
! 491: for ( d = 0; g; ) {
! 492: for ( h_reducible = 0, l = b; l; l = NEXT(l) ) {
! 493: if ( dp_redble(g,p = ps[(int)BDY(l)]) ) {
! 494: h_reducible = 1;
! 495: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 496: _dp_red_mod_destructive(g,p,mod,&u); g = u;
! 497: sugar = MAX(sugar,psugar);
! 498: if ( !g ) {
! 499: if ( d )
! 500: d->sugar = sugar;
! 501: _dptodp(d,rp); _free_dp(d); return;
! 502: }
! 503: break;
! 504: }
! 505: }
! 506: if ( !h_reducible ) {
! 507: /* head term is not reducible */
! 508: if ( !full ) {
! 509: if ( g )
! 510: g->sugar = sugar;
! 511: _dptodp(g,rp); _free_dp(g); return;
! 512: } else {
! 513: m = BDY(g);
! 514: if ( NEXT(m) ) {
! 515: BDY(g) = NEXT(m); NEXT(m) = 0;
! 516: } else {
! 517: FREEDP(g); g = 0;
! 518: }
! 519: if ( d ) {
! 520: for ( mrd = BDY(d); NEXT(mrd); mrd = NEXT(mrd) );
! 521: NEXT(mrd) = m;
! 522: } else {
! 523: _MKDP(n,m,d);
! 524: }
! 525: }
! 526: }
! 527: }
! 528: if ( d )
! 529: d->sugar = sugar;
! 530: _dptodp(d,rp); _free_dp(d);
! 531: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>