=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/Hgfs.c,v retrieving revision 1.19 retrieving revision 1.23 diff -u -p -r1.19 -r1.23 --- OpenXM_contrib2/asir2000/engine/Hgfs.c 2001/10/30 07:25:58 1.19 +++ OpenXM_contrib2/asir2000/engine/Hgfs.c 2002/09/27 08:40:48 1.23 @@ -1,8 +1,10 @@ -/* $OpenXM: OpenXM_contrib2/asir2000/engine/Hgfs.c,v 1.18 2001/10/09 01:36:10 noro Exp $ */ +/* $OpenXM: OpenXM_contrib2/asir2000/engine/Hgfs.c,v 1.22 2002/09/27 04:24:04 noro Exp $ */ #include "ca.h" +#include "inline.h" void lnfsf(int n,UM p0,UM p1,struct p_pair *list,UM np0,UM np1); +void extractcoefbm(BM f,int dx,UM r); int comp_dum(DUM a,DUM b) { @@ -26,7 +28,9 @@ void fctrsf(P p,DCP *dcp) simp_ff((Obj)p,&obj); p = (P)obj; if ( !p ) { - *dcp = 0; return; + NEWDC(dc); COEF(dc) = 0; DEG(dc) = ONE; + NEXT(dc) = 0; *dcp = dc; + return; } mp = W_UMALLOC(UDEG(p)); ptosfum(p,mp); @@ -509,7 +513,7 @@ void ptosfbm(int,P,BM); /* f = f(x,y) */ -void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *listp) +void sfhensel(int count,P f,V x,int degbound,GFS *evp,P *sfp,ML *listp) { int i; int fn; @@ -520,7 +524,7 @@ void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *li int dx,dy,bound; GFS ev; P f1,t,c,sf; - DCP dc; + DCP dc,dct,dc0; UM q,fm,hm; UM *gm; struct oEGT tmp0,tmp1,eg_hensel,eg_hensel_t; @@ -543,9 +547,35 @@ void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *li *listp = rlist = MLALLOC(1); rlist->n = fn; rlist->c[0] = 0; return; } - /* pass the the leading coeff. to the first element */ - c = dc->c; dc = NEXT(dc); - mulp(vl,dc->c,c,&t); dc->c = t; + if ( degbound >= 0 ) { + /* + * reconstruct dc so that + * dc[1],... : factors satisfy degree bound + * dc[0] : product of others + */ + c = dc->c; dc = NEXT(dc); + dc0 = 0; + fn = 0; + while ( dc ) { + if ( getdeg(x,COEF(dc)) <= degbound ) { + dct = NEXT(dc); NEXT(dc) = dc0; dc0 = dc; dc = dct; + fn++; + } else { + mulp(vl,COEF(dc),c,&t); c = t; + dc = NEXT(dc); + } + } + if ( OID(c) == O_P ) { + NEWDC(dc); COEF(dc) = c; DEG(dc) = ONE; NEXT(dc) = dc0; + fn++; + } else { + mulp(vl,dc0->c,c,&t); dc0->c = t; dc = dc0; + } + } else { + /* pass the the leading coeff. to the first element */ + c = dc->c; dc = NEXT(dc); + mulp(vl,dc->c,c,&t); dc->c = t; + } /* convert mod y-a factors into UM */ gm = (UM *)ALLOCA(fn*sizeof(UM)); @@ -555,6 +585,8 @@ void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *li } /* set bound */ + /* g | f, lc_y(g) = lc_y(f) => deg_y(g) <= deg_y(f) */ + /* so, bound = dy is sufficient, but we use slightly large value */ bound = dy+2; /* f(x,y) -> f(x,y+ev) */ @@ -618,7 +650,7 @@ int sfberle(VL vl,P f,int count,GFS *ev,DCP *dcp) V x,y; P lc,lc0,f0; Obj obj; - int j,q1,index,i; + int j,q,index,i; clctv(vl,f,&nvl); vl = nvl; x = vl->v; y = vl->next->v; @@ -626,11 +658,11 @@ int sfberle(VL vl,P f,int count,GFS *ev,DCP *dcp) n = QTOS(DEG(DC(f))); wf = W_UMALLOC(n); wf1 = W_UMALLOC(n); wf2 = W_UMALLOC(n); wfs = W_UMALLOC(n); gcd = W_UMALLOC(n); - q1 = field_order_sf()-1; + q = field_order_sf(); lc = DC(f)->c; for ( j = 0, fn = n + 1, index = 0; - index < q1 && j < count && fn > 1; index++ ) { - MKGFS(index,m); + index < q && j < count && fn > 1; index++ ) { + indextogfs(index,&m); substp(vl,lc,y,(P)m,&lc0); if ( lc0 ) { substp(vl,f,y,(P)m,&f0); @@ -646,7 +678,7 @@ int sfberle(VL vl,P f,int count,GFS *ev,DCP *dcp) } } } - if ( index == q1 ) + if ( index == q ) return 0; else if ( fn == 1 ) return 1; @@ -833,7 +865,7 @@ void sfbmtop(BM f,V x,V y,P *fp) if ( DEG(c[j]) >= i && (a = COEF(c[j])[i]) ) { NEWDC(dct); STOQ(j,DEG(dct)); - MKGFS(IFTOF(a),b); + iftogfs(a,&b); COEF(dct) = (P)b; NEXT(dct) = dc; dc = dct; @@ -866,8 +898,10 @@ void sfsqfr(P f,DCP *dcp) NEWDC(dc); DEG(dc) = ONE; COEF(dc) = f; NEXT(dc) = 0; *dcp = dc; } else if ( !NEXT(vl) ) sfusqfr(f,dcp); +#if 0 else if ( !NEXT(NEXT(vl)) ) sfbsqfr(f,vl->v,NEXT(vl)->v,dcp); +#endif else error("sfsqfr : not implemented yet"); } @@ -900,16 +934,21 @@ void sfusqfr(P f,DCP *dcp) *dcp = dct; } +void sfbsqfrmain(P f,V x,V y,DCP *dcp) +{ + /* XXX*/ +} + +/* f is bivariate */ + void sfbsqfr(P f,V x,V y,DCP *dcp) { P t,rf,cx,cy; VL vl,rvl; - DCP dcx,dcy; + DCP dcx,dcy,dct,dc; struct oVL vl0,vl1; - /* vl = [x,y] */ - vl0.v = x; vl0.next = &vl1; vl1.v = y; vl1.next = 0; vl = &vl0; - /* cy(y) = cont(f,x), f /= cx */ + /* cy(y) = cont(f,x), f /= cy */ cont_pp_sfp(vl,f,&cy,&t); f = t; /* rvl = [y,x] */ reordvar(vl,y,&rvl); reorderp(rvl,vl,f,&rf); @@ -918,13 +957,32 @@ void sfbsqfr(P f,V x,V y,DCP *dcp) reorderp(vl,rvl,rf,&f); /* f -> cx*cy*f */ - sfusqfr(cx,&dcx); - sfusqfr(cy,&dcy); + sfsqfr(cx,&dcx); dcx = NEXT(dcx); + sfsqfr(cy,&dcy); dcy = NEXT(dcy); + if ( dcx ) { + for ( dct = dcx; NEXT(dct); dct = NEXT(dct) ); + NEXT(dct) = dcy; + } else + dcx = dcy; + if ( OID(f) == O_N ) + *dcp = dcx; + else { + /* f must be bivariate */ + sfbsqfrmain(f,x,y,&dc); + if ( dcx ) { + for ( dct = dcx; NEXT(dct); dct = NEXT(dct) ); + NEXT(dct) = dc; + } else + dcx = dc; + *dcp = dcx; + } } void sfdtest(P,ML,V,V,DCP *); -void sfbfctr(P f,V x,V y,DCP *dcp) +/* if degbound >= 0 find factor s.t. deg_x(factor) <= degbound */ + +void sfbfctr(P f,V x,V y,int degbound,DCP *dcp) { ML list; P sf; @@ -934,7 +992,7 @@ void sfbfctr(P f,V x,V y,DCP *dcp) int dx,dy; /* sf(x) = f(x+ev) = list->c[0]*list->c[1]*... */ - sfhensel(5,f,x,&ev,&sf,&list); + sfhensel(5,f,x,degbound,&ev,&sf,&list); if ( list->n == 0 ) error("sfbfctr : short of evaluation points"); else if ( list->n == 1 ) { @@ -962,14 +1020,15 @@ void sfbfctr(P f,V x,V y,DCP *dcp) void sfdtest(P f,ML list,V x,V y,DCP *dcp) { int np,dx,dy; - int i,j,k; + int i,j,k,bound; int *win; P g,lcg,factor,cofactor,lcyx; P csum; DCP dcf,dcf0,dc; BM *c; BM lcy; - UM lcg0; + UM lcg0,lcy0,w; + UM *d1c; ML wlist; struct oVL vl1,vl0; VL vl; @@ -985,7 +1044,7 @@ void sfdtest(P f,ML list,V x,V y,DCP *dcp) win = W_ALLOC(np+1); wlist = W_MLALLOC(np); wlist->n = list->n; - wlist->bound = list->bound; + bound = wlist->bound = list->bound; c = (BM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(BM)*np)); @@ -1009,11 +1068,30 @@ void sfdtest(P f,ML list,V x,V y,DCP *dcp) NEWP(lcyx); VR(lcyx) = x; DC(lcyx) = dc; ptosfbm(dy,lcyx,lcy); + /* initialize lcy0 by LC(f) */ + lcy0 = W_UMALLOC(bound); + ptosfum(COEF(DC(g)),lcy0); + + /* ((d-1 coefs)*lcy0 */ + d1c = (UM *)W_ALLOC(np*sizeof(UM)); + w = W_UMALLOC(2*bound); + for ( i = 1; i < np; i++ ) { + extractcoefbm(c[i],degbm(c[i])-1,w); + d1c[i] = W_UMALLOC(2*bound); + mulsfum(w,lcy0,d1c[i]); + /* d1c[i] = d1c[i] mod y^(bound+1) */ + if ( DEG(d1c[i]) > bound ) { + for ( j = DEG(d1c[i]); j > bound; j-- ) + COEF(d1c[i])[j] = 0; + degum(d1c[i],bound); + } + } + fprintf(stderr,"np = %d\n",np); dtok = 0; for ( g = f, k = 1, dcf = dcf0 = 0, win[0] = 1, --np, z = 0; ; z++ ) { if ( !(z % 1000) ) fprintf(stderr,"."); - dt = sfdegtest(dy,wlist,k,win); + dt = sfdegtest(dy,bound,d1c,k,win); if ( dt ) dtok++; if ( dt && sfdtestmain(vl,lcg,lcg0,lcy,csum,wlist, @@ -1054,6 +1132,22 @@ void sfdtest(P f,ML list,V x,V y,DCP *dcp) else for ( i = 1; i < k; i++ ) win[i] = win[0] + i; + + + /* update lcy0 */ + ptosfum(COEF(DC(g)),lcy0); + + /* update d-1 coeffs */ + for ( i = 1; i <= np; i++ ) { + extractcoefbm(c[i],degbm(c[i])-1,w); + mulsfum(w,lcy0,d1c[i]); + /* d1c[i] = d1c[1] mod y^(bound+1) */ + if ( DEG(d1c[i]) > bound ) { + for ( j = DEG(d1c[i]); j > bound; j-- ) + COEF(d1c[i])[j] = 0; + degum(d1c[i],bound); + } + } } else if ( !ncombi(1,np,k,win) ) if ( k == np ) break; @@ -1066,15 +1160,15 @@ void sfdtest(P f,ML list,V x,V y,DCP *dcp) DEG(dcf) = ONE; NEXT(dcf) = 0; *dcp = dcf0; } -void extractcoefbm(BM f,int d,UM r) +void extractcoefbm(BM f,int dx,UM r) { int j; UM fj; for ( j = DEG(f); j >= 0; j-- ) { fj = COEF(f)[j]; - if ( fj && DEG(fj) >= d ) { - COEF(r)[j] = COEF(fj)[d]; + if ( fj && DEG(fj) >= dx ) { + COEF(r)[j] = COEF(fj)[dx]; } else COEF(r)[j] = 0; } @@ -1083,30 +1177,19 @@ void extractcoefbm(BM f,int d,UM r) /* deg_y(prod mod y^(bound+1)) <= dy ? */ -int sfdegtest(int dy,ML list,int k,int *in) +int sfdegtest(int dy,int bound,UM *d1c,int k,int *in) { - int bound,dx,dx1,i,j; - UM w,w1,w2,wt; + int i,j; + UM w,w1,wt; BM t; - bound = list->bound; w = W_UMALLOC(bound); w1 = W_UMALLOC(bound); - w2 = W_UMALLOC(bound); clearum(w,bound); for ( i = 0; i < k; i++ ) { - t = (BM)list->c[in[i]]; - dx = degbm(t); - dx1 = dx-1; - /* t = t->c[0] + t->c[1]*y + ... + t->c[j]*y^j + ... */ - /* extract coef. of x^dx1 and add it to w */ - extractcoefbm(t,dx1,w1); - addsfum(w,w1,w2); wt = w; w = w2; w2 = wt; + addsfum(w,d1c[in[i]],w1); wt = w; w = w1; w1 = wt; } - for ( j = bound; j >= dy; j-- ) - if ( COEF(w)[j] ) - break; - return j <= dy ? 1 : 0; + return DEG(w) <= dy ? 1 : 0; } /* lcy = LC(g), lcg = lcy*g, lcg0 = const part of lcg */ @@ -1239,7 +1322,7 @@ void cont_pp_sfp(VL vl,P f,P *cp,P *fp) y = vl->next->v; d = getdeg(y,f); if ( d == 0 ) { - MKGFS(0,g); + itogfs(1,&g); *cp = (P)g; *fp = f; /* XXX */ } else { @@ -1305,6 +1388,7 @@ int divtp_by_sfbm(VL vl,P f,P g,P *qp) /* XXX generate an irreducible poly of degree n */ extern int current_gfs_q1; +extern int *current_gfs_ntoi; void generate_defpoly_sfum(int n,UM *dp) { @@ -1332,8 +1416,12 @@ void generate_defpoly_sfum(int n,UM *dp) for ( j = 0; j < i; j++ ) w[j] = 0; w[i]++; - for ( i = 0; i < n; i++ ) - c[i] = w[i]?FTOIF(w[i]-1):0; + if ( !current_gfs_ntoi ) + for ( i = 0; i < n; i++ ) + c[i] = w[i]?FTOIF(w[i]):0; + else + for ( i = 0; i < n; i++ ) + c[i] = w[i]?FTOIF(w[i]-1):0; if ( !c[0] ) continue; diffsfum(r,dr); cpyum(r,t); gcdsfum(t,dr,g);