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

Annotation of OpenXM_contrib2/asir2000/engine/dist.c, Revision 1.5

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

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