[BACK]Return to distm.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / engine

Annotation of OpenXM_contrib2/asir2000/engine/distm.c, Revision 1.2

1.2     ! noro        1: /* $OpenXM: OpenXM_contrib2/asir2000/engine/distm.c,v 1.1.1.1 1999/12/03 07:39:08 noro Exp $ */
1.1       noro        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)();
1.2     ! noro       16: extern int do_weyl;
        !            17:
        !            18: void comm_mulmd();
        !            19: void weyl_mulmd();
        !            20: void weyl_mulmdm();
        !            21: void weyl_mulmmm();
        !            22: void _comm_mulmd();
        !            23: void _weyl_mulmd();
        !            24: void _weyl_mulmmm();
        !            25: void _weyl_mulmdm();
1.1       noro       26:
                     27: void ptomd(vl,mod,dvl,p,pr)
                     28: VL vl,dvl;
                     29: int mod;
                     30: P p;
                     31: DP *pr;
                     32: {
                     33:        P t;
                     34:
                     35:        ptomp(mod,p,&t);
                     36:        mptomd(vl,mod,dvl,t,pr);
                     37: }
                     38:
                     39: void mptomd(vl,mod,dvl,p,pr)
                     40: VL vl,dvl;
                     41: int mod;
                     42: P p;
                     43: DP *pr;
                     44: {
                     45:        int n,i;
                     46:        VL tvl;
                     47:        V v;
                     48:        DL d;
                     49:        MP m;
                     50:        DCP dc;
                     51:        DP r,s,t,u;
                     52:        P x,c;
                     53:
                     54:        if ( !p )
                     55:                *pr = 0;
                     56:        else {
                     57:                for ( n = 0, tvl = dvl; tvl; tvl = NEXT(tvl), n++ );
                     58:                if ( NUM(p) ) {
                     59:                        NEWDL(d,n);
                     60:                        NEWMP(m); m->dl = d; C(m) = p; NEXT(m) = 0; MKDP(n,m,*pr);
                     61:                } else {
                     62:                        for ( i = 0, tvl = dvl, v = VR(p);
                     63:                                tvl && tvl->v != v; tvl = NEXT(tvl), i++ );
                     64:                        if ( !tvl ) {
                     65:                                for ( dc = DC(p), s = 0, MKV(v,x); dc; dc = NEXT(dc) ) {
                     66:                                        mptomd(vl,mod,dvl,COEF(dc),&t); pwrmp(vl,mod,x,DEG(dc),&c);
                     67:                                        mulmdc(vl,mod,t,c,&r); addmd(vl,mod,r,s,&t); s = t;
                     68:                                }
                     69:                                *pr = s;
                     70:                        } else {
                     71:                                for ( dc = DC(p), s = 0; dc; dc = NEXT(dc) ) {
                     72:                                        mptomd(vl,mod,dvl,COEF(dc),&t);
                     73:                                        NEWDL(d,n); d->td = QTOS(DEG(dc)); d->d[i] = d->td;
                     74:                                        NEWMP(m); m->dl = d; C(m) = (P)ONEM; NEXT(m) = 0; MKDP(n,m,u);
1.2     ! noro       75:                                        comm_mulmd(vl,mod,t,u,&r); addmd(vl,mod,r,s,&t); s = t;
1.1       noro       76:                                }
                     77:                                *pr = s;
                     78:                        }
                     79:                }
                     80:        }
                     81: }
                     82:
                     83: void mdtop(vl,mod,dvl,p,pr)
                     84: VL vl,dvl;
                     85: int mod;
                     86: DP p;
                     87: P *pr;
                     88: {
                     89:        int n,i;
                     90:        DL d;
                     91:        MP m;
                     92:        P r,s,t,u,w;
                     93:        Q q;
                     94:        VL tvl;
                     95:
                     96:        if ( !p )
                     97:                *pr = 0;
                     98:        else {
                     99:                for ( n = p->nv, m = BDY(p), s = 0; m; m = NEXT(m) ) {
                    100:                        for ( i = 0, t = C(m), d = m->dl, tvl = dvl;
                    101:                                i < n; tvl = NEXT(tvl), i++ ) {
                    102:                                MKMV(tvl->v,r); STOQ(d->d[i],q); pwrmp(vl,mod,r,q,&u);
                    103:                                mulmp(vl,mod,t,u,&w); t = w;
                    104:                        }
                    105:                        addmp(vl,mod,s,t,&u); s = u;
                    106:                }
                    107:                mptop(s,pr);
                    108:        }
                    109: }
                    110:
                    111: void addmd(vl,mod,p1,p2,pr)
                    112: VL vl;
                    113: int mod;
                    114: DP p1,p2,*pr;
                    115: {
                    116:        int n;
                    117:        MP m1,m2,mr,mr0;
                    118:        P t;
                    119:        int tmp;
                    120:        MQ q;
                    121:
                    122:        if ( !p1 )
                    123:                *pr = p2;
                    124:        else if ( !p2 )
                    125:                *pr = p1;
                    126:        else {
                    127:                for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; )
                    128:                        switch ( (*cmpdl)(n,m1->dl,m2->dl) ) {
                    129:                                case 0:
                    130:                                        if ( NUM(C(m1)) && NUM(C(m2)) ) {
                    131:                                                tmp = (CONT((MQ)C(m1))+CONT((MQ)C(m2))) - mod;
                    132:                                                if ( tmp < 0 )
                    133:                                                        tmp += mod;
                    134:                                                if ( tmp ) {
                    135:                                                        STOMQ(tmp,q); t = (P)q;
                    136:                                                } else
                    137:                                                        t = 0;
                    138:                                        } else
                    139:                                                addmp(vl,mod,C(m1),C(m2),&t);
                    140:                                        if ( t ) {
                    141:                                                NEXTMP(mr0,mr); mr->dl = m1->dl; C(mr) = t;
                    142:                                        }
                    143:                                        m1 = NEXT(m1); m2 = NEXT(m2); break;
                    144:                                case 1:
                    145:                                        NEXTMP(mr0,mr); mr->dl = m1->dl; C(mr) = C(m1);
                    146:                                        m1 = NEXT(m1); break;
                    147:                                case -1:
                    148:                                        NEXTMP(mr0,mr); mr->dl = m2->dl; C(mr) = C(m2);
                    149:                                        m2 = NEXT(m2); break;
                    150:                        }
                    151:                if ( !mr0 )
                    152:                        if ( m1 )
                    153:                                mr0 = m1;
                    154:                        else if ( m2 )
                    155:                                mr0 = m2;
                    156:                        else {
                    157:                                *pr = 0;
                    158:                                return;
                    159:                        }
                    160:                else if ( m1 )
                    161:                        NEXT(mr) = m1;
                    162:                else if ( m2 )
                    163:                        NEXT(mr) = m2;
                    164:                else
                    165:                        NEXT(mr) = 0;
                    166:                MKDP(NV(p1),mr0,*pr);
                    167:                if ( *pr )
                    168:                        (*pr)->sugar = MAX(p1->sugar,p2->sugar);
                    169:        }
                    170: }
                    171:
                    172: void submd(vl,mod,p1,p2,pr)
                    173: VL vl;
                    174: int mod;
                    175: DP p1,p2,*pr;
                    176: {
                    177:        DP t;
                    178:
                    179:        if ( !p2 )
                    180:                *pr = p1;
                    181:        else {
                    182:                chsgnmd(mod,p2,&t); addmd(vl,mod,p1,t,pr);
                    183:        }
                    184: }
                    185:
                    186: void chsgnmd(mod,p,pr)
                    187: int mod;
                    188: DP p,*pr;
                    189: {
                    190:        MP m,mr,mr0;
                    191:
                    192:        if ( !p )
                    193:                *pr = 0;
                    194:        else {
                    195:                for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                    196:                        NEXTMP(mr0,mr); chsgnmp(mod,C(m),&C(mr)); mr->dl = m->dl;
                    197:                }
                    198:                NEXT(mr) = 0; MKDP(NV(p),mr0,*pr);
                    199:                if ( *pr )
                    200:                        (*pr)->sugar = p->sugar;
                    201:        }
                    202: }
                    203:
                    204: void mulmd(vl,mod,p1,p2,pr)
                    205: VL vl;
                    206: int mod;
                    207: DP p1,p2,*pr;
                    208: {
1.2     ! noro      209:        if ( !do_weyl )
        !           210:                comm_mulmd(vl,mod,p1,p2,pr);
        !           211:        else
        !           212:                weyl_mulmd(vl,mod,p1,p2,pr);
        !           213: }
        !           214:
        !           215: void comm_mulmd(vl,mod,p1,p2,pr)
        !           216: VL vl;
        !           217: int mod;
        !           218: DP p1,p2,*pr;
        !           219: {
        !           220:        MP m;
        !           221:        DP s,t,u;
        !           222:        int i,l,l1;
        !           223:        static MP *w;
        !           224:        static int wlen;
        !           225:
        !           226:        if ( !p1 || !p2 )
        !           227:                *pr = 0;
        !           228:        else if ( OID(p1) <= O_P )
        !           229:                mulmdc(vl,mod,p2,(P)p1,pr);
        !           230:        else if ( OID(p2) <= O_P )
        !           231:                mulmdc(vl,mod,p1,(P)p2,pr);
        !           232:        else {
        !           233:                for ( m = BDY(p1), l1 = 0; m; m = NEXT(m), l1++ );
        !           234:                for ( m = BDY(p2), l = 0; m; m = NEXT(m), l++ );
        !           235:                if ( l1 < l ) {
        !           236:                        t = p1; p1 = p2; p2 = t;
        !           237:                        l = l1;
        !           238:                }
        !           239:                if ( l > wlen ) {
        !           240:                        if ( w ) GC_free(w);
        !           241:                        w = (MP *)MALLOC(l*sizeof(MP));
        !           242:                        wlen = l;
        !           243:                }
        !           244:                for ( m = BDY(p2), i = 0; i < l; m = NEXT(m), i++ )
        !           245:                        w[i] = m;
        !           246:                for ( s = 0, i = l-1; i >= 0; i-- ) {
        !           247:                        mulmdm(vl,mod,p1,w[i],&t); addmd(vl,mod,s,t,&u); s = u;
        !           248:                }
        !           249:                bzero(w,l*sizeof(MP));
        !           250:                *pr = s;
        !           251:        }
        !           252: }
        !           253:
        !           254: void weyl_mulmd(vl,mod,p1,p2,pr)
        !           255: VL vl;
        !           256: int mod;
        !           257: DP p1,p2,*pr;
        !           258: {
1.1       noro      259:        MP m;
                    260:        DP s,t,u;
1.2     ! noro      261:        int i,l,l1;
        !           262:        static MP *w;
        !           263:        static int wlen;
1.1       noro      264:
                    265:        if ( !p1 || !p2 )
                    266:                *pr = 0;
                    267:        else if ( OID(p1) <= O_P )
                    268:                mulmdc(vl,mod,p2,(P)p1,pr);
                    269:        else if ( OID(p2) <= O_P )
                    270:                mulmdc(vl,mod,p1,(P)p2,pr);
                    271:        else {
1.2     ! noro      272:                for ( m = BDY(p2), l = 0; m; m = NEXT(m), l++ );
        !           273:                if ( l > wlen ) {
        !           274:                        if ( w ) GC_free(w);
        !           275:                        w = (MP *)MALLOC(l*sizeof(MP));
        !           276:                        wlen = l;
        !           277:                }
        !           278:                for ( m = BDY(p2), i = 0; i < l; m = NEXT(m), i++ )
        !           279:                        w[i] = m;
        !           280:                for ( s = 0, i = l-1; i >= 0; i-- ) {
        !           281:                        weyl_mulmdm(vl,mod,p1,w[i],&t); addmd(vl,mod,s,t,&u); s = u;
1.1       noro      282:                }
1.2     ! noro      283:                bzero(w,l*sizeof(MP));
1.1       noro      284:                *pr = s;
                    285:        }
                    286: }
                    287:
                    288: void mulmdm(vl,mod,p,m0,pr)
                    289: VL vl;
                    290: int mod;
                    291: DP p;
                    292: MP m0;
                    293: DP *pr;
                    294: {
                    295:        MP m,mr,mr0;
                    296:        P c;
                    297:        DL d;
                    298:        int n,t;
                    299:        MQ q;
                    300:
                    301:        if ( !p )
                    302:                *pr = 0;
                    303:        else {
                    304:                for ( mr0 = 0, m = BDY(p), c = C(m0), d = m0->dl, n = NV(p);
                    305:                        m; m = NEXT(m) ) {
                    306:                        NEXTMP(mr0,mr);
                    307:                        if ( NUM(C(m)) && NUM(c) ) {
                    308:                                t = dmar(((MQ)(C(m)))->cont,((MQ)c)->cont,0,mod);
                    309:                                STOMQ(t,q); C(mr) = (P)q;
                    310:                        } else
                    311:                                mulmp(vl,mod,C(m),c,&C(mr));
                    312:                        adddl(n,m->dl,d,&mr->dl);
                    313:                }
                    314:                NEXT(mr) = 0; MKDP(NV(p),mr0,*pr);
                    315:                if ( *pr )
                    316:                        (*pr)->sugar = p->sugar + m0->dl->td;
                    317:        }
                    318: }
                    319:
