Annotation of OpenXM/src/kan96xx/Kan/gbGM.c, Revision 1.1.1.1
1.1 maekawa 1: /* gbGM.c GM=Gebauer and Moller
2: */
3:
4: #include <stdio.h>
5: #include "datatype.h"
6: #include "extern2.h"
7: #include "matrix.h"
8: #include "gradedset.h"
9:
10:
11: /*#define DEBUG*/
12: /* Take statistics of mmLarger_matrix in orderT.c */
13: /* #define STATISTICS */
14:
15: struct polySet_gm {
16: POLY *g;
17: int lim;
18: int size;
19: int *del;
20: };
21:
22: struct pair_gm {
23: POLY lcm;
24: int i;
25: int j;
26: };
27:
28: struct pairSet {
29: struct pair_gm *p;
30: int lim;
31: int size;
32: int *del;
33: };
34:
35: /* prototypes */
36: struct polySet_gm newPolySet_gm(int n);
37: struct pairSet newPairSet(int n);
38: int pairSetSize(struct pairSet d);
39: struct pairSet pairSetJoin(struct pairSet a,struct pairSet b);
40: struct polySet_gm enlargePolySet_gm(struct polySet_gm g);
41: struct pairSet deletePair_gm(struct pairSet d,int index);
42: int minPair_gm(struct pairSet d);
43: struct pairSet updatePair_gm(struct pairSet d,int t,
44: struct polySet_gm g,POLY gt);
45: struct polySet_gm markRedundant_gm(struct polySet_gm g,int j);
46: /*
47: struct gradedPolySet *groebner_gm(struct arrayOfPOLY f,
48: int needBack,
49: int needSyz, struct pair **grP);
50: */
51: void outputPairSet(struct pairSet d);
52: void outputPolySet_gm(struct polySet_gm g);
53: void errorGBGM(char *s);
54: POLY mReductionBySet(POLY f, POLY *s,int size);
55: POLY mReductionCdrBySet(POLY f, POLY *s,int size);
56: int criterion1(POLY f,POLY g,POLY lc);
57:
58: extern int UseCriterion1;
59: extern int Verbose;
60:
61: #define GLIMIT 100
62: int Criterion1,Criterion2; /* for taking a statistics. */
63: int Spairs;
64: extern int Criterion2B, Criterion2F, Criterion2M;
65: extern int Statistics;
66:
67: #ifdef STATISTICS
68: int CountE;
69: int CountI[2*N0];
70: #endif
71:
72: struct polySet_gm newPolySet_gm(n)
73: int n;
74: {
75: struct polySet_gm g;
76: int i;
77: g.g = (POLY *) sGC_malloc(sizeof(POLY)*(n+1));
78: g.del = (int *) sGC_malloc(sizeof(int)*(n+1));
79: if ((g.g == (POLY *)NULL) ||
80: (g.del == (int *)NULL))
81: errorGBGM("No more memory.");
82: g.lim = n;
83: g.size = 0;
84: for (i=0; i<n; i++) g.del[i] = 0;
85: return(g);
86: }
87:
88: struct pairSet newPairSet(n)
89: int n;
90: {
91: struct pairSet g;
92: int i;
93: g.p = (struct pair_gm *) sGC_malloc(sizeof(struct pair_gm)*(n+1));
94: g.del = (int *) sGC_malloc(sizeof(int)*(n+1));
95: if ((g.p == (struct pair_gm *)NULL) ||
96: (g.del == (int *)NULL))
97: errorGBGM("No more memory.");
98: g.lim = n;
99: g.size = 0;
100: for (i=0; i<n; i++) g.del[i] = 0;
101: return(g);
102: }
103:
104: int pairSetSize(d)
105: struct pairSet d;
106: {
107: int s,i;
108: s = 0;
109: for (i=0; i< d.size; i++) {
110: if (d.del[i] == 0) s++;
111: }
112: return(s);
113: }
114:
115: struct pairSet pairSetJoin(a,b)
116: struct pairSet a,b;
117: {
118: int m,n,k,i;
119: struct pairSet ans;
120: m = pairSetSize(a);
121: n = pairSetSize(b);
122: ans = newPairSet(m+n);
123: k = 0;
124: for (i=0 ; i<a.size; i++) {
125: if (a.del[i] == 0) {
126: ans.p[k] = a.p[i]; ans.del[k++] = 0;
127: }
128: }
129: for (i=0; i<b.size; i++) {
130: if (b.del[i] == 0) {
131: ans.p[k] = b.p[i]; ans.del[k++] = 0;
132: }
133: }
134: if (k != (m+n)) errorGBGM("Internal error in pairSetJoin().");
135: ans.size = m+n;
136: return(ans);
137: }
138:
139: struct polySet_gm enlargePolySet_gm(g)
140: struct polySet_gm g;
141: {
142: int i;
143: struct polySet_gm ans;
144: if (g.lim < g.size+3) {
145: ans = newPolySet_gm((g.lim)*2);
146: for (i=0; i<g.size; i++) {
147: ans.g[i] = g.g[i];
148: ans.del[i] = g.del[i];
149: }
150: ans.size = g.size;
151: }else{ ans = g; }
152: return(ans);
153: }
154:
155: struct pairSet deletePair_gm(d,index)
156: struct pairSet d;
157: int index;
158: /* delete d[index] */
159: {
160: int i;
161: d.del[index] = 0;
162: for (i= index; i<d.size-1; i++) {
163: d.p[i] = d.p[i+1];
164: }
165: d.size--;
166: return(d);
167: }
168:
169: int minPair_gm(d)
170: struct pairSet d;
171: {
172: POLY min;
173: int index,i;
174: min = d.p[0].lcm;
175: index = 0;
176: for (i=0; i < d.size; i++) {
177: if ( (*mmLarger)(min, d.p[i].lcm)) {
178: index = i;
179: min = d.p[i].lcm;
180: }
181: }
182: return(index);
183: }
184:
185: struct pairSet updatePair_gm(d,t,g,gt)
186: struct pairSet d;
187: int t;
188: struct polySet_gm g;
189: POLY gt;
190: {
191: int i,j,k;
192: struct pairSet new;
193: POLY it;
194: POLY jt;
195:
196: if (Verbose >= 2) {
197: printf("\nupdatepair_gm(): ");
198: printf("g.size=%d ",g.size);
199: printf("d.size=%d; ",d.size);
200: }
201:
202: /* make list (1,t), (2,t), .... ====> new ( D1 ) */
203: new = newPairSet(g.size); new.size = 0;
204: for (i=0; i<g.size; i++) {
205: if (g.del[i] == 0) {
206: new.p[i].i = i;
207: new.p[i].j = t;
208: new.p[i].lcm = (*lcm)(g.g[i],gt);
209: }else{
210: new.p[i].i = i;
211: new.p[i].j = t;
212: new.p[i].lcm = ZERO; /* Compute it when it is necessary. */
213: }
214: new.del[i] = g.del[i];
215: new.size++;
216: }
217: #ifdef DEBUG
218: /*printf("\nnew is ...");
219: outputPairSet(new);*/
220: #endif
221:
222: /* Candel in D=d all (i,j) such that B_t(i,j) */
223:
224: for (k=0; k<d.size; k++) {
225: if ((d.del[k] == 0) && ((*isReducible)(d.p[k].lcm,gt)) ) {
226: /* check T(it) != T(i,j) != T(j,t) */
227: i = d.p[k].i; j = d.p[k].j;
228: if ((new.del[i] == 1) || (new.del[j] == 1)) {
229: /* fprintf(stderr,"Warning in updatepair_gm(): i=%d, j=%d; rewriting new.\n",i,j); */
230: if (new.del[i] == 1) {
231: new.p[i].lcm = (*lcm)(g.g[i],gt);
232: }
233: if (new.del[j] == 1) {
234: new.p[j].lcm = (*lcm)(g.g[j],gt);
235: }
236: }
237: if (((*mmLarger)((new.p[i].lcm),(new.p[j].lcm)) != 2) &&
238: ((*mmLarger)((new.p[i].lcm),(d.p[k].lcm)) != 2) &&
239: ((*mmLarger)((new.p[j].lcm),(d.p[k].lcm)) != 2)) {
240: /* delete T(i,j) in d */
241: d.del[k] = 1;
242: if (Verbose >= 2) printf("B%d(%d,%d) ",t,i,j);
243: Criterion2B++;
244: }
245: }
246: }
247:
248: /* Then, d is D' */
249: /* Next, check M(i,t) and F(i,t) */
250: for (i=0; i<g.size; i++) {
251: for (j=i+1; j<g.size; j++) {
252: if ((g.del[i] == 0) && (g.del[j] == 0)) {
253: it = new.p[i].lcm;
254: jt = new.p[j].lcm;
255: switch ( (*mmLarger)(it,jt)) {
256: case 2:
257: /* F(j,t), i<j */
258: new.del[j] = 1;
259: if (Verbose >= 2) printf("F%d(%d,%d) ",i,j,t);
260: Criterion2F++;
261: break;
262: case 1:
263: /* g[i] > g[j], M(i,t) */
264: if ((*isReducible)(it,jt)) {
265: new.del[i] = 1;
266: if (Verbose >=2) printf("M%d(%d,%d) ",j,i,t);
267: Criterion2M++;
268: }
269: break;
270: case 0: /* M(j,t) */
271: if ((*isReducible)(jt,it)) {
272: new.del[j] = 1;
273: if (Verbose >=2) printf("M%d(%d,%d) ",i,j,t);
274: Criterion2M++;
275: }
276: break;
277:
278: }
279: }
280: }
281: }
282:
283: /* Finally, check T(i) T(t) = T(i,t) */
284: if (UseCriterion1) {
285: for (i=0; i<g.size; i++) {
286: if (new.del[i] == 0) {
287: if (criterion1(g.g[i],gt,new.p[i].lcm)) {
288: new.del[i] = 1;
289: if (Verbose >=2) printf("1(%d,%d) ",i,t);
290: Criterion1++;
291: }
292: }
293: }
294: }
295:
296: /* d <-- D' \cup new */
297: d = pairSetJoin(d,new);
298: if (Verbose >=2) printf("new d.size = %d.\n",d.size);
299: #ifdef DEBUG
300: outputPairSet(d);
301: #endif
302: return(d);
303: }
304:
305:
306: struct polySet_gm markRedundant_gm(g,j)
307: struct polySet_gm g;
308: int j;
309: /* compare only with g[j] */
310: {
311: int i;
312: for (i=0; i<g.size; i++) {
313: if ((g.del[i] == 0) && (i != j)) {
314: if (g.del[j] == 0) {
315: switch((*mmLarger)((g.g[i]),(g.g[j]))) {
316: case 2:
317: g.del[j] = 1;
318: break;
319: case 1:
320: if ((*isReducible)((g.g[i]),(g.g[j]))) {
321: g.del[i] = 1;
322: }
323: break;
324: case 0:
325: if ((*isReducible)((g.g[j]),(g.g[i]))) {
326: g.del[j] = 1;
327: }
328: break;
329: }
330: }
331: }
332: }
333: #ifdef DEBUG
334: /*printf("\nend of markRedundant_gm...");
335: outputPolySet_gm(g);*/
336: #endif
337: return(enlargePolySet_gm(g));
338: }
339:
340:
341:
342: struct gradedPolySet *groebner_gm(f,needBack,needSyz,grP,countDown,forceReduction)
343: struct arrayOfPOLY *f;
344: int needBack;
345: int needSyz;
346: struct pair **grP;
347: int countDown;
348: int forceReduction;
349: {
350: int r;
351: struct pair_gm top;
352: int tindex;
353: POLY h;
354: int i,j;
355: int ss;
356: struct polySet_gm g;
357: struct pairSet d;
358: int t;
359: struct spValue sv;
360: struct gradedPolySet *ans;
361: int grade,indx;
362: extern int ReduceLowerTerms;
363:
364: if (needBack || needSyz) {
365: fprintf(stderr,"Warning: groebner_gm() does not compute the backward transformation and syzygies.\n");
366: }
367:
368: #ifdef STATISTICS
369: CountE = 0;
370: for (i=0; i<2*N; i++) CountI[i]=0;
371: #endif
372: /* taking the statistics. */
373: Criterion1 = Criterion2B = Criterion2M = Criterion2F = 0;
374: Spairs = 0;
375:
376: r = f->n;
377: g = newPolySet_gm(r + GLIMIT);
378: d = newPairSet(1);
379:
380: g.size = 0;
381: g.g[g.size] = getArrayOfPOLY(f,g.size);
382: g.del[g.size] = 0; g.size ++;
383:
384: for (t=1; t<r; t++) {
385: d = updatePair_gm(d,t,g,getArrayOfPOLY(f,t));
386: g.g[t] = getArrayOfPOLY(f,t); g.del[t] = 0; g.size ++ ;
387: g = markRedundant_gm(g,t);
388: }
389:
390: #ifdef DEBUG
391: outputPolySet_gm(g);
392: #endif
393:
394: while (d.size > 0) {
395: tindex = minPair_gm(d);
396: top = d.p[tindex];
397: if (Verbose) {
398: printf("\nRemaining pairs = %d : ",d.size);
399: }
400: i = top.i;
401: j = top.j;
402: if (Verbose >=2) printf("sp(%d,%d) ",i,j);
403: Spairs++;
404: sv = (*sp)(g.g[i],g.g[j]);
405: h = ppAddv(ppMult(sv.a,g.g[i]),ppMult(sv.b,g.g[j]));
406: h = mReductionBySet(h,g.g,g.size);
407: if (Verbose >=2) printf("->%s ",POLYToString(h,' ',0));
408:
409: if (!Verbose) {
410: printf(" <%d>",d.size);
411: fflush(stdout);
412: }
413:
414: if (!(h ISZERO)) {
415: if (ReduceLowerTerms) {
416: h = mReductionCdrBySet(h,g.g,g.size);
417: }
418: d = updatePair_gm(d,r,g,h);
419: g.g[r] = h; g.del[r] = 0;
420: r++; g.size++;
421: g = markRedundant_gm(g,r-1);
422: }
423: d = deletePair_gm(d,tindex);
424: #ifdef DEBUG
425: outputPolySet_gm(g);
426: #endif
427: }
428:
429:
430: if (Verbose || Statistics) {
431: printf("\n\nThe number of s-pairs is %d.\n",Spairs);
432: printf("Criterion1 is applied %d times.\n",Criterion1);
433: printf("Criterions M,F and B are applied M=%d, F=%d, B=%d times.\n",Criterion2M,Criterion2F,Criterion2B);
434: Criterion1 = Criterion2M = Criterion2F = Criterion2B = 0;
435: Spairs = 0;
436: }
437: #ifdef STATISTICS
438: printf("\n\nEqual : %d\n",CountE);
439: for (i=0; i<2*N; i++) {
440: printf("%d times of loop : %d\n",i,CountI[i]);
441: }
442: #endif
443:
444: ans = newGradedPolySet(1);
445: for (i=0; i<ans->lim; i++) {
446: ans->polys[i] = newPolySet(1);
447: }
448:
449: for (i=0; i<g.size; i++) {
450: if (g.del[i] == 0) {
451: grade=-1;whereInG(ans,g.g[i],&grade,&indx,0); /* we do not use sugar. */
452: ans = putPolyInG(ans,g.g[i],grade,indx,(struct syz0 *)NULL,0,-1);
453: }
454: }
455:
456: printf("\n");
457: return(ans);
458: }
459:
460:
461: void outputPairSet(d)
462: struct pairSet d;
463: { int i;
464: printf("\nOutput struct pairSet. ");
465: printf(".size=%d, .lim=%d :\n",d.size,d.lim);
466: for (i=0; i<d.size; i++) {
467: printf("%d[%d] i=%d,j=%d, lcm=%s ",i,d.del[i],d.p[i].i,d.p[i].j,
468: POLYToString(d.p[i].lcm,' ',0));
469: }
470: printf("\n"); fflush(stdout);
471: }
472:
473: void outputPolySet_gm(g)
474: struct polySet_gm g;
475: { int i;
476: printf("\nOutput struct polySet_gm. ");
477: printf(".size=%d, .lim=%d :\n",g.size,g.lim);
478: for (i=0; i<g.size; i++) {
479: printf("%d[%d] %s\n",i,g.del[i],POLYToString(g.g[i],' ',0));
480: }
481: printf("\n"); fflush(stdout);
482: }
483:
484: int criterion1(f0,g0,lc0)
485: POLY f0;
486: POLY g0;
487: POLY lc0;
488: {
489: /* This is used only for commutative case. */
490: register int i;
491: MONOMIAL f,g,lc;
492: int n;
493: f = f0->m; g = g0->m; lc = lc0->m;
494: if (f->ringp != g->ringp) return(0);
495: if (f->ringp != lc->ringp) return(0);
496: n = f->ringp->n;
497: for (i = 0; i<n ; i++) {
498: if (( f->e[i].x + g->e[i].x) != (lc->e[i].x)) return(0);
499: }
500: for (i = 0; i<n ; i++) {
501: if (( f->e[i].D + g->e[i].D) != (lc->e[i].D)) return(0);
502: }
503: return(1);
504: }
505:
506:
507: POLY mReductionBySet(f,s,size)
508: POLY f;
509: POLY *s;
510: int size;
511: {
512: int reduced1;
513: int i;
514: POLY cc,cg;
515: do {
516: reduced1 = 0;
517: for (i=0; i<size; i++) {
518: if (f ISZERO) goto ss;
519: if ((*isReducible)(f,s[i])) {
520: f = (*reduction1)(f,s[i],0,&cc,&cg);
521: reduced1 = 1;
522: }
523: }
524: } while (reduced1 != 0);
525: ss: ;
526: return(f);
527: }
528:
529: POLY mReductionCdrBySet(f,s,size)
530: POLY f;
531: POLY *s;
532: int size;
533: {
534: int reduced1;
535: int i;
536: POLY cc,cg;
537: POLY fs;
538: do {
539: reduced1 = 0;
540: for (i=0; i<size; i++) {
541: if (f ISZERO) goto ss;
542: if ((fs=(*isCdrReducible)(f,s[i])) != ZERO) {
543: f = (*reduction1Cdr)(f,fs,s[i],0,&cc,&cg);
544: reduced1 = 1;
545: }
546: }
547: } while (reduced1 != 0);
548: ss: ;
549: return(f);
550: }
551:
552:
553: void errorGBGM(s)
554: char *s;
555: {
556: fprintf(stderr,"Fatal error in yaGbasis.c: %s \n",s);
557: exit(10);
558: }
559:
560:
561:
562:
563:
564:
565:
566:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>