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

Annotation of OpenXM_contrib2/asir2000/engine/Fgfs.c, Revision 1.4

1.4     ! noro        1: /* $OpenXM: OpenXM_contrib2/asir2000/engine/Fgfs.c,v 1.3 2002/09/27 08:40:48 noro Exp $ */
1.1       noro        2:
                      3: #include "ca.h"
                      4:
1.3       noro        5: void cont_pp_mv_sf(VL vl,VL rvl,P p,P *c,P *pp);
                      6: void gcdsf_main(VL vl,P *pa,int m,P *r);
                      7: void ugcdsf(P *pa,int m,P *r);
                      8: void head_monomial(V v,P p,P *coef,P *term);
1.4     ! noro        9: void sqfrsfmain(VL vl,P f,DCP *dcp);
        !            10: void pthrootsf(P f,Q m,P *r);
        !            11: void partial_sqfrsf(VL vl,V v,P f,P *r,DCP *dcp);
        !            12: void gcdsf(VL vl,P *pa,int k,P *r);
        !            13:
        !            14: void lex_lc(P f,P *c)
        !            15: {
        !            16:        if ( !f || NUM(f) )
        !            17:                *c = f;
        !            18:        else
        !            19:                lex_lc(COEF(DC(f)),c);
        !            20: }
        !            21:
        !            22: DCP append_dc(DCP dc,DCP dct)
        !            23: {
        !            24:        DCP dcs;
        !            25:
        !            26:        if ( !dc )
        !            27:                return dct;
        !            28:        else {
        !            29:                for ( dcs = dc; NEXT(dcs); dcs = NEXT(dcs) );
        !            30:                NEXT (dcs) = dct;
        !            31:                return dc;
        !            32:        }
        !            33: }
        !            34:
        !            35: void sqfrsf(VL vl, P f, DCP *dcp)
        !            36: {
        !            37:        DCP dc,dct;
        !            38:        Obj obj;
        !            39:        P t,s,c;
        !            40:        VL tvl,nvl;
        !            41:
        !            42:        simp_ff((Obj)f,&obj); f = (P)obj;
        !            43:        lex_lc(f,&c); divsp(vl,f,c,&t); f = t;
        !            44:        monomialfctr(vl,f,&t,&dc); f = t;
        !            45:        clctv(vl,f,&tvl); vl = tvl;
        !            46:        if ( !vl )
        !            47:                ;
        !            48:        else if ( !NEXT(vl) ) {
        !            49:                sfusqfr(f,&dct);
        !            50:                dc = append_dc(dc,NEXT(dct));
        !            51:        } else {
        !            52:                t = f;
        !            53:                for ( tvl = vl; tvl; tvl = NEXT(tvl) ) {
        !            54:                        reordvar(vl,tvl->v,&nvl);
        !            55:                        cont_pp_mv_sf(vl,NEXT(nvl),t,&c,&s); t = s;
        !            56:                        sqfrsf(vl,c,&dct);
        !            57:                        dc = append_dc(dc,NEXT(dct));
        !            58:                }
        !            59:                sqfrsfmain(vl,t,&dct);
        !            60:                dc = append_dc(dc,dct);
        !            61:        }
        !            62:        NEWDC(dct); DEG(dct) = ONE; COEF(dct) = (P)c; NEXT(dct) = dc;
        !            63:        *dcp = dct;
        !            64: }
        !            65:
        !            66: void sqfrsfmain(VL vl,P f,DCP *dcp)
        !            67: {
        !            68:        VL tvl;
        !            69:        DCP dc,dct,dcs;
        !            70:        P t,s;
        !            71:        Q m,m1;
        !            72:        V v;
        !            73:
        !            74:        clctv(vl,f,&tvl); vl = tvl;
        !            75:        dc = 0;
        !            76:        t = f;
        !            77:        for ( tvl = vl; tvl; tvl = NEXT(tvl) ) {
        !            78:                v = tvl->v;
        !            79:                partial_sqfrsf(vl,v,t,&s,&dct); t = s;
        !            80:                dc = append_dc(dc,dct);
        !            81:        }
        !            82:        if ( !NUM(t) ) {
        !            83:                STOQ(characteristic_sf(),m);
        !            84:                pthrootsf(t,m,&s);
        !            85:                sqfrsfmain(vl,s,&dct);
        !            86:                for ( dcs = dct; dcs; dcs = NEXT(dcs) ) {
        !            87:                        mulq(DEG(dcs),m,&m1); DEG(dcs) = m1;
        !            88:                }
        !            89:                dc = append_dc(dc,dct);
        !            90:        }
        !            91:        *dcp = dc;
        !            92: }
        !            93:
        !            94: void pthrootsf(P f,Q m,P *r)
        !            95: {
        !            96:        DCP dc,dc0,dct;
        !            97:        N qn,rn;
        !            98:
        !            99:        if ( NUM(f) )
        !           100:                pthrootgfs(f,r);
        !           101:        else {
        !           102:                dc = DC(f);
        !           103:                dc0 = 0;
        !           104:                for ( dc0 = 0; dc; dc = NEXT(dc) ) {
        !           105:                        NEXTDC(dc0,dct);
        !           106:                        pthrootsf(COEF(dc),m,&COEF(dct));
        !           107:                        if ( DEG(dc) ) {
        !           108:                                divn(NM(DEG(dc)),NM(m),&qn,&rn);
        !           109:                                if ( rn )
        !           110:                                        error("pthrootsf : cannot happen");
        !           111:                                NTOQ(qn,1,DEG(dct));
        !           112:                        } else
        !           113:                                DEG(dct) = 0;
        !           114:                }
        !           115:                NEXT(dct) = 0;
        !           116:                MKP(VR(f),dc0,*r);
        !           117:        }
        !           118: }
        !           119:
        !           120: void partial_sqfrsf(VL vl,V v,P f,P *r,DCP *dcp)
        !           121: {
        !           122:        P ps[2];
        !           123:        DCP dc0,dc;
        !           124:        int m;
        !           125:        P t,flat,flat1,g,df,q;
        !           126:
        !           127:        diffp(vl,f,v,&df);
        !           128:        if ( !df ) {
        !           129:                *dcp = 0;
        !           130:                *r = f;
        !           131:                return;
        !           132:        }
        !           133:        ps[0] = f; ps[1] = df;
        !           134:        gcdsf(vl,ps,2,&g);
        !           135:        divsp(vl,f,g,&flat);
        !           136:        m = 0;
        !           137:        t = f;
        !           138:        dc0 = 0;
        !           139:        while ( !NUM(flat) ) {
        !           140:                while ( divtp(vl,t,flat,&q) ) {
        !           141:                        t = q; m++;
        !           142:                }
        !           143:                ps[0] = t; ps[1] = flat;
        !           144:                gcdsf(vl,ps,2,&flat1);
        !           145:                divsp(vl,flat,flat1,&g);
        !           146:                flat = flat1;
        !           147:                NEXTDC(dc0,dc);
        !           148:                COEF(dc) = g;
        !           149:                STOQ(m,DEG(dc));
        !           150:        }
        !           151:        NEXT(dc) = 0;
        !           152:        *dcp = dc0;
        !           153:        *r = t;
        !           154: }