1.2     ! noro      320: void weyl_mulmdm(vl,mod,p,m0,pr)
        !           321: VL vl;
        !           322: int mod;
        !           323: DP p;
        !           324: MP m0;
        !           325: DP *pr;
        !           326: {
        !           327:        DP r,t,t1;
        !           328:        MP m;
        !           329:        int n,l,i;
        !           330:        static MP *w;
        !           331:        static int wlen;
        !           332:
        !           333:        if ( !p )
        !           334:                *pr = 0;
        !           335:        else {
        !           336:                for ( m = BDY(p), l = 0; m; m = NEXT(m), l++ );
        !           337:                if ( l > wlen ) {
        !           338:                        if ( w ) GC_free(w);
        !           339:                        w = (MP *)MALLOC(l*sizeof(MP));
        !           340:                        wlen = l;
        !           341:                }
        !           342:                for ( m = BDY(p), i = 0; i < l; m = NEXT(m), i++ )
        !           343:                        w[i] = m;
        !           344:                for ( r = 0, i = l-1, n = NV(p); i >= 0; i-- ) {
        !           345:                        weyl_mulmmm(vl,mod,w[i],m0,n,&t);
        !           346:                        addmd(vl,mod,r,t,&t1); r = t1;
        !           347:                }
        !           348:                bzero(w,l*sizeof(MP));
        !           349:                if ( r )
        !           350:                        r->sugar = p->sugar + m0->dl->td;
        !           351:                *pr = r;
        !           352:        }
        !           353: }
        !           354:
        !           355: /* m0 = x0^d0*x1^d1*... * dx0^d(n/2)*dx1^d(n/2+1)*... */
        !           356:
        !           357: void weyl_mulmmm(vl,mod,m0,m1,n,pr)
        !           358: VL vl;
        !           359: int mod;
        !           360: MP m0,m1;
        !           361: int n;
        !           362: DP *pr;
        !           363: {
        !           364:        MP m,mr,mr0;
        !           365:        MQ mq;
        !           366:        DP r,t,t1;
        !           367:        P c,c0,c1,cc;
        !           368:        DL d,d0,d1;
        !           369:        int i,j,a,b,k,l,n2,s,min,h;
        !           370:        static int *tab;
        !           371:        static int tablen;
        !           372:
        !           373:        if ( !m0 || !m1 )
        !           374:                *pr = 0;
        !           375:        else {
        !           376:                c0 = C(m0); c1 = C(m1);
        !           377:                mulmp(vl,mod,c0,c1,&c);
        !           378:                d0 = m0->dl; d1 = m1->dl;
        !           379:                n2 = n>>1;
        !           380:                if ( n & 1 ) {
        !           381:                        /* homogenized computation; dx-xd=h^2 */
        !           382:                        /* offset of h-degree */
        !           383:                        NEWDL(d,n); d->d[n-1] = d0->d[n-1]+d1->d[n-1]; d->td = d->d[n-1];
        !           384:                        NEWMP(mr); mr->c = (P)ONEM; mr->dl = d;
        !           385:                        MKDP(n,mr,r); r->sugar = d->d[n-1];
        !           386:
        !           387:                        for ( i = 0; i < n2; i++ ) {
        !           388:                                a = d0->d[i]; b = d1->d[n2+i];
        !           389:                                k = d0->d[n2+i]; l = d1->d[i];
        !           390:                                /* degree of xi^a*(Di^k*xi^l)*Di^b */
        !           391:                                h = a+k+l+b;
        !           392:                                /* compute xi^a*(Di^k*xi^l)*Di^b */
        !           393:                                min = MIN(k,l);
        !           394:
        !           395:                                if ( min+1 > tablen ) {
        !           396:                                        if ( tab ) GC_free(tab);
        !           397:                                        tab = (int *)MALLOC((min+1)*sizeof(int));
        !           398:                                        tablen = min+1;
        !           399:                                }
        !           400:                                mkwcm(k,l,mod,tab);
        !           401:                                for ( mr0 = 0, j = 0; j <= min; j++ ) {
        !           402:                                        NEXTMP(mr0,mr);
        !           403:                                        NEWDL(d,n);
        !           404:                                        d->d[i] = l-j+a; d->d[n2+i] = k-j+b;
        !           405:                                        d->td = h;
        !           406:                                        d->d[n-1] = h-(d->d[i]+d->d[n2+i]);
        !           407:                                        STOMQ(tab[j],mq); mr->c = (P)mq;
        !           408:                                        mr->dl = d;
        !           409:                                }
        !           410:                                bzero(tab,(min+1)*sizeof(int));
        !           411:                                if ( mr0 )
        !           412:                                        NEXT(mr) = 0;
        !           413:                                MKDP(n,mr0,t);
        !           414:                                if ( t )
        !           415:                                        t->sugar = h;
        !           416:                                comm_mulmd(vl,mod,r,t,&t1); r = t1;
        !           417:                        }
        !           418:                } else
        !           419:                        for ( i = 0, r = (DP)ONEM; i < n2; i++ ) {
        !           420:                                a = d0->d[i]; b = d1->d[n2+i];
        !           421:                                k = d0->d[n2+i]; l = d1->d[i];
        !           422:                                /* compute xi^a*(Di^k*xi^l)*Di^b */
        !           423:                                min = MIN(k,l);
        !           424:
        !           425:                                if ( min+1 > tablen ) {
        !           426:                                        if ( tab ) GC_free(tab);
        !           427:                                        tab = (int *)MALLOC((min+1)*sizeof(int));
        !           428:                                        tablen = min+1;
        !           429:                                }
        !           430:                                mkwcm(k,l,mod,tab);
        !           431:                                for ( mr0 = 0, s = 0, j = 0; j <= min; j++ ) {
        !           432:                                        NEXTMP(mr0,mr);
        !           433:                                        NEWDL(d,n);
        !           434:                                        d->d[i] = l-j+a; d->d[n2+i] = k-j+b;
        !           435:                                        d->td = d->d[i]+d->d[n2+i]; /* XXX */
        !           436:                                        s = MAX(s,d->td); /* XXX */
        !           437:                                        STOMQ(tab[j],mq); mr->c = (P)mq;
        !           438:                                        mr->dl = d;
        !           439:                                }
        !           440:                                bzero(tab,(min+1)*sizeof(int));
        !           441:                                if ( mr0 )
        !           442:                                        NEXT(mr) = 0;
        !           443:                                MKDP(n,mr0,t);
        !           444:                                if ( t )
        !           445:                                        t->sugar = s;
        !           446:                                comm_mulmd(vl,mod,r,t,&t1); r = t1;
        !           447:                        }
        !           448:                mulmdc(vl,mod,r,c,pr);
        !           449:        }
        !           450: }
        !           451:
