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