[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.16

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.16    ! noro       48:  * $OpenXM: OpenXM_contrib2/asir2000/builtin/gf.c,v 1.15 2002/03/15 02:52:09 noro Exp $
1.3       noro       49: */
1.1       noro       50: #include "ca.h"
                     51: #include "parse.h"
                     52:
                     53: struct resf_dlist {
1.16    ! noro       54:   int ib,id;
1.1       noro       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[] = {
1.16    ! noro       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},
        !           103:   {"uhensel_incremental",Puhensel_incremental,5},
        !           104:   {"sfuhensel",Psfuhensel,4},
        !           105:   {0,0,0},
1.1       noro      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: {
1.16    ! noro      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;
1.1       noro      139: }
                    140:
                    141: void Puhensel(arg,rp)
                    142: NODE arg;
                    143: LIST *rp;
                    144: {
1.16    ! noro      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);
1.1       noro      155: }
                    156:
1.15      noro      157: void Puhensel_incremental(arg,rp)
                    158: NODE arg;
                    159: LIST *rp;
                    160: {
1.16    ! noro      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);
1.15      noro      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: {
1.16    ! noro      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);
        !           201:     MKNODE(t,s,top); top = t;
        !           202:   }
        !           203:   *rp = top;
1.15      noro      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: {
1.16    ! noro      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);
        !           242:     MKNODE(t,s,top); top = t;
        !           243:   }
        !           244:   *rp = top;
1.6       noro      245: }
                    246:
                    247: void Psfuhensel(arg,rp)
                    248: NODE arg;
                    249: LIST *rp;
                    250: {
1.16    ! noro      251:   P f;
        !           252:   int bound;
        !           253:   NODE r,mfl;
        !           254:   GFS ev;
        !           255:
        !           256:   f = (P)ARG0(arg);
        !           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.16    ! noro      271:   BM fl;
        !           272:   BM *r;
        !           273:   VL vl,nvl;
        !           274:   int i,fn,dx,dy,d;
        !           275:   NODE t,top;
        !           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");
        !           284:
        !           285:   for ( i = 0, t = mfl; t; i++, t = NEXT(t) );
        !           286:   fn = i;
        !           287:
        !           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:
        !           294:   for ( i = 0, t = mfl, d = 0; i < fn; i++, t = NEXT(t) ) {
        !           295:     gm[i] = (pointer)UMALLOC(getdeg(x,(P)BDY(t)));
        !           296:     ptosfum((P)BDY(t),gm[i]);
        !           297:     d += DEG(gm[i]);
        !           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);
        !           306:   if ( dx != d )
        !           307:     error("sfuhensel : product of factors has incompatible degree");
        !           308:
        !           309:   dy = getdeg(y,f);
        !           310:   dy = MAX(dy,bound);
        !           311:   fl = BMALLOC(dx,dy);
        !           312:   ptosfbm(dy,f,fl);
        !           313:   if ( ev ) shiftsfbm(fl,FTOIF(CONT(ev)));
        !           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;
        !           332:
        !           333:   for ( i = fn-1, top = 0; i >= 0; i-- ) {
        !           334:     sfbmtop(r[i],x,y,&s);
        !           335:     reorderp(CO,vl,s,&u);
        !           336:     MKNODE(t,u,top); top = t;
        !           337:   }
        !           338:   *rp = top;
1.1       noro      339: }
                    340:
                    341: void Presfmain(arg,rp)
                    342: NODE arg;
                    343: LIST *rp;
                    344: {
1.16    ! noro      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);
1.1       noro      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: {
1.16    ! noro      390:   register int i,j;
        !           391:   int q,n,bound,inv,lc;
        !           392:   int *p;
        !           393:   int **pp;
        !           394:   ML blist,clist,bqlist,cqlist,rlist;
        !           395:   UM *b;
        !           396:   LUM fl,tl;
        !           397:   LUM *l;
        !           398:   UM w;
        !           399:
        !           400:   w = W_UMALLOC(UDEG(f));
        !           401:   blist = MLALLOC(nf); blist->n = nf; blist->mod = mod;
        !           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++ ) {
        !           418:     blist->c[i] = (pointer)UMALLOC(UDEG(mfl[i]));
        !           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]);
        !           425:   }
        !           426:
        !           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:   }