1.1       noro      452: void mulmdc(vl,mod,p,c,pr)
                    453: VL vl;
                    454: int mod;
                    455: DP p;
                    456: P c;
                    457: DP *pr;
                    458: {
                    459:        MP m,mr,mr0;
                    460:        int t;
                    461:        MQ q;
                    462:
                    463:        if ( !p || !c )
                    464:                *pr = 0;
                    465:        else {
                    466:                for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                    467:                        NEXTMP(mr0,mr);
                    468:                        if ( NUM(C(m)) && NUM(c) ) {
                    469:                                t = dmar(((MQ)(C(m)))->cont,((MQ)c)->cont,0,mod);
                    470:                                STOMQ(t,q); C(mr) = (P)q;
                    471:                        } else
                    472:                                mulmp(vl,mod,C(m),c,&C(mr));
                    473:                        mr->dl = m->dl;
                    474:                }
                    475:                NEXT(mr) = 0; MKDP(NV(p),mr0,*pr);
                    476:                if ( *pr )
                    477:                        (*pr)->sugar = p->sugar;
                    478:        }
                    479: }
                    480:
                    481: void divsmdc(vl,mod,p,c,pr)
                    482: VL vl;
                    483: int mod;
                    484: DP p;
                    485: P c;
                    486: DP *pr;
                    487: {
                    488:        MP m,mr,mr0;
                    489:
                    490:        if ( !c )
                    491:                error("disvsdc : division by 0");
                    492:        else if ( !p )
                    493:                *pr = 0;
                    494:        else {
                    495:                for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                    496:                        NEXTMP(mr0,mr); divsmp(vl,mod,C(m),c,&C(mr)); mr->dl = m->dl;
                    497:                }
                    498:                NEXT(mr) = 0; MKDP(NV(p),mr0,*pr);
                    499:                if ( *pr )
                    500:                        (*pr)->sugar = p->sugar;
                    501:        }
                    502: }
                    503:
                    504: #define MKDPM(n,m,d) (NEWDP(d),(d)->nv=(n),BDY(d)=(m))
                    505:
                    506: void _mdtop(vl,mod,dvl,p,pr)
                    507: VL vl,dvl;
                    508: int mod;
                    509: DP p;
                    510: P *pr;
                    511: {
                    512:        int n,i;
                    513:        DL d;
                    514:        MP m;
                    515:        P r,s,t,u,w;
                    516:        Q q;
                    517:        MQ tq;
                    518:        VL tvl;
                    519:
                    520:        if ( !p )
                    521:                *pr = 0;
                    522:        else {
                    523:                for ( n = p->nv, m = BDY(p), s = 0; m; m = NEXT(m) ) {
                    524:                        STOMQ(ITOS(C(m)),tq); t = (P)tq;
                    525:                        for ( i = 0, d = m->dl, tvl = dvl;
                    526:                                i < n; tvl = NEXT(tvl), i++ ) {
                    527:                                MKV(tvl->v,r); STOQ(d->d[i],q); pwrmp(vl,mod,r,q,&u);
                    528:                                mulmp(vl,mod,t,u,&w); t = w;
                    529:                        }
                    530:                        addmp(vl,mod,s,t,&u); s = u;
                    531:                }
                    532:                mptop(s,pr);
                    533:        }
                    534: }
                    535:
                    536: void _addmd(vl,mod,p1,p2,pr)
                    537: VL vl;
                    538: int mod;
                    539: DP p1,p2,*pr;
                    540: {
                    541:        int n;
                    542:        MP m1,m2,mr,mr0;
                    543:        int t;
                    544:
                    545:        if ( !p1 )
                    546:                *pr = p2;
                    547:        else if ( !p2 )
                    548:                *pr = p1;
                    549:        else {
                    550:                for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; )
                    551:                        switch ( (*cmpdl)(n,m1->dl,m2->dl) ) {
                    552:                                case 0:
                    553:                                        t = (ITOS(C(m1))+ITOS(C(m2))) - mod;
                    554:                                        if ( t < 0 )
                    555:                                                t += mod;
                    556:                                        if ( t ) {
                    557:                                                NEXTMP(mr0,mr); mr->dl = m1->dl; C(mr) = STOI(t);
                    558:                                        }
                    559:                                        m1 = NEXT(m1); m2 = NEXT(m2); break;
                    560:                                case 1:
                    561:                                        NEXTMP(mr0,mr); mr->dl = m1->dl; C(mr) = C(m1);
                    562:                                        m1 = NEXT(m1); break;
                    563:                                case -1:
                    564:                                        NEXTMP(mr0,mr); mr->dl = m2->dl; C(mr) = C(m2);
                    565:                                        m2 = NEXT(m2); break;
                    566:                        }
                    567:                if ( !mr0 )
                    568:                        if ( m1 )
                    569:                                mr0 = m1;
                    570:                        else if ( m2 )
                    571:                                mr0 = m2;
                    572:                        else {
                    573:                                *pr = 0;
                    574:                                return;
                    575:                        }
                    576:                else if ( m1 )
                    577:                        NEXT(mr) = m1;
                    578:                else if ( m2 )
                    579:                        NEXT(mr) = m2;
                    580:                else
                    581:                        NEXT(mr) = 0;
                    582:                MKDPM(NV(p1),mr0,*pr);
                    583:                if ( *pr )
                    584:                        (*pr)->sugar = MAX(p1->sugar,p2->sugar);
                    585:        }
                    586: }
                    587:
                    588: void _submd(vl,mod,p1,p2,pr)
                    589: VL vl;
                    590: int mod;
                    591: DP p1,p2,*pr;
                    592: {
                    593:        DP t;
                    594:
                    595:        if ( !p2 )
                    596:                *pr = p1;
                    597:        else {
                    598:                _chsgnmd(mod,p2,&t); _addmd(vl,mod,p1,t,pr);
                    599:        }
                    600: }
                    601:
                    602: void _chsgnmd(mod,p,pr)
                    603: int mod;
                    604: DP p,*pr;
                    605: {
                    606:        MP m,mr,mr0;
                    607:
                    608:        if ( !p )
                    609:                *pr = 0;
                    610:        else {
                    611:                for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                    612:                        NEXTMP(mr0,mr); C(mr) = STOI(mod - ITOS(C(m))); mr->dl = m->dl;
                    613:                }
                    614:                NEXT(mr) = 0; MKDPM(NV(p),mr0,*pr);
                    615:                if ( *pr )
                    616:                        (*pr)->sugar = p->sugar;
                    617:        }
                    618: }
                    619:
                    620: void _mulmd(vl,mod,p1,p2,pr)
                    621: VL vl;
                    622: int mod;
                    623: DP p1,p2,*pr;
                    624: {
1.2     ! noro      625:        if ( !do_weyl )
        !           626:                _comm_mulmd(vl,mod,p1,p2,pr);
        !           627:        else
        !           628:                _weyl_mulmd(vl,mod,p1,p2,pr);
        !           629: }
        !           630:
        !           631: void _comm_mulmd(vl,mod,p1,p2,pr)
        !           632: VL vl;
        !           633: int mod;
        !           634: DP p1,p2,*pr;
        !           635: {
1.1       noro      636:        MP m;
                    637:        DP s,t,u;
1.2     ! noro      638:        int i,l,l1;
        !           639:        static MP *w;
        !           640:        static int wlen;
1.1       noro      641:
                    642:        if ( !p1 || !p2 )
                    643:                *pr = 0;
                    644:        else {
1.2     ! noro      645:                for ( m = BDY(p1), l1 = 0; m; m = NEXT(m), l1++ );
        !           646:                for ( m = BDY(p2), l = 0; m; m = NEXT(m), l++ );
        !           647:                if ( l1 < l ) {
        !           648:                        t = p1; p1 = p2; p2 = t;
        !           649:                        l = l1;
        !           650:                }
        !           651:                if ( l > wlen ) {
        !           652:                        if ( w ) GC_free(w);
        !           653:                        w = (MP *)MALLOC(l*sizeof(MP));
        !           654:                        wlen = l;
        !           655:                }
        !           656:                for ( m = BDY(p2), i = 0; i < l; m = NEXT(m), i++ )
        !           657:                        w[i] = m;
        !           658:                for ( s = 0, i = l-1; i >= 0; i-- ) {
        !           659:                        _mulmdm(vl,mod,p1,w[i],&t); _addmd(vl,mod,s,t,&u); s = u;
1.1       noro      660:                }
1.2     ! noro      661:                bzero(w,l*sizeof(MP));
        !           662:                *pr = s;
        !           663:        }
        !           664: }
        !           665:
        !           666: void _weyl_mulmd(vl,mod,p1,p2,pr)
        !           667: VL vl;
        !           668: int mod;
        !           669: DP p1,p2,*pr;
        !           670: {
        !           671:        MP m;
        !           672:        DP s,t,u;
        !           673:        int i,l,l1;
        !           674:        static MP *w;
        !           675:        static int wlen;
        !           676:
        !           677:        if ( !p1 || !p2 )
        !           678:                *pr = 0;
        !           679:        else {
        !           680:                for ( m = BDY(p2), l = 0; m; m = NEXT(m), l++ );
        !           681:                if ( l > wlen ) {
        !           682:                        if ( w ) GC_free(w);
        !           683:                        w = (MP *)MALLOC(l*sizeof(MP));
        !           684:                        wlen = l;
        !           685:                }
        !           686:                for ( m = BDY(p2), i = 0; i < l; m = NEXT(m), i++ )
        !           687:                        w[i] = m;
        !           688:                for ( s = 0, i = l-1; i >= 0; i-- ) {
        !           689:                        _weyl_mulmdm(vl,mod,p1,w[i],&t); _addmd(vl,mod,s,t,&u); s = u;
        !           690:                }
        !           691:                bzero(w,l*sizeof(MP));
1.1       noro      692:                *pr = s;
                    693:        }
                    694: }
                    695:
                    696: void _mulmdm(vl,mod,p,m0,pr)
                    697: VL vl;
                    698: int mod;
                    699: DP p;
                    700: MP m0;
                    701: DP *pr;
                    702: {
                    703:        MP m,mr,mr0;
                    704:        DL d;
                    705:        int c,n,r;
                    706:
                    707:        if ( !p )
                    708:                *pr = 0;
                    709:        else {
                    710:                for ( mr0 = 0, m = BDY(p), c = ITOS(C(m0)), d = m0->dl, n = NV(p);
                    711:                        m; m = NEXT(m) ) {
                    712:                        NEXTMP(mr0,mr);
                    713:                        C(mr) = STOI(dmar(ITOS(C(m)),c,0,mod));
                    714:                        adddl(n,m->dl,d,&mr->dl);
                    715:                }
                    716:                NEXT(mr) = 0; MKDPM(NV(p),mr0,*pr);
                    717:                if ( *pr )
                    718:                        (*pr)->sugar = p->sugar + m0->dl->td;
                    719:        }
                    720: }
                    721:
