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

Annotation of OpenXM_contrib2/asir2000/builtin/gf.c, Revision 1.15

1.3       noro        1: /*
                      2:  * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
                      3:  * All rights reserved.
                      4:  *
                      5:  * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
                      6:  * non-exclusive and royalty-free license to use, copy, modify and
                      7:  * redistribute, solely for non-commercial and non-profit purposes, the
                      8:  * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
                      9:  * conditions of this Agreement. For the avoidance of doubt, you acquire
                     10:  * only a limited right to use the SOFTWARE hereunder, and FLL or any
                     11:  * third party developer retains all rights, including but not limited to
                     12:  * copyrights, in and to the SOFTWARE.
                     13:  *
                     14:  * (1) FLL does not grant you a license in any way for commercial
                     15:  * purposes. You may use the SOFTWARE only for non-commercial and
                     16:  * non-profit purposes only, such as academic, research and internal
                     17:  * business use.
                     18:  * (2) The SOFTWARE is protected by the Copyright Law of Japan and
                     19:  * international copyright treaties. If you make copies of the SOFTWARE,
                     20:  * with or without modification, as permitted hereunder, you shall affix
                     21:  * to all such copies of the SOFTWARE the above copyright notice.
                     22:  * (3) An explicit reference to this SOFTWARE and its copyright owner
                     23:  * shall be made on your publication or presentation in any form of the
                     24:  * results obtained by use of the SOFTWARE.
                     25:  * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.4       noro       26:  * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.3       noro       27:  * for such modification or the source code of the modified part of the
                     28:  * SOFTWARE.
                     29:  *
                     30:  * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
                     31:  * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
                     32:  * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
                     33:  * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
                     34:  * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
                     35:  * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
                     36:  * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
                     37:  * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
                     38:  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
                     39:  * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
                     40:  * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
                     41:  * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
                     42:  * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
                     43:  * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
                     44:  * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
                     45:  * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
                     46:  * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
                     47:  *
1.15    ! noro       48:  * $OpenXM: OpenXM_contrib2/asir2000/builtin/gf.c,v 1.14 2001/10/09 01:36:06 noro Exp $
1.3       noro       49: */
1.1       noro       50: #include "ca.h"
                     51: #include "parse.h"
                     52:
                     53: struct resf_dlist {
                     54:        int ib,id;
                     55: };
                     56:
                     57: int resf_degtest(int,int *,int,struct resf_dlist *);
                     58: void uhensel(P,NODE,int,int,NODE *);
1.15    ! noro       59: void uhensel_incremental(P,NODE,int,int,int,NODE *);
1.1       noro       60: void resf_hensel(int,P,int,P *,ML *);
                     61: void resf_dtest(P,ML,int,int *,int *,DCP *);
                     62: void resf_dtest_special(P,ML,int,int *,int *,DCP *);
                     63: void dtest_special(P,ML,P *);
                     64: void hensel_special(int,int,P,P *,ML *);
                     65:
                     66: void nullspace(UM **,UM,int,int,int *);
                     67: void nullspace_lm(LM **,int,int *);
                     68: void nullspace_gf2n(GF2N **,int,int *);
                     69: void nullspace_gfpn(GFPN **,int,int *);
1.5       noro       70: void nullspace_gfs(GFS **,int,int *);
1.12      noro       71: void nullspace_gfsn(GFSN **,int,int *);
1.1       noro       72: void null_to_sol(int **,int *,int,int,UM *);
                     73:
                     74: void showgfmat(UM **,int);
                     75: void pwr_mod(P,P,V,P,int,N,P *);
                     76: void rem_mod(P,P,V,P,int,P *);
                     77:
                     78: void Pnullspace(),Pgcda_mod(),Pftest(),Presfmain(),Ppwr_mod(),Puhensel();
1.15    ! noro       79: void Puhensel_incremental();
1.6       noro       80: void Psfuhensel();
1.1       noro       81:
                     82: void Pnullspace_ff();
                     83:
                     84: void Psolve_linear_equation_gf2n();
                     85: void Plinear_form_to_vect(),Pvect_to_linear_form();
                     86:
                     87: void solve_linear_equation_gf2n(GF2N **,int,int,int *);
                     88: void linear_form_to_array(P,VL,int,Num *);
                     89: void array_to_linear_form(Num *,VL,int,P *);
1.9       noro       90: void sfuhensel(P,NODE,GFS,int,NODE *);
1.1       noro       91:
                     92: extern int current_ff;
                     93:
                     94: struct ftab gf_tab[] = {
                     95:        {"solve_linear_equation_gf2n",Psolve_linear_equation_gf2n,1},
                     96:        {"nullspace",Pnullspace,3},
                     97:        {"nullspace_ff",Pnullspace_ff,1},
                     98: /*     {"gcda_mod",Pgcda_mod,5}, */
                     99:        {"ftest",Pftest,2},
                    100:        {"resfmain",Presfmain,4},
                    101:        {"pwr_mod",Ppwr_mod,6},
                    102:        {"uhensel",Puhensel,4},
1.15    ! noro      103:        {"uhensel_incremental",Puhensel_incremental,5},
1.9       noro      104:        {"sfuhensel",Psfuhensel,4},
1.1       noro      105:        {0,0,0},
                    106: };
                    107:
                    108: int resf_degtest(k,in,nb,dlist)
                    109: int k;
                    110: int *in;
                    111: int nb;
                    112: struct resf_dlist *dlist;
                    113: {
                    114:        int i,d0,d;
                    115:        int dl_i;
                    116:        struct resf_dlist *t;
                    117:
                    118:        if ( k < nb )
                    119:                return 0;
                    120:        if ( nb == 1 )
                    121:                return 1;
                    122:        d0 = 0; d = 0; dl_i = 0;
                    123:        for ( i = 0; i < k; i++ ) {
                    124:                t = &dlist[in[i]];
                    125:                if ( t->ib > dl_i + 1 )
                    126:                        return 0;
                    127:                else if ( t->ib == dl_i )
                    128:                        d += t->id;
                    129:                else if ( !d || (dl_i && d0 != d) )
                    130:                        return 0;
                    131:                else {
                    132:                        d0 = d; dl_i++; d = t->id;
                    133:                }
                    134:        }
                    135:        if ( dl_i != nb - 1 || d0 != d )
                    136:                return 0;
                    137:        else
                    138:                return 1;
                    139: }
                    140:
                    141: void Puhensel(arg,rp)
                    142: NODE arg;
                    143: LIST *rp;
                    144: {
                    145:        P f;
                    146:        NODE mfl,r;
                    147:        int mod,bound;
                    148:
                    149:        f = (P)ARG0(arg);
                    150:        mfl = BDY((LIST)ARG1(arg));
                    151:        mod = QTOS((Q)ARG2(arg));
                    152:        bound = QTOS((Q)ARG3(arg));
                    153:        uhensel(f,mfl,mod,bound,&r);
                    154:        MKLIST(*rp,r);
                    155: }
                    156:
1.15    ! noro      157: void Puhensel_incremental(arg,rp)
        !           158: NODE arg;
        !           159: LIST *rp;
        !           160: {
        !           161:        P f;
        !           162:        NODE mfl,r;
        !           163:        int mod,bound,start;
        !           164:
        !           165:        f = (P)ARG0(arg);
        !           166:        mfl = BDY((LIST)ARG1(arg));
        !           167:        mod = QTOS((Q)ARG2(arg));
        !           168:        start = QTOS((Q)ARG3(arg));
        !           169:        bound = QTOS((Q)ARG4(arg));
        !           170:        uhensel_incremental(f,mfl,mod,start,bound,&r);
        !           171:        MKLIST(*rp,r);
        !           172: }
        !           173:
1.1       noro      174: void uhensel(f,mfl,mod,bound,rp)
                    175: P f;
                    176: NODE mfl;
                    177: int mod,bound;
                    178: NODE *rp;
                    179: {
                    180:        ML blist,clist,rlist;
                    181:        LUM fl;
                    182:        int nf,i;
                    183:        P s;
                    184:        V v;
                    185:        NODE t,top;
                    186:
                    187:        nf = length(mfl);
                    188:        blist = MLALLOC(nf); blist->n = nf; blist->mod = mod;
                    189:        for ( i = 0, t = mfl; i < nf; i++, t = NEXT(t) ) {
                    190:                blist->c[i] = (pointer)UMALLOC(UDEG((P)BDY(t)));
                    191:                ptoum(mod,(P)BDY(t),blist->c[i]);
                    192:        }
                    193:        gcdgen(f,blist,&clist);
                    194:        blist->bound = clist->bound = bound;
                    195:        W_LUMALLOC((int)UDEG(f),bound,fl);
                    196:        ptolum(mod,bound,f,fl);
                    197:        henmain(fl,blist,clist,&rlist);
                    198:        v = VR(f);
                    199:        for ( i = nf-1, top = 0; i >= 0; i-- ) {
                    200:                lumtop(v,mod,bound,rlist->c[i],&s);
1.15    ! noro      201:                MKNODE(t,s,top); top = t;
        !           202:        }
        !           203:        *rp = top;
        !           204: }
        !           205:
        !           206: void uhensel_incremental(f,mfl,mod,start,bound,rp)
        !           207: P f;
        !           208: NODE mfl;
        !           209: int mod,start,bound;
        !           210: NODE *rp;
        !           211: {
        !           212:        ML blist,clist,rlist;
        !           213:        LUM fl;
        !           214:        LUM *lblist;
        !           215:        int nf,i,j,k;
        !           216:        int **p;
        !           217:        P s;
        !           218:        V v;
        !           219:        NODE t,top;
        !           220:
        !           221:        nf = length(mfl);
        !           222:        blist = MLALLOC(nf); blist->n = nf; blist->mod = mod;
        !           223:        lblist = (LUM *)MALLOC(nf*sizeof(LUM));
        !           224:        for ( i = 0, t = mfl; i < nf; i++, t = NEXT(t) ) {
        !           225:                blist->c[i] = (pointer)UMALLOC(UDEG((P)BDY(t)));
        !           226:                ptoum(mod,(P)BDY(t),blist->c[i]);
        !           227:                W_LUMALLOC((int)UDEG((P)BDY(t)),bound,lblist[i]);
        !           228:                ptolum(mod,start,(P)BDY(t),lblist[i]);
        !           229:                p = lblist[i]->c;
        !           230:                for ( j = DEG(lblist[i]); j >= 0; j-- )
        !           231:                        for ( k = start; k < bound; k++ )
        !           232:                                p[j][k] = 0;
        !           233:        }
        !           234:        gcdgen(f,blist,&clist);
        !           235:        clist->bound = bound;
        !           236:        W_LUMALLOC((int)UDEG(f),bound,fl);
        !           237:        ptolum(mod,bound,f,fl);
        !           238:        henmain_incremental(fl,lblist,clist,nf,mod,start,bound);
        !           239:        v = VR(f);
        !           240:        for ( i = nf-1, top = 0; i >= 0; i-- ) {
        !           241:                lumtop_unsigned(v,mod,bound,lblist[i],&s);
1.1       noro      242:                MKNODE(t,s,top); top = t;
1.6       noro      243:        }
                    244:        *rp = top;
                    245: }
                    246:
                    247: void Psfuhensel(arg,rp)
                    248: NODE arg;
                    249: LIST *rp;
                    250: {
                    251:        P f;
1.9       noro      252:        int bound;
                    253:        NODE r,mfl;
1.8       noro      254:        GFS ev;
1.6       noro      255:
                    256:        f = (P)ARG0(arg);
1.9       noro      257:        mfl = BDY((LIST)ARG1(arg));
                    258:        ev = (GFS)ARG2(arg);
                    259:        bound = QTOS((Q)ARG3(arg));
                    260:        sfuhensel(f,mfl,ev,bound,&r);
                    261:        MKLIST(*rp,r);
1.6       noro      262: }
                    263:
1.9       noro      264: void sfuhensel(f,mfl,ev,bound,rp)
1.6       noro      265: P f;
1.9       noro      266: NODE mfl;
                    267: GFS ev;
                    268: int bound;
