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

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

1.1     ! noro        1: /* $OpenXM$ */
        !             2:
        !             3: #include "ca.h"
        !             4:
        !             5: struct p_pair {
        !             6:        UM p0;
        !             7:        UM p1;
        !             8:        struct p_pair *next;
        !             9: };
        !            10:
        !            11: void canzassf(UM,int,UM *);
        !            12: void lnfsf(int,UM,UM,struct p_pair *,UM,UM);
        !            13: void minipolysf(UM,UM,UM);
        !            14: void czsfum(UM,UM *);
        !            15: void gensqfrsfum(UM,DUM);
        !            16:
        !            17: void fctrsf(p,dcp)
        !            18: P p;
        !            19: DCP *dcp;
        !            20: {
        !            21:        int n,i,j,k;
        !            22:        DCP dc,dc0;
        !            23:        P lc;
        !            24:        P zp;
        !            25:        UM mp;
        !            26:        UM *tl;
        !            27:        struct oDUM *udc,*udc1;
        !            28:
        !            29:        simp_ff(p,&zp); p = zp;
        !            30:        if ( !p ) {
        !            31:                *dcp = 0; return;
        !            32:        }
        !            33:        mp = W_UMALLOC(UDEG(p));
        !            34:        ptosfum(p,mp);
        !            35:        if ( (n = DEG(mp)) < 0 ) {
        !            36:                *dcp = 0; return;
        !            37:        } else if ( n == 0 ) {
        !            38:                NEWDC(dc); COEF(dc) = p; DEG(dc) = ONE;
        !            39:                NEXT(dc) = 0; *dcp = dc;
        !            40:                return;
        !            41:        }
        !            42:        lc = COEF(DC(p));
        !            43:        if ( !_isonesf(COEF(mp)[n]) ) {
        !            44:                monicsfum(mp);
        !            45:        }
        !            46:
        !            47:        W_CALLOC(n+1,struct oDUM,udc);
        !            48:        gensqfrsfum(mp,udc);
        !            49:
        !            50:        tl = (UM *)ALLOCA((n+1)*sizeof(UM));
        !            51:        W_CALLOC(DEG(mp)+1,struct oDUM,udc1);
        !            52:
        !            53:        for ( i = 0,j = 0; udc[i].f; i++ )
        !            54:                if ( DEG(udc[i].f) == 1 ) {
        !            55:                        udc1[j].f = udc[i].f; udc1[j].n = udc[i].n; j++;
        !            56:                } else {
        !            57:                        bzero((char *)tl,(n+1)*sizeof(UM));
        !            58:                        czsfum(udc[i].f,tl);
        !            59:                        for ( k = 0; tl[k]; k++, j++ ) {
        !            60:                                udc1[j].f = tl[k]; udc1[j].n = udc[i].n;
        !            61:                        }
        !            62:                }
        !            63:        udc = udc1;
        !            64:        NEWDC(dc0); COEF(dc0) = lc; DEG(dc0) = ONE; dc = dc0;
        !            65:        for ( n = 0; udc[n].f; n++ ) {
        !            66:                NEWDC(NEXT(dc)); dc = NEXT(dc);
        !            67:                STOQ(udc[n].n,DEG(dc)); sfumtop(VR(p),udc[n].f,&COEF(dc));
        !            68:        }
        !            69:        NEXT(dc) = 0; *dcp = dc0;
        !            70: }
        !            71:
        !            72: void gensqfrsfum(p,dc)
        !            73: UM p;
        !            74: struct oDUM *dc;
        !            75: {
        !            76:        int n,i,j,d,mod;
        !            77:        UM t,s,g,f,f1,b;
        !            78:
        !            79:        if ( (n = DEG(p)) == 1 ) {
        !            80:                dc[0].f = UMALLOC(DEG(p)); cpyum(p,dc[0].f); dc[0].n = 1;
        !            81:                return;
        !            82:        }
        !            83:        t = W_UMALLOC(n); s = W_UMALLOC(n); g = W_UMALLOC(n);
        !            84:        f = W_UMALLOC(n); f1 = W_UMALLOC(n); b = W_UMALLOC(n);
        !            85:        diffsfum(p,t); cpyum(p,s); gcdsfum(t,s,g);
        !            86:        if ( !DEG(g) ) {
        !            87:                dc[0].f = UMALLOC(DEG(p)); cpyum(p,dc[0].f); dc[0].n = 1;
        !            88:                return;
        !            89:        }
        !            90:        cpyum(p,b); cpyum(p,t); divsfum(t,g,f);
        !            91:        for ( i = 0, d = 0; DEG(f); i++ ) {
        !            92:                while ( 1 ) {
        !            93:                        cpyum(b,t);
        !            94:                        if ( divsfum(t,f,s) >= 0 )
        !            95:                                break;
        !            96:                        else {
        !            97:                                cpyum(s,b); d++;
        !            98:                        }
        !            99:                }
        !           100:                cpyum(b,t); cpyum(f,s); gcdsfum(t,s,f1);
        !           101:                divsfum(f,f1,s); cpyum(f1,f);
        !           102:                dc[i].f = UMALLOC(DEG(s)); cpyum(s,dc[i].f); dc[i].n = d;
        !           103:        }
        !           104:        mod = characteristic_sf();
        !           105:        if ( DEG(b) > 0 ) {
        !           106:                d = 1;
        !           107:                while ( 1 ) {
        !           108:                        cpyum(b,t);
        !           109:                        for ( j = DEG(t); j >= 0; j-- )
        !           110:                                if ( COEF(t)[j] && (j % mod) )
        !           111:                                        break;
        !           112:                        if ( j >= 0 )
        !           113:                                break;
        !           114:                        else {
        !           115:                                DEG(s) = DEG(t)/mod;
        !           116:                                for ( j = 0; j <= DEG(t); j++ )
        !           117:                                        COEF(s)[j] = COEF(t)[j*mod];
        !           118:                                cpyum(s,b); d *= mod;
        !           119:                        }
        !           120:                }
        !           121:                gensqfrsfum(b,dc+i);
        !           122:                for ( j = i; dc[j].f; j++ )
        !           123:                        dc[j].n *= d;
        !           124:        }
        !           125: }
        !           126:
        !           127: void randsfum(d,p)
        !           128: int d;
        !           129: UM p;
        !           130: {
        !           131:        unsigned int n;
        !           132:        int i;
        !           133:
        !           134:        n = ((unsigned int)random()) % d; DEG(p) = n; COEF(p)[n] = _onesf();
        !           135:        for ( i = 0; i < (int)n; i++ )
        !           136:                COEF(p)[i] = _randomsf();
        !           137: }
        !           138:
        !           139: void pwrmodsfum(p,e,f,pr)
        !           140: int e;
        !           141: UM p,f,pr;
        !           142: {
        !           143:        UM wt,ws,q;
        !           144:
        !           145:        if ( e == 0 ) {
        !           146:                DEG(pr) = 0; COEF(pr)[0] = _onesf();
        !           147:        } else if ( DEG(p) < 0 )
        !           148:                DEG(pr) = -1;
        !           149:        else if ( e == 1 ) {
        !           150:                q = W_UMALLOC(DEG(p)); cpyum(p,pr);
        !           151:                DEG(pr) = divsfum(pr,f,q);
        !           152:        } else if ( DEG(p) == 0 ) {
        !           153:                DEG(pr) = 0; COEF(pr)[0] = _pwrsf(COEF(p)[0],e);
        !           154:        } else {
        !           155:                wt = W_UMALLOC(2*DEG(f)); ws = W_UMALLOC(2*DEG(f));
        !           156:                q = W_UMALLOC(2*DEG(f));
        !           157:                pwrmodsfum(p,e/2,f,wt);
        !           158:                if ( !(e%2) )  {
        !           159:                        mulsfum(wt,wt,pr); DEG(pr) = divsfum(pr,f,q);
        !           160:                } else {
        !           161:                        mulsfum(wt,wt,ws);
        !           162:                        DEG(ws) = divsfum(ws,f,q);
        !           163:                        mulsfum(ws,p,pr);
        !           164:                        DEG(pr) = divsfum(pr,f,q);
        !           165:                }
        !           166:        }
        !           167: }
        !           168:
        !           169: void spwrum0sf(m,f,e,r)
        !           170: UM f,m,r;
        !           171: N e;
        !           172: {
        !           173:        UM t,s,q;
        !           174:        N e1;
        !           175:        int a;
        !           176:
        !           177:        if ( !e ) {
        !           178:                DEG(r) = 0; COEF(r)[0] = _onesf();
        !           179:        } else if ( UNIN(e) )
        !           180:                cpyum(f,r);
        !           181:        else {
        !           182:                a = divin(e,2,&e1);
        !           183:                t = W_UMALLOC(2*DEG(m)); spwrum0sf(m,f,e1,t);
        !           184:                s = W_UMALLOC(2*DEG(m)); q = W_UMALLOC(2*DEG(m));
        !           185:                mulsfum(t,t,s); DEG(s) = divsfum(s,m,q);
        !           186:                if ( a ) {
        !           187:                        mulsfum(s,f,t); DEG(t) = divsfum(t,m,q); cpyum(t,r);
        !           188:         } else
        !           189:                        cpyum(s,r);
        !           190:        }
        !           191: }
        !           192:
        !           193: void make_qmatsf(p,tab,mp)
        !           194: UM p;
        !           195: UM *tab;
        !           196: int ***mp;
        !           197: {
        !           198:        int n,i,j;
        !           199:        int *c;
        !           200:        UM q,r;
        !           201:        int **mat;
        !           202:        int one;
        !           203:
        !           204:        n = DEG(p);
        !           205:        *mp = mat = almat(n,n);
        !           206:        for ( j = 0; j < n; j++ ) {
        !           207:                r = W_UMALLOC(DEG(tab[j])); q = W_UMALLOC(DEG(tab[j]));
        !           208:                cpyum(tab[j],r); DEG(r) = divsfum(r,p,q);
        !           209:                for ( i = 0, c = COEF(r); i <= DEG(r); i++ )
        !           210:                        mat[i][j] = c[i];
        !           211:        }
        !           212:        one = _onesf();
        !           213:        for ( i = 0; i < n; i++ )
        !           214:                mat[i][i] = _subsf(mat[i][i],one);
        !           215: }
        !           216:
        !           217: void nullsf(mat,n,ind)
        !           218: int **mat;
        !           219: int *ind;
        !           220: int n;
        !           221: {
        !           222:        int i,j,l,s,h,inv;
        !           223:        int *t,*u;
        !           224:
        !           225:        bzero((char *)ind,n*sizeof(int));
        !           226:        ind[0] = 0;
        !           227:        for ( i = j = 0; j < n; i++, j++ ) {
        !           228:                for ( ; j < n; j++ ) {
        !           229:                        for ( l = i; l < n; l++ )
        !           230:                                if ( mat[l][j] )
        !           231:                                        break;
        !           232:                        if ( l < n ) {
        !           233:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
        !           234:                        } else
        !           235:                                ind[j] = 1;
        !           236:                }
        !           237:                if ( j == n )
        !           238:                        break;
        !           239:                inv = _invsf(mat[i][j]);
        !           240:                for ( s = j, t = mat[i]; s < n; s++ )
        !           241:                        t[s] = _mulsf(t[s],inv);
        !           242:                for ( l = 0; l < n; l++ ) {
        !           243:                        if ( l == i )
        !           244:                                continue;
        !           245:                        u = mat[l]; h = _chsgnsf(u[j]);
        !           246:                        for ( s = j; s < n; s++ )
        !           247:                                u[s] = _addsf(_mulsf(h,t[s]),u[s]);
        !           248:                }
        !           249:        }
        !           250: }
        !           251:
        !           252: void null_to_solsf(mat,ind,n,r)
        !           253: int **mat;
        !           254: int *ind;
        !           255: int n;
        !           256: UM *r;
        !           257: {
        !           258:        int i,j,k,l;
        !           259:        int *c;
        !           260:        UM w;
        !           261:
        !           262:        for ( i = 0, l = 0; i < n; i++ ) {
        !           263:                if ( !ind[i] )
        !           264:                        continue;
        !           265:                w = UMALLOC(n);
        !           266:                for ( j = k = 0, c = COEF(w); j < n; j++ )
        !           267:                        if ( ind[j] )
        !           268:                                c[j] = 0;
        !           269:                        else
        !           270:                                c[j] = mat[k++][i];
        !           271:                c[i] = _chsgnsf(_onesf());
        !           272:                for ( j = n; j >= 0; j-- )
        !           273:                        if ( c[j] )
        !           274:                                break;
        !           275:                DEG(w) = j;
        !           276:                r[l++] = w;
        !           277:        }
        !           278: }
        !           279: /*
        !           280: make_qmatsf(p,tab,mp)
        !           281: nullsf(mat,n,ind)
        !           282: null_to_solsf(ind,n,r)
        !           283: */
        !           284:
        !           285: void czsfum(f,r)
        !           286: UM f,*r;
        !           287: {
        !           288:        int i,j;
        !           289:        int d,n,ord;
        !           290:        UM s,t,u,v,w,g,x,m,q;
        !           291:        UM *base;
        !           292:
        !           293:        n = DEG(f); base = (UM *)ALLOCA(n*sizeof(UM));
        !           294:        bzero((char *)base,n*sizeof(UM));
        !           295:
        !           296:        w = W_UMALLOC(2*n); q = W_UMALLOC(2*n); m = W_UMALLOC(2*n);
        !           297:
        !           298:        base[0] = W_UMALLOC(0); DEG(base[0]) = 0; COEF(base[0])[0] = _onesf();
        !           299:
        !           300:        t = W_UMALLOC(1); DEG(t) = 1; COEF(t)[0] = 0; COEF(t)[1] = _onesf();
        !           301:
        !           302:        ord = field_order_sf();
        !           303:        pwrmodsfum(t,ord,f,w);
        !           304:        base[1] = W_UMALLOC(DEG(w));
        !           305:        cpyum(w,base[1]);
        !           306:
        !           307:        for ( i = 2; i < n; i++ ) {
        !           308:                mulsfum(base[i-1],base[1],m);
        !           309:                DEG(m) = divsfum(m,f,q);
        !           310:                base[i] = W_UMALLOC(DEG(m)); cpyum(m,base[i]);
        !           311:        }
        !           312:
        !           313:        v = W_UMALLOC(n); cpyum(f,v);
        !           314:        DEG(w) = 1; COEF(w)[0] = 0; COEF(w)[1] = _onesf();
        !           315:        x = W_UMALLOC(1); DEG(x) = 1; COEF(x)[0] = 0; COEF(x)[1] = _onesf();
        !           316:        t = W_UMALLOC(n); s = W_UMALLOC(n); u = W_UMALLOC(n); g = W_UMALLOC(n);
        !           317:
        !           318:        for ( j = 0, d = 1; 2*d <= DEG(v); d++ ) {
        !           319:                for ( DEG(t) = -1, i = 0; i <= DEG(w); i++ )
        !           320:                        if ( COEF(w)[i] ) {
        !           321:                                mulssfum(base[i],COEF(w)[i],s);
        !           322:                                addsfum(s,t,u); cpyum(u,t);
        !           323:                        }
        !           324:                cpyum(t,w); cpyum(v,s); subsfum(w,x,t);
        !           325:                gcdsfum(s,t,g);
        !           326:                if ( DEG(g) >= 1 ) {
        !           327:                        berlekampsf(g,d,base,r+j); j += DEG(g)/d;
        !           328:                        divsfum(v,g,q); cpyum(q,v);
        !           329:                        DEG(w) = divsfum(w,v,q);
        !           330:                        for ( i = 0; i < DEG(v); i++ )
        !           331:                                DEG(base[i]) = divsfum(base[i],v,q);
        !           332:                }
        !           333:        }
        !           334:        if ( DEG(v) ) {
        !           335:                r[j] = UMALLOC(DEG(v)); cpyum(v,r[j]); j++;
        !           336:        }
        !           337:        r[j] = 0;
        !           338: }
        !           339:
        !           340: int berlekampsf(p,df,tab,r)
        !           341: UM p;
        !           342: int df;
        !           343: UM *tab,*r;
        !           344: {
        !           345:        int n,i,j,k,nf,d,nr;
        !           346:        int **mat;
        !           347:        int *ind;
        !           348:        UM mp,w,q,gcd,w1,w2;
        !           349:        UM *u;
        !           350:        int *root;
        !           351:
        !           352:        n = DEG(p);
        !           353:        ind = ALLOCA(n*sizeof(int));
        !           354:        make_qmatsf(p,tab,&mat);
        !           355:        nullsf(mat,n,ind);
        !           356:        for ( i = 0, d = 0; i < n; i++ )
        !           357:                if ( ind[i] )
        !           358:                        d++;
        !           359:        if ( d == 1 ) {
        !           360:                r[0] = UMALLOC(n); cpyum(p,r[0]); return 1;
        !           361:        }
        !           362:        u = ALLOCA(d*sizeof(UM *));
        !           363:        r[0] = UMALLOC(n); cpyum(p,r[0]);
        !           364:        null_to_solsf(mat,ind,n,u);
        !           365:        root = ALLOCA(d*sizeof(int));
        !           366:        w = W_UMALLOC(n); mp = W_UMALLOC(d);
        !           367:        w1 = W_UMALLOC(n); w2 = W_UMALLOC(n);
        !           368:        for ( i = 1, nf = 1; i < d; i++ ) {
        !           369:                minipolysf(u[i],p,mp);
        !           370:                nr = find_rootsf(mp,root);
        !           371:                for ( j = 0; j < nf; j++ ) {
        !           372:                        if ( DEG(r[j]) == df )
        !           373:                                continue;
        !           374:                        for ( k = 0; k < nr; k++ ) {
        !           375:                                cpyum(u[i],w1); cpyum(r[j],w2);
        !           376:                                COEF(w1)[0] = _chsgnsf(root[k]);
        !           377:                                gcdsfum(w1,w2,w);
        !           378:                                if ( DEG(w) > 0 && DEG(w) < DEG(r[j]) ) {
        !           379:                                        gcd = UMALLOC(DEG(w));
        !           380:                                        q = UMALLOC(DEG(r[j])-DEG(w));
        !           381:                                        cpyum(w,gcd); divsfum(r[j],w,q);
        !           382:                                        r[j] = q; r[nf++] = gcd;
        !           383:                                }
        !           384:                                if ( nf == d )
        !           385:                                        return d;
        !           386:                        }
        !           387:                }
        !           388:        }
        !           389: }
        !           390:
        !           391: void minipolysf(f,p,mp)
        !           392: UM f,p,mp;
        !           393: {
        !           394:        struct p_pair *list,*l,*l1,*lprev;
        !           395:        int n,d;
        !           396:        UM u,p0,p1,np0,np1,q,w;
        !           397:
        !           398:        list = (struct p_pair *)MALLOC(sizeof(struct p_pair));
        !           399:        list->p0 = u = W_UMALLOC(0); DEG(u) = 0; COEF(u)[0] = _onesf();
        !           400:        list->p1 = W_UMALLOC(0); cpyum(list->p0,list->p1);
        !           401:        list->next = 0;
        !           402:        n = DEG(p); w = UMALLOC(2*n);
        !           403:        p0 = UMALLOC(2*n); cpyum(list->p0,p0);
        !           404:        p1 = UMALLOC(2*n); cpyum(list->p1,p1);
        !           405:        q = W_UMALLOC(2*n);
        !           406:        while ( 1 ) {
        !           407:                COEF(p0)[DEG(p0)] = 0; DEG(p0)++; COEF(p0)[DEG(p0)] = _onesf();
        !           408:                mulsfum(f,p1,w); DEG(w) = divsfum(w,p,q); cpyum(w,p1);
        !           409:                np0 = UMALLOC(n); np1 = UMALLOC(n);
        !           410:                lnfsf(n,p0,p1,list,np0,np1);
        !           411:                if ( DEG(np1) < 0 ) {
        !           412:                        cpyum(np0,mp); return;
        !           413:                } else {
        !           414:                        l1 = (struct p_pair *)MALLOC(sizeof(struct p_pair));
        !           415:                        l1->p0 = np0; l1->p1 = np1;
        !           416:                        for ( l = list, lprev = 0, d = DEG(np1);
        !           417:                                l && (DEG(l->p1) > d); lprev = l, l = l->next );
        !           418:                        if ( lprev ) {
        !           419:                                lprev->next = l1; l1->next = l;
        !           420:                        } else {
        !           421:                                l1->next = list; list = l1;
        !           422:                        }
        !           423:                }
        !           424:        }
        !           425: }
        !           426:
        !           427: void lnfsf(n,p0,p1,list,np0,np1)
        !           428: int n;
        !           429: UM p0,p1;
        !           430: struct p_pair *list;
        !           431: UM np0,np1;
        !           432: {
        !           433:        int inv,h,d1;
        !           434:        UM t0,t1,s0,s1;
        !           435:        struct p_pair *l;
        !           436:
        !           437:        cpyum(p0,np0); cpyum(p1,np1);
        !           438:        t0 = W_UMALLOC(n); t1 = W_UMALLOC(n);
        !           439:        s0 = W_UMALLOC(n); s1 = W_UMALLOC(n);
        !           440:        for ( l = list; l; l = l->next ) {
        !           441:                d1 = DEG(np1);
        !           442:                if ( d1 == DEG(l->p1) ) {
        !           443:                        h = _divsf(COEF(np1)[d1],_chsgnsf(COEF(l->p1)[d1]));
        !           444:                        mulssfum(l->p0,h,t0); addsfum(np0,t0,s0); cpyum(s0,np0);
        !           445:                        mulssfum(l->p1,h,t1); addsfum(np1,t1,s1); cpyum(s1,np1);
        !           446:                }
        !           447:        }
        !           448: }
        !           449:
        !           450: int find_rootsf(p,root)
        !           451: UM p;
        !           452: int *root;
        !           453: {
        !           454:        UM *r;
        !           455:        int i,j,n;
        !           456:
        !           457:        n = DEG(p);
        !           458:        r = ALLOCA((DEG(p))*sizeof(UM));
        !           459:        canzassf(p,1,r);
        !           460:        for ( i = 0; i < n; i++ )
        !           461:                root[i] = _chsgnsf(COEF(r[i])[0]);
        !           462:        return n;
        !           463: }
        !           464:
        !           465: void canzassf(f,d,r)
        !           466: UM f,*r;
        !           467: int d;
        !           468: {
        !           469:        UM t,s,u,w,g,o;
        !           470:        N n1,n2,n3,n4,n5;
        !           471:        UM *b;
        !           472:        int n,m,i,q;
        !           473:
        !           474:        if ( DEG(f) == d ) {
        !           475:                r[0] = UMALLOC(d); cpyum(f,r[0]);
        !           476:                return;
        !           477:        } else {
        !           478:                n = DEG(f); b = (UM *)ALLOCA(n*sizeof(UM));
        !           479:                bzero((char *)b,n*sizeof(UM));
        !           480:
        !           481:                t = W_UMALLOC(2*d);
        !           482:                s = W_UMALLOC(DEG(f)); u = W_UMALLOC(DEG(f));
        !           483:                w = W_UMALLOC(DEG(f)); g = W_UMALLOC(DEG(f));
        !           484:                o = W_UMALLOC(0); DEG(o) = 0; COEF(o)[0] = _onesf();
        !           485:                q = field_order_sf();
        !           486:                STON(q,n1); pwrn(n1,d,&n2); subn(n2,ONEN,&n3);
        !           487:                STON(2,n4); divsn(n3,n4,&n5);
        !           488:                while ( 1 ) {
        !           489:                        randsfum(2*d,t); spwrum0sf(f,t,n5,s);
        !           490:                        subsfum(s,o,u); cpyum(f,w); gcdsfum(w,u,g);
        !           491:                        if ( (DEG(g) >= 1) && (DEG(g) < DEG(f)) ) {
        !           492:                                canzassf(g,d,r);
        !           493:                                cpyum(f,w); divsfum(w,g,s);
        !           494:                                canzassf(s,d,r+DEG(g)/d);
        !           495:                                return;
        !           496:                        }
        !           497:                }
        !           498:        }
        !           499: }
        !           500:

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