1.2     ! noro      722: void _weyl_mulmdm(vl,mod,p,m0,pr)
        !           723: VL vl;
        !           724: int mod;
        !           725: DP p;
        !           726: MP m0;
        !           727: DP *pr;
        !           728: {
        !           729:        DP r,t,t1;
        !           730:        MP m;
        !           731:        int n,l,i;
        !           732:        static MP *w;
        !           733:        static int wlen;
        !           734:
        !           735:        if ( !p )
        !           736:                *pr = 0;
        !           737:        else {
        !           738:                for ( m = BDY(p), l = 0; m; m = NEXT(m), l++ );
        !           739:                if ( l > wlen ) {
        !           740:                        if ( w ) GC_free(w);
        !           741:                        w = (MP *)MALLOC(l*sizeof(MP));
        !           742:                        wlen = l;
        !           743:                }
        !           744:                for ( m = BDY(p), i = 0; i < l; m = NEXT(m), i++ )
        !           745:                        w[i] = m;
        !           746:                for ( r = 0, i = l-1, n = NV(p); i >= 0; i-- ) {
        !           747:                        _weyl_mulmmm(vl,mod,w[i],m0,n,&t);
        !           748:                        _addmd(vl,mod,r,t,&t1); r = t1;
        !           749:                }
        !           750:                bzero(w,l*sizeof(MP));
        !           751:                if ( r )
        !           752:                        r->sugar = p->sugar + m0->dl->td;
        !           753:                *pr = r;
        !           754:        }
        !           755: }
        !           756:
        !           757: /* m0 = x0^d0*x1^d1*... * dx0^d(n/2)*dx1^d(n/2+1)*... */
        !           758:
        !           759: void _weyl_mulmmm(vl,mod,m0,m1,n,pr)
        !           760: VL vl;
        !           761: int mod;
        !           762: MP m0,m1;
        !           763: int n;
        !           764: DP *pr;
        !           765: {
        !           766:        MP m,mr,mr0;
        !           767:        DP r,t,t1;
        !           768:        int c,c0,c1,cc;
        !           769:        DL d,d0,d1;
        !           770:        int i,j,a,b,k,l,n2,s,min,h;
        !           771:        static int *tab;
        !           772:        static int tablen;
        !           773:
        !           774:        if ( !m0 || !m1 )
        !           775:                *pr = 0;
        !           776:        else {
        !           777:                c0 = ITOS(C(m0)); c1 = ITOS(C(m1));
        !           778:                c = dmar(c0,c1,0,mod);
        !           779:                d0 = m0->dl; d1 = m1->dl;
        !           780:                n2 = n>>1;
        !           781:
        !           782:                if ( n & 1 ) {
        !           783:                        /* offset of h-degree */
        !           784:                        NEWDL(d,n); d->d[n-1] = d0->d[n-1]+d1->d[n-1]; d->td = d->d[n-1];
        !           785:                        NEWMP(mr); mr->c = STOI(c); mr->dl = d;
        !           786:                        MKDPM(n,mr,r); r->sugar = d->d[n-1];
        !           787:
        !           788:                        /* homogenized computation; dx-xd=h^2 */
        !           789:                        for ( i = 0; i < n2; i++ ) {
        !           790:                                a = d0->d[i]; b = d1->d[n2+i];
        !           791:                                k = d0->d[n2+i]; l = d1->d[i];
        !           792:                                /* degree of xi^a*(Di^k*xi^l)*Di^b */
        !           793:                                h = a+k+l+b;
        !           794:                                /* compute xi^a*(Di^k*xi^l)*Di^b */
        !           795:                                min = MIN(k,l);
        !           796:
        !           797:                                if ( min+1 > tablen ) {
        !           798:                                        if ( tab ) GC_free(tab);
        !           799:                                        tab = (int *)MALLOC((min+1)*sizeof(int));
        !           800:                                        tablen = min+1;
        !           801:                                }
        !           802:                                mkwcm(k,l,mod,tab);
        !           803:                                for ( mr0 = 0, j = 0; j <= min; j++ ) {
        !           804:                                        NEXTMP(mr0,mr);
        !           805:                                        NEWDL(d,n);
        !           806:                                        d->d[i] = l-j+a; d->d[n2+i] = k-j+b;
        !           807:                                        d->td = h;
        !           808:                                        d->d[n-1] = h-(d->d[i]+d->d[n2+i]);
        !           809:                                        mr->c = STOI(tab[j]);
        !           810:                                        mr->dl = d;
        !           811:                                }
        !           812:                                bzero(tab,(min+1)*sizeof(int));
        !           813:                                if ( mr0 )
        !           814:                                        NEXT(mr) = 0;
        !           815:                                MKDP(n,mr0,t);
        !           816:                                if ( t )
        !           817:                                        t->sugar = h;
        !           818:                                _comm_mulmd(vl,mod,r,t,&t1); r = t1;
        !           819:                        }
        !           820:                } else {
        !           821:                        NEWDL(d,n); d->td = 0;
        !           822:                        NEWMP(mr); mr->c = STOI(c); mr->dl = d;
        !           823:                        MKDPM(n,mr,r); r->sugar = 0;
        !           824:
        !           825:                        for ( i = 0; i < n2; i++ ) {
        !           826:                                a = d0->d[i]; b = d1->d[n2+i];
        !           827:                                k = d0->d[n2+i]; l = d1->d[i];
        !           828:                                /* compute xi^a*(Di^k*xi^l)*Di^b */
        !           829:                                min = MIN(k,l);
        !           830:
        !           831:                                if ( min+1 > tablen ) {
        !           832:                                        if ( tab ) GC_free(tab);
        !           833:                                        tab = (int *)MALLOC((min+1)*sizeof(int));
        !           834:                                        tablen = min+1;
        !           835:                                }
        !           836:                                mkwcm(k,l,mod,tab);
        !           837:                                for ( mr0 = 0, s = 0, j = 0; j <= min; j++ ) {
        !           838:                                        NEXTMP(mr0,mr);
        !           839:                                        NEWDL(d,n);
        !           840:                                        d->d[i] = l-j+a; d->d[n2+i] = k-j+b;
        !           841:                                        d->td = d->d[i]+d->d[n2+i]; /* XXX */
        !           842:                                        s = MAX(s,d->td); /* XXX */
        !           843:                                        mr->c = STOI(tab[j]);
        !           844:                                        mr->dl = d;
        !           845:                                }
        !           846:                                bzero(tab,(min+1)*sizeof(int));
        !           847:                                if ( mr0 )
        !           848:                                        NEXT(mr) = 0;
        !           849:                                MKDP(n,mr0,t);
        !           850:                                if ( t )
        !           851:                                        t->sugar = s;
        !           852:                                _comm_mulmd(vl,mod,r,t,&t1); r = t1;
        !           853:                        }
        !           854:                }
        !           855:                *pr = r;
        !           856:        }
        !           857: }
        !           858:
