/* $OpenXM: OpenXM/src/kan96xx/Kan/kanExport1.c,v 1.6 2003/08/21 12:28:57 takayama Exp $ */ #include #include "datatype.h" #include "stackm.h" #include "extern.h" #include "extern2.h" #include "lookup.h" #include "matrix.h" #include "gradedset.h" #include "kclass.h" static int Message = 1; extern int KanGBmessage; struct object DegreeShifto; int DegreeShifto_size = 0; int *DegreeShifto_vec = NULL; /** :kan, :ring */ struct object Kreduction(f,set) struct object f; struct object set; { POLY r; struct gradedPolySet *grG; struct syz0 syz; struct object rob; int flag; extern int ReduceLowerTerms; if (f.tag != Spoly) errorKan1("%s\n","Kreduction(): the first argument must be a polynomial."); if (ectag(set) == CLASSNAME_GradedPolySet) { grG = KopGradedPolySet(set); flag = 1; }else{ if (set.tag != Sarray) errorKan1("%s\n","Kreduction(): the second argument must be a set of polynomials."); grG = arrayToGradedPolySet(set); flag = 0; } if (ReduceLowerTerms) { r = (*reductionCdr)(f.lc.poly,grG,1,&syz); }else{ r = (*reduction)(f.lc.poly,grG,1,&syz); } /* outputGradedPolySet(grG,0); */ if (flag) { rob = newObjectArray(3); putoa(rob,0,KpoPOLY(r)); putoa(rob,1,KpoPOLY(syz.cf)); putoa(rob,2,syzPolyToArray(countGradedPolySet(grG),syz.syz,grG)); }else { rob = newObjectArray(4); putoa(rob,0,KpoPOLY(r)); putoa(rob,1,KpoPOLY(syz.cf)); putoa(rob,2,syzPolyToArray(getoaSize(set),syz.syz,grG)); putoa(rob,3,gradedPolySetToArray(grG,1)); } return(rob); } struct object Kgroebner(ob) struct object ob; { int needSyz = 0; int needBack = 0; int needInput = 0; int countDown = 0; int cdflag = 0; struct object ob1,ob2,ob2c; int i; struct gradedPolySet *grG; struct pair *grP; struct arrayOfPOLY *a; struct object rob; struct gradedPolySet *grBases; struct matrixOfPOLY *mp; struct matrixOfPOLY *backwardMat; struct object ob1New; extern char *F_groebner; extern int CheckHomogenization; extern int StopDegree; int sdflag = 0; int forceReduction = 0; int ob1Size, ob2Size, noZeroEntry; int *ob1ToOb2; int *ob1ZeroPos; int method; int j,k; struct object rob2; struct object rob3; struct object rob4; struct ring *myring; POLY f; struct object orgB; struct object newB; struct object orgC; struct object newC; static struct object paddingVector(struct object ob, int table[], int m); static struct object unitVector(int pos, int size,struct ring *r); extern struct ring *CurrentRingp; StopDegree = 0x7fff; if (ob.tag != Sarray) errorKan1("%s\n","Kgroebner(): The argument must be an array."); switch(getoaSize(ob)) { case 1: needBack = 0; needSyz = 0; needInput = 0; ob1 = getoa(ob,0); break; case 2: ob1 = getoa(ob,0); ob2 = getoa(ob,1); if (ob2.tag != Sarray) { errorKan1("%s\n","Kgroebner(): The options must be given by an array."); } for (i=0; i 0 */ if (ob2Size == 0) { rob2 = newObjectArray(1); putoa(rob2,0,KpoPOLY(POLYNULL)); if (needBack && needSyz) { rob = newObjectArray(3); putoa(rob,0,rob2); rob3 = newObjectArray(1); putoa(rob3,0,unitVector(-1,ob1Size,(struct ring *)NULL)); putoa(rob,1,rob3); rob4 = newObjectArray(ob1Size); for (i=0; i 0 */ ob2 = newObjectArray(ob2Size); ob1ToOb2 = (int *)GC_malloc(sizeof(int)*ob1Size); ob1ZeroPos = (int *)GC_malloc(sizeof(int)*(ob1Size-ob2Size+1)); if (ob1ToOb2 == NULL || ob1ZeroPos == NULL) errorKan1("%s\n","No more memory."); j = 0; k = 0; for (i=0; im->ringp; putoa(ob2,j,KpoPOLY(f)); ob1ToOb2[i] = j; j++; }else{ ob1ToOb2[i] = -1; ob1ZeroPos[k] = i; k++; } } a = arrayToArrayOfPOLY(ob2); grG = (*groebner)(a,needBack,needSyz,&grP,countDown,forceReduction); if (strcmp(F_groebner,"gm") == 0 && (needBack || needSyz)) { warningKan("The options needBack and needSyz are ignored."); needBack = needSyz = 0; } /*return(gradedPolySetToGradedArray(grG,0));*/ if (needBack && needSyz) { rob = newObjectArray(3); if (Message && KanGBmessage) { printf("Computing the backward transformation "); fflush(stdout); } getBackwardTransformation(grG); /* mark and syz is modified. */ if (KanGBmessage) printf("Done.\n"); /* Computing the syzygies. */ if (Message && KanGBmessage) { printf("Computing the syzygies "); fflush(stdout); } mp = getSyzygy(grG,grP->next,&grBases,&backwardMat); if (KanGBmessage) printf("Done.\n"); putoa(rob,0,gradedPolySetToArray(grG,0)); putoa(rob,1,matrixOfPOLYToArray(backwardMat)); putoa(rob,2,matrixOfPOLYToArray(mp)); }else if (needBack) { rob = newObjectArray(2); if (Message && KanGBmessage) { printf("Computing the backward transformation....."); fflush(stdout); } getBackwardTransformation(grG); /* mark and syz is modified. */ if (KanGBmessage) printf("Done.\n"); putoa(rob,0,gradedPolySetToArray(grG,0)); putoa(rob,1,getBackwardArray(grG)); }else { rob = newObjectArray(1); putoa(rob,0,gradedPolySetToArray(grG,0)); } /* To handle zero entries in the input. */ if (noZeroEntry) { return(rob); } method = getoaSize(rob); switch(method) { case 1: return(rob); break; case 2: orgB = getoa(rob,1); /* backward transformation. */ newB = newObjectArray(getoaSize(orgB)); for (i=0; ilim; i++) { grG->polys[i] = newPolySet(INITSIZE); } for (i=0; isize; }else{ for (i=0; isize; i++) { if (ps->del[i] == 0) ++n; } } ob = newObjectArray(n); j = 0; for (i=0; isize; i++) { if (keepRedundant || (ps->del[i] == 0)) { putoa(ob,j,KpoPOLY(ps->g[i])); j++; } } return(ob); } struct object gradedPolySetToGradedArray(gps,keepRedundant) struct gradedPolySet *gps; int keepRedundant; { struct object ob,vec; int i; if (gps == (struct gradedPolySet *)NULL) return(NullObject); ob = newObjectArray(gps->maxGrade +1); vec = newObjectArray(gps->maxGrade); for (i=0; imaxGrade; i++) { putoa(vec,i,KpoInteger(i)); putoa(ob,i+1,polySetToArray(gps->polys[i],keepRedundant)); } putoa(ob,0,vec); return(ob); } struct object gradedPolySetToArray(gps,keepRedundant) struct gradedPolySet *gps; int keepRedundant; { struct object ob,vec; struct polySet *ps; int k; int i,j; int size; if (gps == (struct gradedPolySet *)NULL) return(NullObject); size = 0; for (i=0; imaxGrade; i++) { ps = gps->polys[i]; if (keepRedundant) { size += ps->size; }else{ for (j=0; jsize; j++) { if (ps->del[j] == 0) ++size; } } } ob = newObjectArray(size); k = 0; for (i=0; imaxGrade; i++) { ps = gps->polys[i]; for (j=0; jsize; j++) { if (keepRedundant || (ps->del[j] == 0)) { putoa(ob,k,KpoPOLY(ps->g[j])); k++; } } } return(ob); } /* serial == -1 : It's not in the marix input. */ struct object syzPolyToArray(size,f,grG) int size; POLY f; struct gradedPolySet *grG; { struct object ob; int i,g0,i0,serial; ob = newObjectArray(size); for (i=0; ipolys[g0]->serial[i0]; if (serial < 0) { errorKan1("%s\n","syzPolyToArray(): invalid serial[i] of grG."); } if (KopPOLY(getoa(ob,serial)) != ZERO) { errorKan1("%s\n","syzPolyToArray(): syzygy polynomial is broken."); } putoa(ob,serial,KpoPOLY(f->coeffp->val.f)); f = f->next; } return(ob); } struct object getBackwardArray(grG) struct gradedPolySet *grG; { /* use serial, del. cf. getBackwardTransformation(). */ int inputSize,outputSize; int i,j,k; struct object ob; 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; } } ob = newObjectArray(outputSize); k = 0; for (i=0; imaxGrade; i++) { ps = grG->polys[i]; for (j=0; jsize; j++) { if (ps->del[j] == 0) { putoa(ob,k,syzPolyToArray(inputSize,ps->syz[j]->syz,grG)); k++; } } } return(ob); } POLY arrayToPOLY(ob) struct object ob; { int size,i; struct object f; POLY r; static int nn,mm,ll,cc,n,m,l,c; static struct ring *cr = (struct ring *)NULL; POLY ff,ee; MONOMIAL tf; if (ob.tag != Sarray) errorKan1("%s\n","arrayToPOLY(): The argument must be an array."); size = getoaSize(ob); r = ZERO; for (i=0; im; if (tf->ringp != cr) { n = tf->ringp->n; m = tf->ringp->m; l = tf->ringp->l; c = tf->ringp->c; nn = tf->ringp->nn; mm = tf->ringp->mm; ll = tf->ringp->ll; cc = tf->ringp->cc; cr = tf->ringp; } if (n-nn >0) ee = cxx(1,n-1,i,tf->ringp); else if (m-mm >0) ee = cxx(1,m-1,i,tf->ringp); else if (l-ll >0) ee = cxx(1,l-1,i,tf->ringp); else if (c-cc >0) ee = cxx(1,c-1,i,tf->ringp); else ee = ZERO; r = ppAddv(r,ppMult(ee,ff)); } } return(r); } struct object POLYToArray(ff) POLY ff; { static int nn,mm,ll,cc,n,m,l,c; static struct ring *cr = (struct ring *)NULL; POLY ee; MONOMIAL tf; int k,i,matn,size; struct matrixOfPOLY *mat; POLY ex,sizep; struct object ob; if (ff != ZERO) { tf = ff->m; if (tf->ringp != cr) { n = tf->ringp->n; m = tf->ringp->m; l = tf->ringp->l; c = tf->ringp->c; nn = tf->ringp->nn; mm = tf->ringp->mm; ll = tf->ringp->ll; cc = tf->ringp->cc; cr = tf->ringp; } if (n-nn >0) ee = cxx(1,n-1,1,tf->ringp); else if (m-mm >0) ee = cxx(1,m-1,1,tf->ringp); else if (l-ll >0) ee = cxx(1,l-1,1,tf->ringp); else if (c-cc >0) ee = cxx(1,c-1,1,tf->ringp); else ee = ZERO; }else{ ob = newObjectArray(1); getoa(ob,0) = KpoPOLY(ZERO); return(ob); } mat = parts(ff,ee); matn = mat->n; sizep = getMatrixOfPOLY(mat,0,0); if (sizep == ZERO) size = 1; else size = coeffToInt(sizep->coeffp)+1; ob = newObjectArray(size); for (i=0; icoeffp); } getoa(ob,k) = KpoPOLY(getMatrixOfPOLY(mat,1,i)); } return(ob); } static int isThereh(f) POLY f; { POLY t; if (f == 0) return(0); t = f; while (t != POLYNULL) { if (t->m->e[0].D) return(1); t = t->next; } return(0); } struct object homogenizeObject(ob,gradep) struct object ob; int *gradep; { struct object rob,ob1; int maxg; int gr,flag,i,d,size; struct ring *rp; POLY f; extern struct ring *CurrentRingp; extern int Homogenize_vec; if (!Homogenize_vec) return(homogenizeObject_vec(ob,gradep)); switch(ob.tag) { case Spoly: if (isThereh(KopPOLY(ob))) { fprintf(stderr,"\n%s\n",KPOLYToString(KopPOLY(ob))); errorKan1("%s\n","homogenizeObject(): The above polynomial has already had a homogenization variable.\nPut the homogenization variable 1 before homogenization.\ncf. replace."); } f = homogenize( KopPOLY(ob) ); *gradep = (*grade)(f); return(KpoPOLY(f)); break; case Sarray: size = getoaSize(ob); if (size == 0) { errorKan1("%s\n","homogenizeObject() is called for the empty array."); } rob = newObjectArray(size); flag = 0; ob1 = getoa(ob,0); if (ob1.tag == Sdollar) return(homogenizeObject_go(ob,gradep)); ob1 = homogenizeObject(ob1,&gr); maxg = gr; getoa(rob,0) = ob1; for (i=1; i maxg) { maxg = gr; } getoa(rob,i) = ob1; } maxg = maxg+size-1; if (1) { rp = oRingp(rob); if (rp == (struct ring *)NULL) rp = CurrentRingp; for (i=0; i gr) { f = cdd(1,0,maxg-gr-i,rp); /* h^{maxg-gr-i} */ getoa(rob,i) = KooMult(KpoPOLY(f),getoa(rob,i)); } } } *gradep = maxg; return(rob); break; default: errorKan1("%s\n","homogenizeObject(): Invalid argument data type."); break; } } struct object homogenizeObject_vec(ob,gradep) struct object ob; int *gradep; { struct object rob,ob1; int maxg; int gr,i,size; POLY f; extern struct ring *CurrentRingp; switch(ob.tag) { case Spoly: if (isThereh(KopPOLY(ob))) { fprintf(stderr,"\n%s\n",KPOLYToString(KopPOLY(ob))); errorKan1("%s\n","homogenizeObject_vec(): The above polynomial has already had a homogenization variable.\nPut the homogenization variable 1 before homogenization.\ncf. replace."); } if (containVectorVariable(KopPOLY(ob))) { errorKan1("%s\n","homogenizedObject_vec(): The given polynomial contains a variable to express a vector component."); } f = homogenize( KopPOLY(ob) ); *gradep = (*grade)(f); return(KpoPOLY(f)); break; case Sarray: size = getoaSize(ob); if (size == 0) { errorKan1("%s\n","homogenizeObject_vec() is called for the empty array."); } if (getoa(ob,0).tag == Sdollar) return(homogenizeObject_go(ob,gradep)); rob = newObjectArray(size); for (i=0; i gr? maxg: gr); } putoa(rob,i,ob1); } *gradep = maxg; return(rob); break; default: errorKan1("%s\n","homogenizeObject_vec(): Invalid argument data type."); break; } } struct object homogenizeObject_go(struct object ob,int *gradep) { int size,i,dssize,j; struct object ob0; struct object ob1; struct object ob2; struct object rob; struct object tob; struct object ob1t; int *ds; POLY f; rob = NullObject; if (ob.tag != Sarray) errorKan1("%s\n","homogenizeObject_go(): Invalid argument data type."); size = getoaSize(ob); if (size == 0) errorKan1("%s\n","homogenizeObject_go(): the first argument must be a string."); ob0 = getoa(ob,0); if (ob0.tag != Sdollar) { errorKan1("%s\n","homogenizeObject_go(): the first argument must be a string."); } if (strcmp(KopString(ob0),"degreeShift") == 0) { if (size < 2) errorKan1("%s\n","homogenizeObject_go(): [(degreeShift) shift-vector obj] or [(degreeShift) shift-vector] or [(degreeShift) (value)] homogenize"); ob1 = getoa(ob,1); if (ob1.tag != Sarray) { if (DegreeShifto_size != 0) { return DegreeShifto; }else{ rob = NullObject; return rob; } } dssize = getoaSize(ob1); ds = (int *)sGC_malloc(sizeof(int)*(dssize>0?dssize:1)); for (i=0; im->ringp); break; case Sarray: size = getoaSize(ob); rp = (struct ring *)NULL; for (i=0; i maxg) maxg = tmpg; } return(maxg); break; default: errorKan1("%s\n","oGrade(): Invalid data type for the argument."); break; } } struct object oPrincipalPart(ob) struct object ob; { POLY f; struct object rob; switch(ob.tag) { case Spoly: f = KopPOLY(ob); return( KpoPOLY(POLYToPrincipalPart(f))); break; default: errorKan1("%s\n","oPrincipalPart(): Invalid data type for the argument."); break; } } struct object oInitW(ob,oWeight) struct object ob; struct object oWeight; { POLY f; struct object rob; int w[2*N0]; int n,i; struct object ow; if (oWeight.tag != Sarray) { errorKan1("%s\n","oInitW(): the second argument must be array."); } n = getoaSize(oWeight); if (n >= 2*N0) errorKan1("%s\n","oInitW(): the size of the second argument is invalid."); for (i=0; inext; size++; } return(size); } int validOutputOrder(int ord[],int n) { int i,j,flag; for (i=0; in; ox = ob; if (getoaSize(ox) != 2*n) { errorKan1("%s\n","KsetOutputOrder(): the argument must be of the form [x y z ...] and the length of [x y z ...] must be equal to the number of x and D variables."); } xxx = (int *)sGC_malloc(sizeof(int)*n*2); if (xxx == NULL ) { errorKan1("%s\n","KsetOutputOrder(): no more memory."); } for (i=0; i<2*n; i++) { otmp = getoa(ox,i); if(otmp.tag != Sinteger) { errorKan1("%s\n","KsetOutputOrder(): elements must be integers."); } xxx[i] = KopInteger(otmp); } if (!validOutputOrder(xxx,2*n)) { errorKan1("%s\n","KsetOutputOrder(): Invalid output order for variables."); } rp->outputOrder = xxx; return(ob); } struct object KschreyerSkelton(struct object g) { struct object rob; struct object ij; struct object ab; struct object tt; struct arrayOfPOLY *ap; struct arrayOfMonomialSyz ans; int k; rob.tag = Snull; if (g.tag != Sarray) { errorKan1("%s\n","KschreyerSkelton(): argument must be an array of polynomials."); } ap = arrayToArrayOfPOLY(g); ans = schreyerSkelton(*ap); rob = newObjectArray(ans.size); for (k=0; ki)); putoa(ij,1, KpoInteger(ans.p[k]->j)); ab = newObjectArray(2); putoa(ab,0, KpoPOLY(ans.p[k]->a)); putoa(ab,1, KpoPOLY(ans.p[k]->b)); tt = newObjectArray(2); putoa(tt,0, ij); putoa(tt,1, ab); putoa(rob,k,tt); } return(rob); } struct object KisOrdered(struct object of) { if (of.tag != Spoly) { errorKan1("%s\n","KisOrdered(): argument must be a polynomial."); } if (isOrdered(KopPOLY(of))) { return(KpoInteger(1)); }else{ return(KpoInteger(0)); } } struct object KvectorToSchreyer_es(struct object obarray) { int m,i; int nn; POLY f; POLY g; struct object ob; struct ring *rp; if (obarray.tag != Sarray) { errorKan1("%s\n","KvectorToSchreyer_es(): argument must be an array of polynomials."); } m = getoaSize(obarray); f = POLYNULL; for (i=0; im->ringp; nn = rp->nn; /* g = es^i g */ g = mpMult_poly(cxx(1,nn,i,rp), g); if (!isOrdered(g)) { errorKan1("%s\n","KvectorToSchreyer_es(): given polynomial is not ordered properly by the given Schreyer order."); } f = ppAdd(f,g); } } return(KpoPOLY(f)); } int objToInteger(struct object ob) { if (ob.tag == Sinteger) { return KopInteger(ob); }else if (ob.tag == SuniversalNumber) { return(coeffToInt(KopUniversalNumber(ob))); }else { errorKan1("%s\n","objToInteger(): invalid argument."); } }