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

Annotation of OpenXM_contrib2/asir2000/engine/PUM.c, Revision 1.1

1.1     ! noro        1: /* $OpenXM: OpenXM/src/asir99/engine/PUM.c,v 1.1.1.1 1999/11/10 08:12:26 noro Exp $ */
        !             2: #include "ca.h"
        !             3:
        !             4: void gcdcmp(), sprsm();
        !             5:
        !             6: void detmp(vl,mod,rmat,n,dp)
        !             7: VL vl;
        !             8: int mod;
        !             9: P **rmat;
        !            10: int n;
        !            11: P *dp;
        !            12: {
        !            13:        int i,j,k,sgn;
        !            14:        P mjj,mij,t,s,u,d;
        !            15:        P **mat;
        !            16:        P *mi,*mj;
        !            17:
        !            18:        mat = (P **)almat_pointer(n,n);
        !            19:        for ( i = 0; i < n; i++ )
        !            20:                for ( j = 0; j < n; j++ )
        !            21:                        mat[i][j] = rmat[i][j];
        !            22:        for ( j = 0, d = (P)ONEM, sgn = 1; j < n; j++ ) {
        !            23:                for ( i = j; (i < n) && !mat[i][j]; i++ );
        !            24:                if ( i == n ) {
        !            25:                        *dp = 0; return;
        !            26:                }
        !            27:                for ( k = i; k < n; k++ )
        !            28:                        if ( mat[k][j] && (nmonop(mat[k][j]) < nmonop(mat[i][j]) ) )
        !            29:                                i = k;
        !            30:                if ( j != i ) {
        !            31:                        mj = mat[j]; mat[j] = mat[i]; mat[i] = mj; sgn = -sgn;
        !            32:                }
        !            33:                for ( i = j + 1, mj = mat[j], mjj = mj[j]; i < n; i++ )
        !            34:                        for ( k = j + 1, mi = mat[i], mij = mi[j]; k < n; k++ ) {
        !            35:                                mulmp(vl,mod,mi[k],mjj,&t); mulmp(vl,mod,mj[k],mij,&s);
        !            36:                                submp(vl,mod,t,s,&u); divsmp(vl,mod,u,d,&mi[k]);
        !            37:                        }
        !            38:                d = mjj;
        !            39:        }
        !            40:        if ( sgn < 0 )
        !            41:                chsgnmp(mod,d,dp);
        !            42:        else
        !            43:                *dp = d;
        !            44: }
        !            45:
        !            46: void resultmp(vl,mod,v,p1,p2,pr)
        !            47: VL vl;
        !            48: int mod;
        !            49: V v;
        !            50: P p1,p2,*pr;
        !            51: {
        !            52:        P q1,q2,m,m1,m2,lc,q,r,t,g1,g2,adj;
        !            53:        int d,d1,d2,j,k;
        !            54:        VL nvl;
        !            55:        Q dq;
        !            56:        MQ mq;
        !            57:
        !            58:        if ( !p1 || !p2 ) {
        !            59:                *pr = 0; return;
        !            60:        }
        !            61:        reordvar(vl,v,&nvl);
        !            62:        reordermp(nvl,mod,vl,p1,&q1); reordermp(nvl,mod,vl,p2,&q2);
        !            63:
        !            64:        if ( VR(q1) != v )
        !            65:                if ( VR(q2) != v ) {
        !            66:                        *pr = 0;
        !            67:                        return;
        !            68:                } else {
        !            69:                        d = deg(v,q2); STOQ(d,dq);
        !            70:                        pwrmp(vl,mod,q1,dq,pr);
        !            71:                        return;
        !            72:                }
        !            73:        else if ( VR(q2) != v ) {
        !            74:                d = deg(v,q1); STOQ(d,dq);
        !            75:                pwrmp(vl,mod,q2,dq,pr);
        !            76:                return;
        !            77:        }
        !            78:
        !            79:        if ( ( VR(q1) != v ) || ( VR(q2) != v ) ) {
        !            80:                *pr = 0;
        !            81:                return;
        !            82:        }
        !            83:
        !            84:        d1 = deg(v,q1); d2 = deg(v,q2);
        !            85:        if ( d1 > d2 ) {
        !            86:                g1 = q1; g2 = q2; adj = (P)ONEM;
        !            87:        } else if ( d1 < d2 ) {
        !            88:                g2 = q1; g1 = q2;
        !            89:                if ( (d1 % 2) && (d2 % 2) ) {
        !            90:                        STOMQ(-1,mq); adj = (P)mq;
        !            91:                } else
        !            92:                        adj = (P)ONEM;
        !            93:        } else {
        !            94:                premmp(nvl,mod,q1,q2,&t);
        !            95:                d = deg(v,t); STOQ(d,dq); pwrmp(nvl,mod,LC(q2),dq,&adj);
        !            96:                g1 = q2; g2 = t;
        !            97:                if ( d1 % 2 ) {
        !            98:                        chsgnmp(mod,adj,&t); adj = t;
        !            99:                }
        !           100:        }
        !           101:        d1 = deg(v,g1); j = d1 - 1;
        !           102:
        !           103:        for ( lc = (P)ONEM; ; ) {
        !           104:                if ( ( k = deg(v,g2) ) < 0 ) {
        !           105:                        *pr = 0;
        !           106:                        return;
        !           107:                }
        !           108:
        !           109:                if ( k == j )
        !           110:                        if ( !k ) {
        !           111:                                divsmp(nvl,mod,g2,adj,pr);
        !           112:                                return;
        !           113:                        } else {
        !           114:                                premmp(nvl,mod,g1,g2,&r); mulmp(nvl,mod,lc,lc,&m);
        !           115:                                divsmp(nvl,mod,r,m,&q);
        !           116:                                g1 = g2; g2 = q;
        !           117:                                lc = LC(g1); /* g1 is not const */
        !           118:                                j = k - 1;
        !           119:                        }
        !           120:                else {
        !           121:                        d = j - k; STOQ(d,dq);
        !           122:                        pwrmp(nvl,mod,(VR(g2)==v?LC(g2):g2),dq,&m);
        !           123:                        mulmp(nvl,mod,g2,m,&m1);
        !           124:                        pwrmp(nvl,mod,lc,dq,&m); divsmp(nvl,mod,m1,m,&t);
        !           125:                        if ( k == 0 ) {
        !           126:                                divsmp(nvl,mod,t,adj,pr);
        !           127:                                return;
        !           128:                        } else {
        !           129:                                premmp(nvl,mod,g1,g2,&r);
        !           130:                                mulmp(nvl,mod,lc,lc,&m1); mulmp(nvl,mod,m,m1,&m2);
        !           131:                                divsmp(nvl,mod,r,m2,&q);
        !           132:                                g1 = t; g2 = q;
        !           133:                                if ( d % 2 ) {
        !           134:                                        chsgnmp(mod,g2,&t); g2 = t;
        !           135:                                }
        !           136:                                lc = LC(g1); /* g1 is not const */
        !           137:                                j = k - 1;
        !           138:                        }
        !           139:                }
        !           140:        }
        !           141: }
        !           142:
        !           143: void premmp(vl,mod,p1,p2,pr)
        !           144: VL vl;
        !           145: int mod;
        !           146: P p1,p2,*pr;
        !           147: {
        !           148:        P m,m1,m2;
        !           149:        P *pw;
        !           150:        DCP dc;
        !           151:        V v1,v2;
        !           152:        register int i,j;
        !           153:        int n1,n2,d;
        !           154:
        !           155:        if ( NUM(p1) )
        !           156:                if ( NUM(p2) )
        !           157:                        *pr = 0;
        !           158:                else
        !           159:                        *pr = p1;
        !           160:        else if ( NUM(p2) )
        !           161:                *pr = 0;
        !           162:        else if ( ( v1 = VR(p1) ) == ( v2 = VR(p2) ) ) {
        !           163:                n1 = deg(v1,p1); n2 = deg(v1,p2);
        !           164:                pw = (P *)ALLOCA((n1+1)*sizeof(P));
        !           165:                bzero((char *)pw,(int)((n1+1)*sizeof(P)));
        !           166:
        !           167:                for ( dc = DC(p1); dc; dc = NEXT(dc) )
        !           168:                        pw[QTOS(DEG(dc))] = COEF(dc);
        !           169:
        !           170:                for ( i = n1; i >= n2; i-- ) {
        !           171:                        if ( pw[i] ) {
        !           172:                                m = pw[i];
        !           173:                                for ( j = i; j >= 0; j-- ) {
        !           174:                                        mulmp(vl,mod,pw[j],LC(p2),&m1); pw[j] = m1;
        !           175:                                }
        !           176:
        !           177:                                for ( dc = DC(p2), d = i - n2; dc; dc = NEXT(dc) ) {
        !           178:                                        mulmp(vl,mod,COEF(dc),m,&m1);
        !           179:                                        submp(vl,mod,pw[QTOS(DEG(dc))+d],m1,&m2);
        !           180:                                        pw[QTOS(DEG(dc))+d] = m2;
        !           181:                                }
        !           182:                        } else
        !           183:                                for ( j = i; j >= 0; j-- )
        !           184:                                        if ( pw[j] ) {
        !           185:                                                mulmp(vl,mod,pw[j],LC(p2),&m1); pw[j] = m1;
        !           186:                                        }
        !           187:                }
        !           188:                plisttop(pw,v1,n2-1,pr);
        !           189:        } else {
        !           190:                while ( v1 != vl->v && v2 != vl->v )
        !           191:                        vl = NEXT(vl);
        !           192:                if ( v1 == vl->v )
        !           193:                        *pr = 0;
        !           194:                else
        !           195:                        *pr = p1;
        !           196:        }
        !           197: }
        !           198:
        !           199: void srchmp(vl,mod,v,p1,p2,pr)
        !           200: VL vl;
        !           201: int mod;
        !           202: V v;
        !           203: P p1,p2,*pr;
        !           204: {
        !           205:        P a,b,q1,q2,x,t,s,d,bg,c,c0,db;
        !           206:        int i,m,k;
        !           207:        V v0;
        !           208:        VL nvl,tvl,nvl1,nvl2;
        !           209:        Q dq;
        !           210:        MQ q;
        !           211:
        !           212:        if ( vl->v != v ) {
        !           213:                reordvar(vl,v,&tvl);
        !           214:                reordermp(tvl,mod,vl,p1,&q1); reordermp(tvl,mod,vl,p2,&q2);
        !           215:        } else {
        !           216:                q1 = p1; q2 = p2; tvl = vl;
        !           217:        }
        !           218:        clctv(tvl,q1,&nvl1); clctv(tvl,q2,&nvl2); mergev(tvl,nvl1,nvl2,&nvl);
        !           219:        if ( VR(q1) != v )
        !           220:                if ( VR(q2) != v )
        !           221:                        *pr = 0;
        !           222:                else {
        !           223:                        m = getdeg(v,q2); STOQ(m,dq); pwrmp(vl,mod,q1,dq,pr);
        !           224:                }
        !           225:        else if ( VR(q2) != v ) {
        !           226:                m = getdeg(v,q1); STOQ(m,dq); pwrmp(vl,mod,q2,dq,pr);
        !           227:        } else if ( !NEXT(nvl) )
        !           228:                srchump(mod,p1,p2,pr);
        !           229:        else {
        !           230:                v0 = NEXT(nvl)->v;
        !           231:                k = getdeg(v,q1)*getdeg(v0,q2)+getdeg(v,q2)*getdeg(v0,q1)+1;
        !           232:                for ( i = 0, c = 0, d = (P)ONEM, MKMV(v0,x);
        !           233:                        ( i < mod ) && (getdeg(v0,d) < k) ; i++ ) {
        !           234:                        STOMQ(i,q),bg = (P)q; substmp(nvl,mod,LC(q1),v0,bg,&t);
        !           235:                        if ( !t )
        !           236:                                continue;
        !           237:                        substmp(nvl,mod,LC(q2),v0,bg,&t);
        !           238:                        if ( !t )
        !           239:                                continue;
        !           240:                        substmp(nvl,mod,q1,v0,bg,&a); substmp(nvl,mod,q2,v0,bg,&b);
        !           241:                        srchmp(nvl,mod,v,a,b,&c0); substmp(nvl,mod,c,v0,bg,&t);
        !           242:                        submp(nvl,mod,c0,t,&s); mulmp(nvl,mod,s,d,&t);
        !           243:                        substmp(nvl,mod,d,v0,bg,&db);
        !           244:                        divsmp(nvl,mod,t,db,&s); addmp(nvl,mod,s,c,&t); c = t;
        !           245:                        submp(nvl,mod,x,bg,&t); mulmp(nvl,mod,d,t,&s); d = s;
        !           246:                }
        !           247:                if ( i == mod )
        !           248:                        error("srchmp : ???");
        !           249:                *pr = c;
        !           250:        }
        !           251: }
        !           252:
        !           253: int ucmpp(p,q)
        !           254: P p,q;
        !           255: {
        !           256:        DCP dcp,dcq;
        !           257:
        !           258:        if ( !p )
        !           259:                if ( !q )
        !           260:                        return ( 0 );
        !           261:                else
        !           262:                        return ( 1 );
        !           263:        else if ( !q )
        !           264:                return ( 1 );
        !           265:        else if ( NUM(p) )
        !           266:                if ( !NUM(q) )
        !           267:                        return ( 1 );
        !           268:                else
        !           269:                        return ( cmpq((Q)p,(Q)q) );
        !           270:        else if ( NUM(q) )
        !           271:                        return ( 1 );
        !           272:        else {
        !           273:                for ( dcp = DC(p), dcq = DC(q); dcp && dcq;
        !           274:                        dcp = NEXT(dcp), dcq = NEXT(dcq) )
        !           275:                        if ( cmpq(DEG(dcp),DEG(dcq) ) )
        !           276:                                return ( 1 );
        !           277:                        else if ( cmpq((Q)COEF(dcp),(Q)COEF(dcq) ) )
        !           278:                                return ( 1 );
        !           279:                if ( dcp || dcq )
        !           280:                        return ( 1 );
        !           281:                else
        !           282:                        return ( 0 );
        !           283:        }
        !           284: }
        !           285:
        !           286: #if 0
        !           287: srchump(mod,p1,p2,pr)
        !           288: int mod;
        !           289: P p1,p2,*pr;
        !           290: {
        !           291:        int r;
        !           292:        MQ mq;
        !           293:
        !           294:        r = eucresum(mod,p1,p2);
        !           295:        STOMQ(r,mq); *pr = (P)mq;
        !           296: }
        !           297: #endif
        !           298:
        !           299: void srchump(mod,p1,p2,pr)
        !           300: int mod;
        !           301: P p1,p2,*pr;
        !           302: {
        !           303:        UM m,m1,q,r,t,g1,g2;
        !           304:        int lc,d,d1,d2,i,j,k,l,l1,l2,tmp,adj;
        !           305:        V v;
        !           306:
        !           307:        v = VR(p1); d = MAX(UDEG(p1),UDEG(p2));
        !           308:        g1 = W_UMALLOC(d); g2 = W_UMALLOC(d);
        !           309:        bzero((char *)g1,(int)((d+2)*sizeof(int))); bzero((char *)g2,(int)((d+2)*sizeof(int)));
        !           310:        if ( d == (int)UDEG(p1) ) {
        !           311:                mptoum(p1,g1); mptoum(p2,g2);
        !           312:        } else {
        !           313:                mptoum(p2,g1); mptoum(p1,g2);
        !           314:        }
        !           315:        if ( ( d1 = DEG(g1) ) > ( d2 = DEG(g2) ) ) {
        !           316:                j = d1 - 1; adj = 1;
        !           317:        } else
        !           318:                j = d2;
        !           319:        lc = 1;
        !           320:        r = W_UMALLOC(d1+d2); q = W_UMALLOC(d1+d2);
        !           321:        m1 = W_UMALLOC(d1+d2); t = W_UMALLOC(d1+d2);
        !           322:        bzero((char *)r,(int)((d1+d2+2)*sizeof(int))); bzero((char *)q,(int)((d1+d2+2)*sizeof(int)));
        !           323:        bzero((char *)m1,(int)((d1+d2+2)*sizeof(int))); bzero((char *)t,(int)((d1+d2+2)*sizeof(int)));
        !           324:        m = W_UMALLOC(0); bzero((char *)m,(int)(2*sizeof(int)));
        !           325:        adj = pwrm(mod,COEF(g2)[DEG(g2)],DEG(g1));
        !           326:        DEG(m) = 0; COEF(m)[0] = invm(COEF(g2)[DEG(g2)],mod);
        !           327:        mulum(mod,g2,m,r); cpyum(r,g2);
        !           328:        while ( 1 ) {
        !           329:                if ( ( k = DEG(g2) ) < 0 ) {
        !           330:                        *pr = 0;
        !           331:                        return;
        !           332:                }
        !           333:                if ( k == j ) {
        !           334:                        if ( k == 0 ) {
        !           335:                                DEG(m) = 0; COEF(m)[0] = adj;
        !           336:                                mulum(mod,g2,m,r); umtomp(v,r,pr);
        !           337:                                return;
        !           338:                        } else {
        !           339:                                DEG(m) = 0;
        !           340:                                COEF(m)[0] = pwrm(mod,COEF(g2)[k],DEG(g1)-k+1);
        !           341:                                mulum(mod,g1,m,r); DEG(r) = divum(mod,r,g2,t);
        !           342:                                DEG(m) = 0; COEF(m)[0] = dmb(mod,lc,lc,&tmp);
        !           343:                                divum(mod,r,m,q); cpyum(g2,g1); cpyum(q,g2);
        !           344:                                lc = COEF(g1)[DEG(g1)]; j = k - 1;
        !           345:                        }
        !           346:                } else {
        !           347:                        d = j - k;
        !           348:                        DEG(m) = 0; COEF(m)[0] = pwrm(mod,COEF(g2)[DEG(g2)],d);
        !           349:                        mulum(mod,g2,m,m1); l = pwrm(mod,lc,d);
        !           350:                        DEG(m) = 0; COEF(m)[0] = l; divum(mod,m1,m,t);
        !           351:                        if ( k == 0 ) {
        !           352:                                DEG(m) = 0; COEF(m)[0] = adj;
        !           353:                                mulum(mod,t,m,r); umtomp(v,r,pr);
        !           354:                                return;
        !           355:                        } else {
        !           356:                                DEG(m) = 0;
        !           357:                                COEF(m)[0] = pwrm(mod,COEF(g2)[k],DEG(g1)-k+1);
        !           358:                                mulum(mod,g1,m,r); DEG(r) = divum(mod,r,g2,q);
        !           359:                                l1 = dmb(mod,lc,lc,&tmp); l2 = dmb(mod,l,l1,&tmp);
        !           360:                                DEG(m) = 0; COEF(m)[0] = l2;
        !           361:                                divum(mod,r,m,q); cpyum(t,g1); cpyum(q,g2);
        !           362:                                if ( d % 2 )
        !           363:                                        for ( i = DEG(g2); i >= 0; i-- )
        !           364:                                                COEF(g2)[i] = ( mod - COEF(g2)[i] ) % mod;
        !           365:                                lc = COEF(g1)[DEG(g1)]; j = k - 1;
        !           366:                        }
        !           367:                }
        !           368:        }
        !           369: }
        !           370:
        !           371: void substmp(vl,mod,p,v0,p0,pr)
        !           372: VL vl;
        !           373: int mod;
        !           374: V v0;
        !           375: P p,p0;
        !           376: P *pr;
        !           377: {
        !           378:        P x,t,m,c,s,a;
        !           379:        DCP dc;
        !           380:        Q d;
        !           381:
        !           382:        if ( !p )
        !           383:                *pr = 0;
        !           384:        else if ( NUM(p) )
        !           385:                *pr = p;
        !           386:        else if ( VR(p) != v0 ) {
        !           387:                MKMV(VR(p),x);
        !           388:                for ( c = 0, dc = DC(p); dc; dc = NEXT(dc) ) {
        !           389:                        substmp(vl,mod,COEF(dc),v0,p0,&t);
        !           390:                        if ( DEG(dc) ) {
        !           391:                                pwrmp(vl,mod,x,DEG(dc),&s); mulmp(vl,mod,s,t,&m);
        !           392:                                addmp(vl,mod,m,c,&a);
        !           393:                                c = a;
        !           394:                        } else {
        !           395:                                addmp(vl,mod,t,c,&a);
        !           396:                                c = a;
        !           397:                        }
        !           398:                }
        !           399:                *pr = c;
        !           400:        } else {
        !           401:                dc = DC(p);
        !           402:                c = COEF(dc);
        !           403:                for ( d = DEG(dc), dc = NEXT(dc);
        !           404:                        dc; d = DEG(dc), dc = NEXT(dc) ) {
        !           405:                                subq(d,DEG(dc),(Q *)&t); pwrmp(vl,mod,p0,(Q)t,&s);
        !           406:                                mulmp(vl,mod,s,c,&m);
        !           407:                                addmp(vl,mod,m,COEF(dc),&c);
        !           408:                }
        !           409:                if ( d ) {
        !           410:                        pwrmp(vl,mod,p0,d,&t); mulmp(vl,mod,t,c,&m);
        !           411:                        c = m;
        !           412:                }
        !           413:                *pr = c;
        !           414:        }
        !           415: }
        !           416:
        !           417: void reordermp(nvl,mod,ovl,p,pr)
        !           418: VL nvl,ovl;
        !           419: int mod;
        !           420: P p;
        !           421: P *pr;
        !           422: {
        !           423:        DCP dc;
        !           424:        P x,m,s,t,c;
        !           425:
        !           426:        if ( !p )
        !           427:                *pr = 0;
        !           428:        else if ( NUM(p) )
        !           429:                *pr = p;
        !           430:        else {
        !           431:                MKMV(VR(p),x);
        !           432:                for ( s = 0, dc = DC(p); dc; dc = NEXT(dc) ) {
        !           433:                        reordermp(nvl,mod,ovl,COEF(dc),&c);
        !           434:                        if ( DEG(dc) ) {
        !           435:                                pwrmp(nvl,mod,x,DEG(dc),&t); mulmp(nvl,mod,c,t,&m);
        !           436:                                addmp(nvl,mod,m,s,&t);
        !           437:                        } else
        !           438:                                addmp(nvl,mod,s,c,&t);
        !           439:                        s = t;
        !           440:                }
        !           441:                *pr = s;
        !           442:        }
        !           443: }
        !           444:
        !           445: void chnremp(vl,mod,p,q,c,r)
        !           446: VL vl;
        !           447: int mod;
        !           448: P p;
        !           449: Q q;
        !           450: P c;
        !           451: P *r;
        !           452: {
        !           453:        P tg,sg,ug;
        !           454:        P t,u;
        !           455:        MQ mq;
        !           456:
        !           457:        ptomp(mod,p,&tg); submp(vl,mod,c,tg,&sg);
        !           458:        UTOMQ(rem(NM(q),mod),mq),tg = (P)mq; divsmp(vl,mod,sg,tg,&ug);
        !           459:        normalizemp(mod,ug);
        !           460:        mptop(ug,&u); mulp(vl,u,(P)q,&t); addp(vl,t,p,r);
        !           461: }
        !           462:
        !           463: /* XXX  strange behavior of invm() on SPARC */
        !           464:
        !           465: void chnrem(mod,v,c,q,t,cr,qr)
        !           466: int mod;
        !           467: V v;
        !           468: UM t;
        !           469: Q q,*qr;
        !           470: P c,*cr;
        !           471: {
        !           472:        int n,m,i,d,a,sd,tmp;
        !           473:        Q b,s,z;
        !           474:        Q *pc,*pcr;
        !           475:        DCP dc;
        !           476:
        !           477:        if ( !c || NUM(c) )
        !           478:                n = 0;
        !           479:        else
        !           480:                n = UDEG(c);
        !           481:        m = DEG(t); d = MAX(n,m); W_CALLOC(n,Q,pc); W_CALLOC(d,Q,pcr);
        !           482:        if ( !c )
        !           483:                pc[0] = 0;
        !           484:        else if ( NUM(c) )
        !           485:                pc[0] = (Q)c;
        !           486:        else
        !           487:                for ( dc = DC(c); dc; dc = NEXT(dc) )
        !           488:                        pc[QTOS(DEG(dc))] = (Q)COEF(dc);
        !           489:        for ( i = 0; i <= d; i++ ) {
        !           490:                b = (i>n?0:pc[i]); a = (i>m?0:COEF(t)[i]);
        !           491:                if ( b )
        !           492:                        a = (a-SGN(pc[i])*((int)rem(NM(pc[i]),mod)))%mod;
        !           493:                sd = dmb(mod,(a>=0?a:a+mod),invm(rem(NM(q),mod),mod),&tmp);
        !           494:                if ( ( 2 * sd ) > mod )
        !           495:                        sd -= mod;
        !           496:                STOQ(sd,z); mulq(z,q,&s); addq(s,b,&pcr[i]);
        !           497:        }
        !           498:        STOQ(mod,z); mulq(q,z,qr); plisttop((P *)pcr,v,d,cr);
        !           499: }
        !           500:
        !           501: void normalizemp(mod,g)
        !           502: int mod;
        !           503: P g;
        !           504: {
        !           505:        DCP dc;
        !           506:
        !           507:        if ( !g )
        !           508:                return;
        !           509:        else if ( NUM(g) ) {
        !           510:                if ( 2 * CONT((MQ)g) > mod )
        !           511:                        CONT((MQ)g) -= mod;
        !           512:                return;
        !           513:        } else
        !           514:                for ( dc = DC(g); dc; dc = NEXT(dc) )
        !           515:                        normalizemp(mod,COEF(dc));
        !           516: }
        !           517:
        !           518: void norm(p,r)
        !           519: P p;
        !           520: Q *r;
        !           521: {
        !           522:        N t;
        !           523:        DCP dc;
        !           524:
        !           525:        for ( dc = DC(p), t = ONEN; dc; dc = NEXT(dc) )
        !           526:                if ( cmpn(NM((Q)COEF(dc)),t) > 0 ) {
        !           527:                        t = NM((Q)COEF(dc));
        !           528:                }
        !           529:        NTOQ(t,1,*r);
        !           530: }
        !           531:
        !           532: void norm1(p,r)
        !           533: P p,*r;
        !           534: {
        !           535:        DCP dc;
        !           536:        P t,s,u;
        !           537:        Q q;
        !           538:
        !           539:        if ( NUM(p) )
        !           540:                NTOQ(NM((Q)p),1,q),*r = (P)q;
        !           541:        else {
        !           542:                for ( t = 0, dc = DC(p); dc; dc = NEXT(dc) ) {
        !           543:                        norm1(COEF(dc),&s); addq((Q)t,(Q)s,(Q *)&u); t = u;
        !           544:                }
        !           545:                *r = t;
        !           546:        }
        !           547: }
        !           548:
        !           549: void norm1c(p,r)
        !           550: P p;
        !           551: Q *r;
        !           552: {
        !           553:        N t;
        !           554:        Q s;
        !           555:        DCP dc;
        !           556:
        !           557:        if ( NUM(p) )
        !           558:                norm1(p,(P *)r);
        !           559:        else {
        !           560:                for ( dc = DC(p), t = ONEN; dc; dc = NEXT(dc) ) {
        !           561:                        norm1(COEF(dc),(P *)&s);
        !           562:                        if ( cmpn(NM(s),t) > 0 )
        !           563:                                t = NM(s);
        !           564:                }
        !           565:                NTOQ(t,1,*r);
        !           566:        }
        !           567: }
        !           568:
        !           569: void gcdprsmp(vl,mod,p1,p2,pr)
        !           570: VL vl;
        !           571: int mod;
        !           572: P p1,p2,*pr;
        !           573: {
        !           574:        P g1,g2,gc1,gc2,gp1,gp2,g,gc,gp,gcr;
        !           575:        V v1,v2;
        !           576:
        !           577:        if ( !p1 )
        !           578:                *pr = p2;
        !           579:        else if ( !p2 )
        !           580:                *pr = p1;
        !           581:        else if ( NUM(p1) || NUM(p2) )
        !           582:                *pr = (P)ONEM;
        !           583:        else {
        !           584:                g1 = p1; g2 = p2;
        !           585:                if ( ( v1 = VR(g1) ) == ( v2 = VR(g2) ) ) {
        !           586:                        gcdcmp(vl,mod,g1,&gc1); divsmp(vl,mod,g1,gc1,&gp1);
        !           587:                        gcdcmp(vl,mod,g2,&gc2); divsmp(vl,mod,g2,gc2,&gp2);
        !           588:                        gcdprsmp(vl,mod,gc1,gc2,&gcr);
        !           589:                        sprsm(vl,mod,v1,gp1,gp2,&g);
        !           590:
        !           591:                        if ( VR(g) == v1 ) {
        !           592:                                gp = g;
        !           593:                                gcdcmp(vl,mod,gp,&gc); divsmp(vl,mod,gp,gc,&gp1);
        !           594:                                mulmp(vl,mod,gp1,gcr,pr);
        !           595:                        } else
        !           596:                                *pr = gcr;
        !           597:                } else {
        !           598:                        while ( v1 != vl->v && v2 != vl->v )
        !           599:                                vl = NEXT(vl);
        !           600:                        if ( v1 == vl->v ) {
        !           601:                                gcdcmp(vl,mod,g1,&gc1); gcdprsmp(vl,mod,gc1,g2,pr);
        !           602:                        } else {
        !           603:                                gcdcmp(vl,mod,g2,&gc2); gcdprsmp(vl,mod,gc2,g1,pr);
        !           604:                        }
        !           605:                }
        !           606:        }
        !           607: }
        !           608:
        !           609: void gcdcmp(vl,mod,p,pr)
        !           610: VL vl;
        !           611: int mod;
        !           612: P p,*pr;
        !           613: {
        !           614:        P g,g1;
        !           615:        DCP dc;
        !           616:
        !           617:        if ( NUM(p) )
        !           618:                *pr = (P)ONEM;
        !           619:        else {
        !           620:                dc = DC(p);
        !           621:                g = COEF(dc);
        !           622:                for ( dc = NEXT(dc); dc; dc = NEXT(dc) ) {
        !           623:                        gcdprsmp(vl,mod,g,COEF(dc),&g1);
        !           624:                        g = g1;
        !           625:                }
        !           626:                *pr = g;
        !           627:        }
        !           628: }
        !           629:
        !           630: void sprsm(vl,mod,v,p1,p2,pr)
        !           631: VL vl;
        !           632: int mod;
        !           633: V v;
        !           634: P p1,p2,*pr;
        !           635: {
        !           636:        P q1,q2,m,m1,m2,x,h,r,g1,g2;
        !           637:        int d;
        !           638:        Q dq;
        !           639:        VL nvl;
        !           640:
        !           641:        reordvar(vl,v,&nvl);
        !           642:        reordermp(nvl,mod,vl,p1,&q1); reordermp(nvl,mod,vl,p2,&q2);
        !           643:
        !           644:        if ( ( VR(q1) != v ) || ( VR(q2) != v ) ) {
        !           645:                *pr = 0;
        !           646:                return;
        !           647:        }
        !           648:
        !           649:        if ( deg(v,q1) >= deg(v,q2) ) {
        !           650:                g1 = q1; g2 = q2;
        !           651:        } else {
        !           652:                g2 = q1; g1 = q2;
        !           653:        }
        !           654:
        !           655:        for ( h = (P)ONEM, x = (P)ONEM; ; ) {
        !           656:                if ( !deg(v,g2) )
        !           657:                        break;
        !           658:
        !           659:                premmp(nvl,mod,g1,g2,&r);
        !           660:                if ( !r )
        !           661:                        break;
        !           662:
        !           663:                d = deg(v,g1) - deg(v,g2); STOQ(d,dq);
        !           664:                pwrmp(nvl,mod,h,dq,&m); mulmp(nvl,mod,m,x,&m1); g1 = g2;
        !           665:                divsmp(nvl,mod,r,m1,&g2); x = LC(g1); /* g1 is not const w.r.t v */
        !           666:                pwrmp(nvl,mod,x,dq,&m1); mulmp(nvl,mod,m1,h,&m2);
        !           667:                divsmp(nvl,mod,m2,m,&h);
        !           668:        }
        !           669:        *pr = g2;
        !           670: }

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