1.1       noro      859: void _dtop_mod(vl,dvl,p,pr)
                    860: VL vl,dvl;
                    861: DP p;
                    862: P *pr;
                    863: {
                    864:        int n,i;
                    865:        DL d;
                    866:        MP m;
                    867:        P r,s,t,u,w;
                    868:        Q q;
                    869:        VL tvl;
                    870:
                    871:        if ( !p )
                    872:                *pr = 0;
                    873:        else {
                    874:                for ( n = p->nv, m = BDY(p), s = 0; m; m = NEXT(m) ) {
                    875:                        i = ITOS(m->c); STOQ(i,q); t = (P)q;
                    876:                        for ( i = 0, d = m->dl, tvl = dvl;
                    877:                                i < n; tvl = NEXT(tvl), i++ ) {
                    878:                                MKV(tvl->v,r); STOQ(d->d[i],q); pwrp(vl,r,q,&u);
                    879:                                mulp(vl,t,u,&w); t = w;
                    880:                        }
                    881:                        addp(vl,s,t,&u); s = u;
                    882:                }
                    883:                *pr = s;
                    884:        }
                    885: }
                    886:
                    887: void _dp_red_mod(p1,p2,mod,rp)
                    888: DP p1,p2;
                    889: int mod;
                    890: DP *rp;
                    891: {
                    892:        int i,n;
                    893:        DL d1,d2,d;
                    894:        MP m;
                    895:        DP t,s;
                    896:        int c,c1;
                    897:
                    898:        n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
                    899:        NEWDL(d,n); d->td = d1->td - d2->td;
                    900:        for ( i = 0; i < n; i++ )
                    901:                d->d[i] = d1->d[i]-d2->d[i];
                    902:        c = invm(ITOS(BDY(p2)->c),mod); c1 = dmar(c,ITOS(BDY(p1)->c),0,mod);
                    903:        NEWMP(m); m->dl = d; m->c = STOI(mod-c1); NEXT(m) = 0;
                    904:        MKDP(n,m,s); s->sugar = d->td;
1.2     ! noro      905:        _mulmd(CO,mod,s,p2,&t); _addmd(CO,mod,p1,t,rp);
1.1       noro      906: }
                    907:
                    908: void _dp_mod(p,mod,subst,rp)
                    909: DP p;
                    910: int mod;
                    911: NODE subst;
                    912: DP *rp;
                    913: {
                    914:        MP m,mr,mr0;
                    915:        P t,s;
                    916:        NODE tn;
                    917:
                    918:        if ( !p )
                    919:                *rp = 0;
                    920:        else {
                    921:                for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                    922:                        for ( tn = subst, s = m->c; tn; tn = NEXT(NEXT(tn)) ) {
                    923:                                substp(CO,s,BDY(tn),BDY(NEXT(tn)),&t);
                    924:                                s = t;
                    925:                        }
                    926:                        ptomp(mod,s,&t);
                    927:                        if ( t ) {
                    928:                                NEXTMP(mr0,mr); mr->c = STOI(CONT((MQ)t)); mr->dl = m->dl;
                    929:                        }
                    930:                }
                    931:                if ( mr0 ) {
                    932:                        NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
                    933:                } else
                    934:                        *rp = 0;
                    935:        }
                    936: }
                    937:
