/* $OpenXM: OpenXM/src/kan96xx/Kan/syz0.c,v 1.5 2005/07/03 11:08:54 ohara Exp $ */ #include #include #include "datatype.h" #include "extern2.h" #include "matrix.h" #include "gradedset.h" extern int KanGBmessage; static int Debugsyz0 = 0; static POLY getFactor0(struct gradedPolySet *grG,int grd,int index); static void clearMark(struct gradedPolySet *grG); static void printMatrixOfPOLY(struct matrixOfPOLY *mat); static void printArrayOfPOLY(struct arrayOfPOLY *mat); static int isZeroRow(struct matrixOfPOLY *mat,int i); static int getSize00OfGradedSet(struct gradedPolySet *g); static int positionInPairs(struct pair *top,struct pair *pairs); /* if the top is not in the list pairs, it returns -1. */ static struct pair *oldPairsToNewPairs(struct pair *opairs, int *table,int size); /* In the function getSyzygy(), reduced Grobner basis *grBases is constructed from grG by deleting unnecessary elements. The array <> gives the correspondence between the index ig (i-grade), ii (i-index) of *grBases and grG. When <> keeps syzygies for grG, it returns syzygies for *grBases. Note that the result syzygies are not necessarily COMPLETE. Note that the <> fields are not set properly. */ struct matrixOfPOLY *getSyzygy01(struct gradedPolySet *reducedBasis, struct pair *excludedPairs); /* When <> is NULL, this function computes all syzygies for the <>. If not, this function computes all syzygies except those in excludedPairs. The <> field of the <> is used to change syzygy polynomials into arrays. March 15, 1997 */ /* if (mark[j]), then the simplification is done. */ void getBackwardTransformation(grG) struct gradedPolySet *grG; /* grG->polys[i]->mark[j],syz[j] are modified. */ { int i,j; struct polySet *ps; for (i=0; imaxGrade; i++) { ps = grG->polys[i]; for (j=0; jsize; j++) { if (ps->mark[j] == 0 && ps->del[j] == 0) { simplifyBT(i,j,grG); } } } } void simplifyBT(grd,index,grG) int grd; int index; struct gradedPolySet *grG; { POLY s,r; int g0,i0; s = grG->polys[grd]->syz[index]->syz; r = ZERO; if (KanGBmessage) {printf("."); fflush(stdout); } while (s != ZERO) { g0 = srGrade(s); i0 = srIndex(s); if (grG->polys[g0]->mark[i0]) { r = ppAdd(r,cpMult(s->coeffp,grG->polys[g0]->syz[i0]->syz)); }else{ simplifyBT(g0,i0,grG); r = ppAdd(r,cpMult(s->coeffp,grG->polys[g0]->syz[i0]->syz)); } s = s->next; } grG->polys[grd]->syz[index]->syz = r; grG->polys[grd]->mark[index] = 1; } static POLY getFactor0(grG,grd,index) struct gradedPolySet *grG; int grd; int index; { POLY ans; int i,j; struct polySet *ps; ans = cxx(1,0,0,grG->polys[grd]->g[index]->m->ringp); for (i=0; imaxGrade; i++) { ps = grG->polys[i]; for (j=0; jsize; j++) { if (ps->mark[j] && !(i == grd && j == index)) { ans = ppMult(ps->syz[j]->cf,ans); } } } return(ans); } struct arrayOfPOLY *getSyzygy0(grG,zeroPairs) struct gradedPolySet *grG; struct pair *zeroPairs; { struct pair *tmp; int size,k,i; POLY s; struct arrayOfPOLY *r; struct arrayOfPOLY *ans; /* outputGradedPolySet(grG); */ /* outputNode(zeroPairs); */ /* outputNode() workds as outputPairs() */ tmp = zeroPairs; size = 0; while (tmp != (struct pair *)NULL) { size++; tmp = tmp->next; } ans = newArrayOfPOLY(size+1); k = 0; while (zeroPairs != (struct pair *)NULL) { s = getSyzPolyFromSp(zeroPairs,grG); if (s ISZERO) { }else { getArrayOfPOLY(ans,k) = s; k++; } zeroPairs = zeroPairs->next; } r = newArrayOfPOLY(k); for (i=0; imaxGrade;i++) { ps = newG->polys[i]; for (j=0; jsize; j++) { fi = ps->g[j]; r = (*reduction)(fi,*grBasesp,1,&syz); if (KanGBmessage) {printf("."); fflush(stdout);} if (! (r ISZERO)) errorSyz0("Internal error; getSyzygy(): groebner basis must be given."); ps->syz[j] = newSyz0(); /* printf("%s : ",POLYToString(syz.cf,'*',1)); printf("%s\n",POLYToString(syz.syz,'*',1)); */ ps->syz[j]->cf = syz.cf; ps->syz[j]->syz = syz.syz; } } ap = getSyzygy0(newG,zeroPairs); /* */ excludePairs = oldPairsToNewPairs(zeroPairs,table,size); if (Debugsyz0) { printf("zeroPairs = "); outputNode(zeroPairs); for (i=0; in,serial); for (i=0; i < ap->n; i++) { vec = syzPolyToArrayOfPOLY(serial,getArrayOfPOLY(ap,i),*grBasesp); for (j=0; j < serial; j++) { getMatrixOfPOLY(mp,i,j) = getArrayOfPOLY(vec,j); } } /*printf(" ap->n = %d, serial=%d \n",ap->n, serial); printf("\nmp = \n"); printMatrixOfPOLY(mp); */ if (KanGBmessage) {printf(";"); fflush(stdout);} m1 = aaMult(mp,b); m0 = aaMult(mp0,b); /* printf("\nm0 = \n"); printMatrixOfPOLY(m0); */ ans = newMatrixOfPOLY((m0->m)+(m1->m)+(m2->m),m2->n); kk = 0; for (i=0; im; i++) { if (!isZeroRow(m0,i)) { for (j=0; jn; j++) { getMatrixOfPOLY(ans,kk,j) = getMatrixOfPOLY(m0,i,j); } kk++; } } for (i=0; im; i++) { if (!isZeroRow(m1,i)) { for (j=0; jn; j++) { getMatrixOfPOLY(ans,kk,j) = getMatrixOfPOLY(m1,i,j); } kk++; } } for (i=0; im; i++) { if (!isZeroRow(m2,i)) { for (j=0; jn; j++) { getMatrixOfPOLY(ans,kk,j) = getMatrixOfPOLY(m2,i,j); } kk++; if (KanGBmessage) printf("*"); } } if (kk != ans->m) { ans2 = newMatrixOfPOLY(kk,ans->n); for (i=0; in; j++) { getMatrixOfPOLY(ans2,i,j) = getMatrixOfPOLY(ans,i,j); } } return(ans2); }else{ return(ans); } } POLY getSyzPolyFromSp(spij,grG) struct pair *spij; struct gradedPolySet *grG; { int ig,ii,jg,ji; POLY dk; POLY f; POLY t,ans; int grd,indx; ig = spij->ig; ii = spij->ii; jg = spij->jg; ji = spij->ji; if (grG->polys[ig]->del[ii] != 0 || grG->polys[jg]->del[ji] != 0) return(ZERO); dk = spij->syz; /* in SyzRing */ clearMark(grG); f = dk; while (f != POLYNULL) { grd = srGrade(f); indx = srIndex(f); grG->polys[grd]->mark[indx] = 1; f=f->next; } f = dk; ans = ZERO; while (f != POLYNULL) { grd = srGrade(f); indx = srIndex(f); t = grG->polys[grd]->syz[indx]->syz; t = cpMult(f->coeffp,t); t = cpMult(toSyzCoeff(getFactor0(grG,grd,indx)),t); ans = ppAdd(ans,t); f = f->next; } return(ans); } static void clearMark(grG) struct gradedPolySet *grG; { int i,j; struct polySet *ps; for (i=0; imaxGrade; i++) { ps = grG->polys[i]; for (j=0; jsize; j++) { ps->mark[j] = 0; } } } struct arrayOfPOLY *syzPolyToArrayOfPOLY(size,f,grG) int size; POLY f; /* f is in the SyzRingp */ struct gradedPolySet *grG; { struct arrayOfPOLY *ap; int i,g0,i0,serial; ap = newArrayOfPOLY(size); for (i=0; ipolys[g0]->serial[i0]; if (serial < 0) { errorSyz0("syzPolyToArrayOfPOLY(): invalid serial[i] of grG."); } if (getArrayOfPOLY(ap,serial) != ZERO) { errorSyz0("syzPolyToArrayOfPOLY(): syzygy polynomial is broken."); } getArrayOfPOLY(ap,serial) = srSyzCoeffToPOLY(f->coeffp); f = f->next; } return(ap); } struct matrixOfPOLY *getBackwardMatrixOfPOLY(struct gradedPolySet *grG) { /* use serial, del. cf. getBackwardArray() */ int inputSize,outputSize; int i,j,k,p; struct arrayOfPOLY *vec; struct matrixOfPOLY *mat; struct polySet *ps; inputSize = 0; outputSize = 0; for (i=0; imaxGrade; i++) { ps = grG->polys[i]; for (j=0; jsize; j++) { if (ps->serial[j] >= 0) ++inputSize; if (ps->del[j] == 0) ++outputSize; } } mat = newMatrixOfPOLY(outputSize,inputSize); k = 0; for (i=0; imaxGrade; i++) { ps = grG->polys[i]; for (j=0; jsize; j++) { if (ps->del[j] == 0) { vec = syzPolyToArrayOfPOLY(inputSize,ps->syz[j]->syz,grG); for (p=0; pmaxGrade; i++) { ps = newG->polys[i]; for (j=0; jsize; j++) { if (ps->serial[j] >= 0) size++; } } mat = newMatrixOfPOLY(size,n); for (i=0; imaxGrade; i++) { ps = newG->polys[i]; for (j=0; jsize; j++) { if (ps->serial[j] >= 0) { ii = ps->serial[j]; vec = syzPolyToArrayOfPOLY(n,ps->syz[j]->syz,grBases); for (k=0; kmaxGrade; i++) { ps = newG->polys[i]; for (j=0; jsize; j++) { if (ps->serial[j] >= 0) size++; } } mat = newArrayOfPOLY(size); for (i=0; imaxGrade; i++) { ps = newG->polys[i]; for (j=0; jsize; j++) { if (ps->serial[j] >= 0) { ii = ps->serial[j]; getArrayOfPOLY(mat,ii) = ps->syz[j]->cf; } } } return(mat); } /* Syzygy from E-CB */ struct matrixOfPOLY *getSyzygy1(b,nc,dc) struct matrixOfPOLY *b; struct matrixOfPOLY *nc; struct arrayOfPOLY *dc; { int m,n2,n; struct matrixOfPOLY *mat; int i,j,k; POLY r; POLY tmp; m = nc->m; n2 = nc->n; n = b->n; mat = newMatrixOfPOLY(m,n); for (i=0; in; for (j=0; jm; n = mat->n; for (i=0; in; for (i=0; imaxGrade+1); for (i=0; ilim; i++) { g->polys[i] = newPolySet(1); } d = newGradedPairs((reducedBasis->maxGrade)*(reducedBasis->maxGrade)+1); for (i=0; i< reducedBasis->maxGrade; i++) { ps = reducedBasis->polys[i]; for (j=0; j< ps->size; j++) { gt = ps->g[j]; grade=-1;whereInG(g,gt,&grade,&indx,Sugar); d = updatePairs(d,gt,grade,indx,g); g = putPolyInG(g,gt,grade,indx,newSyz0(),1,ps->serial[j]); if (Debugsyz0) { outputGradedPairs(d); outputGradedPolySet(g,1); } } } listP = newPair((struct pair *)NULL); /* A list of syzygies will be stored*/ listPfirst = listP; while ((top = getPair(d)) != (struct pair *)NULL) { if (positionInPairs(top,excludePairs) < 0) { ig = top->ig; ii = top->ii; /* [ig,ii] */ jg = top->jg; ji = top->ji; /* [jg,ji] */ gi = g->polys[ig]->g[ii]; gj = g->polys[jg]->g[ji]; h = (*sp)(gi,gj); rd = ppAddv(ppMult(h.a,gi),ppMult(h.b,gj)); rd = (*reduction)(rd,g,1,&syz); syzPoly = syz.syz; syzCf = syz.cf; if (KanGBmessage) { if (pgrade != top->grade) { pgrade = top->grade; printf(" %d",pgrade); fflush(stdout); }else{ if (rd ISZERO) { printf("o"); fflush(stdout); }else{ printf("."); fflush(stdout); } } } if (!(rd ISZERO)) { fprintf(stderr,"The given argument of getSyzygy01 is not a g-basis.\n"); return((struct matrixOfPOLY *)NULL); }else{ top->syz = ppAdd(toSyzPoly(h.a,ig,ii),toSyzPoly(h.b,jg,ji)); top->syz = cpMult(toSyzCoeff(syzCf),top->syz); top->syz = ppAdd(top->syz,syzPoly); listP->next = top; top->prev = listP; listP = listP->next; listPsize++; } } } if (KanGBmessage) { printf("c"); fflush(stdout); } size = getSize00OfGradedSet(g); listPfirst = listPfirst->next; /* It is the true top of sygyzies. */ mp = newMatrixOfPOLY(listPsize,size); for (i=0; isyz,g); for (j=0; jnext; } return(mp); } static int getSize00OfGradedSet(struct gradedPolySet *g) { int size; int i,j; struct polySet *ps; size = 0; if (g == (struct gradedPolySet *)NULL) return(0); for (i=0; imaxGrade; i++) { ps = g->polys[i]; for (j=0; jsize; j++) { if (ps->del[j] == 0) { size += 1; } } } return(size); } static int positionInPairs(struct pair *top, struct pair *pairs) { struct pair *tmp; int pos; tmp = pairs; pos = 0; if (top == (struct pair *)NULL) return(-1); while (tmp != (struct pair *)NULL) { if (((top->ig == tmp->ig) && (top->ii == tmp->ii) && (top->jg == tmp->jg) && (top->ji == tmp->ji)) || ((top->ig == tmp->jg) && (top->ii == tmp->ji) && (top->jg == tmp->ig) && (top->ji == tmp->ii))) { return(pos); } pos++; tmp = tmp->next; } return(-1); } static struct pair *oldPairsToNewPairs(struct pair *opairs, int *table,int size) { /* Never loop up prev field. */ int ig,ii,jg,ji; int p,q; struct pair *ans; if (opairs == (struct pair *)NULL) return((struct pair *)NULL); ig = opairs->ig; ii = opairs->ii; jg = opairs->jg; ji = opairs->ji; for (p=0; pprev = NULL; ans->ig = table[4*p+2]; ans->ii = table[4*p+3]; ans->jg = table[4*q+2]; ans->ji = table[4*q+3]; ans->next = oldPairsToNewPairs(opairs->next,table,size); return(ans); } } } } return(oldPairsToNewPairs(opairs->next,table,size)); }