Annotation of OpenXM_contrib2/asir2018/builtin/gf.c, Revision 1.1
1.1 ! 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
! 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
! 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: *
! 48: * $OpenXM$
! 49: */
! 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 *);
! 59: void uhensel_incremental(P,NODE,int,int,int,NODE *);
! 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 *);
! 70: void nullspace_gfs(GFS **,int,int *);
! 71: void nullspace_gfsn(GFSN **,int,int *);
! 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,Z,P *);
! 76: void rem_mod(P,P,V,P,int,P *);
! 77:
! 78: void Pnullspace(),Pgcda_mod(),Pftest(),Presfmain(),Ppwr_mod(),Puhensel();
! 79: void Puhensel_incremental();
! 80: void Psfuhensel();
! 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 *);
! 90: void sfuhensel(P,NODE,GFS,int,NODE *);
! 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},
! 103: {"uhensel_incremental",Puhensel_incremental,5},
! 104: {"sfuhensel",Psfuhensel,4},
! 105: {0,0,0},
! 106: };
! 107:
! 108: int resf_degtest(int k,int *in,int nb,struct resf_dlist *dlist)
! 109: {
! 110: int i,d0,d;
! 111: int dl_i;
! 112: struct resf_dlist *t;
! 113:
! 114: if ( k < nb )
! 115: return 0;
! 116: if ( nb == 1 )
! 117: return 1;
! 118: d0 = 0; d = 0; dl_i = 0;
! 119: for ( i = 0; i < k; i++ ) {
! 120: t = &dlist[in[i]];
! 121: if ( t->ib > dl_i + 1 )
! 122: return 0;
! 123: else if ( t->ib == dl_i )
! 124: d += t->id;
! 125: else if ( !d || (dl_i && d0 != d) )
! 126: return 0;
! 127: else {
! 128: d0 = d; dl_i++; d = t->id;
! 129: }
! 130: }
! 131: if ( dl_i != nb - 1 || d0 != d )
! 132: return 0;
! 133: else
! 134: return 1;
! 135: }
! 136:
! 137: void Puhensel(NODE arg,LIST *rp)
! 138: {
! 139: P f;
! 140: NODE mfl,r;
! 141: int mod,bound;
! 142:
! 143: f = (P)ARG0(arg);
! 144: mfl = BDY((LIST)ARG1(arg));
! 145: mod = QTOS((Q)ARG2(arg));
! 146: bound = QTOS((Q)ARG3(arg));
! 147: uhensel(f,mfl,mod,bound,&r);
! 148: MKLIST(*rp,r);
! 149: }
! 150:
! 151: void Puhensel_incremental(NODE arg,LIST *rp)
! 152: {
! 153: P f;
! 154: NODE mfl,r;
! 155: int mod,bound,start;
! 156:
! 157: f = (P)ARG0(arg);
! 158: mfl = BDY((LIST)ARG1(arg));
! 159: mod = QTOS((Q)ARG2(arg));
! 160: start = QTOS((Q)ARG3(arg));
! 161: bound = QTOS((Q)ARG4(arg));
! 162: uhensel_incremental(f,mfl,mod,start,bound,&r);
! 163: MKLIST(*rp,r);
! 164: }
! 165:
! 166: void uhensel(P f,NODE mfl,int mod,int bound,NODE *rp)
! 167: {
! 168: ML blist,clist,rlist;
! 169: LUM fl;
! 170: int nf,i;
! 171: P s;
! 172: V v;
! 173: NODE t,top;
! 174:
! 175: nf = length(mfl);
! 176: blist = MLALLOC(nf); blist->n = nf; blist->mod = mod;
! 177: for ( i = 0, t = mfl; i < nf; i++, t = NEXT(t) ) {
! 178: blist->c[i] = (pointer)UMALLOC(UDEG((P)BDY(t)));
! 179: ptoum(mod,(P)BDY(t),blist->c[i]);
! 180: }
! 181: gcdgen(f,blist,&clist);
! 182: blist->bound = clist->bound = bound;
! 183: W_LUMALLOC((int)UDEG(f),bound,fl);
! 184: ptolum(mod,bound,f,fl);
! 185: henmain(fl,blist,clist,&rlist);
! 186: v = VR(f);
! 187: for ( i = nf-1, top = 0; i >= 0; i-- ) {
! 188: lumtop(v,mod,bound,rlist->c[i],&s);
! 189: MKNODE(t,s,top); top = t;
! 190: }
! 191: *rp = top;
! 192: }
! 193:
! 194: void uhensel_incremental(P f,NODE mfl,int mod,int start,int bound,NODE *rp)
! 195: {
! 196: ML blist,clist,rlist;
! 197: LUM fl;
! 198: LUM *lblist;
! 199: int nf,i,j,k;
! 200: int **p;
! 201: P s;
! 202: V v;
! 203: NODE t,top;
! 204:
! 205: nf = length(mfl);
! 206: blist = MLALLOC(nf); blist->n = nf; blist->mod = mod;
! 207: lblist = (LUM *)MALLOC(nf*sizeof(LUM));
! 208: for ( i = 0, t = mfl; i < nf; i++, t = NEXT(t) ) {
! 209: blist->c[i] = (pointer)UMALLOC(UDEG((P)BDY(t)));
! 210: ptoum(mod,(P)BDY(t),blist->c[i]);
! 211: W_LUMALLOC((int)UDEG((P)BDY(t)),bound,lblist[i]);
! 212: ptolum(mod,start,(P)BDY(t),lblist[i]);
! 213: p = lblist[i]->c;
! 214: for ( j = DEG(lblist[i]); j >= 0; j-- )
! 215: for ( k = start; k < bound; k++ )
! 216: p[j][k] = 0;
! 217: }
! 218: gcdgen(f,blist,&clist);
! 219: clist->bound = bound;
! 220: W_LUMALLOC((int)UDEG(f),bound,fl);
! 221: ptolum(mod,bound,f,fl);
! 222: henmain_incremental(fl,lblist,clist,nf,mod,start,bound);
! 223: v = VR(f);
! 224: for ( i = nf-1, top = 0; i >= 0; i-- ) {
! 225: lumtop_unsigned(v,mod,bound,lblist[i],&s);
! 226: MKNODE(t,s,top); top = t;
! 227: }
! 228: *rp = top;
! 229: }
! 230:
! 231: void Psfuhensel(NODE arg,LIST *rp)
! 232: {
! 233: P f;
! 234: int bound;
! 235: NODE r,mfl;
! 236: GFS ev;
! 237:
! 238: f = (P)ARG0(arg);
! 239: mfl = BDY((LIST)ARG1(arg));
! 240: ev = (GFS)ARG2(arg);
! 241: bound = QTOS((Q)ARG3(arg));
! 242: sfuhensel(f,mfl,ev,bound,&r);
! 243: MKLIST(*rp,r);
! 244: }
! 245:
! 246: void sfuhensel(P f,NODE mfl,GFS ev,int bound,NODE *rp)
! 247: {
! 248: BM fl;
! 249: BM *r;
! 250: VL vl,nvl;
! 251: int i,fn,dx,dy,d;
! 252: NODE t,top;
! 253: UM fm,hm,q;
! 254: UM *gm;
! 255: V x,y;
! 256: P g,s,u;
! 257:
! 258: clctv(CO,f,&vl);
! 259: if ( !vl || !vl->next || vl->next->next )
! 260: error("sfuhensel : f must be a bivariate poly");
! 261:
! 262: for ( i = 0, t = mfl; t; i++, t = NEXT(t) );
! 263: fn = i;
! 264:
! 265: gm = (UM *)MALLOC(fn*sizeof(UM));
! 266:
! 267: /* XXX : more severe check is necessary */
! 268: x = VR((P)BDY(mfl));
! 269: y = vl->v == x ? vl->next->v : vl->v;
! 270:
! 271: for ( i = 0, t = mfl, d = 0; i < fn; i++, t = NEXT(t) ) {
! 272: gm[i] = (pointer)UMALLOC(getdeg(x,(P)BDY(t)));
! 273: ptosfum((P)BDY(t),gm[i]);
! 274: d += DEG(gm[i]);
! 275: }
! 276:
! 277: /* reorder f if necessary */
! 278: if ( vl->v != x ) {
! 279: reordvar(vl,x,&nvl); reorderp(nvl,vl,f,&g);
! 280: vl = nvl; f = g;
! 281: }
! 282: dx = getdeg(x,f);
! 283: if ( dx != d )
! 284: error("sfuhensel : product of factors has incompatible degree");
! 285:
! 286: dy = getdeg(y,f);
! 287: dy = MAX(dy,bound);
! 288: fl = BMALLOC(dx,dy);
! 289: ptosfbm(dy,f,fl);
! 290: if ( ev ) shiftsfbm(fl,FTOIF(CONT(ev)));
! 291:
! 292: /* fm = fl mod y */
! 293: fm = W_UMALLOC(dx);
! 294: cpyum(COEF(fl)[0],fm);
! 295: hm = W_UMALLOC(dx);
! 296:
! 297: q = W_UMALLOC(dx);
! 298: r = (BM *)MLALLOC(fn*sizeof(BM));
! 299: for ( i = 0; i < fn-1; i++ ) {
! 300: /* fl = gm[i]*hm mod y */
! 301: divsfum(fm,gm[i],hm);
! 302: /* fl is replaced by the cofactor of gk mod y^bound */
! 303: /* r[i] = gk */
! 304: sfhenmain2(fl,gm[i],hm,bound,r+i);
! 305: cpyum(hm,fm);
! 306: }
! 307: /* finally, fl must be the lift of gm[fn-1] */
! 308: r[i] = fl;
! 309:
! 310: for ( i = fn-1, top = 0; i >= 0; i-- ) {
! 311: sfbmtop(r[i],x,y,&s);
! 312: reorderp(CO,vl,s,&u);
! 313: MKNODE(t,u,top); top = t;
! 314: }
! 315: *rp = top;
! 316: }
! 317:
! 318: void Presfmain(NODE arg,LIST *rp)
! 319: {
! 320: P f;
! 321: int mod,n,nb,i,j,k;
! 322: int *nf,*md;
! 323: P *mf;
! 324: NODE mfl,mdl,t,s,u;
! 325: ML list;
! 326: DCP dc;
! 327: int sflag;
! 328:
! 329: f = (P)ARG0(arg);
! 330: mod = QTOS((Q)ARG1(arg));
! 331: mfl = BDY((LIST)ARG2(arg));
! 332: mdl = BDY((LIST)ARG3(arg));
! 333: for ( n = nb = 0, t = mfl; t; nb++, t = NEXT(t) )
! 334: for ( s = BDY((LIST)BDY(t)); s; n++, s = NEXT(s) );
! 335: if ( n == nb ) {
! 336: /* f must be irreducible! */
! 337: NEWDC(dc);
! 338: dc->c = f; dc->d = ONE;
! 339: } else {
! 340: nf = W_ALLOC(nb); md = W_ALLOC(nb); mf = (P *)ALLOCA(n*sizeof(P));
! 341: for ( k = i = 0, t = mfl, u = mdl, sflag = 1; t;
! 342: i++, t = NEXT(t), u = NEXT(u) ) {
! 343: if ( sflag && length(BDY((LIST)BDY(t))) != 2 )
! 344: sflag = 0;
! 345: for ( j = 0, s = BDY((LIST)BDY(t)); s; j++, s = NEXT(s) )
! 346: mf[k++] = (P)BDY(s);
! 347: nf[i] = j; md[i] = QTOS((Q)BDY(u));
! 348: }
! 349: resf_hensel(mod,f,n,mf,&list);
! 350: if ( sflag )
! 351: resf_dtest_special(f,list,nb,nf,md,&dc);
! 352: else
! 353: resf_dtest(f,list,nb,nf,md,&dc);
! 354: }
! 355: dcptolist(dc,rp);
! 356: }
! 357:
! 358: void resf_hensel(int mod,P f,int nf,P *mfl,ML *listp)
! 359: {
! 360: register int i,j;
! 361: int q,n,bound,inv,lc;
! 362: int *p;
! 363: int **pp;
! 364: ML blist,clist,bqlist,cqlist,rlist;
! 365: UM *b;
! 366: LUM fl,tl;
! 367: LUM *l;
! 368: UM w;
! 369:
! 370: w = W_UMALLOC(UDEG(f));
! 371: blist = MLALLOC(nf); blist->n = nf; blist->mod = mod;
! 372:
! 373: /* c[0] must have lc(f) */
! 374: blist->c[0] = (pointer)UMALLOC(UDEG(mfl[0]));
! 375: ptoum(mod,mfl[0],w);
! 376: inv = invm(w->c[UDEG(mfl[0])],mod);
! 377: lc = remqi((Q)LC(f),mod);
! 378: lc = dmar(inv,lc,0,mod);
! 379: if ( lc == 1 )
! 380: copyum(w,blist->c[0]);
! 381: else
! 382: mulsum(mod,w,lc,blist->c[0]);
! 383:
! 384: /* c[i] (i=1,...,nf-1) must be monic */
! 385: for ( i = 1; i < nf; i++ ) {
! 386: blist->c[i] = (pointer)UMALLOC(UDEG(mfl[i]));
! 387: ptoum(mod,mfl[i],w);
! 388: inv = invm(w->c[UDEG(mfl[i])],mod);
! 389: if ( inv == 1 )
! 390: copyum(w,blist->c[i]);
! 391: else
! 392: mulsum(mod,w,inv,blist->c[i]);
! 393: }
! 394:
! 395: gcdgen(f,blist,&clist); henprep(f,blist,clist,&bqlist,&cqlist);
! 396: n = bqlist->n; q = bqlist->mod;
! 397: bqlist->bound = cqlist->bound = bound = mignotte(q,f);
! 398: if ( bound == 1 ) {
! 399: *listp = rlist = MLALLOC(n);
! 400: rlist->n = n; rlist->mod = q; rlist->bound = bound;
! 401: for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c; i < n; i++ ) {
! 402: tl = LUMALLOC(DEG(b[i]),1); l[i] = tl; p = COEF(b[i]);
! 403: for ( j = 0, pp = COEF(tl); j <= DEG(tl); j++ )
! 404: pp[j][0] = p[j];
! 405: }
! 406: } else {
! 407: W_LUMALLOC((int)UDEG(f),bound,fl);
! 408: ptolum(q,bound,f,fl); henmain(fl,bqlist,cqlist,listp);
! 409: }
! 410: }
! 411:
! 412: void resf_dtest(P f,ML list,int nb,int *nfl,int *mdl,DCP *dcp)
! 413: {
! 414: int n,np,bound,q;
! 415: int i,j,k;
! 416: int *win;
! 417: P g,factor,cofactor;
! 418: Q csum,csumt;
! 419: DCP dcf,dcf0;
! 420: LUM *c;
! 421: ML wlist;
! 422: struct resf_dlist *dlist;
! 423: int z;
! 424:
! 425: n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
! 426: win = W_ALLOC(np+1);
! 427: ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
! 428: wlist = W_MLALLOC(np); wlist->n = list->n;
! 429: wlist->mod = list->mod; wlist->bound = list->bound;
! 430: c = (LUM *)COEF(wlist);
! 431: bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
! 432: dlist = (struct resf_dlist *)ALLOCA(np*sizeof(struct resf_dlist));
! 433: for ( i = 0, j = 0; j < nb; j++ )
! 434: for ( k = 0; k < nfl[j]; k++, i++ ) {
! 435: dlist[i].ib = j; dlist[i].id = DEG(c[i])/mdl[j];
! 436: }
! 437: k = nb;
! 438: for ( i = 0; i < nb; i++ )
! 439: win[i] = i+1;
! 440: for ( g = f, dcf = dcf0 = 0, --np, z = 0; ; ) {
! 441: #if 0
! 442: if ( !(z++ % 10000) )
! 443: fputc('.',stderr);
! 444: #endif
! 445: if ( resf_degtest(k,win,nb,dlist) &&
! 446: dtestmain(g,csum,wlist,k,win,&factor,&cofactor) ) {
! 447: NEXTDC(dcf0,dcf); DEG(dcf) = ONE; COEF(dcf) = factor;
! 448: g = cofactor;
! 449: ucsump(g,&csum); mulq(csum,(Q)COEF(DC(g)),&csumt); csum = csumt;
! 450: for ( i = 0; i < k - 1; i++ )
! 451: for ( j = win[i] + 1; j < win[i + 1]; j++ ) {
! 452: c[j-i-1] = c[j];
! 453: dlist[j-i-1] = dlist[j];
! 454: }
! 455: for ( j = win[k-1] + 1; j <= np; j++ ) {
! 456: c[j-k] = c[j];
! 457: dlist[j-k] = dlist[j];
! 458: }
! 459: if ( ( np -= k ) < k )
! 460: break;
! 461: if ( np - win[0] + 1 < k )
! 462: if ( ++k > np )
! 463: break;
! 464: else
! 465: for ( i = 0; i < k; i++ )
! 466: win[i] = i + 1;
! 467: else
! 468: for ( i = 1; i < k; i++ )
! 469: win[i] = win[0] + i;
! 470: } else if ( !ncombi(1,np,k,win) )
! 471: if ( k == np )
! 472: break;
! 473: else
! 474: for ( i = 0, ++k; i < k; i++ )
! 475: win[i] = i + 1;
! 476: }
! 477: NEXTDC(dcf0,dcf); COEF(dcf) = g;
! 478: DEG(dcf) = ONE; NEXT(dcf) = 0;*dcp = dcf0;
! 479: }
! 480:
! 481: void resf_dtest_special(P f,ML list,int nb,int *nfl,int *mdl,DCP *dcp)
! 482: {
! 483: int n,np,bound,q;
! 484: int i,j;
! 485: int *win;
! 486: P g,factor,cofactor;
! 487: Q csum,csumt;
! 488: DCP dcf,dcf0;
! 489: LUM *c;
! 490: ML wlist;
! 491: int max;
! 492:
! 493: n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
! 494: win = W_ALLOC(np+1);
! 495: ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
! 496: wlist = W_MLALLOC(np); wlist->n = list->n;
! 497: wlist->mod = list->mod; wlist->bound = list->bound;
! 498: c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
! 499: max = 1<<nb;
! 500: for ( g = f, dcf = dcf0 = 0, i = 0; i < max; i++ ) {
! 501: #if 0
! 502: if ( !(i % 1000) )
! 503: fprintf(stderr,"i=%d\n",i);
! 504: #endif
! 505: for ( j = 0; j < nb; j++ )
! 506: win[j] = (i&(1<<j)) ? 2*j+1 : 2*j;
! 507: if ( dtestmain(g,csum,wlist,nb,win,&factor,&cofactor) ) {
! 508: #if 0
! 509: fprintf(stderr,"success : i=%d\n",i);
! 510: #endif
! 511: NEXTDC(dcf0,dcf); DEG(dcf) = ONE; COEF(dcf) = factor;
! 512: NEXTDC(dcf0,dcf); DEG(dcf) = ONE; COEF(dcf) = cofactor;
! 513: NEXT(dcf) = 0;*dcp = dcf0;
! 514: return;
! 515: }
! 516: }
! 517: NEXTDC(dcf0,dcf); COEF(dcf) = g;
! 518: DEG(dcf) = ONE; NEXT(dcf) = 0;*dcp = dcf0;
! 519: }
! 520:
! 521: #if 0
! 522: void Pftest(arg,rp)
! 523: NODE arg;
! 524: P *rp;
! 525: {
! 526: ML list;
! 527: DCP dc;
! 528: P p;
! 529: P *mfl;
! 530:
! 531: p = (P)ARG0(arg); mfl = (P *)(((VECT)ARG1(arg))->body);
! 532: hensel_special(4,1,p,mfl,&list);
! 533: dtest_special(p,list,rp);
! 534: }
! 535:
! 536: void dtest_special(f,list,pr)
! 537: P f;
! 538: ML list;
! 539: P *pr;
! 540: {
! 541: int n,np,bound,q;
! 542: int i,j,k;
! 543: int *win;
! 544: P g,factor,cofactor;
! 545: Q csum,csumt;
! 546: DCP dc,dcf,dcf0;
! 547: LUM *c;
! 548: ML wlist;
! 549:
! 550: n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
! 551: win = W_ALLOC(np+1);
! 552: ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
! 553: wlist = W_MLALLOC(np); wlist->n = list->n;
! 554: wlist->mod = list->mod; wlist->bound = list->bound;
! 555: c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
! 556: for ( g = f, i = 130000; i < (1<<20); i++ ) {
! 557: #if 0
! 558: if ( !(i % 1000) )
! 559: fprintf(stderr,"i=%d\n",i);
! 560: #endif
! 561: for ( j = 0; j < 20; j++ )
! 562: win[j] = (i&(1<<j)) ? 2*j+1 : 2*j;
! 563: if ( dtestmain(g,csum,wlist,20,win,&factor,&cofactor) ) {
! 564: #if 0
! 565: fprintf(stderr,"success : i=%d\n",i);
! 566: #endif
! 567: *pr = factor; return;
! 568: }
! 569: }
! 570: }
! 571:
! 572: void hensel_special(index,count,f,mfl,listp)
! 573: int index,count;
! 574: P f;
! 575: P *mfl;
! 576: ML *listp;
! 577: {
! 578: register int i,j;
! 579: int q,n,t,d,r,u,br,tmp,bound;
! 580: int *c,*p,*m,*w;
! 581: int **pp;
! 582: DCP dc;
! 583: ML blist,clist,bqlist,cqlist,rlist;
! 584: UM *b;
! 585: LUM fl,tl;
! 586: LUM *l;
! 587:
! 588: blist = MLALLOC(40); blist->n = 40; blist->mod = 11;
! 589: for ( i = 0; i < 40; i++ ) {
! 590: blist->c[i] = (pointer)UMALLOC(6);
! 591: ptoum(11,mfl[i],blist->c[i]);
! 592: }
! 593: gcdgen(f,blist,&clist); henprep(f,blist,clist,&bqlist,&cqlist);
! 594: n = bqlist->n; q = bqlist->mod;
! 595: bqlist->bound = cqlist->bound = bound = mignotte(q,f);
! 596: if ( bound == 1 ) {
! 597: *listp = rlist = MLALLOC(n);
! 598: rlist->n = n; rlist->mod = q; rlist->bound = bound;
! 599: for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c; i < n; i++ ) {
! 600: tl = LUMALLOC(DEG(b[i]),1); l[i] = tl; p = COEF(b[i]);
! 601: for ( j = 0, pp = COEF(tl); j <= DEG(tl); j++ )
! 602: pp[j][0] = p[j];
! 603: }
! 604: } else {
! 605: W_LUMALLOC(UDEG(f),bound,fl);
! 606: ptolum(q,bound,f,fl); henmain(fl,bqlist,cqlist,listp);
! 607: }
! 608: }
! 609: #endif
! 610:
! 611: #if 0
! 612: void Pftest(arg,rp)
! 613: NODE arg;
! 614: P *rp;
! 615: {
! 616: ML list;
! 617: DCP dc;
! 618: P p;
! 619: P *mfl;
! 620:
! 621: p = (P)ARG0(arg); mfl = (P *)(((VECT)ARG1(arg))->body);
! 622: hensel_special(2,1,p,mfl,&list);
! 623: dtest_special(p,list,rp);
! 624: }
! 625:
! 626: void dtest_special(f,list,pr)
! 627: P f;
! 628: ML list;
! 629: P *pr;
! 630: {
! 631: int n,np,bound,q;
! 632: int i,j,k,t,b0;
! 633: int *win;
! 634: P g,factor,cofactor;
! 635: Q csum,csumt;
! 636: DCP dc,dcf,dcf0;
! 637: LUM *c;
! 638: ML wlist;
! 639: static int nbits[16] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
! 640:
! 641: n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
! 642: win = W_ALLOC(np+1);
! 643: ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
! 644: wlist = W_MLALLOC(np); wlist->n = list->n;
! 645: wlist->mod = list->mod; wlist->bound = list->bound;
! 646: c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
! 647: for ( g = f, i = 0; i < (1<<23); i++ ) {
! 648: #if 0
! 649: if ( !(i % 1000) )
! 650: fprintf(stderr,"i=%d\n",i);
! 651: #endif
! 652: t = i>>20; b0 = nbits[t];
! 653: if ( !b0 )
! 654: continue;
! 655: for ( j = 1; j < 6; j++ ) {
! 656: t = (i>>(20-4*j))&0xf;
! 657: if ( nbits[t] != b0 )
! 658: break;
! 659: }
! 660: if ( j != 6 )
! 661: continue;
! 662: for ( j = k = 0; j < 24; j++ )
! 663: if ( i & (1<<(23-j)) )
! 664: win[k++] = j;
! 665: if ( dtestmain(g,csum,wlist,k,win,&factor,&cofactor) ) {
! 666: #if 0
! 667: fprintf(stderr,"success : i=%d\n",i);
! 668: #endif
! 669: *pr = factor; return;
! 670: }
! 671: }
! 672: *pr = f;
! 673: }
! 674:
! 675: void hensel_special(index,count,f,mfl,listp)
! 676: int index,count;
! 677: P f;
! 678: P *mfl;
! 679: ML *listp;
! 680: {
! 681: register int i,j;
! 682: int q,n,t,d,r,u,br,tmp,bound;
! 683: int *c,*p,*m,*w;
! 684: int **pp;
! 685: DCP dc;
! 686: ML blist,clist,bqlist,cqlist,rlist;
! 687: UM *b;
! 688: LUM fl,tl;
! 689: LUM *l;
! 690:
! 691: blist = MLALLOC(24); blist->n = 24; blist->mod = 5;
! 692: for ( i = 0; i < 24; i++ ) {
! 693: blist->c[i] = (pointer)UMALLOC(7);
! 694: ptoum(5,mfl[i],blist->c[i]);
! 695: }
! 696: gcdgen(f,blist,&clist); henprep(f,blist,clist,&bqlist,&cqlist);
! 697: n = bqlist->n; q = bqlist->mod;
! 698: bqlist->bound = cqlist->bound = bound = mignotte(q,f);
! 699: if ( bound == 1 ) {
! 700: *listp = rlist = MLALLOC(n);
! 701: rlist->n = n; rlist->mod = q; rlist->bound = bound;
! 702: for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c; i < n; i++ ) {
! 703: tl = LUMALLOC(DEG(b[i]),1); l[i] = tl; p = COEF(b[i]);
! 704: for ( j = 0, pp = COEF(tl); j <= DEG(tl); j++ )
! 705: pp[j][0] = p[j];
! 706: }
! 707: } else {
! 708: W_LUMALLOC(UDEG(f),bound,fl);
! 709: ptolum(q,bound,f,fl); henmain(fl,bqlist,cqlist,listp);
! 710: }
! 711: }
! 712: #endif
! 713:
! 714: void Pftest(NODE arg,P *rp)
! 715: {
! 716: ML list;
! 717: P p;
! 718: P *mfl;
! 719:
! 720: p = (P)ARG0(arg); mfl = (P *)(((VECT)ARG1(arg))->body);
! 721: hensel_special(5,1,p,mfl,&list);
! 722: dtest_special(p,list,rp);
! 723: }
! 724:
! 725: int nbits(int a)
! 726: {
! 727: int i,s;
! 728:
! 729: for ( i = 0, s = 0; a && (i < 20); i++, a >>= 1 )
! 730: if ( a & 1 ) s++;
! 731: return s;
! 732: }
! 733:
! 734: void dtest_special(P f,ML list,P *pr)
! 735: {
! 736: int n,np,bound,q;
! 737: int i,j,k,b0;
! 738: int *win;
! 739: P g,factor,cofactor;
! 740: Q csum,csumt;
! 741: LUM *c;
! 742: ML wlist;
! 743:
! 744: n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
! 745: win = W_ALLOC(np+1);
! 746: ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
! 747: wlist = W_MLALLOC(np); wlist->n = list->n;
! 748: wlist->mod = list->mod; wlist->bound = list->bound;
! 749: c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
! 750: for ( g = f, i = 0; i < (1<<19); i++ ) {
! 751: #if 0
! 752: if ( !(i % 10000) )
! 753: fprintf(stderr,"i=%d\n",i);
! 754: #endif
! 755: b0 = nbits(i>>10);
! 756: if ( !b0 || (nbits(i&0x3ff) != b0) )
! 757: continue;
! 758: for ( j = k = 0; j < 20; j++ )
! 759: if ( i & (1<<(19-j)) )
! 760: win[k++] = j;
! 761: if ( dtestmain(g,csum,wlist,k,win,&factor,&cofactor) ) {
! 762: #if 0
! 763: fprintf(stderr,"success : i=%d\n",i);
! 764: #endif
! 765: *pr = factor; return;
! 766: }
! 767: }
! 768: *pr = f;
! 769: }
! 770:
! 771: void hensel_special(int index,int count,P f,P *mfl,ML *listp)
! 772: {
! 773: register int i,j;
! 774: int q,n,bound;
! 775: int *p;
! 776: int **pp;
! 777: ML blist,clist,bqlist,cqlist,rlist;
! 778: UM *b;
! 779: LUM fl,tl;
! 780: LUM *l;
! 781:
! 782: blist = MLALLOC(20); blist->n = 20; blist->mod = 11;
! 783: for ( i = 0; i < 20; i++ ) {
! 784: blist->c[i] = (pointer)UMALLOC(10);
! 785: ptoum(11,mfl[i],blist->c[i]);
! 786: }
! 787: gcdgen(f,blist,&clist); henprep(f,blist,clist,&bqlist,&cqlist);
! 788: n = bqlist->n; q = bqlist->mod;
! 789: bqlist->bound = cqlist->bound = bound = mignotte(q,f);
! 790: if ( bound == 1 ) {
! 791: *listp = rlist = MLALLOC(n);
! 792: rlist->n = n; rlist->mod = q; rlist->bound = bound;
! 793: for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c; i < n; i++ ) {
! 794: tl = LUMALLOC(DEG(b[i]),1); l[i] = tl; p = COEF(b[i]);
! 795: for ( j = 0, pp = COEF(tl); j <= DEG(tl); j++ )
! 796: pp[j][0] = p[j];
! 797: }
! 798: } else {
! 799: W_LUMALLOC((int)UDEG(f),bound,fl);
! 800: ptolum(q,bound,f,fl); henmain(fl,bqlist,cqlist,listp);
! 801: }
! 802: }
! 803:
! 804: void Pnullspace(NODE arg,LIST *rp)
! 805: {
! 806: int i,j,n,mod;
! 807: MAT mat,r;
! 808: VECT u;
! 809: V v;
! 810: P p,z;
! 811: Z q;
! 812: UM **w;
! 813: UM mp;
! 814: P *t;
! 815: UM *s;
! 816: int *ind;
! 817: NODE n0,n1;
! 818:
! 819: mat = (MAT)ARG0(arg);
! 820: p = (P)ARG1(arg);
! 821: v = VR(p);
! 822: mod = QTOS((Q)ARG2(arg));
! 823: n = mat->row;
! 824: w = (UM **)almat_pointer(n,n);
! 825: for ( i = 0; i < n; i++ )
! 826: for ( j = 0, t = (P *)mat->body[i], s = w[i]; j < n; j++ ) {
! 827: ptomp(mod,t[j],&z);
! 828: s[j] = W_UMALLOC((z&&!NUM(z))?UDEG(z):0);
! 829: mptoum(z,s[j]);
! 830: }
! 831: mp = W_UMALLOC(UDEG(p)); ptoum(mod,p,mp);
! 832: ind = (int *)ALLOCA(n*sizeof(int));
! 833: nullspace(w,mp,mod,n,ind);
! 834: MKMAT(r,n,n);
! 835: for ( i = 0; i < n; i++ )
! 836: for ( j = 0, t = (P *)r->body[i], s = w[i]; j < n; j++ )
! 837: umtop(v,s[j],&t[j]);
! 838: MKVECT(u,n);
! 839: for ( i = 0; i < n; i++ ) {
! 840: STOQ(ind[i],q); u->body[i] = (pointer)q;
! 841: }
! 842: MKNODE(n1,u,0); MKNODE(n0,r,n1); MKLIST(*rp,n0);
! 843: }
! 844:
! 845: void nullspace(UM **mat,UM p,int mod,int n,int *ind)
! 846: {
! 847: int i,j,l,s,d;
! 848: UM q,w,w1,h,inv;
! 849: UM *t,*u;
! 850:
! 851: d = DEG(p); inv = W_UMALLOC(d); q = W_UMALLOC(2*d);
! 852: w = W_UMALLOC(2*d); w1 = W_UMALLOC(2*d); h = W_UMALLOC(d);
! 853: bzero(ind,n*sizeof(int));
! 854: ind[0] = 0;
! 855: for ( i = j = 0; j < n; i++, j++ ) {
! 856: for ( ; j < n; j++ ) {
! 857: for ( l = i; l < n; l++ )
! 858: if ( DEG(mat[l][j])>=0 )
! 859: break;
! 860: if ( l < n ) {
! 861: t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
! 862: } else
! 863: ind[j] = 1;
! 864: }
! 865: if ( j == n )
! 866: break;
! 867: invum(mod,p,mat[i][j],inv);
! 868: for ( s = j, t = mat[i]; s < n; s++ ) {
! 869: mulum(mod,t[s],inv,w);
! 870: DEG(w) = divum(mod,w,p,q);
! 871: cpyum(w,t[s]);
! 872: }
! 873: for ( l = 0; l < n; l++ ) {
! 874: if ( l == i )
! 875: continue;
! 876: u = mat[l]; DEG(w) = -1; subum(mod,w,u[j],h);
! 877: for ( s = j; s < n; s++ ) {
! 878: mulum(mod,h,t[s],w); addum(mod,w,u[s],w1);
! 879: DEG(w1) = divum(mod,w1,p,q); cpyum(w1,u[s]);
! 880: }
! 881: }
! 882: }
! 883: }
! 884:
! 885: void Pnullspace_ff(NODE arg,LIST *rp)
! 886: {
! 887: int i,j,n;
! 888: MAT mat,r;
! 889: VECT u;
! 890: Z q;
! 891: Obj **w;
! 892: Obj *t;
! 893: Obj *s;
! 894: int *ind;
! 895: NODE n0,n1;
! 896:
! 897: mat = (MAT)ARG0(arg);
! 898: n = mat->row;
! 899: w = (Obj **)almat_pointer(n,n);
! 900: for ( i = 0; i < n; i++ )
! 901: for ( j = 0, t = (Obj *)mat->body[i], s = w[i]; j < n; j++ )
! 902: s[j] = t[j];
! 903: ind = (int *)ALLOCA(n*sizeof(int));
! 904: switch ( current_ff ) {
! 905: case FF_GFP:
! 906: nullspace_lm((LM **)w,n,ind); break;
! 907: case FF_GF2N:
! 908: nullspace_gf2n((GF2N **)w,n,ind); break;
! 909: case FF_GFPN:
! 910: nullspace_gfpn((GFPN **)w,n,ind); break;
! 911: case FF_GFS:
! 912: nullspace_gfs((GFS **)w,n,ind); break;
! 913: case FF_GFSN:
! 914: nullspace_gfsn((GFSN **)w,n,ind); break;
! 915: default:
! 916: error("nullspace_ff : current_ff is not set");
! 917: }
! 918: MKMAT(r,n,n);
! 919: for ( i = 0; i < n; i++ )
! 920: for ( j = 0, t = (Obj *)r->body[i], s = w[i]; j < n; j++ )
! 921: t[j] = s[j];
! 922: MKVECT(u,n);
! 923: for ( i = 0; i < n; i++ ) {
! 924: STOQ(ind[i],q); u->body[i] = (pointer)q;
! 925: }
! 926: MKNODE(n1,u,0); MKNODE(n0,r,n1); MKLIST(*rp,n0);
! 927: }
! 928:
! 929: void nullspace_lm(LM **mat,int n,int *ind)
! 930: {
! 931: int i,j,l,s;
! 932: Z q,z,mod;
! 933: LM w,w1,h,inv;
! 934: LM *t,*u;
! 935:
! 936: getmod_lm(&mod);
! 937:
! 938: bzero(ind,n*sizeof(int));
! 939: ind[0] = 0;
! 940: for ( i = j = 0; j < n; i++, j++ ) {
! 941: for ( ; j < n; j++ ) {
! 942: for ( l = i; l < n; l++ ) {
! 943: simplm(mat[l][j],&w); mat[l][j] = w;
! 944: if ( mat[l][j] )
! 945: break;
! 946: }
! 947: if ( l < n ) {
! 948: t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
! 949: } else
! 950: ind[j] = 1;
! 951: }
! 952: if ( j == n )
! 953: break;
! 954: lmtolf(mat[i][j],&q); invz(q,mod,&z); MKLM(BDY(z),inv);
! 955: for ( s = j, t = mat[i]; s < n; s++ ) {
! 956: mullm(t[s],inv,&w); t[s] = w;
! 957: }
! 958: for ( l = 0; l < n; l++ ) {
! 959: if ( l == i )
! 960: continue;
! 961: u = mat[l]; chsgnlm(u[j],&h);
! 962: for ( s = j; s < n; s++ ) {
! 963: mullm(h,t[s],&w); addlm(w,u[s],&w1); u[s] = w1;
! 964: }
! 965: }
! 966: }
! 967: }
! 968:
! 969: void nullspace_gf2n(GF2N **mat,int n,int *ind)
! 970: {
! 971: int i,j,l,s;
! 972: GF2N w,w1,h,inv;
! 973: GF2N *t,*u;
! 974: extern int gf2n_lazy;
! 975:
! 976: bzero(ind,n*sizeof(int));
! 977: ind[0] = 0;
! 978: for ( i = j = 0; j < n; i++, j++ ) {
! 979: for ( ; j < n; j++ ) {
! 980: for ( l = i; l < n; l++ ) {
! 981: simpgf2n(mat[l][j],&w); mat[l][j] = w;
! 982: if ( mat[l][j] )
! 983: break;
! 984: }
! 985: if ( l < n ) {
! 986: t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
! 987: } else
! 988: ind[j] = 1;
! 989: }
! 990: if ( j == n )
! 991: break;
! 992: invgf2n(mat[i][j],&inv);
! 993: for ( s = j, t = mat[i]; s < n; s++ ) {
! 994: mulgf2n(t[s],inv,&w); t[s] = w;
! 995: }
! 996: for ( l = 0; l < n; l++ ) {
! 997: if ( l == i )
! 998: continue;
! 999: u = mat[l]; h = u[j];
! 1000: for ( s = j; s < n; s++ ) {
! 1001: mulgf2n(h,t[s],&w); addgf2n(w,u[s],&w1); u[s] = w1;
! 1002: }
! 1003: }
! 1004: }
! 1005: }
! 1006:
! 1007: void nullspace_gfpn(GFPN **mat,int n,int *ind)
! 1008: {
! 1009: int i,j,l,s;
! 1010: GFPN w,w1,h,inv;
! 1011: GFPN *t,*u;
! 1012:
! 1013: bzero(ind,n*sizeof(int));
! 1014: ind[0] = 0;
! 1015: for ( i = j = 0; j < n; i++, j++ ) {
! 1016: for ( ; j < n; j++ ) {
! 1017: for ( l = i; l < n; l++ ) {
! 1018: simpgfpn(mat[l][j],&w); mat[l][j] = w;
! 1019: if ( mat[l][j] )
! 1020: break;
! 1021: }
! 1022: if ( l < n ) {
! 1023: t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
! 1024: } else
! 1025: ind[j] = 1;
! 1026: }
! 1027: if ( j == n )
! 1028: break;
! 1029: divgfpn((GFPN)ONE,(GFPN)mat[i][j],&inv);
! 1030: for ( s = j, t = mat[i]; s < n; s++ ) {
! 1031: mulgfpn(t[s],inv,&w); t[s] = w;
! 1032: }
! 1033: for ( l = 0; l < n; l++ ) {
! 1034: if ( l == i )
! 1035: continue;
! 1036: u = mat[l]; chsgngfpn(u[j],&h);
! 1037: for ( s = j; s < n; s++ ) {
! 1038: mulgfpn(h,t[s],&w); addgfpn(w,u[s],&w1); u[s] = w1;
! 1039: }
! 1040: }
! 1041: }
! 1042: }
! 1043:
! 1044: void nullspace_gfs(GFS **mat,int n,int *ind)
! 1045: {
! 1046: int i,j,l,s;
! 1047: GFS w,w1,h,inv;
! 1048: GFS *t,*u;
! 1049: GFS one;
! 1050:
! 1051: bzero(ind,n*sizeof(int));
! 1052: ind[0] = 0;
! 1053: mqtogfs(ONEM,&one);
! 1054:
! 1055: for ( i = j = 0; j < n; i++, j++ ) {
! 1056: for ( ; j < n; j++ ) {
! 1057: for ( l = i; l < n; l++ )
! 1058: if ( mat[l][j] )
! 1059: break;
! 1060: if ( l < n ) {
! 1061: t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
! 1062: } else
! 1063: ind[j] = 1;
! 1064: }
! 1065: if ( j == n )
! 1066: break;
! 1067: divgfs(one,mat[i][j],&inv);
! 1068: for ( s = j, t = mat[i]; s < n; s++ ) {
! 1069: mulgfs(t[s],inv,&w); t[s] = w;
! 1070: }
! 1071: for ( l = 0; l < n; l++ ) {
! 1072: if ( l == i )
! 1073: continue;
! 1074: u = mat[l];
! 1075: chsgngfs(u[j],&h);
! 1076: for ( s = j; s < n; s++ ) {
! 1077: mulgfs(h,t[s],&w); addgfs(w,u[s],&w1); u[s] = w1;
! 1078: }
! 1079: }
! 1080: }
! 1081: }
! 1082:
! 1083: void nullspace_gfsn(GFSN **mat,int n,int *ind)
! 1084: {
! 1085: int i,j,l,s;
! 1086: GFSN w,w1,h,inv;
! 1087: GFSN *t,*u;
! 1088:
! 1089: bzero(ind,n*sizeof(int));
! 1090: ind[0] = 0;
! 1091:
! 1092: for ( i = j = 0; j < n; i++, j++ ) {
! 1093: for ( ; j < n; j++ ) {
! 1094: for ( l = i; l < n; l++ )
! 1095: if ( mat[l][j] )
! 1096: break;
! 1097: if ( l < n ) {
! 1098: t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
! 1099: } else
! 1100: ind[j] = 1;
! 1101: }
! 1102: if ( j == n )
! 1103: break;
! 1104: invgfsn(mat[i][j],&inv);
! 1105: for ( s = j, t = mat[i]; s < n; s++ ) {
! 1106: mulgfsn(t[s],inv,&w); t[s] = w;
! 1107: }
! 1108: for ( l = 0; l < n; l++ ) {
! 1109: if ( l == i )
! 1110: continue;
! 1111: u = mat[l];
! 1112: chsgngfsn(u[j],&h);
! 1113: for ( s = j; s < n; s++ ) {
! 1114: mulgfsn(h,t[s],&w); addgfsn(w,u[s],&w1); u[s] = w1;
! 1115: }
! 1116: }
! 1117: }
! 1118: }
! 1119:
! 1120: /* p = a(0)vl[0]+a(1)vl[1]+...+a(m-1)vl[m-1]+a(m) -> array = [a(0) a(1) ... a(m)] */
! 1121:
! 1122: void linear_form_to_array(P p,VL vl,int m,Num *array)
! 1123: {
! 1124: int i;
! 1125: DCP dc;
! 1126:
! 1127: bzero((char *)array,(m+1)*sizeof(Num *));
! 1128: for ( i = 0; p && vl; vl = NEXT(vl), i++ ) {
! 1129: if ( ID(p) == O_N )
! 1130: break;
! 1131: else if ( VR(p) == vl->v ) {
! 1132: dc = DC(p);
! 1133: array[i] = (Num)COEF(dc);
! 1134: dc = NEXT(dc);
! 1135: p = dc ? COEF(dc) : 0;
! 1136: }
! 1137: }
! 1138: array[m] = (Num)p;
! 1139: }
! 1140:
! 1141: void array_to_linear_form(Num *array,VL vl,int m,P *r)
! 1142: {
! 1143: P t;
! 1144: DCP dc0,dc1;
! 1145:
! 1146: if ( !m )
! 1147: *r = (P)array[0];
! 1148: else {
! 1149: array_to_linear_form(array+1,NEXT(vl),m-1,&t);
! 1150: if ( !array[0] )
! 1151: *r = t;
! 1152: else {
! 1153: NEWDC(dc0); DEG(dc0) = ONE; COEF(dc0) = (P)array[0];
! 1154: if ( !t )
! 1155: NEXT(dc0) = 0;
! 1156: else {
! 1157: NEWDC(dc1); DEG(dc1) = 0; COEF(dc1) = t;
! 1158: NEXT(dc1) = 0;
! 1159: NEXT(dc0) = dc1;
! 1160: }
! 1161: MKP(vl->v,dc0,*r);
! 1162: }
! 1163: }
! 1164: }
! 1165:
! 1166: void Psolve_linear_equation_gf2n(NODE arg,LIST *rp)
! 1167: {
! 1168: NODE eqs,tn;
! 1169: VL vars,tvl;
! 1170: int i,j,n,m,dim,codim;
! 1171: GF2N **w;
! 1172: int *ind;
! 1173: NODE n0,n1;
! 1174:
! 1175: get_vars(ARG0(arg),&vars);
! 1176: eqs = BDY((LIST)ARG0(arg));
! 1177: for ( n = 0, tn = eqs; tn; tn = NEXT(tn), n++);
! 1178: for ( m = 0, tvl = vars; tvl; tvl = NEXT(tvl), m++);
! 1179: w = (GF2N **)almat_pointer(n,m+1);
! 1180: for ( i = 0, tn = eqs; i < n; i++, tn = NEXT(tn) )
! 1181: linear_form_to_array(BDY(tn),vars,m,(Num *)w[i]);
! 1182: ind = (int *)ALLOCA(m*sizeof(int));
! 1183: solve_linear_equation_gf2n(w,n,m,ind);
! 1184: for ( j = 0, dim = 0; j < m; j++ )
! 1185: if ( ind[j] )
! 1186: dim++;
! 1187: codim = m-dim;
! 1188: for ( i = codim; i < n; i++ )
! 1189: if ( w[i][m] ) {
! 1190: MKLIST(*rp,0); return;
! 1191: }
! 1192: for ( i = 0, n0 = 0; i < codim; i++ ) {
! 1193: NEXTNODE(n0,n1);
! 1194: array_to_linear_form((Num *)w[i],vars,m,(P *)&BDY(n1));
! 1195: }
! 1196: if ( n0 )
! 1197: NEXT(n1) = 0;
! 1198: MKLIST(*rp,n0);
! 1199: }
! 1200:
! 1201: void solve_linear_equation_gf2n(GF2N **mat,int n,int m,int *ind)
! 1202: {
! 1203: int i,j,l,s;
! 1204: GF2N w,w1,h,inv;
! 1205: GF2N *t,*u;
! 1206: extern int gf2n_lazy;
! 1207:
! 1208: bzero(ind,m*sizeof(int));
! 1209: ind[0] = 0;
! 1210: for ( i = j = 0; j < m; i++, j++ ) {
! 1211: for ( ; j < m; j++ ) {
! 1212: for ( l = i; l < n; l++ ) {
! 1213: simpgf2n(mat[l][j],&w); mat[l][j] = w;
! 1214: if ( mat[l][j] )
! 1215: break;
! 1216: }
! 1217: if ( l < n ) {
! 1218: t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
! 1219: } else
! 1220: ind[j] = 1;
! 1221: }
! 1222: if ( j == m )
! 1223: break;
! 1224: invgf2n(mat[i][j],&inv);
! 1225: for ( s = j, t = mat[i]; s <= m; s++ ) {
! 1226: mulgf2n(t[s],inv,&w); t[s] = w;
! 1227: }
! 1228: for ( l = 0; l < n; l++ ) {
! 1229: if ( l == i )
! 1230: continue;
! 1231: u = mat[l]; h = u[j];
! 1232: for ( s = j; s <= m; s++ ) {
! 1233: mulgf2n(h,t[s],&w); addgf2n(w,u[s],&w1); u[s] = w1;
! 1234: }
! 1235: }
! 1236: }
! 1237: }
! 1238:
! 1239: /*
! 1240: void null_to_sol(mat,ind,mod,n,r)
! 1241: int **mat;
! 1242: int *ind;
! 1243: int mod,n;
! 1244: UM *r;
! 1245: {
! 1246: int i,j,k,l;
! 1247: int *c;
! 1248: UM w;
! 1249:
! 1250: for ( i = 0, l = 0; i < n; i++ ) {
! 1251: if ( !ind[i] )
! 1252: continue;
! 1253: w = UMALLOC(n);
! 1254: for ( j = k = 0, c = COEF(w); j < n; j++ )
! 1255: if ( ind[j] )
! 1256: c[j] = 0;
! 1257: else
! 1258: c[j] = mat[k++][i];
! 1259: c[i] = mod-1;
! 1260: for ( j = n; j >= 0; j-- )
! 1261: if ( c[j] )
! 1262: break;
! 1263: DEG(w) = j;
! 1264: r[l++] = w;
! 1265: }
! 1266: }
! 1267: */
! 1268:
! 1269: void showgfmat(UM **mat,int n)
! 1270: {
! 1271: int i,j,k;
! 1272: int *c;
! 1273: UM p;
! 1274:
! 1275: for ( i = 0; i < n; i++ ) {
! 1276: for ( j = 0; j < n; j++ ) {
! 1277: p = mat[i][j];
! 1278: if ( DEG(p) < 0 )
! 1279: fprintf(asir_out,"0");
! 1280: else
! 1281: for ( p = mat[i][j], k = DEG(p), c = COEF(p); k >= 0; k-- ) {
! 1282: if ( c[k] )
! 1283: fprintf(asir_out,"+%d",c[k]);
! 1284: if ( k > 1 )
! 1285: fprintf(asir_out,"a^%d",k);
! 1286: else if ( k == 1 )
! 1287: fprintf(asir_out,"a",k);
! 1288: }
! 1289: fprintf(asir_out," ");
! 1290: }
! 1291: fprintf(asir_out,"\n");
! 1292: }
! 1293: }
! 1294:
! 1295: #if 0
! 1296: void Pgcda_mod(arg,rp)
! 1297: NODE arg;
! 1298: P *rp;
! 1299: {
! 1300: p1 = (P)ARG0(arg);
! 1301: p2 = (P)ARG1(arg);
! 1302: v = VR((P)ARG2(arg));
! 1303: d = (P)ARG3(arg);
! 1304: m = QTOS((Q)ARG4(arg));
! 1305: reordvar(CO,v,&vl);
! 1306: reorderp(vl,CO,p1,&t); ptomp(m,t,&m1);
! 1307: reorderp(vl,CO,p2,&t); ptomp(m,t,&m2);
! 1308: if ( NUM(m1) || NUM(m2) || VR(m1) != v || VR(m2) != v ) {
! 1309: *rp = ONE; return;
! 1310: }
! 1311: if ( deg(v,m1) >= deg(v,m2) ) {
! 1312: t = m1; m1 = m2; m2 = t;
! 1313: }
! 1314: while ( 1 ) {
! 1315: inva_mod(COEF(DC(m2)),d,m,&inv);
! 1316: NEWDC(dc); NEXT(dc) = 0; MKP(v,dc,h);
! 1317: d0 = deg(v,m1)-deg(v,m2); STOQ(d0,DEG(dc));
! 1318: mulgq(m,d,inv,COEF(DC(m1)),&COEF(dc));
! 1319: mulgp(vl,m,d,m2,h,&t); subgp(vl,m,d,m1,t,&s);
! 1320: }
! 1321: }
! 1322: #endif
! 1323:
! 1324: void Ppwr_mod(NODE arg,P *rp)
! 1325: {
! 1326: P p,a,d,r;
! 1327: int m;
! 1328: Z n;
! 1329:
! 1330: m = QTOS((Q)ARG4(arg)); n = (Z)ARG5(arg);
! 1331: ptomp(m,(P)ARG0(arg),&p); ptomp(m,(P)ARG1(arg),&a);
! 1332: ptomp(m,(P)ARG3(arg),&d);
! 1333: pwr_mod(p,a,VR((P)ARG2(arg)),d,m,n,&r);
! 1334: mptop(r,rp);
! 1335: }
! 1336:
! 1337: void pwr_mod(P p,P a,V v,P d,int m,Z n,P *rp)
! 1338: {
! 1339: P t,s,r;
! 1340: Z n1,two,b;
! 1341:
! 1342: if ( !n )
! 1343: *rp = (P)ONEM;
! 1344: else if ( UNIZ(n) )
! 1345: *rp = p;
! 1346: else {
! 1347: STOQ(2,two);
! 1348: divqrz(n,two,&n1,&b);
! 1349: pwr_mod(p,a,v,d,m,n1,&t);
! 1350: mulmp(CO,m,t,t,&s); rem_mod(s,a,v,d,m,&r);
! 1351: if ( b ) {
! 1352: mulmp(CO,m,r,p,&t); rem_mod(t,a,v,d,m,rp);
! 1353: } else
! 1354: *rp = r;
! 1355: }
! 1356: }
! 1357:
! 1358: void rem_mod(P p,P a,V v,P d,int m,P *rp)
! 1359: {
! 1360: P tmp,r1,r2;
! 1361:
! 1362: divsrmp(CO,m,p,d,&tmp,&r1);
! 1363: divsrmp(CO,m,r1,a,&tmp,&r2);
! 1364: divsrmp(CO,m,r2,d,&tmp,rp);
! 1365: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>