1.2     ! noro      938: void _dp_monic(p,mod,rp)
        !           939: DP p;
        !           940: int mod;
        !           941: DP *rp;
        !           942: {
        !           943:        MP m,mr,mr0;
        !           944:        int c,c1;
        !           945:        NODE tn;
        !           946:
        !           947:        if ( !p )
        !           948:                *rp = 0;
        !           949:        else {
        !           950:                c = invm(ITOS(BDY(p)->c),mod);
        !           951:                for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
        !           952:                        c1 = dmar(ITOS(m->c),c,0,mod);
        !           953:                        NEXTMP(mr0,mr); mr->c = STOI(c1); mr->dl = m->dl;
        !           954:                }
        !           955:                NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
        !           956:        }
        !           957: }
        !           958:
1.1       noro      959: void _dp_sp_mod(p1,p2,mod,rp)
                    960: DP p1,p2;
                    961: int mod;
                    962: DP *rp;
                    963: {
                    964:        int i,n,td;
                    965:        int *w;
                    966:        DL d1,d2,d;
                    967:        MP m;
                    968:        DP t,s,u;
                    969:
                    970:        n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
                    971:        w = (int *)ALLOCA(n*sizeof(int));
                    972:        for ( i = 0, td = 0; i < n; i++ ) {
                    973:                w[i] = MAX(d1->d[i],d2->d[i]); td += w[i];
                    974:        }
                    975:        NEWDL(d,n); d->td = td - d1->td;
                    976:        for ( i = 0; i < n; i++ )
                    977:                d->d[i] = w[i] - d1->d[i];
                    978:        NEWMP(m); m->dl = d; m->c = BDY(p2)->c; NEXT(m) = 0;
1.2     ! noro      979:        MKDP(n,m,s); s->sugar = d->td; _mulmd(CO,mod,s,p1,&t);
1.1       noro      980:        NEWDL(d,n); d->td = td - d2->td;
                    981:        for ( i = 0; i < n; i++ )
                    982:                d->d[i] = w[i] - d2->d[i];
                    983:        NEWMP(m); m->dl = d; m->c = STOI(mod - ITOS(BDY(p1)->c)); NEXT(m) = 0;
1.2     ! noro      984:        MKDP(n,m,s); s->sugar = d->td; _mulmd(CO,mod,s,p2,&u);
1.1       noro      985:        _addmd(CO,mod,t,u,rp);
                    986: }
                    987:
                    988: void _dp_sp_component_mod(p1,p2,mod,f1,f2)
                    989: DP p1,p2;
                    990: int mod;
                    991: DP *f1,*f2;
                    992: {
                    993:        int i,n,td;
                    994:        int *w;
                    995:        DL d1,d2,d;
                    996:        MP m;
                    997:        DP t,s,u;
                    998:
                    999:        n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
                   1000:        w = (int *)ALLOCA(n*sizeof(int));
                   1001:        for ( i = 0, td = 0; i < n; i++ ) {
                   1002:                w[i] = MAX(d1->d[i],d2->d[i]); td += w[i];
                   1003:        }
                   1004:        NEWDL(d,n); d->td = td - d1->td;
                   1005:        for ( i = 0; i < n; i++ )
                   1006:                d->d[i] = w[i] - d1->d[i];
                   1007:        NEWMP(m); m->dl = d; m->c = BDY(p2)->c; NEXT(m) = 0;
1.2     ! noro     1008:        MKDP(n,m,s); s->sugar = d->td; _mulmd(CO,mod,s,p1,f1);
1.1       noro     1009:        NEWDL(d,n); d->td = td - d2->td;
                   1010:        for ( i = 0; i < n; i++ )
                   1011:                d->d[i] = w[i] - d2->d[i];
                   1012:        NEWMP(m); m->dl = d; m->c = BDY(p1)->c; NEXT(m) = 0;
1.2     ! noro     1013:        MKDP(n,m,s); s->sugar = d->td; _mulmd(CO,mod,s,p2,f2);
1.1       noro     1014: }
                   1015:
                   1016: void _printdp(d)
                   1017: DP d;
                   1018: {
                   1019:        int n,i;
                   1020:        MP m;
                   1021:        DL dl;
                   1022:
                   1023:        if ( !d ) {
                   1024:                printf("0"); return;
                   1025:        }
                   1026:        for ( n = d->nv, m = BDY(d); m; m = NEXT(m) ) {
                   1027:                printf("%d*<<",ITOS(m->c));
                   1028:                for ( i = 0, dl = m->dl; i < n-1; i++ )
                   1029:                        printf("%d,",dl->d[i]);
                   1030:                printf("%d",dl->d[i]);
                   1031:                printf(">>");
                   1032:                if ( NEXT(m) )
                   1033:                        printf("+");
                   1034:        }
                   1035: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>