Annotation of OpenXM_contrib2/asir2000/engine/NEZ.c, Revision 1.1.1.1
1.1 noro 1: /* $OpenXM: OpenXM/src/asir99/engine/NEZ.c,v 1.1.1.1 1999/11/10 08:12:26 noro Exp $ */
2: #include "ca.h"
3:
4: void nezgcdnpz(vl,ps,m,pr)
5: VL vl;
6: P *ps,*pr;
7: int m;
8: {
9: P t,s,mg;
10: VL tvl,svl,avl,nvl;
11: int i,j,k;
12: N c;
13: Q cq;
14: P *pl,*pm;
15: DCP *ml;
16: Q *cl;
17: P **cp;
18: int *cn;
19:
20: pl = (P *)ALLOCA(m*sizeof(P));
21: ml = (DCP *)ALLOCA(m*sizeof(DCP));
22: cl = (Q *)ALLOCA(m*sizeof(Q));
23: for ( i = 0; i < m; i++ )
24: monomialfctr(vl,ps[i],&pl[i],&ml[i]);
25: gcdmonomial(vl,ml,m,&mg);
26: for ( i = 0; i < m; i++ ) {
27: ptozp(pl[i],1,&cl[i],&t); pl[i] = t;
28: }
29: for ( i = 1, cq = cl[0]; i < m; i++ ) {
30: gcdn(NM(cl[i]),NM(cq),&c); NTOQ(c,1,cq);
31: }
32: for ( i = 0; i < m; i++ )
33: if ( NUM(pl[i]) ) {
34: mulp(vl,(P)cq,mg,pr); return;
35: }
36: for ( i = 0, nvl = vl, avl = 0; nvl && i < m; i++ ) {
37: clctv(vl,pl[i],&tvl);
38: intersectv(nvl,tvl,&svl); nvl = svl;
39: mergev(vl,avl,tvl,&svl); avl = svl;
40: }
41: if ( !nvl ) {
42: mulp(vl,(P)cq,mg,pr); return;
43: }
44: if ( !NEXT(avl) ) {
45: nuezgcdnpzmain(vl,pl,m,&t); mulp(vl,t,(P)cq,&s); mulp(vl,s,mg,pr);
46: return;
47: }
48: for ( tvl = nvl, i = 0; tvl; tvl = NEXT(tvl), i++ );
49: for ( tvl = avl, j = 0; tvl; tvl = NEXT(tvl), j++ );
50: if ( i == j ) {
51: /* all the pl[i]'s have the same variables */
52: sortplistbyhomdeg(pl,m); nezgcdnpzmain(nvl,pl,m,&t);
53: #if 0
54: /* search the minimal degree poly */
55: for ( i = 0; i < m; i++ ) {
56: for ( tvl = nvl; tvl; tvl = NEXT(tvl) ) {
57: dt = getdeg(tvl->v,pl[i]);
58: if ( tvl == nvl || dt < d1 ) {
59: v1 = tvl->v; d1 = dt;
60: }
61: }
62: if ( i == 0 || d1 < d ) {
63: v = v1; d = d1; j = i;
64: }
65: }
66: t = pl[0]; pl[0] = pl[j]; pl[j] = t;
67: if ( v != nvl->v ) {
68: reordvar(nvl,v,&mvl);
69: for ( i = 0; i < m; i++ ) {
70: reorderp(mvl,nvl,pl[i],&t); pl[i] = t;
71: }
72: nezgcdnpzmain(mvl,pl,m,&s); reorderp(nvl,mvl,s,&t);
73: } else
74: nezgcdnpzmain(nvl,pl,m,&t);
75: #endif
76: } else {
77: cp = (P **)ALLOCA(m*sizeof(P *));
78: cn = (int *)ALLOCA(m*sizeof(int));
79: for ( i = 0; i < m; i++ ) {
80: cp[i] = (P *)ALLOCA(lengthp(pl[i])*sizeof(P));
81: cn[i] = pcoef(vl,nvl,pl[i],cp[i]);
82: }
83: for ( i = j = 0; i < m; i++ )
84: j += cn[i];
85: pm = (P *)ALLOCA(j*sizeof(P));
86: for ( i = k = 0; i < m; i++ )
87: for ( j = 0; j < cn[i]; j++ )
88: pm[k++] = cp[i][j];
89: nezgcdnpz(vl,pm,k,&t);
90: }
91: mulp(vl,t,(P)cq,&s); mulp(vl,s,mg,pr);
92: }
93:
94: void sortplistbyhomdeg(p,n)
95: P *p;
96: int n;
97: {
98: int i,j,k;
99: int *l;
100: P t;
101:
102: l = (int *)ALLOCA(n*sizeof(int));
103: for ( i = 0; i < n; i++ )
104: l[i] = homdeg(p[i]);
105: for ( i = 0; i < n; i++ )
106: for ( j = i + 1; j < n; j++ )
107: if ( l[j] < l[i] ) {
108: t = p[i]; p[i] = p[j]; p[j] = t;
109: k = l[i]; l[i] = l[j]; l[j] = k;
110: }
111: }
112:
113: void nuezgcdnpzmain(vl,ps,m,r)
114: VL vl;
115: P *ps;
116: int m;
117: P *r;
118: {
119: P *tps;
120: P f,t;
121: int i;
122:
123: for ( i = 0; i < m; i++ )
124: if ( NUM(ps[i]) ) {
125: *r = (P)ONE; return;
126: }
127: tps = (P *) ALLOCA(m*sizeof(P));
128: for ( i = 0; i < m; i++ )
129: tps[i] = ps[i];
130: sortplist(tps,m);
131: for ( i = 1, f = tps[0]; i < m && !NUM(f); i++ ) {
132: uezgcdpz(vl,f,tps[i],&t); f = t;
133: }
134: *r = f;
135: }
136:
137: void gcdmonomial(vl,dcl,m,r)
138: VL vl;
139: DCP *dcl;
140: int m;
141: P *r;
142: {
143: int i,j,n;
144: P g,x,s,t;
145: Q d;
146: DCP dc;
147: VN vn;
148:
149: for ( i = 0; i < m; i++ )
150: if ( !dcl[i] ) {
151: *r = (P)ONE; return;
152: }
153: for ( n = 0, dc = dcl[0]; dc; dc = NEXT(dc), n++ );
154: vn = (VN)ALLOCA(n*sizeof(struct oVN));
155: for ( i = 0, dc = dcl[0]; i < n; dc = NEXT(dc), i++ ) {
156: vn[i].v = VR(COEF(dc)); vn[i].n = QTOS(DEG(dc));
157: }
158: for ( i = 1; i < m; i++ ) {
159: for ( j = 0; j < n; j++ ) {
160: for ( dc = dcl[i]; dc; dc = NEXT(dc) )
161: if ( VR(COEF(dc)) == vn[j].v ) {
162: vn[j].n = MIN(vn[j].n,QTOS(DEG(dc))); break;
163: }
164: if ( !dc )
165: vn[j].n = 0;
166: }
167: for ( j = n-1; j >= 0 && !vn[j].n; j-- );
168: if ( j < 0 ) {
169: *r = (P)ONE; return;
170: } else
171: n = j+1;
172: }
173: for ( j = 0, g = (P)ONE; j < n; j++ )
174: if ( vn[j].n ) {
175: MKV(vn[j].v,x); STOQ(vn[j].n,d);
176: pwrp(vl,x,d,&t); mulp(vl,t,g,&s); g = s;
177: }
178: *r = g;
179: }
180:
181: void nezgcdnpzmain(vl,pl,m,pr)
182: VL vl;
183: P *pl,*pr;
184: int m;
185: {
186: P *ppl,*pcl;
187: int i;
188: P cont,gcd,t,s;
189: DCP dc;
190:
191: ppl = (P *)ALLOCA(m*sizeof(P));
192: pcl = (P *)ALLOCA(m*sizeof(P));
193: for ( i = 0; i < m; i++ )
194: pcp(vl,pl[i],&ppl[i],&pcl[i]);
195: nezgcdnpz(vl,pcl,m,&cont);
196: sqfrp(vl,ppl[0],&dc);
197: for ( dc = NEXT(dc), gcd = (P)ONE; dc; dc = NEXT(dc) ) {
198: if ( NUM(COEF(dc)) )
199: continue;
200: nezgcdnpp(vl,dc,ppl+1,m-1,&t);
201: if ( NUM(t) )
202: continue;
203: mulp(vl,gcd,t,&s); gcd = s;
204: }
205: mulp(vl,gcd,cont,pr);
206: }
207:
208: void nezgcdnpp(vl,dc,pl,m,r)
209: VL vl;
210: DCP dc;
211: P *pl;
212: int m;
213: P *r;
214: {
215: int i,k;
216: P g,t,s,gcd;
217: P *pm;
218:
219: nezgcdnp_sqfr_primitive(vl,COEF(dc),pl,m,&gcd);
220: if ( NUM(gcd) ) {
221: *r = (P)ONE; return;
222: }
223: pm = (P *) ALLOCA(m*sizeof(P));
224: for ( i = 0; i < m; i++ ) {
225: divsp(vl,pl[i],gcd,&pm[i]);
226: if ( NUM(pm[i]) ) {
227: *r = gcd; return;
228: }
229: }
230: for ( g = gcd, k = QTOS(DEG(dc))-1; k > 0; k-- ) {
231: nezgcdnp_sqfr_primitive(vl,g,pm,m,&t);
232: if ( NUM(t) )
233: break;
234: mulp(vl,gcd,t,&s); gcd = s;
235: for ( i = 0; i < m; i++ ) {
236: divsp(vl,pm[i],t,&s);
237: if ( NUM(s) ) {
238: *r = gcd; return;
239: }
240: pm[i] = s;
241: }
242: }
243: *r = gcd;
244: }
245:
246: /*
247: * pr = gcd(p0,ps[0],...,ps[m-1])
248: *
249: * p0 is already square-free and primitive.
250: * ps[i] is at least primitive.
251: *
252: */
253:
254: void nezgcdnp_sqfr_primitive(vl,p0,ps,m,pr)
255: VL vl;
256: int m;
257: P p0,*ps,*pr;
258: {
259: /* variables */
260: P p00,g,h,g0,h0,a0,b0;
261: P lp0,lgp0,lp00,lg,lg0,cbd,tq,t;
262: P *lc;
263: P *tps;
264: VL nvl1,nvl2,nvl,tvl;
265: V v;
266: int i,j,k,d0,dg,dg0,dmin;
267: VN vn0,vn1,vnt;
268: int nv,flag;
269:
270: /* set-up */
271: if ( NUM(p0) ) {
272: *pr = (P) ONE; return;
273: }
274: for ( v = VR(p0), i = 0; i < m; i++ )
275: if ( NUM(ps[i]) || (v != VR(ps[i])) ) {
276: *pr = (P)ONE; return;
277: }
278: tps = (P *) ALLOCA(m*sizeof(P));
279: for ( i = 0; i < m; i++ )
280: tps[i] = ps[i];
281: sortplist(tps,m);
282: /* deg(tps[0]) <= deg(tps[1]) <= ... */
283:
284: if ( !cmpq(DEG(DC(p0)),ONE) ) {
285: if ( divcheck(vl,tps,m,(P)ONE,p0) )
286: *pr = p0;
287: else
288: *pr = (P)ONE;
289: return;
290: }
291:
292: lp0 = LC(p0); dmin = d0 = deg(v,p0); lc = (P *)ALLOCA((m+1)*sizeof(P));
293: for ( lc[0] = lp0, i = 0; i < m; i++ )
294: lc[i+1] = LC(tps[i]);
295: clctv(vl,p0,&nvl);
296: for ( i = 0; i < m; i++ ) {
297: clctv(vl,tps[i],&nvl1); mergev(vl,nvl,nvl1,&nvl2); nvl = nvl2;
298: }
299: nezgcdnpz(nvl,lc,m+1,&lg);
300:
301: mulp(nvl,p0,lg,&lgp0); k = dbound(v,lgp0)+1; cbound(nvl,lgp0,(Q *)&cbd);
302: for ( nv = 0, tvl = nvl; tvl; tvl = NEXT(tvl), nv++ );
303: W_CALLOC(nv,struct oVN,vn0); W_CALLOC(nv,struct oVN,vnt);
304: W_CALLOC(nv,struct oVN,vn1);
305: for ( i = 0, tvl = NEXT(nvl); tvl; tvl = NEXT(tvl), i++ )
306: vn1[i].v = vn0[i].v = tvl->v;
307:
308: /* main loop */
309: for ( dg = deg(v,tps[0]) + 1; ; next(vn0) )
310: do {
311: for ( i = 0, j = 0; vn0[i].v; i++ )
312: if ( vn0[i].n ) vnt[j++].v = (V)i;
313: vnt[j].n = 0;
314:
315: /* find b s.t. LC(p0)(b), LC(tps[i])(b) != 0 */
316: mulsgn(vn0,vnt,j,vn1); substvp(nvl,p0,vn1,&p00);
317: flag = (!zerovpchk(nvl,lp0,vn1) && sqfrchk(p00));
318: for ( i = 0; flag && (i < m); i++ )
319: flag &= (!zerovpchk(nvl,LC(tps[i]),vn1));
320: if ( !flag )
321: continue;
322:
323: /* substitute y -> b */
324: substvp(nvl,lg,vn1,&lg0); lp00 = LC(p00);
325: /* extended-gcd in 1-variable */
326: uexgcdnp(nvl,p00,tps,m,vn1,(Q)cbd,&g0,&h0,&a0,&b0,(Q *)&tq);
327: if ( NUM(g0) ) {
328: *pr = (P)ONE; return;
329: } else if ( dg > ( dg0 = deg(v,g0) ) ) {
330: dg = dg0;
331: if ( dg == d0 ) {
332: if ( divcheck(nvl,tps,m,lp0,p0) ) {
333: *pr = p0; return;
334: }
335: } else if ( dg == deg(v,tps[0]) ) {
336: if ( divtpz(nvl,p0,tps[0],&t) &&
337: divcheck(nvl,tps+1,m-1,LC(tps[0]),tps[0]) ) {
338: *pr = tps[0]; return;
339: } else
340: break;
341: } else {
342: henmv(nvl,vn1,lgp0,g0,h0,a0,b0,lg,lp0,lg0,lp00,(Q)tq,k,&g,&h);
343: if ( divtpz(nvl,lgp0,g,&t) &&
344: divcheck(nvl,tps,m,lg,g) ) {
345: pcp(nvl,g,pr,&t); return;
346: }
347: }
348: }
349: } while ( !nextbin(vnt,j) );
350: }
351:
352: void intersectv(vl1,vl2,vlp)
353: VL vl1,vl2,*vlp;
354: {
355: int i,n;
356: VL tvl;
357: VN tvn;
358:
359: if ( !vl1 || !vl2 ) {
360: *vlp = 0; return;
361: }
362: for ( n = 0, tvl = vl1; tvl; tvl = NEXT(tvl), n++ );
363: tvn = (VN) ALLOCA(n*sizeof(struct oVN));
364: for ( i = 0, tvl = vl1; i < n; tvl = NEXT(tvl), i++ ) {
365: tvn[i].v = tvl->v; tvn[i].n = 0;
366: }
367: for ( tvl = vl2; tvl; tvl = NEXT(tvl) )
368: for ( i = 0; i < n; i++ )
369: if ( tvn[i].v == tvl->v ) {
370: tvn[i].n = 1; break;
371: }
372: vntovl(tvn,n,vlp);
373: }
374:
375: int pcoef(vl,ivl,p,cp)
376: VL vl,ivl;
377: P p;
378: P *cp;
379: {
380: VL nvl,tvl,svl,mvl,mvl0;
381: P t;
382:
383: if ( NUM(p) ) {
384: cp[0] = p; return 1;
385: } else {
386: clctv(vl,p,&nvl);
387: for ( tvl = nvl, mvl0 = 0; tvl; tvl = NEXT(tvl) ) {
388: for ( svl = ivl; svl; svl = NEXT(svl) )
389: if ( tvl->v == svl->v )
390: break;
391: if ( !svl ) {
392: if ( !mvl0 ) {
393: NEWVL(mvl0); mvl = mvl0;
394: } else {
395: NEWVL(NEXT(mvl)); mvl = NEXT(mvl);
396: }
397: mvl->v = tvl->v;
398: }
399: }
400: if ( mvl0 )
401: NEXT(mvl) = ivl;
402: else
403: mvl0 = ivl;
404: reorderp(mvl0,nvl,p,&t);
405: return pcoef0(mvl0,ivl,t,cp);
406: }
407: }
408:
409: int pcoef0(vl,ivl,p,cp)
410: VL vl,ivl;
411: P p;
412: P *cp;
413: {
414: int cn,n;
415: DCP dc;
416: V v;
417: VL tvl;
418:
419: if ( NUM(p) ) {
420: cp[0] = p; return 1;
421: } else {
422: for ( v = VR(p), tvl = ivl; tvl; tvl = NEXT(tvl) )
423: if ( v == tvl->v )
424: break;
425: if ( tvl ) {
426: cp[0] = p; return 1;
427: } else {
428: for ( dc = DC(p), n = 0; dc; dc = NEXT(dc) ) {
429: cn = pcoef0(vl,ivl,COEF(dc),cp); cp += cn; n += cn;
430: }
431: return n;
432: }
433: }
434: }
435:
436: int lengthp(p)
437: P p;
438: {
439: int n;
440: DCP dc;
441:
442: if ( NUM(p) )
443: return 1;
444: else {
445: for ( dc = DC(p), n = 0; dc; dc = NEXT(dc) )
446: n += lengthp(COEF(dc));
447: return n;
448: }
449: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>