Annotation of OpenXM_contrib2/asir2000/engine/Fgfs.c, Revision 1.2
1.2 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2000/engine/Fgfs.c,v 1.1 2002/09/26 04:33:16 noro Exp $ */
1.1 noro 2:
3: #include "ca.h"
4:
5:
6: void gcdsf(VL vl,P *pa,int k,P *r)
7: {
8: P *ps,*pl,*pm,*cp;
9: int *cn;
10: DCP *ml;
11: Obj obj;
12: int i,j,l,m;
13: P mg,mgsf,t;
14: VL avl,nvl,tvl,svl;
15:
16: ps = (P *)ALLOCA(k*sizeof(P));
17: for ( i = 0, m = 0; i < k; i++ ) {
18: simp_ff((Obj)pa[i],&obj);
19: if ( obj )
20: ps[m++] = obj;
21: }
22: if ( !m ) {
23: *r = 0;
24: return;
25: }
26: if ( m == 1 ) {
27: *r = BDY(n0);
28: return;
29: }
30: pl = (P *)ALLOCA(m*sizeof(P));
31: ml = (DCP *)ALLOCA(m*sizeof(DCP));
32: for ( i = 0; i < m; i++ )
33: monomialfctr(vl,ps[i],&pl[i],&ml[i]);
34: gcdmonomial(vl,ml,m,&mg); simp_ff(mg,&mgsf);
35: for ( i = 0, nvl = vl, avl = 0; nvl && i < m; i++ ) {
36: clctv(vl,pl[i],&tvl);
37: intersectv(nvl,tvl,&svl); nvl = svl;
38: mergev(vl,avl,tvl,&svl); avl = svl;
39: }
40: if ( !nvl ) {
41: *r = mgsf;
42: return;
43: }
44: if ( !NEXT(avl) ) {
45: ugcdsf(pl,m,&t);
46: mulp(vl,mgsf,t,r);
47: return;
48: }
49: for ( tvl = nvl, i = 0; tvl; tvl = NEXT(tvl), i++ );
50: for ( tvl = avl, j = 0; tvl; tvl = NEXT(tvl), j++ );
51: if ( i == j ) {
52: /* all the pl[i]'s have the same variables */
53: gcdsf_main(avl,pl,m,&t);
54: } else {
55: cp = (P **)ALLOCA(m*sizeof(P *));
56: cn = (int *)ALLOCA(m*sizeof(int));
57: for ( i = 0; i < m; i++ ) {
58: cp[i] = (P *)ALLOCA(lengthp(pl[i])*sizeof(P));
59: cn[i] = pcoef(vl,nvl,pl[i],cp[i]);
60: }
61: for ( i = j = 0; i < m; i++ )
62: j += cn[i];
63: pm = (P *)ALLOCA(j*sizeof(P));
64: for ( i = l = 0; i < m; i++ )
65: for ( j = 0; j < cn[i]; j++ )
66: pm[l++] = cp[i][j];
67: gcdsf(vl,pm,l,&t);
68: }
69: mulp(vl,mgsf,t,r);
70: }
71:
72: /* univariate gcd */
73:
74: void ugcdsf(P *pa,int m,P *r)
75: {
76: P *pa;
77: int i;
78: UM w1,w2,w3,w;
79: int d;
80: V v;
81:
82: if ( m == 1 ) {
83: *r = pa[0];
84: return;
85: }
86: ps = (P *)ALLOCA(m*sizeof(P));
87: v = VR(pa[0]);
88: sort_by_deg(m,pa,ps);
89: d = getdeg(ps[m-1],v);
90: w1 = W_UMALLOC(d);
91: w2 = W_UMALLOC(d);
92: w3 = W_UMALLOC(d);
93: ptosfum(ps[0],w1);
94: for ( i = 1; i < m; i++ ) {
95: ptosfum(ps[i],w2);
96: gcdsfum(w1,w2,w3);
97: w = w1; w1 = w3; w3 = w;
98: if ( !DEG(w1) ) {
99: MKGFS(0,*r);
100: return;
101: }
102: }
103: sfumtop(v,w1,r);
104: }
105:
106:
107: /* all the pa[i]'s have the same variables (=vl) */
108:
109: void gcdsf_main(VL vl,P *pa,int m,P *r)
110: {
1.2 ! noro 111: int nv,i,i0,imin,d,d0,d1,d2;
! 112: V v0,vmin;
! 113: VL tvl,nvl,rvl,nvl0,rvl0;
! 114: P *pc, *ps, *ph;
! 115:
1.1 noro 116: for ( nv = 0, tvl = vl; tvl; tvl = NEXT(tvl), nv++);
117: if ( nv == 1 ) {
118: ugcdsf(pa,m,r);
119: return;
120: }
121: /* find v s.t. min(deg(pa[i],v)) is minimal */
122: tvl = vl;
123: do {
124: v = tvl->v;
125: i = 0;
126: do {
127: d = getdeg(pa[i],v);
128: if ( i == 0 || (d < d0) ) {
129: d0 = d; i0 = i; v0 = v;
130: }
131: } while ( ++i < m );
132: if ( tvl == vl || (d0 < dmin) ) {
133: dmin = d0; imin = i0; vmin = v0;
134: }
135: } while ( tvl = NEXT(tvl) );
136:
137: /* reorder variables so that vmin is the last variable */
138: for ( nvl0 = 0, rvl0 = 0, tvl = vl; tvl; tvl = NEXT(tvl) )
139: if ( tvl->v != vmin ) {
140: NEXTVL(nvl0,nvl); nvl->v = tvl->v;
141: NEXTVL(rvl0,rvl); rvl->v = tvl->v;
142: }
143: /* rvl = remaining variables */
144: NEXT(rvl) = 0;
145: /* nvl = ...,vmin */
146: NEXTVL(nvl0,nvl); nvl->v = vmin; NEXT(nvl) = 0;
1.2 ! noro 147: MKV(vmin,x);
1.1 noro 148:
149: /* for content and primitive part */
150: pc = (P *)ALLOCA(m*sizeof(P));
151: ps = (P *)ALLOCA(m*sizeof(P));
152: ph = (P *)ALLOCA(m*sizeof(P));
153: /* separate the contents */
154: for ( i = 0; i < m; i++ ) {
155: reorderp(vl,nvl,pa[i],&t);
156: cont_pp_mv_sf(nvl,rvl,t,&pc[i],&ps[i]);
157: head_monomial(vmin,ps[i],&ph[i],&t);
158: }
159: ugcdsf(pc,m,&cont);
160: ugcdsf(ph,m,&hg);
161:
162: /* for hg*pp (used in check phase) */
163: lps = (P *)ALLOCA(m*sizeof(P));
164: for ( i = 0; i < m; i++ )
165: mulp(nvl,hg,ps[i],&lps[i]);
166:
167: while ( 1 ) {
168: g = 0;
169: cofmin = 0;
170: hm = 0;
171: MKGFS(0,mod);
172: index = 0;
173: while ( getdeg(mod,vmin) <= d+1 ) {
174: /* evaluation pt */
175: MKGFS(index,s);
176: substp(nvl,hg,vmin,s,&hge);
177: if ( !hge )
178: continue;
179: for ( i = 0; i < m; i++ )
180: substp(nvl,ps[i],vmin,s,&ph[i]);
181: /* ge = GCD(ps[0]|x=s,...,ps[m-1]|x=s) */
182: gcdsf(nvl,ph,m,&ge);
183: head_monomial(vmin,ge,&ce,&he);
184: if ( NUM(hge) ) {
185: *r = cont;
186: return;
187: }
188: divgfs(hge,ce,&t); mulp(nvl,t,ge,&u); ge = u;
189: divsp(nvl,ph[imin],ge,&t); mulp(nvl,hge,t,&cof1e);
1.2 ! noro 190: /* hm=0 : reset; he==hm : lucky */
1.1 noro 191: if ( !hm || !cmpp(he,hm) ) {
1.2 ! noro 192: substp(nvl,mod,vmin,s,&mode); divsp(nvl,mod,mode,&mod1);
! 193: /* adj = mod/(mod|x=s)*(ge-g|x=s) */
! 194: substp(nvl,g,vmin,s,&t);
! 195: subp(nvl,ge,t,&u); mulp(nvl,mod1,u,&adj);
! 196: /* coadj = mod/(mod|vmin=s)*(cof1e-cof1e|vmin=s) */
! 197: substp(nvl,cof1,vmin,s,&t);
! 198: subp(nvl,cof1,t,&u); mulp(nvl,mod1,u,&coadj);
! 199: if ( !adj ) {
! 200: /* adj == gcd ? */
! 201: for ( i = 0; i < m; i++ )
! 202: if ( !divtp(nvl,lps[i],adj,&t) )
! 203: break;
! 204: if ( i == m ) {
! 205: cont_pp_mv_sf(nvl,rvl,adj,&t,&u);
! 206: mulp(nvl,cont,u,&t);
! 207: reorderp(nvl,vl,t,r);
! 208: return;
! 209: }
! 210: } else if ( !coadj ) {
! 211: /* ps[vmin]/coadj == gcd ? */
! 212: if ( divtp(nvl,lps[vmin],coadj,&q) ) {
! 213: for ( i = 0; i < m; i++ )
! 214: if ( !divtp(nvl,lps[i],q,&t) )
! 215: break;
! 216: if ( i == m ) {
! 217: cont_pp_mv_sf(nvl,rvl,q,&t,&u);
! 218: mulp(nvl,cont,u,&t);
! 219: reorderp(nvl,vl,t,r);
! 220: return;
! 221: }
! 222: }
! 223: }
! 224: addp(nvl,g,adj,&t); g = t;
! 225: addp(nvl,cof1,coadj,&t); cof1 = t;
! 226: subp(nvl,x,s,&t); mulp(nvl,mod,t,&u); mod = u;
! 227: hm = he;
! 228: } else {
! 229: d1 = homdeg(hm); d2 = homdeg(he);
! 230: if ( d1 < d2 ) /* we use current hm */
! 231: continue;
! 232: else if ( d1 > d2 ) {
! 233: /* use he */
! 234: g = ge;
! 235: cof1 = cof1e;
! 236: hm = he;
! 237: subp(nvl,x,s,&mod);
! 238: } else {
! 239: /* d1==d2, but hm!=he => both are unlucky */
! 240: g = 0;
! 241: cof1 = 0;
! 242: MKGFS(0,mod);
! 243: }
1.1 noro 244: }
245: }
246: }
247: }
248:
249: void head_monomial(V v,P p,P *coef,P *term)
250: {
251: P t,s,u;
252: DCP dc;
253: GFS one;
254:
255: MKGFS(0,one); t = one;
256: while ( 1 ) {
257: if ( NUM(p) || VR(p) == v ) {
258: *coef = p;
259: *term = t;
260: return;
261: } else {
262: NEWDC(dc); MKGFS(0,one);
263: COEF(dc) = one; DEG(dc) = DEG(DC(p));
264: MKP(VR(p),dc,s);
265: mulp(vl,t,s,&u); t = u;
266: p = COEF(DC(p));
267: }
268: }
269: }
270:
271: void cont_pp_mv_sf(VL vl,VL rvl,P p,P *c,P *pp)
272: {
273: DP dp;
274: MP t;
275: int i,m;
276: P *ps;
277:
278: ptod(vl,rvl,p,&dp);
279: for ( t = BDY(dp), m = 0; t; t = NEXT(t), m++ );
280: ps = (P *)ALLOCA(m*sizeof(P));
281: for ( t = BDY(dp), i = 0; t; t = NEXT(t), i++ );
282: ps[i] = C(t);
283: ugcdsf(ps,m,c);
284: divsp(vl,p,c,pp);
285: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>