1.1       noro      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: {
1.16    ! noro      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; ; ) {
1.1       noro      478: #if 0
1.16    ! noro      479:     if ( !(z++ % 10000) )
        !           480:       fputc('.',stderr);
1.1       noro      481: #endif
1.16    ! noro      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;
1.1       noro      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: {
1.16    ! noro      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++ ) {
1.1       noro      543: #if 0
1.16    ! noro      544:     if ( !(i % 1000) )
        !           545:       fprintf(stderr,"i=%d\n",i);
1.1       noro      546: #endif
1.16    ! noro      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) ) {
1.1       noro      550: #if 0
1.16    ! noro      551:       fprintf(stderr,"success : i=%d\n",i);
1.1       noro      552: #endif
1.16    ! noro      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;
1.1       noro      561: }
                    562:
                    563: #if 0
                    564: void Pftest(arg,rp)
                    565: NODE arg;
                    566: P *rp;
                    567: {
1.16    ! noro      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);
1.1       noro      576: }
                    577:
                    578: void dtest_special(f,list,pr)
                    579: P f;
                    580: ML list;
                    581: P *pr;
                    582: {
1.16    ! noro      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++ ) {
1.1       noro      599: #if 0
1.16    ! noro      600:     if ( !(i % 1000) )
        !           601:       fprintf(stderr,"i=%d\n",i);
1.1       noro      602: #endif
1.16    ! noro      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) ) {
1.1       noro      606: #if 0
1.16    ! noro      607:       fprintf(stderr,"success : i=%d\n",i);
1.1       noro      608: #endif
1.16    ! noro      609:       *pr = factor; return;
        !           610:     }
        !           611:   }
1.1       noro      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: {
1.16    ! noro      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:   }
1.1       noro      650: }
                    651: #endif
                    652:
                    653: #if 0
                    654: void Pftest(arg,rp)
                    655: NODE arg;
                    656: P *rp;
                    657: {
1.16    ! noro      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);
1.1       noro      666: }
                    667:
                    668: void dtest_special(f,list,pr)
                    669: P f;
                    670: ML list;
                    671: P *pr;
                    672: {
1.16    ! noro      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++ ) {
1.1       noro      690: #if 0
1.16    ! noro      691:     if ( !(i % 1000) )
        !           692:     fprintf(stderr,"i=%d\n",i);
1.1       noro      693: #endif
1.16    ! noro      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) ) {
1.1       noro      708: #if 0
1.16    ! noro      709:       fprintf(stderr,"success : i=%d\n",i);
1.1       noro      710: #endif
1.16    ! noro      711:       *pr = factor; return;
        !           712:     }
        !           713:   }
        !           714:   *pr = f;
1.1       noro      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: {
1.16    ! noro      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:   }
1.1       noro      753: }
                    754: #endif
                    755:
                    756: void Pftest(arg,rp)
                    757: NODE arg;
                    758: P *rp;
                    759: {
1.16    ! noro      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);
1.1       noro      767: }
                    768:
                    769: int nbits(a)
                    770: int a;
                    771: {
1.16    ! noro      772:   int i,s;
1.1       noro      773:
1.16    ! noro      774:   for ( i = 0, s = 0; a && (i < 20); i++, a >>= 1 )
        !           775:     if ( a & 1 ) s++;
        !           776:   return s;
1.1       noro      777: }
                    778:
                    779: void dtest_special(f,list,pr)
                    780: P f;
                    781: ML list;
                    782: P *pr;
                    783: {
1.16    ! noro      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++ ) {
1.1       noro      799: #if 0
1.16    ! noro      800:     if ( !(i % 10000) )
        !           801:     fprintf(stderr,"i=%d\n",i);
1.1       noro      802: #endif
1.16    ! noro      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) ) {
1.1       noro      810: #if 0
1.16    ! noro      811:       fprintf(stderr,"success : i=%d\n",i);
1.1       noro      812: #endif
1.16    ! noro      813:       *pr = factor; return;
        !           814:     }
        !           815:   }
        !           816:   *pr = f;