1.6       noro      269: NODE *rp;
                    270: {
1.9       noro      271:        BM fl;
                    272:        BM *r;
                    273:        VL vl,nvl;
1.13      noro      274:        int i,fn,dx,dy,d;
1.6       noro      275:        NODE t,top;
1.9       noro      276:        UM fm,hm,q;
                    277:        UM *gm;
                    278:        V x,y;
                    279:        P g,s,u;
                    280:
                    281:        clctv(CO,f,&vl);
                    282:        if ( !vl || !vl->next || vl->next->next )
                    283:                error("sfuhensel : f must be a bivariate poly");
1.8       noro      284:
1.9       noro      285:        for ( i = 0, t = mfl; t; i++, t = NEXT(t) );
                    286:        fn = i;
1.8       noro      287:
1.9       noro      288:        gm = (UM *)MALLOC(fn*sizeof(UM));
                    289:
                    290:        /* XXX : more severe check is necessary */
                    291:        x = VR((P)BDY(mfl));
                    292:        y = vl->v == x ? vl->next->v : vl->v;
                    293:
1.13      noro      294:        for ( i = 0, t = mfl, d = 0; i < fn; i++, t = NEXT(t) ) {
1.9       noro      295:                gm[i] = (pointer)UMALLOC(getdeg(x,(P)BDY(t)));
                    296:                ptosfum((P)BDY(t),gm[i]);
1.13      noro      297:                d += DEG(gm[i]);
1.9       noro      298:        }
                    299:
                    300:        /* reorder f if necessary */
                    301:        if ( vl->v != x ) {
                    302:                reordvar(vl,x,&nvl); reorderp(nvl,vl,f,&g);
                    303:                vl = nvl; f = g;
                    304:        }
                    305:        dx = getdeg(x,f);
1.13      noro      306:        if ( dx != d )
                    307:                error("sfuhensel : product of factors has incompatible degree");
                    308:
1.9       noro      309:        dy = getdeg(y,f);
1.10      noro      310:        dy = MAX(dy,bound);
                    311:        fl = BMALLOC(dx,dy);
                    312:        ptosfbm(dy,f,fl);
1.11      noro      313:        if ( ev ) shiftsfbm(fl,FTOIF(CONT(ev)));
1.9       noro      314:
                    315:        /* fm = fl mod y */
                    316:        fm = W_UMALLOC(dx);
                    317:        cpyum(COEF(fl)[0],fm);
                    318:        hm = W_UMALLOC(dx);
                    319:
                    320:        q = W_UMALLOC(dx);
                    321:        r = (BM *)MLALLOC(fn*sizeof(BM));
                    322:        for ( i = 0; i < fn-1; i++ ) {
                    323:                /* fl = gm[i]*hm mod y */
                    324:                divsfum(fm,gm[i],hm);
                    325:                /* fl is replaced by the cofactor of gk mod y^bound */
                    326:                /* r[i] = gk */
                    327:                sfhenmain2(fl,gm[i],hm,bound,r+i);
                    328:                cpyum(hm,fm);
                    329:        }
                    330:        /* finally, fl must be the lift of gm[fn-1] */
                    331:        r[i] = fl;
1.6       noro      332:
1.9       noro      333:        for ( i = fn-1, top = 0; i >= 0; i-- ) {
1.10      noro      334:                sfbmtop(r[i],x,y,&s);
1.9       noro      335:                reorderp(CO,vl,s,&u);
1.8       noro      336:                MKNODE(t,u,top); top = t;
1.1       noro      337:        }
                    338:        *rp = top;
                    339: }
                    340:
                    341: void Presfmain(arg,rp)
                    342: NODE arg;
                    343: LIST *rp;
                    344: {
                    345:        P f;
                    346:        int mod,n,nb,i,j,k;
                    347:        int *nf,*md;
                    348:        P *mf;
                    349:        NODE mfl,mdl,t,s,u;
                    350:        ML list;
                    351:        DCP dc;
                    352:        int sflag;
                    353:
                    354:        f = (P)ARG0(arg);
                    355:        mod = QTOS((Q)ARG1(arg));
                    356:        mfl = BDY((LIST)ARG2(arg));
                    357:        mdl = BDY((LIST)ARG3(arg));
                    358:        for ( n = nb = 0, t = mfl; t; nb++, t = NEXT(t) )
                    359:                for ( s = BDY((LIST)BDY(t)); s; n++, s = NEXT(s) );
                    360:        if ( n == nb ) {
                    361:                /* f must be irreducible! */
                    362:                NEWDC(dc);
                    363:                dc->c = f; dc->d = ONE;
                    364:        } else {
                    365:                nf = W_ALLOC(nb); md = W_ALLOC(nb); mf = (P *)ALLOCA(n*sizeof(P));
                    366:                for ( k = i = 0, t = mfl, u = mdl, sflag = 1; t;
                    367:                        i++, t = NEXT(t), u = NEXT(u) ) {
                    368:                        if ( sflag && length(BDY((LIST)BDY(t))) != 2 )
                    369:                                sflag = 0;
                    370:                        for ( j = 0, s = BDY((LIST)BDY(t)); s; j++, s = NEXT(s) )
                    371:                                mf[k++] = (P)BDY(s);
                    372:                        nf[i] = j; md[i] = QTOS((Q)BDY(u));
                    373:                }
                    374:                resf_hensel(mod,f,n,mf,&list);
                    375:                if ( sflag )
                    376:                        resf_dtest_special(f,list,nb,nf,md,&dc);
                    377:                else
                    378:                        resf_dtest(f,list,nb,nf,md,&dc);
                    379:        }
                    380:        dcptolist(dc,rp);
                    381: }
                    382:
                    383: void resf_hensel(mod,f,nf,mfl,listp)
                    384: int mod;
                    385: P f;
                    386: int nf;
                    387: P *mfl;
                    388: ML *listp;
                    389: {
                    390:        register int i,j;
1.2       noro      391:        int q,n,bound,inv,lc;
1.1       noro      392:        int *p;
                    393:        int **pp;
                    394:        ML blist,clist,bqlist,cqlist,rlist;
                    395:        UM *b;
                    396:        LUM fl,tl;
                    397:        LUM *l;
1.2       noro      398:        UM w;
1.1       noro      399:
1.2       noro      400:        w = W_UMALLOC(UDEG(f));
1.1       noro      401:        blist = MLALLOC(nf); blist->n = nf; blist->mod = mod;
1.2       noro      402:
                    403:        /* c[0] must have lc(f) */
                    404:        blist->c[0] = (pointer)UMALLOC(UDEG(mfl[0]));
                    405:        ptoum(mod,mfl[0],w);
                    406:        inv = invm(w->c[UDEG(mfl[0])],mod);
                    407:        lc = rem(NM((Q)LC(f)),mod);
                    408:        if ( SGN((Q)LC(f)) < 0 )
                    409:                lc = (mod-lc)%mod;
                    410:        lc = dmar(inv,lc,0,mod);
                    411:        if ( lc == 1 )
                    412:                copyum(w,blist->c[0]);
                    413:        else
                    414:                mulsum(mod,w,lc,blist->c[0]);
                    415:
                    416:        /* c[i] (i=1,...,nf-1) must be monic */
                    417:        for ( i = 1; i < nf; i++ ) {
1.1       noro      418:                blist->c[i] = (pointer)UMALLOC(UDEG(mfl[i]));
1.2       noro      419:                ptoum(mod,mfl[i],w);
                    420:                inv = invm(w->c[UDEG(mfl[i])],mod);
                    421:                if ( inv == 1 )
                    422:                        copyum(w,blist->c[i]);
                    423:                else
                    424:                        mulsum(mod,w,inv,blist->c[i]);
1.1       noro      425:        }
1.2       noro      426:
1.1       noro      427:        gcdgen(f,blist,&clist); henprep(f,blist,clist,&bqlist,&cqlist);
                    428:        n = bqlist->n; q = bqlist->mod;
                    429:        bqlist->bound = cqlist->bound = bound = mignotte(q,f);
                    430:        if ( bound == 1 ) {
                    431:                *listp = rlist = MLALLOC(n);
                    432:                rlist->n = n; rlist->mod = q; rlist->bound = bound;
                    433:                for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c; i < n; i++ ) {
                    434:                        tl = LUMALLOC(DEG(b[i]),1); l[i] = tl; p = COEF(b[i]);
                    435:                        for ( j = 0, pp = COEF(tl); j <= DEG(tl); j++ )
                    436:                                        pp[j][0] = p[j];
                    437:                }
                    438:        } else {
                    439:                W_LUMALLOC((int)UDEG(f),bound,fl);
                    440:                ptolum(q,bound,f,fl); henmain(fl,bqlist,cqlist,listp);
                    441:        }
                    442: }
                    443:
                    444: void resf_dtest(f,list,nb,nfl,mdl,dcp)
                    445: P f;
                    446: ML list;
                    447: int nb;
                    448: int *nfl,*mdl;
                    449: DCP *dcp;
                    450: {
                    451:        int n,np,bound,q;
                    452:        int i,j,k;
                    453:        int *win;
                    454:        P g,factor,cofactor;
                    455:        Q csum,csumt;
                    456:        DCP dcf,dcf0;
                    457:        LUM *c;
                    458:        ML wlist;
                    459:        struct resf_dlist *dlist;
                    460:        int z;
                    461:
                    462:        n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
                    463:        win = W_ALLOC(np+1);
                    464:        ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
                    465:        wlist = W_MLALLOC(np); wlist->n = list->n;
                    466:        wlist->mod = list->mod; wlist->bound = list->bound;
                    467:        c = (LUM *)COEF(wlist);
                    468:        bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
                    469:        dlist = (struct resf_dlist *)ALLOCA(np*sizeof(struct resf_dlist));
                    470:        for ( i = 0, j = 0; j < nb; j++ )
                    471:                for ( k = 0; k < nfl[j]; k++, i++ ) {
                    472:                        dlist[i].ib = j; dlist[i].id = DEG(c[i])/mdl[j];
                    473:                }
                    474:        k = nb;
                    475:        for ( i = 0; i < nb; i++ )
                    476:                win[i] = i+1;
                    477:        for ( g = f, dcf = dcf0 = 0, --np, z = 0; ; ) {
                    478: #if 0
                    479:                if ( !(z++ % 10000) )
                    480:                        fputc('.',stderr);
                    481: #endif
                    482:                if ( resf_degtest(k,win,nb,dlist) &&
                    483:                        dtestmain(g,csum,wlist,k,win,&factor,&cofactor) ) {
                    484:                        NEXTDC(dcf0,dcf); DEG(dcf) = ONE; COEF(dcf) = factor;
                    485:                        g = cofactor;
                    486:                        ucsump(g,&csum); mulq(csum,(Q)COEF(DC(g)),&csumt); csum = csumt;
                    487:                        for ( i = 0; i < k - 1; i++ )
                    488:                                for ( j = win[i] + 1; j < win[i + 1]; j++ ) {
                    489:                                        c[j-i-1] = c[j];
                    490:                                        dlist[j-i-1] = dlist[j];
                    491:                                }
                    492:                        for ( j = win[k-1] + 1; j <= np; j++ ) {
                    493:                                c[j-k] = c[j];
                    494:                                dlist[j-k] = dlist[j];
                    495:                        }
                    496:                        if ( ( np -= k ) < k )
                    497:                                break;
                    498:                        if ( np - win[0] + 1 < k )
                    499:                                if ( ++k > np )
                    500:                                        break;
                    501:                                else
                    502:                                        for ( i = 0; i < k; i++ )
                    503:                                                win[i] = i + 1;
                    504:                        else
                    505:                                for ( i = 1; i < k; i++ )
                    506:                                        win[i] = win[0] + i;
                    507:                } else if ( !ncombi(1,np,k,win) )
                    508:                        if ( k == np )
                    509:                                break;
                    510:                        else
                    511:                                for ( i = 0, ++k; i < k; i++ )
                    512:                                        win[i] = i + 1;
                    513:        }
                    514:        NEXTDC(dcf0,dcf); COEF(dcf) = g;
                    515:        DEG(dcf) = ONE; NEXT(dcf) = 0;*dcp = dcf0;
                    516: }
                    517:
                    518: void resf_dtest_special(f,list,nb,nfl,mdl,dcp)
                    519: P f;
                    520: ML list;
                    521: int nb;
                    522: int *nfl,*mdl;
                    523: DCP *dcp;
                    524: {
                    525:        int n,np,bound,q;
                    526:        int i,j;
                    527:        int *win;
                    528:        P g,factor,cofactor;
                    529:        Q csum,csumt;
                    530:        DCP dcf,dcf0;
                    531:        LUM *c;
                    532:        ML wlist;
                    533:        int max;
                    534:
                    535:        n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
                    536:        win = W_ALLOC(np+1);
                    537:        ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
                    538:        wlist = W_MLALLOC(np); wlist->n = list->n;
                    539:        wlist->mod = list->mod; wlist->bound = list->bound;
                    540:        c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
                    541:        max = 1<<nb;
                    542:        for ( g = f, dcf = dcf0 = 0, i = 0; i < max; i++ ) {
                    543: #if 0
                    544:                if ( !(i % 1000) )
                    545:                        fprintf(stderr,"i=%d\n",i);
                    546: #endif
                    547:                for ( j = 0; j < nb; j++ )
                    548:                        win[j] = (i&(1<<j)) ? 2*j+1 : 2*j;
                    549:                if ( dtestmain(g,csum,wlist,nb,win,&factor,&cofactor) ) {
                    550: #if 0
                    551:                        fprintf(stderr,"success : i=%d\n",i);
                    552: #endif
                    553:                        NEXTDC(dcf0,dcf); DEG(dcf) = ONE; COEF(dcf) = factor;
                    554:                        NEXTDC(dcf0,dcf); DEG(dcf) = ONE; COEF(dcf) = cofactor;
                    555:                        NEXT(dcf) = 0;*dcp = dcf0;
                    556:                        return;
                    557:                }
                    558:        }
                    559:        NEXTDC(dcf0,dcf); COEF(dcf) = g;
                    560:        DEG(dcf) = ONE; NEXT(dcf) = 0;*dcp = dcf0;
                    561: }
                    562:
                    563: #if 0
                    564: void Pftest(arg,rp)
                    565: NODE arg;
                    566: P *rp;
                    567: {
                    568:        ML list;
                    569:        DCP dc;
                    570:        P p;
                    571:        P *mfl;
                    572:
                    573:        p = (P)ARG0(arg); mfl = (P *)(((VECT)ARG1(arg))->body);
                    574:        hensel_special(4,1,p,mfl,&list);
                    575:        dtest_special(p,list,rp);
                    576: }
                    577:
                    578: void dtest_special(f,list,pr)
                    579: P f;
                    580: ML list;
                    581: P *pr;
                    582: {
                    583:        int n,np,bound,q;
                    584:        int i,j,k;
                    585:        int *win;
                    586:        P g,factor,cofactor;
                    587:        Q csum,csumt;
                    588:        DCP dc,dcf,dcf0;
                    589:        LUM *c;
                    590:        ML wlist;
                    591:
                    592:        n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
                    593:        win = W_ALLOC(np+1);
                    594:        ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
                    595:        wlist = W_MLALLOC(np); wlist->n = list->n;
                    596:        wlist->mod = list->mod; wlist->bound = list->bound;
                    597:        c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
                    598:        for ( g = f, i = 130000; i < (1<<20); i++ ) {
                    599: #if 0
                    600:                if ( !(i % 1000) )
                    601:                        fprintf(stderr,"i=%d\n",i);
                    602: #endif
                    603:                for ( j = 0; j < 20; j++ )
                    604:                        win[j] = (i&(1<<j)) ? 2*j+1 : 2*j;
                    605:                if ( dtestmain(g,csum,wlist,20,win,&factor,&cofactor) ) {
                    606: #if 0
                    607:                        fprintf(stderr,"success : i=%d\n",i);
                    608: #endif
                    609:                        *pr = factor; return;
                    610:                }
                    611:        }
                    612: }
                    613:
                    614: void hensel_special(index,count,f,mfl,listp)
                    615: int index,count;
                    616: P f;
                    617: P *mfl;
                    618: ML *listp;
                    619: {
                    620:        register int i,j;
                    621:        int q,n,t,d,r,u,br,tmp,bound;
                    622:        int *c,*p,*m,*w;
                    623:        int **pp;
                    624:        DCP dc;
                    625:        ML blist,clist,bqlist,cqlist,rlist;
                    626:        UM *b;
                    627:        LUM fl,tl;
                    628:        LUM *l;
                    629:
                    630:        blist = MLALLOC(40); blist->n = 40; blist->mod = 11;
                    631:        for ( i = 0; i < 40; i++ ) {
                    632:                blist->c[i] = (pointer)UMALLOC(6);
                    633:                ptoum(11,mfl[i],blist->c[i]);
                    634:        }
                    635:        gcdgen(f,blist,&clist); henprep(f,blist,clist,&bqlist,&cqlist);
                    636:        n = bqlist->n; q = bqlist->mod;
                    637:        bqlist->bound = cqlist->bound = bound = mignotte(q,f);
                    638:        if ( bound == 1 ) {
                    639:                *listp = rlist = MLALLOC(n);
                    640:                rlist->n = n; rlist->mod = q; rlist->bound = bound;
                    641:                for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c; i < n; i++ ) {
                    642:                        tl = LUMALLOC(DEG(b[i]),1); l[i] = tl; p = COEF(b[i]);
                    643:                        for ( j = 0, pp = COEF(tl); j <= DEG(tl); j++ )
                    644:                                        pp[j][0] = p[j];
                    645:                }
                    646:        } else {
                    647:                W_LUMALLOC(UDEG(f),bound,fl);
                    648:                ptolum(q,bound,f,fl); henmain(fl,bqlist,cqlist,listp);
                    649:        }
                    650: }
                    651: #endif
                    652:
                    653: #if 0
                    654: void Pftest(arg,rp)
                    655: NODE arg;
                    656: P *rp;
                    657: {
                    658:        ML list;
                    659:        DCP dc;
                    660:        P p;
                    661:        P *mfl;
                    662:
                    663:        p = (P)ARG0(arg); mfl = (P *)(((VECT)ARG1(arg))->body);
                    664:        hensel_special(2,1,p,mfl,&list);
                    665:        dtest_special(p,list,rp);
                    666: }
                    667:
                    668: void dtest_special(f,list,pr)
                    669: P f;
                    670: ML list;
                    671: P *pr;
                    672: {
                    673:        int n,np,bound,q;
                    674:        int i,j,k,t,b0;
                    675:        int *win;
                    676:        P g,factor,cofactor;
                    677:        Q csum,csumt;
                    678:        DCP dc,dcf,dcf0;
                    679:        LUM *c;
                    680:        ML wlist;
                    681:        static int nbits[16] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
                    682:
                    683:        n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
                    684:        win = W_ALLOC(np+1);
                    685:        ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
                    686:        wlist = W_MLALLOC(np); wlist->n = list->n;
                    687:        wlist->mod = list->mod; wlist->bound = list->bound;
                    688:        c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
                    689:        for ( g = f, i = 0; i < (1<<23); i++ ) {
                    690: #if 0
                    691:                if ( !(i % 1000) )
                    692:                fprintf(stderr,"i=%d\n",i);
                    693: #endif
                    694:                t = i>>20; b0 = nbits[t];
                    695:                if ( !b0 )
                    696:                        continue;
                    697:                for ( j = 1; j < 6; j++ ) {
                    698:                        t = (i>>(20-4*j))&0xf;
                    699:                        if ( nbits[t] != b0 )
                    700:                                break;
                    701:                }
                    702:                if ( j != 6 )
                    703:                        continue;
                    704:                for ( j = k = 0; j < 24; j++ )
                    705:                        if ( i & (1<<(23-j)) )
                    706:                                win[k++] = j;
                    707:                if ( dtestmain(g,csum,wlist,k,win,&factor,&cofactor) ) {
                    708: #if 0
                    709:                        fprintf(stderr,"success : i=%d\n",i);
                    710: #endif
                    711:                        *pr = factor; return;
                    712:                }
                    713:        }
                    714:        *pr = f;
                    715: }
                    716:
                    717: void hensel_special(index,count,f,mfl,listp)
                    718: int index,count;
                    719: P f;
                    720: P *mfl;
                    721: ML *listp;
                    722: {
                    723:        register int i,j;
                    724:        int q,n,t,d,r,u,br,tmp,bound;
                    725:        int *c,*p,*m,*w;
                    726:        int **pp;
                    727:        DCP dc;
                    728:        ML blist,clist,bqlist,cqlist,rlist;
                    729:        UM *b;
                    730:        LUM fl,tl;
                    731:        LUM *l;
                    732:
                    733:        blist = MLALLOC(24); blist->n = 24; blist->mod = 5;
                    734:        for ( i = 0; i < 24; i++ ) {
                    735:                blist->c[i] = (pointer)UMALLOC(7);
                    736:                ptoum(5,mfl[i],blist->c[i]);
                    737:        }
                    738:        gcdgen(f,blist,&clist); henprep(f,blist,clist,&bqlist,&cqlist);
                    739:        n = bqlist->n; q = bqlist->mod;
                    740:        bqlist->bound = cqlist->bound = bound = mignotte(q,f);
                    741:        if ( bound == 1 ) {
                    742:                *listp = rlist = MLALLOC(n);
                    743:                rlist->n = n; rlist->mod = q; rlist->bound = bound;
                    744:                for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c; i < n; i++ ) {
                    745:                        tl = LUMALLOC(DEG(b[i]),1); l[i] = tl; p = COEF(b[i]);
                    746:                        for ( j = 0, pp = COEF(tl); j <= DEG(tl); j++ )
                    747:                                        pp[j][0] = p[j];
                    748:                }
                    749:        } else {
                    750:                W_LUMALLOC(UDEG(f),bound,fl);
                    751:                ptolum(q,bound,f,fl); henmain(fl,bqlist,cqlist,listp);
                    752:        }
                    753: }
                    754: #endif
                    755:
                    756: void Pftest(arg,rp)
                    757: NODE arg;
                    758: P *rp;
                    759: {
                    760:        ML list;
                    761:        P p;
                    762:        P *mfl;
                    763:
                    764:        p = (P)ARG0(arg); mfl = (P *)(((VECT)ARG1(arg))->body);
                    765:        hensel_special(5,1,p,mfl,&list);
                    766:        dtest_special(p,list,rp);
                    767: }
                    768:
                    769: int nbits(a)
                    770: int a;
                    771: {
                    772:        int i,s;
                    773:
                    774:        for ( i = 0, s = 0; a && (i < 20); i++, a >>= 1 )
                    775:                if ( a & 1 ) s++;
                    776:        return s;
                    777: }
                    778:
                    779: void dtest_special(f,list,pr)
                    780: P f;
                    781: ML list;
                    782: P *pr;
                    783: {
                    784:        int n,np,bound,q;
                    785:        int i,j,k,b0;
                    786:        int *win;
                    787:        P g,factor,cofactor;
                    788:        Q csum,csumt;
                    789:        LUM *c;
                    790:        ML wlist;
                    791:
                    792:        n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
                    793:        win = W_ALLOC(np+1);
                    794:        ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
                    795:        wlist = W_MLALLOC(np); wlist->n = list->n;
                    796:        wlist->mod = list->mod; wlist->bound = list->bound;
                    797:        c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
                    798:        for ( g = f, i = 0; i < (1<<19); i++ ) {
                    799: #if 0
                    800:                if ( !(i % 10000) )
                    801:                fprintf(stderr,"i=%d\n",i);
                    802: #endif
                    803:                b0 = nbits(i>>10);
                    804:                if ( !b0 || (nbits(i&0x3ff) != b0) )
                    805:                        continue;
                    806:                for ( j = k = 0; j < 20; j++ )
                    807:                        if ( i & (1<<(19-j)) )
                    808:                                win[k++] = j;
                    809:                if ( dtestmain(g,csum,wlist,k,win,&factor,&cofactor) ) {
                    810: #if 0
                    811:                        fprintf(stderr,"success : i=%d\n",i);
                    812: #endif
                    813:                        *pr = factor; return;
                    814:                }
                    815:        }
                    816:        *pr = f;
                    817: }
                    818:
                    819: void hensel_special(index,count,f,mfl,listp)
                    820: int index,count;
                    821: P f;
                    822: P *mfl;
                    823: ML *listp;
                    824: {
                    825:        register int i,j;
                    826:        int q,n,bound;
                    827:        int *p;
                    828:        int **pp;
                    829:        ML blist,clist,bqlist,cqlist,rlist;
                    830:        UM *b;
                    831:        LUM fl,tl;
                    832:        LUM *l;
                    833:
                    834:        blist = MLALLOC(20); blist->n = 20; blist->mod = 11;
                    835:        for ( i = 0; i < 20; i++ ) {
                    836:                blist->c[i] = (pointer)UMALLOC(10);
                    837:                ptoum(11,mfl[i],blist->c[i]);
                    838:        }
                    839:        gcdgen(f,blist,&clist); henprep(f,blist,clist,&bqlist,&cqlist);
                    840:        n = bqlist->n; q = bqlist->mod;
                    841:        bqlist->bound = cqlist->bound = bound = mignotte(q,f);
                    842:        if ( bound == 1 ) {
                    843:                *listp = rlist = MLALLOC(n);
                    844:                rlist->n = n; rlist->mod = q; rlist->bound = bound;
                    845:                for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c; i < n; i++ ) {
                    846:                        tl = LUMALLOC(DEG(b[i]),1); l[i] = tl; p = COEF(b[i]);
                    847:                        for ( j = 0, pp = COEF(tl); j <= DEG(tl); j++ )
                    848:                                        pp[j][0] = p[j];
                    849:                }
                    850:        } else {
                    851:                W_LUMALLOC((int)UDEG(f),bound,fl);
                    852:                ptolum(q,bound,f,fl); henmain(fl,bqlist,cqlist,listp);
                    853:        }
                    854: }
                    855:
                    856: void Pnullspace(arg,rp)
                    857: NODE arg;
                    858: LIST *rp;
                    859: {
                    860:        int i,j,n,mod;
                    861:        MAT mat,r;
                    862:        VECT u;
                    863:        V v;
                    864:        P p,z;
                    865:        Q q;
                    866:        UM **w;
                    867:        UM mp;
                    868:        P *t;
                    869:        UM *s;
                    870:        int *ind;
                    871:        NODE n0,n1;
                    872:
                    873:        mat = (MAT)ARG0(arg);
                    874:        p = (P)ARG1(arg);
                    875:        v = VR(p);
                    876:        mod = QTOS((Q)ARG2(arg));
                    877:        n = mat->row;
                    878:        w = (UM **)almat_pointer(n,n);
                    879:        for ( i = 0; i < n; i++ )
                    880:                for ( j = 0, t = (P *)mat->body[i], s = w[i]; j < n; j++ ) {
                    881:                        ptomp(mod,t[j],&z);
                    882:                        s[j] = W_UMALLOC((z&&!NUM(z))?UDEG(z):0);
                    883:                        mptoum(z,s[j]);
                    884:                }
                    885:        mp = W_UMALLOC(UDEG(p)); ptoum(mod,p,mp);
                    886:        ind = (int *)ALLOCA(n*sizeof(int));
                    887:        nullspace(w,mp,mod,n,ind);
                    888:        MKMAT(r,n,n);
                    889:        for ( i = 0; i < n; i++ )
                    890:                for ( j = 0, t = (P *)r->body[i], s = w[i]; j < n; j++ )
                    891:                        umtop(v,s[j],&t[j]);
                    892:        MKVECT(u,n);
                    893:        for ( i = 0; i < n; i++ ) {
                    894:                STOQ(ind[i],q); u->body[i] = (pointer)q;
                    895:        }
                    896:        MKNODE(n1,u,0); MKNODE(n0,r,n1); MKLIST(*rp,n0);
                    897: }
                    898:
                    899: void nullspace(mat,p,mod,n,ind)
                    900: UM **mat;
                    901: UM p;
                    902: int mod,n;
                    903: int *ind;
                    904: {
                    905:        int i,j,l,s,d;
                    906:        UM q,w,w1,h,inv;
                    907:        UM *t,*u;
                    908:
                    909:        d = DEG(p); inv = W_UMALLOC(d); q = W_UMALLOC(2*d);
                    910:        w = W_UMALLOC(2*d); w1 = W_UMALLOC(2*d); h = W_UMALLOC(d);
                    911:        bzero(ind,n*sizeof(int));
                    912:        ind[0] = 0;
                    913:        for ( i = j = 0; j < n; i++, j++ ) {
                    914:                for ( ; j < n; j++ ) {
                    915:                        for ( l = i; l < n; l++ )
                    916:                                if ( DEG(mat[l][j])>=0 )
                    917:                                        break;
                    918:                        if ( l < n ) {
                    919:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
                    920:                        } else
                    921:                                ind[j] = 1;
                    922:                }
                    923:                if ( j == n )
                    924:                        break;
                    925:                invum(mod,p,mat[i][j],inv);
                    926:                for ( s = j, t = mat[i]; s < n; s++ ) {
                    927:                        mulum(mod,t[s],inv,w);
                    928:                        DEG(w) = divum(mod,w,p,q);
                    929:                        cpyum(w,t[s]);
                    930:                }
                    931:                for ( l = 0; l < n; l++ ) {
                    932:                        if ( l == i )
                    933:                                continue;
                    934:                        u = mat[l]; DEG(w) = -1; subum(mod,w,u[j],h);
                    935:                        for ( s = j; s < n; s++ ) {
                    936:                                mulum(mod,h,t[s],w); addum(mod,w,u[s],w1);
                    937:                                DEG(w1) = divum(mod,w1,p,q); cpyum(w1,u[s]);
                    938:                        }
                    939:                }
                    940:        }
                    941: }
                    942:
                    943: void Pnullspace_ff(arg,rp)
                    944: NODE arg;
                    945: LIST *rp;
                    946: {
                    947:        int i,j,n;
                    948:        MAT mat,r;
                    949:        VECT u;
                    950:        Q q;
                    951:        Obj **w;
                    952:        Obj *t;
                    953:        Obj *s;
                    954:        int *ind;
                    955:        NODE n0,n1;
                    956:
                    957:        mat = (MAT)ARG0(arg);
                    958:        n = mat->row;
                    959:        w = (Obj **)almat_pointer(n,n);
                    960:        for ( i = 0; i < n; i++ )
                    961:                for ( j = 0, t = (Obj *)mat->body[i], s = w[i]; j < n; j++ )
                    962:                        s[j] = t[j];
                    963:        ind = (int *)ALLOCA(n*sizeof(int));
                    964:        switch ( current_ff ) {
                    965:                case FF_GFP:
                    966:                        nullspace_lm((LM **)w,n,ind); break;
                    967:                case FF_GF2N:
                    968:                        nullspace_gf2n((GF2N **)w,n,ind); break;
                    969:                case FF_GFPN:
                    970:                        nullspace_gfpn((GFPN **)w,n,ind); break;
1.5       noro      971:                case FF_GFS:
                    972:                        nullspace_gfs((GFS **)w,n,ind); break;
1.12      noro      973:                case FF_GFSN:
                    974:                        nullspace_gfsn((GFSN **)w,n,ind); break;
1.1       noro      975:                default:
                    976:                        error("nullspace_ff : current_ff is not set");
                    977:        }
                    978:        MKMAT(r,n,n);
                    979:        for ( i = 0; i < n; i++ )
                    980:                for ( j = 0, t = (Obj *)r->body[i], s = w[i]; j < n; j++ )
                    981:                        t[j] = s[j];
                    982:        MKVECT(u,n);
                    983:        for ( i = 0; i < n; i++ ) {
                    984:                STOQ(ind[i],q); u->body[i] = (pointer)q;
                    985:        }
                    986:        MKNODE(n1,u,0); MKNODE(n0,r,n1); MKLIST(*rp,n0);
                    987: }
                    988:
                    989: void nullspace_lm(mat,n,ind)
                    990: LM **mat;
                    991: int n;
                    992: int *ind;
                    993: {
                    994:        int i,j,l,s;
                    995:        Q q,mod;
                    996:        N lm;
                    997:        LM w,w1,h,inv;
                    998:        LM *t,*u;
                    999:
                   1000:        getmod_lm(&lm); NTOQ(lm,1,mod);
                   1001:
                   1002:        bzero(ind,n*sizeof(int));
                   1003:        ind[0] = 0;
                   1004:        for ( i = j = 0; j < n; i++, j++ ) {
                   1005:                for ( ; j < n; j++ ) {
                   1006:                        for ( l = i; l < n; l++ ) {
                   1007:                                simplm(mat[l][j],&w); mat[l][j] = w;
                   1008:                                if ( mat[l][j] )
                   1009:                                        break;
                   1010:                        }
                   1011:                        if ( l < n ) {
                   1012:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
                   1013:                        } else
                   1014:                                ind[j] = 1;
                   1015:                }
                   1016:                if ( j == n )
                   1017:                        break;
                   1018:                NTOQ(mat[i][j]->body,1,q); invl(q,mod,(Q *)&inv);
                   1019:                for ( s = j, t = mat[i]; s < n; s++ ) {
                   1020:                        mullm(t[s],inv,&w); t[s] = w;
                   1021:                }
                   1022:                for ( l = 0; l < n; l++ ) {
                   1023:                        if ( l == i )
                   1024:                                continue;
                   1025:                        u = mat[l]; chsgnlm(u[j],&h);
                   1026:                        for ( s = j; s < n; s++ ) {
                   1027:                                mullm(h,t[s],&w); addlm(w,u[s],&w1); u[s] = w1;
                   1028:                        }
                   1029:                }
                   1030:        }
                   1031: }
                   1032:
                   1033: void nullspace_gf2n(mat,n,ind)
                   1034: GF2N **mat;
                   1035: int n;
                   1036: int *ind;
                   1037: {
                   1038:        int i,j,l,s;
                   1039:        GF2N w,w1,h,inv;
                   1040:        GF2N *t,*u;
                   1041:        extern gf2n_lazy;
                   1042:
                   1043:        bzero(ind,n*sizeof(int));
                   1044:        ind[0] = 0;
                   1045:        for ( i = j = 0; j < n; i++, j++ ) {
                   1046:                for ( ; j < n; j++ ) {
                   1047:                        for ( l = i; l < n; l++ ) {
                   1048:                                simpgf2n(mat[l][j],&w); mat[l][j] = w;
                   1049:                                if ( mat[l][j] )
                   1050:                                        break;
                   1051:                        }
                   1052:                        if ( l < n ) {
                   1053:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
                   1054:                        } else
                   1055:                                ind[j] = 1;
                   1056:                }
                   1057:                if ( j == n )
                   1058:                        break;
                   1059:                invgf2n(mat[i][j],&inv);
                   1060:                for ( s = j, t = mat[i]; s < n; s++ ) {
                   1061:                        mulgf2n(t[s],inv,&w); t[s] = w;
                   1062:                }
                   1063:                for ( l = 0; l < n; l++ ) {
                   1064:                        if ( l == i )
                   1065:                                continue;
                   1066:                        u = mat[l]; h = u[j];
                   1067:                        for ( s = j; s < n; s++ ) {
                   1068:                                mulgf2n(h,t[s],&w); addgf2n(w,u[s],&w1); u[s] = w1;
                   1069:                        }
                   1070:                }
                   1071:        }
                   1072: }
                   1073:
                   1074: void nullspace_gfpn(mat,n,ind)
                   1075: GFPN **mat;
                   1076: int n;
                   1077: int *ind;
                   1078: {
                   1079:        int i,j,l,s;
                   1080:        GFPN w,w1,h,inv;
                   1081:        GFPN *t,*u;
                   1082:
                   1083:        bzero(ind,n*sizeof(int));
                   1084:        ind[0] = 0;
                   1085:        for ( i = j = 0; j < n; i++, j++ ) {
                   1086:                for ( ; j < n; j++ ) {
                   1087:                        for ( l = i; l < n; l++ ) {
                   1088:                                simpgfpn(mat[l][j],&w); mat[l][j] = w;
                   1089:                                if ( mat[l][j] )
                   1090:                                        break;
                   1091:                        }
                   1092:                        if ( l < n ) {
                   1093:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
                   1094:                        } else
                   1095:                                ind[j] = 1;
                   1096:                }
                   1097:                if ( j == n )
                   1098:                        break;
                   1099:                divgfpn((GFPN)ONE,(GFPN)mat[i][j],&inv);
                   1100:                for ( s = j, t = mat[i]; s < n; s++ ) {
                   1101:                        mulgfpn(t[s],inv,&w); t[s] = w;
                   1102:                }
                   1103:                for ( l = 0; l < n; l++ ) {
                   1104:                        if ( l == i )
                   1105:                                continue;
                   1106:                        u = mat[l]; chsgngfpn(u[j],&h);
                   1107:                        for ( s = j; s < n; s++ ) {
                   1108:                                mulgfpn(h,t[s],&w); addgfpn(w,u[s],&w1); u[s] = w1;
                   1109:                        }
                   1110:                }
                   1111:        }
                   1112: }