1.1       noro      155:
                    156: void gcdsf(VL vl,P *pa,int k,P *r)
                    157: {
1.3       noro      158:        P *ps,*pl,*pm;
                    159:        P **cp;
1.1       noro      160:        int *cn;
                    161:        DCP *ml;
                    162:        Obj obj;
                    163:        int i,j,l,m;
                    164:        P mg,mgsf,t;
                    165:        VL avl,nvl,tvl,svl;
                    166:
                    167:        ps = (P *)ALLOCA(k*sizeof(P));
                    168:        for ( i = 0, m = 0; i < k; i++ ) {
                    169:                simp_ff((Obj)pa[i],&obj);
                    170:                if ( obj )
1.3       noro      171:                        ps[m++] = (P)obj;
1.1       noro      172:        }
                    173:        if ( !m ) {
                    174:                *r = 0;
                    175:                return;
                    176:        }
                    177:        if ( m == 1 ) {
1.3       noro      178:                *r = ps[0];
1.1       noro      179:                return;
                    180:        }
                    181:        pl = (P *)ALLOCA(m*sizeof(P));
                    182:        ml = (DCP *)ALLOCA(m*sizeof(DCP));
                    183:        for ( i = 0; i < m; i++ )
                    184:                monomialfctr(vl,ps[i],&pl[i],&ml[i]);
1.3       noro      185:        gcdmonomial(vl,ml,m,&mg); simp_ff((Obj)mg,&obj); mgsf = (P)obj;
1.1       noro      186:        for ( i = 0, nvl = vl, avl = 0; nvl && i < m; i++ ) {
                    187:                clctv(vl,pl[i],&tvl);
                    188:                intersectv(nvl,tvl,&svl); nvl = svl;
                    189:                mergev(vl,avl,tvl,&svl); avl = svl;
                    190:        }
                    191:        if ( !nvl ) {
                    192:                *r = mgsf;
                    193:                return;
                    194:        }
                    195:        if ( !NEXT(avl) ) {
                    196:                ugcdsf(pl,m,&t);
                    197:                mulp(vl,mgsf,t,r);
                    198:                return;
                    199:        }
                    200:        for ( tvl = nvl, i = 0; tvl; tvl = NEXT(tvl), i++ );
                    201:        for ( tvl = avl, j = 0; tvl; tvl = NEXT(tvl), j++ );
                    202:        if ( i == j ) {
                    203:                /* all the pl[i]'s have the same variables */
                    204:                gcdsf_main(avl,pl,m,&t);
                    205:        } else {
                    206:                cp = (P **)ALLOCA(m*sizeof(P *));
                    207:                cn = (int *)ALLOCA(m*sizeof(int));
                    208:                for ( i = 0; i < m; i++ ) {
                    209:                        cp[i] = (P *)ALLOCA(lengthp(pl[i])*sizeof(P));
                    210:                        cn[i] = pcoef(vl,nvl,pl[i],cp[i]);
                    211:                }
                    212:                for ( i = j = 0; i < m; i++ )
                    213:                        j += cn[i];
                    214:                pm = (P *)ALLOCA(j*sizeof(P));
                    215:                for ( i = l = 0; i < m; i++ )
                    216:                        for ( j = 0; j < cn[i]; j++ )
                    217:                                pm[l++] = cp[i][j];
                    218:                gcdsf(vl,pm,l,&t);
                    219:        }
                    220:        mulp(vl,mgsf,t,r);
                    221: }
                    222:
                    223: /* univariate gcd */
                    224:
                    225: void ugcdsf(P *pa,int m,P *r)
                    226: {
1.3       noro      227:        P *ps;
1.1       noro      228:        int i;
                    229:        UM w1,w2,w3,w;
                    230:        int d;
                    231:        V v;
                    232:
                    233:        if ( m == 1 ) {
                    234:                *r = pa[0];
                    235:                return;
                    236:        }
1.3       noro      237:        for ( i = 0; i < m; i++ )
                    238:                if ( NUM(pa[i]) ) {
                    239:                        itogfs(1,r);
                    240:                        return;
                    241:                }
1.1       noro      242:        ps = (P *)ALLOCA(m*sizeof(P));
                    243:        sort_by_deg(m,pa,ps);
1.3       noro      244:        v = VR(ps[m-1]);
                    245:        d = getdeg(v,ps[m-1]);
1.1       noro      246:        w1 = W_UMALLOC(d);
                    247:        w2 = W_UMALLOC(d);
                    248:        w3 = W_UMALLOC(d);
                    249:        ptosfum(ps[0],w1);
                    250:        for ( i = 1; i < m; i++ ) {
                    251:                ptosfum(ps[i],w2);
                    252:                gcdsfum(w1,w2,w3);
                    253:                w = w1; w1 = w3; w3 = w;
                    254:                if ( !DEG(w1) ) {
1.3       noro      255:                        itogfs(1,r);
1.1       noro      256:                        return;
                    257:                }
                    258:        }
                    259:        sfumtop(v,w1,r);
                    260: }
                    261:
1.4     ! noro      262: /* deg(HT(p),v), where p is considered as distributed poly over F[v] */
        !           263: int gethdeg(VL vl,V v,P p)
        !           264: {
        !           265:        DCP dc;
        !           266:        Q dmax;
        !           267:        P cmax;
        !           268:
        !           269:        if ( !p )
        !           270:                return -1;
        !           271:        else if ( NUM(p) )
        !           272:                return 0;
        !           273:        else if ( VR(p) != v )
        !           274:                /* HT(p) = HT(lc(p))*x^D */
        !           275:                return gethdeg(vl,v,COEF(DC(p)));
        !           276:        else {
        !           277:                /* VR(p) = v */
        !           278:                dc = DC(p); dmax = DEG(dc); cmax = COEF(dc);
        !           279:                for ( dc = NEXT(dc); dc; dc = NEXT(dc) )
        !           280:                        if ( compp(vl,COEF(dc),cmax) > 0 ) {
        !           281:                                dmax = DEG(dc); cmax = COEF(dc);
        !           282:                        }
        !           283:                return QTOS(dmax);
        !           284:        }
        !           285: }
1.1       noro      286:
                    287: /* all the pa[i]'s have the same variables (=vl) */
                    288:
                    289: void gcdsf_main(VL vl,P *pa,int m,P *r)
                    290: {
1.3       noro      291:        int nv,i,i0,imin,d,d0,d1,d2,dmin,index;
                    292:        V v,v0,vmin;
1.2       noro      293:        VL tvl,nvl,rvl,nvl0,rvl0;
1.3       noro      294:        P *pc, *ps, *ph,*lps;
                    295:        P x,t,cont,hg,g,hm,mod,s;
                    296:        P hge,ge,ce,he,u,cof1e,mode,mod1,adj,cof1,coadj,q;
                    297:        GFS sf;
1.2       noro      298:
1.1       noro      299:        for ( nv = 0, tvl = vl; tvl; tvl = NEXT(tvl), nv++);
                    300:        if ( nv == 1 ) {
                    301:                ugcdsf(pa,m,r);
                    302:                return;
                    303:        }
1.4     ! noro      304:        /* find v s.t. min(deg(pa[i],v)+gethdeg(pa[i],v)) is minimal */
1.1       noro      305:        tvl = vl;
                    306:        do {
                    307:                v = tvl->v;
                    308:                i = 0;
                    309:                do {
1.4     ! noro      310:                        d = getdeg(v,pa[i])+gethdeg(vl,v,pa[i]);
1.1       noro      311:                        if ( i == 0 || (d < d0) ) {
                    312:                                d0 = d; i0 = i; v0 = v;
                    313:                        }
                    314:                } while ( ++i < m );
                    315:                if ( tvl == vl || (d0 < dmin) ) {
                    316:                        dmin = d0; imin = i0; vmin = v0;
                    317:                }
                    318:        } while ( tvl = NEXT(tvl) );
                    319:
                    320:        /* reorder variables so that vmin is the last variable */
                    321:        for ( nvl0 = 0, rvl0 = 0, tvl = vl; tvl; tvl = NEXT(tvl) )
                    322:                if ( tvl->v != vmin ) {
                    323:                        NEXTVL(nvl0,nvl); nvl->v = tvl->v;
                    324:                        NEXTVL(rvl0,rvl); rvl->v = tvl->v;
                    325:                }
                    326:        /* rvl = remaining variables */
1.3       noro      327:        NEXT(rvl) = 0; rvl = rvl0;
1.1       noro      328:        /* nvl = ...,vmin */
1.3       noro      329:        NEXTVL(nvl0,nvl); nvl->v = vmin; NEXT(nvl) = 0; nvl = nvl0;
1.2       noro      330:        MKV(vmin,x);
1.1       noro      331:
                    332:        /* for content and primitive part */
                    333:        pc = (P *)ALLOCA(m*sizeof(P));
                    334:        ps = (P *)ALLOCA(m*sizeof(P));
                    335:        ph = (P *)ALLOCA(m*sizeof(P));
                    336:        /* separate the contents */
                    337:        for ( i = 0; i < m; i++ ) {
1.3       noro      338:                reorderp(nvl,vl,pa[i],&t);
1.1       noro      339:                cont_pp_mv_sf(nvl,rvl,t,&pc[i],&ps[i]);
                    340:                head_monomial(vmin,ps[i],&ph[i],&t);
                    341:        }
                    342:        ugcdsf(pc,m,&cont);
                    343:        ugcdsf(ph,m,&hg);
                    344:
                    345:        /* for hg*pp (used in check phase) */
                    346:        lps = (P *)ALLOCA(m*sizeof(P));
                    347:        for ( i = 0; i < m; i++ )
                    348:                mulp(nvl,hg,ps[i],&lps[i]);
                    349:
                    350:        while ( 1 ) {
                    351:                g = 0;
1.3       noro      352:                cof1 = 0;
1.1       noro      353:                hm = 0;
1.3       noro      354:                itogfs(1,&mod);
1.1       noro      355:                index = 0;
1.3       noro      356:                for ( index = 0; getdeg(vmin,mod) <= d+1; index++ ) {
1.1       noro      357:                        /* evaluation pt */
1.3       noro      358:                        indextogfs(index,&s);
1.1       noro      359:                        substp(nvl,hg,vmin,s,&hge);
                    360:                        if ( !hge )
                    361:                                continue;
                    362:                        for ( i = 0; i < m; i++ )
                    363:                                substp(nvl,ps[i],vmin,s,&ph[i]);
                    364:                        /* ge = GCD(ps[0]|x=s,...,ps[m-1]|x=s) */
                    365:                        gcdsf(nvl,ph,m,&ge);
                    366:                        head_monomial(vmin,ge,&ce,&he);
1.3       noro      367:                        if ( NUM(he) ) {
1.1       noro      368:                                *r = cont;
                    369:                                return;
                    370:                        }
1.3       noro      371:                        divgfs((GFS)hge,(GFS)ce,&sf); t = (P)sf;
                    372:                        mulp(nvl,t,ge,&u); ge = u;
1.1       noro      373:                        divsp(nvl,ph[imin],ge,&t); mulp(nvl,hge,t,&cof1e);
1.2       noro      374:                        /* hm=0 : reset; he==hm : lucky */
1.3       noro      375:                        if ( !hm || !compp(nvl,he,hm) ) {
1.2       noro      376:                                substp(nvl,mod,vmin,s,&mode); divsp(nvl,mod,mode,&mod1);
                    377:                                /* adj = mod/(mod|x=s)*(ge-g|x=s) */
                    378:                                substp(nvl,g,vmin,s,&t);
                    379:                                subp(nvl,ge,t,&u); mulp(nvl,mod1,u,&adj);
                    380:                                /* coadj = mod/(mod|vmin=s)*(cof1e-cof1e|vmin=s) */
                    381:                                substp(nvl,cof1,vmin,s,&t);
1.3       noro      382:                                subp(nvl,cof1e,t,&u); mulp(nvl,mod1,u,&coadj);
1.2       noro      383:                                if ( !adj ) {
                    384:                                        /* adj == gcd ? */
                    385:                                        for ( i = 0; i < m; i++ )
1.3       noro      386:                                                if ( !divtp(nvl,lps[i],g,&t) )
1.2       noro      387:                                                        break;
                    388:                                        if ( i == m ) {
1.3       noro      389:                                                cont_pp_mv_sf(nvl,rvl,g,&t,&u);
1.2       noro      390:                                                mulp(nvl,cont,u,&t);
1.3       noro      391:                                                reorderp(vl,nvl,t,r);
1.2       noro      392:                                                return;
                    393:                                        }
                    394:                                } else if ( !coadj ) {
1.3       noro      395:                                        /* ps[imin]/coadj == gcd ? */
                    396:                                        if ( divtp(nvl,lps[imin],cof1,&q) ) {
1.2       noro      397:                                                for ( i = 0; i < m; i++ )
                    398:                                                        if ( !divtp(nvl,lps[i],q,&t) )
                    399:                                                                break;
                    400:                                                if ( i == m ) {
                    401:                                                        cont_pp_mv_sf(nvl,rvl,q,&t,&u);
                    402:                                                        mulp(nvl,cont,u,&t);
1.3       noro      403:                                                        reorderp(vl,nvl,t,r);
1.2       noro      404:                                                        return;
                    405:                                                }
                    406:                                        }
                    407:                                }
                    408:                                addp(nvl,g,adj,&t); g = t;
                    409:                                addp(nvl,cof1,coadj,&t); cof1 = t;
                    410:                                subp(nvl,x,s,&t); mulp(nvl,mod,t,&u); mod = u;
                    411:                                hm = he;
                    412:                        } else {
                    413:                                d1 = homdeg(hm); d2 = homdeg(he);
                    414:                                if ( d1 < d2 ) /* we use current hm */
                    415:                                        continue;
                    416:                                else if ( d1 > d2 ) {
                    417:                                        /* use he */
                    418:                                        g = ge;
                    419:                                        cof1 = cof1e;
                    420:                                        hm = he;
                    421:                                        subp(nvl,x,s,&mod);
                    422:                                } else {
                    423:                                        /* d1==d2, but hm!=he => both are unlucky */
                    424:                                        g = 0;
                    425:                                        cof1 = 0;
1.3       noro      426:                                        itogfs(1,&mod);
1.2       noro      427:                                }
1.1       noro      428:                        }
                    429:                }
                    430:        }
                    431: }
                    432:
                    433: void head_monomial(V v,P p,P *coef,P *term)
                    434: {
                    435:        P t,s,u;
                    436:        DCP dc;
                    437:        GFS one;
1.3       noro      438:        VL vl;
1.1       noro      439:
1.3       noro      440:        itogfs(1,&one);
                    441:        t = (P)one;
1.1       noro      442:        while ( 1 ) {
                    443:                if ( NUM(p) || VR(p) == v ) {
                    444:                        *coef = p;
                    445:                        *term = t;
                    446:                        return;
                    447:                } else {
1.3       noro      448:                        NEWDC(dc);
                    449:                        COEF(dc) = (P)one; DEG(dc) = DEG(DC(p));
1.1       noro      450:                        MKP(VR(p),dc,s);
                    451:                        mulp(vl,t,s,&u); t = u;
                    452:                        p = COEF(DC(p));
                    453:                }
                    454:        }
                    455: }
                    456:
                    457: void cont_pp_mv_sf(VL vl,VL rvl,P p,P *c,P *pp)
                    458: {
                    459:        DP dp;
                    460:        MP t;
                    461:        int i,m;
                    462:        P *ps;
                    463:
                    464:        ptod(vl,rvl,p,&dp);
                    465:        for ( t = BDY(dp), m = 0; t; t = NEXT(t), m++ );
                    466:        ps = (P *)ALLOCA(m*sizeof(P));
1.3       noro      467:        for ( t = BDY(dp), i = 0; t; t = NEXT(t), i++ )
1.1       noro      468:                ps[i] = C(t);
                    469:        ugcdsf(ps,m,c);
1.3       noro      470:        divsp(vl,p,*c,pp);
1.1       noro      471: }

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