=================================================================== RCS file: /home/cvs/OpenXM/src/kan96xx/Kan/ecart.c,v retrieving revision 1.6 retrieving revision 1.10 diff -u -p -r1.6 -r1.10 --- OpenXM/src/kan96xx/Kan/ecart.c 2003/07/29 08:36:40 1.6 +++ OpenXM/src/kan96xx/Kan/ecart.c 2003/08/20 05:18:35 1.10 @@ -1,4 +1,4 @@ -/* $OpenXM: OpenXM/src/kan96xx/Kan/ecart.c,v 1.5 2003/07/19 06:03:57 takayama Exp $ */ +/* $OpenXM: OpenXM/src/kan96xx/Kan/ecart.c,v 1.9 2003/08/20 01:39:17 takayama Exp $ */ #include #include "datatype.h" #include "extern2.h" @@ -21,6 +21,7 @@ struct ecartPolyArray { }; static struct ecartReducer ecartFindReducer(POLY r,struct gradedPolySet *gset,struct ecartPolyArray *epa); +static struct ecartReducer ecartFindReducer_mod(POLY r,struct gradedPolySet *gset,struct ecartPolyArray *epa); static int ecartCheckPoly(POLY f); /* check if it does not contain s-variables */ static int ecartCheckEnv(); /* check if the environment is OK for ecart div*/ static struct ecartPolyArray *ecartPutPolyInG(POLY g,struct ecartPolyArray *eparray,POLY cf, POLY syz); @@ -32,10 +33,15 @@ static POLY reduction_ecart0(POLY r,struct gradedPolyS /* Automatic homogenization and s->1 */ static POLY reduction_ecart1(POLY r,struct gradedPolySet *gset, int needSyz, struct syz0 *syzp); +static POLY reduction_ecart1_mod(POLY r,struct gradedPolySet *gset); static POLY ecartCheckSyz0(POLY cf,POLY r_0,POLY syz, struct gradedPolySet *gg,POLY r); +static int shouldReduceContent(POLY f,int ss); -extern int DebugReductionRed; +extern int DebugReductionRed; +extern int TraceLift; +struct ring *TraceLift_ringmod; +extern DoCancel; int DebugReductionEcart = 0; /* This is used for goHomogenization */ @@ -241,10 +247,25 @@ POLY reduction_ecart(r,gset,needSyz,syzp) int needSyz; struct syz0 *syzp; /* set */ { - if (EcartAutomaticHomogenization) { - return reduction_ecart1(r,gset,needSyz,syzp); + POLY rn; + if (TraceLift) { + if (EcartAutomaticHomogenization) { + if (TraceLift_ringmod == NULL) { + warningPoly("reduction_ecart: TraceLift_ringmod is not set.\n"); + return reduction_ecart1(r,gset,needSyz,syzp); + } + rn = reduction_ecart1_mod(r,gset); /* BUG: syzygy is not obtained. */ + if (rn == POLYNULL) return rn; + else return reduction_ecart1(r,gset,needSyz,syzp); + }else{ + return reduction_ecart0(r,gset,needSyz,syzp); + } }else{ - return reduction_ecart0(r,gset,needSyz,syzp); + if (EcartAutomaticHomogenization) { + return reduction_ecart1(r,gset,needSyz,syzp); + }else{ + return reduction_ecart0(r,gset,needSyz,syzp); + } } } @@ -380,9 +401,11 @@ static POLY reduction_ecart1(r,gset,needSyz,syzp) POLY pp; int ell; int se; + struct coeff *cont; extern struct ring *CurrentRingp; struct ring *rp; + extern struct ring *SmallRingp; gg = NULL; if (needSyz) { @@ -400,22 +423,37 @@ static POLY reduction_ecart1(r,gset,needSyz,syzp) r = goHomogenize11(r,DegreeShifto_vec,DegreeShifto_size,-1,1); /* 1 means homogenize only s */ + if (DoCancel && (r != POLYNULL)) shouldReduceContent(r,1); + if (DebugReductionEcart&1) printf("=======================================\n"); do { - if (DebugReductionRed) printf("r=%s\n",POLYToString(r,'*',1)); + if (DebugReductionRed) printf("(ecart1(d)) r=%s\n",POLYToString(r,'*',1)); + if (DebugReductionEcart & 1) printf("r=%s+,,,\n",POLYToString(head(r),'*',1)); + ells = ecartFindReducer(r,gset,gg); ell = ells.ell; if (ell > 0) { + if (DebugReductionEcart & 2) printf("%"); gg = ecartPutPolyInG(r,gg,POLYNULL,POLYNULL); } if (ell >= 0) { if (ells.first) { pp = ((gset->polys[ells.grade])->gh)[ells.gseti]; }else{ + if (DebugReductionEcart & 4) {printf("+"); fflush(NULL);} pp = (gg->pa)[ells.ggi]; } if (ell > 0) r = mpMult(cxx(1,0,ell,rp),r); /* r = s^ell r */ r = (*reduction1)(r,pp,needSyz,&cc,&cg); + + if (DoCancel && (r != POLYNULL)) { /* BUG: syzygy should be corrected. */ + if (shouldReduceContent(r,0)) { + r = reduceContentOfPoly(r,&cont); + shouldReduceContent(r,1); + if (DebugReductionEcart || DebugReductionRed) printf("CONT=%d ",coeffToString(cont)); + } + } + if (needSyz) { if (ells.first) { cf = ppMult(cc,cf); @@ -442,6 +480,177 @@ static POLY reduction_ecart1(r,gset,needSyz,syzp) } r = goDeHomogenizeS(r); + if (DoCancel && (r != POLYNULL)) { /* BUG: syzygy should be corrected. */ + if (r->m->ringp->p == 0) { + if (coeffSizeMin(r) >= DoCancel) { + r = reduceContentOfPoly(r,&cont); + if (DebugReductionEcart || DebugReductionRed) printf("cont=%d ",coeffToString(cont)); + } + } + } return(r); +} + +/* Functions for trace lift */ +static struct ecartReducer ecartFindReducer_mod(POLY r, + struct gradedPolySet *gset, + struct ecartPolyArray *epa) +{ + int grd; + struct polySet *set; + int minGrade = 0; + int minGseti = 0; + int minGgi = 0; + int ell1 = LARGE; + int ell2 = LARGE; + int ell; + int i; + struct ecartReducer er; + /* Try to find a reducer in gset; */ + grd = 0; + while (grd < gset->maxGrade) { + set = gset->polys[grd]; + for (i=0; isize; i++) { + if (set->gh[i] == POLYNULL) { + /* goHomogenize set->gh[i] */ + if (EcartAutomaticHomogenization) { + set->gh[i] = goHomogenize11(set->g[i],DegreeShifto_vec,DegreeShifto_size,-1,1); + }else{ + set->gh[i] = set->g[i]; + } + } + if (TraceLift && (set->gmod[i] == POLYNULL)) { + set->gmod[i] = modulop(set->gh[i],TraceLift_ringmod); + } + if (TraceLift) { + ell = ecartGetEll(r,set->gmod[i]); + }else{ + ell = ecartGetEll(r,set->gh[i]); + } + if ((ell>=0) && (ell < ell1)) { + ell1 = ell; + minGrade = grd; minGseti=i; + } + } + grd++; + } + if (epa != NULL) { + /* Try to find in the second group. */ + for (i=0; i< epa->size; i++) { + ell = ecartGetEll(r,(epa->pa)[i]); + if ((ell>=0) && (ell < ell2)) { + ell2 = ell; + minGgi = i; + } + } + } + + if (DebugReductionRed || (DebugReductionEcart&1)) { + printf("ecartFindReducer_mod(): ell1=%d, ell2=%d, minGrade=%d, minGseti=%d, minGgi=%d, p=%d\n",ell1,ell2,minGrade,minGseti,minGgi,TraceLift_ringmod->p); + } + if (ell1 <= ell2) { + if (ell1 == LARGE) { + er.ell = -1; + return er; + }else{ + er.ell = ell1; + er.first = 1; + er.grade = minGrade; + er.gseti = minGseti; + return er; + } + }else{ + er.ell = ell2; + er.first = 0; + er.ggi = minGgi; + return er; + } +} + +static POLY reduction_ecart1_mod(r,gset) + POLY r; + struct gradedPolySet *gset; +{ + int reduced,reduced1,reduced2; + int grd; + struct polySet *set; + int i; + POLY cc,cg; + struct ecartReducer ells; + struct ecartPolyArray *gg; + POLY pp; + int ell; + int se; + + extern struct ring *CurrentRingp; + struct ring *rp; + + gg = NULL; + + if (r != POLYNULL) { + rp = r->m->ringp; + if (! rp->weightedHomogenization) { + errorKan1("%s\n","ecart.c: the given ring must be declared with [(weightedHomogenization) 1]"); + } + } + + r = goHomogenize11(r,DegreeShifto_vec,DegreeShifto_size,-1,1); + /* 1 means homogenize only s */ + /*printf("r=%s (mod 0)\n",POLYToString(head(r),'*',1)); + KshowRing(TraceLift_ringmod); **/ + + r = modulop(r,TraceLift_ringmod); + rp = r->m->ringp; /* reset rp */ + + /* printf("r=%s (mod p)\n",POLYToString(head(r),'*',1)); **/ + + if (DebugReductionEcart&1) printf("=====================================mod\n"); + do { + if (DebugReductionRed) printf("(ecart1_mod(d)) r=%s\n",POLYToString(r,'*',1)); + if (DebugReductionEcart & 1) printf("r=%s+,,,\n",POLYToString(head(r),'*',1)); + + ells = ecartFindReducer_mod(r,gset,gg); + ell = ells.ell; + if (ell > 0) { + if (DebugReductionEcart & 2) printf("%"); + gg = ecartPutPolyInG(r,gg,POLYNULL,POLYNULL); + } + if (ell >= 0) { + if (ells.first) { + pp = ((gset->polys[ells.grade])->gmod)[ells.gseti]; + }else{ + if (DebugReductionEcart & 4) {printf("+"); fflush(NULL);} + pp = (gg->pa)[ells.ggi]; + } + if (ell > 0) r = mpMult(cxx(1,0,ell,rp),r); /* r = s^ell r */ + r = (*reduction1)(r,pp,0,&cc,&cg); + if (r ISZERO) goto ss1; + r = ecartDivideSv(r,&se); /* r = r/s^? */ + } + }while (ell >= 0); + + ss1: ; + + r = goDeHomogenizeS(r); + + return(r); +} + +static int shouldReduceContent(POLY f,int ss) { + static int prevSize = 1; + int size; + if (f == POLYNULL) return 0; + if (f->m->ringp->p != 0) return 0; + if (f->coeffp->tag != MP_INTEGER) return 0; + size = mpz_size(f->coeffp->val.bigp); + if (ss > 0) { + prevSize = size; + return 0; + } + if (size > 2*prevSize) { + return 1; + }else{ + return 0; + } }