1.5       noro     1113:
                   1114: void nullspace_gfs(mat,n,ind)
                   1115: GFS **mat;
                   1116: int n;
                   1117: int *ind;
                   1118: {
                   1119:        int i,j,l,s;
                   1120:        GFS w,w1,h,inv;
                   1121:        GFS *t,*u;
                   1122:        GFS one;
                   1123:
                   1124:        bzero(ind,n*sizeof(int));
                   1125:        ind[0] = 0;
                   1126:        mqtogfs(ONEM,&one);
                   1127:
                   1128:        for ( i = j = 0; j < n; i++, j++ ) {
                   1129:                for ( ; j < n; j++ ) {
                   1130:                        for ( l = i; l < n; l++ )
                   1131:                                if ( mat[l][j] )
                   1132:                                        break;
                   1133:                        if ( l < n ) {
                   1134:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
                   1135:                        } else
                   1136:                                ind[j] = 1;
                   1137:                }
                   1138:                if ( j == n )
                   1139:                        break;
                   1140:                divgfs(one,mat[i][j],&inv);
                   1141:                for ( s = j, t = mat[i]; s < n; s++ ) {
                   1142:                        mulgfs(t[s],inv,&w); t[s] = w;
                   1143:                }
                   1144:                for ( l = 0; l < n; l++ ) {
                   1145:                        if ( l == i )
                   1146:                                continue;
                   1147:                        u = mat[l];
                   1148:                        chsgngfs(u[j],&h);
                   1149:                        for ( s = j; s < n; s++ ) {
                   1150:                                mulgfs(h,t[s],&w); addgfs(w,u[s],&w1); u[s] = w1;
1.12      noro     1151:                        }
                   1152:                }
                   1153:        }
                   1154: }
                   1155:
                   1156: void nullspace_gfsn(mat,n,ind)
                   1157: GFSN **mat;
                   1158: int n;
                   1159: int *ind;
                   1160: {
                   1161:        int i,j,l,s;
                   1162:        GFSN w,w1,h,inv;
                   1163:        GFSN *t,*u;
                   1164:
                   1165:        bzero(ind,n*sizeof(int));
                   1166:        ind[0] = 0;
                   1167:
                   1168:        for ( i = j = 0; j < n; i++, j++ ) {
                   1169:                for ( ; j < n; j++ ) {
                   1170:                        for ( l = i; l < n; l++ )
                   1171:                                if ( mat[l][j] )
                   1172:                                        break;
                   1173:                        if ( l < n ) {
                   1174:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
                   1175:                        } else
                   1176:                                ind[j] = 1;
                   1177:                }
                   1178:                if ( j == n )
                   1179:                        break;
                   1180:                invgfsn(mat[i][j],&inv);
                   1181:                for ( s = j, t = mat[i]; s < n; s++ ) {
                   1182:                        mulgfsn(t[s],inv,&w); t[s] = w;
                   1183:                }
                   1184:                for ( l = 0; l < n; l++ ) {
                   1185:                        if ( l == i )
                   1186:                                continue;
                   1187:                        u = mat[l];
                   1188:                        chsgngfsn(u[j],&h);
                   1189:                        for ( s = j; s < n; s++ ) {
                   1190:                                mulgfsn(h,t[s],&w); addgfsn(w,u[s],&w1); u[s] = w1;
1.5       noro     1191:                        }
                   1192:                }
                   1193:        }
                   1194: }
                   1195:
1.1       noro     1196: /* p = a(0)vl[0]+a(1)vl[1]+...+a(m-1)vl[m-1]+a(m) -> array = [a(0) a(1) ... a(m)] */
                   1197:
                   1198: void linear_form_to_array(p,vl,m,array)
                   1199: P p;
                   1200: VL vl;
                   1201: int m;
                   1202: Num *array;
                   1203: {
                   1204:        int i;
                   1205:        DCP dc;
                   1206:
                   1207:        bzero((char *)array,(m+1)*sizeof(Num *));
                   1208:        for ( i = 0; p && vl; vl = NEXT(vl), i++ ) {
                   1209:                if ( ID(p) == O_N )
                   1210:                        break;
                   1211:                else if ( VR(p) == vl->v ) {
                   1212:                        dc = DC(p);
                   1213:                        array[i] = (Num)COEF(dc);
                   1214:                        dc = NEXT(dc);
                   1215:                        p = dc ? COEF(dc) : 0;
                   1216:                }
                   1217:        }
                   1218:        array[m] = (Num)p;
                   1219: }
                   1220:
                   1221: void array_to_linear_form(array,vl,m,r)
                   1222: Num *array;
                   1223: VL vl;
                   1224: int m;
                   1225: P *r;
                   1226: {
                   1227:        P t;
                   1228:        DCP dc0,dc1;
                   1229:
                   1230:        if ( !m )
                   1231:                *r = (P)array[0];
                   1232:        else {
                   1233:                array_to_linear_form(array+1,NEXT(vl),m-1,&t);
                   1234:                if ( !array[0] )
                   1235:                        *r = t;
                   1236:                else {
                   1237:                        NEWDC(dc0); DEG(dc0) = ONE; COEF(dc0) = (P)array[0];
                   1238:                        if ( !t )
                   1239:                                NEXT(dc0) = 0;
                   1240:                        else {
                   1241:                                NEWDC(dc1); DEG(dc1) = 0; COEF(dc1) = t;
                   1242:                                NEXT(dc1) = 0;
                   1243:                                NEXT(dc0) = dc1;
                   1244:                        }
                   1245:                        MKP(vl->v,dc0,*r);
                   1246:                }
                   1247:        }
                   1248: }
                   1249:
                   1250: void Psolve_linear_equation_gf2n(arg,rp)
                   1251: NODE arg;
                   1252: LIST *rp;
                   1253: {
                   1254:        NODE eqs,tn;
                   1255:        VL vars,tvl;
                   1256:        int i,j,n,m,dim,codim;
                   1257:        GF2N **w;
                   1258:        int *ind;
                   1259:        NODE n0,n1;
                   1260:
                   1261:        get_vars(ARG0(arg),&vars);
                   1262:        eqs = BDY((LIST)ARG0(arg));
                   1263:        for ( n = 0, tn = eqs; tn; tn = NEXT(tn), n++);
                   1264:        for ( m = 0, tvl = vars; tvl; tvl = NEXT(tvl), m++);
                   1265:        w = (GF2N **)almat_pointer(n,m+1);
                   1266:        for ( i = 0, tn = eqs; i < n; i++, tn = NEXT(tn) )
                   1267:                linear_form_to_array(BDY(tn),vars,m,(Num *)w[i]);
                   1268:        ind = (int *)ALLOCA(m*sizeof(int));
                   1269:        solve_linear_equation_gf2n(w,n,m,ind);
                   1270:        for ( j = 0, dim = 0; j < m; j++ )
                   1271:                if ( ind[j] )
                   1272:                        dim++;
                   1273:        codim = m-dim;
                   1274:        for ( i = codim; i < n; i++ )
                   1275:                if ( w[i][m] ) {
                   1276:                        MKLIST(*rp,0); return;
                   1277:                }
                   1278:        for ( i = 0, n0 = 0; i < codim; i++ ) {
                   1279:                NEXTNODE(n0,n1);
                   1280:                array_to_linear_form((Num *)w[i],vars,m,(P *)&BDY(n1));
                   1281:        }
                   1282:        if ( n0 )
                   1283:                NEXT(n1) = 0;
                   1284:        MKLIST(*rp,n0);
                   1285: }
                   1286:
                   1287: void solve_linear_equation_gf2n(mat,n,m,ind)
                   1288: GF2N **mat;
                   1289: int n;
                   1290: int *ind;
                   1291: {
                   1292:        int i,j,l,s;
                   1293:        GF2N w,w1,h,inv;
                   1294:        GF2N *t,*u;
                   1295:        extern gf2n_lazy;
                   1296:
                   1297:        bzero(ind,m*sizeof(int));
                   1298:        ind[0] = 0;
                   1299:        for ( i = j = 0; j < m; i++, j++ ) {
                   1300:                for ( ; j < m; j++ ) {
                   1301:                        for ( l = i; l < n; l++ ) {
                   1302:                                simpgf2n(mat[l][j],&w); mat[l][j] = w;
                   1303:                                if ( mat[l][j] )
                   1304:                                        break;
                   1305:                        }
                   1306:                        if ( l < n ) {
                   1307:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
                   1308:                        } else
                   1309:                                ind[j] = 1;
                   1310:                }
                   1311:                if ( j == m )
                   1312:                        break;
                   1313:                invgf2n(mat[i][j],&inv);
                   1314:                for ( s = j, t = mat[i]; s <= m; s++ ) {
                   1315:                        mulgf2n(t[s],inv,&w); t[s] = w;
                   1316:                }
                   1317:                for ( l = 0; l < n; l++ ) {
                   1318:                        if ( l == i )
                   1319:                                continue;
                   1320:                        u = mat[l]; h = u[j];
                   1321:                        for ( s = j; s <= m; s++ ) {
                   1322:                                mulgf2n(h,t[s],&w); addgf2n(w,u[s],&w1); u[s] = w1;
                   1323:                        }
                   1324:                }
                   1325:        }
                   1326: }
                   1327:
                   1328: /*
                   1329: void null_to_sol(mat,ind,mod,n,r)
                   1330: int **mat;
                   1331: int *ind;
                   1332: int mod,n;
                   1333: UM *r;
                   1334: {
                   1335:        int i,j,k,l;
                   1336:        int *c;
                   1337:        UM w;
                   1338:
                   1339:        for ( i = 0, l = 0; i < n; i++ ) {
                   1340:                if ( !ind[i] )
                   1341:                        continue;
                   1342:                w = UMALLOC(n);
                   1343:                for ( j = k = 0, c = COEF(w); j < n; j++ )
                   1344:                        if ( ind[j] )
                   1345:                                c[j] = 0;
                   1346:                        else
                   1347:                                c[j] = mat[k++][i];
                   1348:                c[i] = mod-1;
                   1349:                for ( j = n; j >= 0; j-- )
                   1350:                        if ( c[j] )
                   1351:                                break;
                   1352:                DEG(w) = j;
                   1353:                r[l++] = w;
                   1354:        }
                   1355: }
                   1356: */
                   1357:
                   1358: void showgfmat(mat,n)
                   1359: UM **mat;
                   1360: int n;
                   1361: {
                   1362:        int i,j,k;
                   1363:        int *c;
                   1364:        UM p;
                   1365:
                   1366:        for ( i = 0; i < n; i++ ) {
                   1367:                for ( j = 0; j < n; j++ ) {
                   1368:                        p = mat[i][j];
                   1369:                        if ( DEG(p) < 0 )
                   1370:                                fprintf(asir_out,"0");
                   1371:                        else
                   1372:                                for ( p = mat[i][j], k = DEG(p), c = COEF(p); k >= 0; k-- ) {
                   1373:                                        if ( c[k] )
                   1374:                                                fprintf(asir_out,"+%d",c[k]);
                   1375:                                        if ( k > 1 )
                   1376:                                                fprintf(asir_out,"a^%d",k);
                   1377:                                        else if ( k == 1 )
                   1378:                                                fprintf(asir_out,"a",k);
                   1379:                                }
                   1380:                        fprintf(asir_out," ");
                   1381:                }
                   1382:                fprintf(asir_out,"\n");
                   1383:        }
                   1384: }
                   1385:
                   1386: #if 0
                   1387: void Pgcda_mod(arg,rp)
                   1388: NODE arg;
                   1389: P *rp;
                   1390: {
                   1391:        p1 = (P)ARG0(arg);
                   1392:        p2 = (P)ARG1(arg);
                   1393:        v = VR((P)ARG2(arg));
                   1394:        d = (P)ARG3(arg);
                   1395:        m = QTOS((Q)ARG4(arg));
                   1396:        reordvar(CO,v,&vl);
                   1397:        reorderp(vl,CO,p1,&t); ptomp(m,t,&m1);
                   1398:        reorderp(vl,CO,p2,&t); ptomp(m,t,&m2);
                   1399:        if ( NUM(m1) || NUM(m2) || VR(m1) != v || VR(m2) != v ) {
                   1400:                *rp = ONE; return;
                   1401:        }
                   1402:        if ( deg(v,m1) >= deg(v,m2) ) {
                   1403:                t = m1; m1 = m2; m2 = t;
                   1404:        }
                   1405:        while ( 1 ) {
                   1406:                inva_mod(COEF(DC(m2)),d,m,&inv);
                   1407:                NEWDC(dc); NEXT(dc) = 0; MKP(v,dc,h);
                   1408:                d0 = deg(v,m1)-deg(v,m2); STOQ(d0,DEG(dc));
                   1409:                mulgq(m,d,inv,COEF(DC(m1)),&COEF(dc));
                   1410:                mulgp(vl,m,d,m2,h,&t); subgp(vl,m,d,m1,t,&s);
                   1411:        }
                   1412: }
                   1413: #endif
                   1414:
                   1415: void Ppwr_mod(arg,rp)
                   1416: NODE arg;
                   1417: P *rp;
                   1418: {
                   1419:        P p,a,d,r;
                   1420:        int m;
                   1421:        Q q;
                   1422:        N n;
                   1423:
                   1424:        m = QTOS((Q)ARG4(arg)); q = (Q)ARG5(arg); n = q ? NM(q) : 0;
                   1425:        ptomp(m,(P)ARG0(arg),&p); ptomp(m,(P)ARG1(arg),&a);
                   1426:        ptomp(m,(P)ARG3(arg),&d);
                   1427:        pwr_mod(p,a,VR((P)ARG2(arg)),d,m,n,&r);
                   1428:        mptop(r,rp);
                   1429: }
                   1430:
                   1431: void pwr_mod(p,a,v,d,m,n,rp)
                   1432: P p,a,d;
                   1433: V v;
                   1434: int m;
                   1435: N n;
                   1436: P *rp;
                   1437: {
                   1438:        int b;
                   1439:        P t,s,r;
                   1440:        N n1;
                   1441:
                   1442:        if ( !n )
                   1443:                *rp = (P)ONEM;
                   1444:        else if ( UNIN(n) )
                   1445:                *rp = p;
                   1446:        else {
                   1447:                b = divin(n,2,&n1);
                   1448:                pwr_mod(p,a,v,d,m,n1,&t);
                   1449:                mulmp(CO,m,t,t,&s); rem_mod(s,a,v,d,m,&r);
                   1450:                if ( b ) {
                   1451:                        mulmp(CO,m,r,p,&t); rem_mod(t,a,v,d,m,rp);
                   1452:                } else
                   1453:                        *rp = r;
                   1454:        }
                   1455: }
                   1456:
                   1457: void rem_mod(p,a,v,d,m,rp)
                   1458: P p,a,d;
                   1459: V v;
                   1460: int m;
                   1461: P *rp;
                   1462: {
                   1463:        P tmp,r1,r2;
                   1464:
                   1465:        divsrmp(CO,m,p,d,&tmp,&r1);
                   1466:        divsrmp(CO,m,r1,a,&tmp,&r2);
                   1467:        divsrmp(CO,m,r2,d,&tmp,rp);
                   1468: }

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