1.1       noro      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: {
1.16    ! noro      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:   }
1.1       noro      854: }
                    855:
                    856: void Pnullspace(arg,rp)
                    857: NODE arg;
                    858: LIST *rp;
                    859: {
1.16    ! noro      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);
1.1       noro      897: }
                    898:
                    899: void nullspace(mat,p,mod,n,ind)
                    900: UM **mat;
                    901: UM p;
                    902: int mod,n;
                    903: int *ind;
                    904: {
1.16    ! noro      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:   }
1.1       noro      941: }
                    942:
                    943: void Pnullspace_ff(arg,rp)
                    944: NODE arg;
                    945: LIST *rp;
                    946: {
1.16    ! noro      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;
        !           971:     case FF_GFS:
        !           972:       nullspace_gfs((GFS **)w,n,ind); break;
        !           973:     case FF_GFSN:
        !           974:       nullspace_gfsn((GFSN **)w,n,ind); break;
        !           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);
1.1       noro      987: }
                    988:
                    989: void nullspace_lm(mat,n,ind)
                    990: LM **mat;
                    991: int n;
                    992: int *ind;
                    993: {
1.16    ! noro      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:   }
1.1       noro     1031: }
                   1032:
                   1033: void nullspace_gf2n(mat,n,ind)
                   1034: GF2N **mat;
                   1035: int n;
                   1036: int *ind;
                   1037: {
1.16    ! noro     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:   }
1.1       noro     1072: }
                   1073:
                   1074: void nullspace_gfpn(mat,n,ind)
                   1075: GFPN **mat;
                   1076: int n;
                   1077: int *ind;
                   1078: {
1.16    ! noro     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:   }
1.1       noro     1112: }
1.5       noro     1113:
                   1114: void nullspace_gfs(mat,n,ind)
                   1115: GFS **mat;
                   1116: int n;
                   1117: int *ind;
                   1118: {
1.16    ! noro     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;
        !          1151:       }
        !          1152:     }
        !          1153:   }
1.12      noro     1154: }
                   1155:
                   1156: void nullspace_gfsn(mat,n,ind)
                   1157: GFSN **mat;
                   1158: int n;
                   1159: int *ind;
                   1160: {
1.16    ! noro     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;
        !          1191:       }
        !          1192:     }
        !          1193:   }
1.5       noro     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: {
1.16    ! noro     1204:   int i;
        !          1205:   DCP dc;
1.1       noro     1206:
1.16    ! noro     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;
1.1       noro     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: {
1.16    ! noro     1227:   P t;
        !          1228:   DCP dc0,dc1;
1.1       noro     1229:
1.16    ! noro     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:   }
1.1       noro     1248: }
                   1249:
                   1250: void Psolve_linear_equation_gf2n(arg,rp)
                   1251: NODE arg;
                   1252: LIST *rp;
                   1253: {
1.16    ! noro     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);
1.1       noro     1285: }
                   1286:
                   1287: void solve_linear_equation_gf2n(mat,n,m,ind)
                   1288: GF2N **mat;
                   1289: int n;
                   1290: int *ind;
                   1291: {
1.16    ! noro     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:   }
1.1       noro     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: {
1.16    ! noro     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:   }
1.1       noro     1355: }
                   1356: */
                   1357:
                   1358: void showgfmat(mat,n)
                   1359: UM **mat;
                   1360: int n;
                   1361: {
1.16    ! noro     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:   }
1.1       noro     1384: }
                   1385:
                   1386: #if 0
                   1387: void Pgcda_mod(arg,rp)
                   1388: NODE arg;
                   1389: P *rp;
                   1390: {
1.16    ! noro     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:   }
1.1       noro     1412: }
                   1413: #endif
                   1414:
                   1415: void Ppwr_mod(arg,rp)
                   1416: NODE arg;
                   1417: P *rp;
                   1418: {
1.16    ! noro     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);
1.1       noro     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: {
1.16    ! noro     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:   }
1.1       noro     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: {
1.16    ! noro     1463:   P tmp,r1,r2;
1.1       noro     1464:
1.16    ! noro     1465:   divsrmp(CO,m,p,d,&tmp,&r1);
        !          1466:   divsrmp(CO,m,r1,a,&tmp,&r2);
        !          1467:   divsrmp(CO,m,r2,d,&tmp,rp);
1.1       noro     1468: }

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