Annotation of OpenXM_contrib2/asir2000/engine/Mgfs.c, Revision 1.15
1.15 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2000/engine/Mgfs.c,v 1.14 2002/09/27 08:40:49 noro Exp $ */
1.1 noro 2:
3: #include "ca.h"
1.13 noro 4: #include "inline.h"
1.1 noro 5:
1.15 ! noro 6: extern int current_gfs_p;
1.5 noro 7: extern int up_kara_mag, current_gfs_q1;
8: extern int *current_gfs_plus1;
9:
1.9 noro 10: #if defined(__GNUC__)
11: #define INLINE inline
12: #elif defined(VISUAL)
13: #define INLINE __inline
14: #else
15: #define INLINE
16: #endif
17:
1.11 noro 18: INLINE int _ADDSF(int a,int b)
1.5 noro 19: {
20: if ( !a )
21: return b;
22: else if ( !b )
23: return a;
24:
25: a = IFTOF(a); b = IFTOF(b);
1.13 noro 26:
27: if ( !current_gfs_ntoi ) {
28: a = a+b-current_gfs_q;
29: if ( a == 0 )
30: return 0;
31: else {
32: if ( a < 0 )
33: a += current_gfs_q;
34: return FTOIF(a);
35: }
36: }
37:
1.5 noro 38: if ( a > b ) {
39: /* tab[a]+tab[b] = tab[b](tab[a-b]+1) */
40: a = current_gfs_plus1[a-b];
41: if ( a < 0 )
42: return 0;
43: else {
44: a += b;
45: if ( a >= current_gfs_q1 )
46: a -= current_gfs_q1;
47: return FTOIF(a);
48: }
49: } else {
50: /* tab[a]+tab[b] = tab[a](tab[b-a]+1) */
51: b = current_gfs_plus1[b-a];
52: if ( b < 0 )
53: return 0;
54: else {
55: b += a;
56: if ( b >= current_gfs_q1 )
57: b -= current_gfs_q1;
58: return FTOIF(b);
59: }
60: }
61: }
62:
1.11 noro 63: INLINE int _MULSF(int a,int b)
1.5 noro 64: {
1.13 noro 65: int c;
66:
1.5 noro 67: if ( !a || !b )
68: return 0;
1.13 noro 69: else if ( !current_gfs_ntoi ) {
70: a = IFTOF(a); b = IFTOF(b);
71: DMAR(a,b,0,current_gfs_q,c);
72: return FTOIF(c);
73: } else {
1.5 noro 74: a = IFTOF(a) + IFTOF(b);
75: if ( a >= current_gfs_q1 )
76: a -= current_gfs_q1;
77: return FTOIF(a);
78: }
79: }
1.1 noro 80:
1.11 noro 81: void addsfum(UM p1,UM p2,UM pr)
1.1 noro 82: {
83: int *c1,*c2,*cr,i,dmax,dmin;
84:
85: if ( DEG(p1) == -1 ) {
86: cpyum(p2,pr);
87: return;
88: }
89: if ( DEG(p2) == -1 ) {
90: cpyum(p1,pr);
91: return;
92: }
93: if ( DEG(p1) >= DEG(p2) ) {
94: c1 = COEF(p1); c2 = COEF(p2); dmax = DEG(p1); dmin = DEG(p2);
95: } else {
96: c1 = COEF(p2); c2 = COEF(p1); dmax = DEG(p2); dmin = DEG(p1);
97: }
98: for ( i = 0, cr = COEF(pr); i <= dmin; i++ )
1.5 noro 99: cr[i] = _ADDSF(c1[i],c2[i]);
1.1 noro 100: for ( ; i <= dmax; i++ )
101: cr[i] = c1[i];
102: if ( dmax == dmin )
103: degum(pr,dmax);
104: else
105: DEG(pr) = dmax;
106: }
107:
1.11 noro 108: void subsfum(UM p1,UM p2,UM pr)
1.1 noro 109: {
110: int *c1,*c2,*cr,i;
111: int dmax,dmin;
112:
113: if ( DEG(p1) == -1 ) {
114: for ( i = DEG(pr) = DEG(p2), c2 = COEF(p2), cr = COEF(pr);
115: i >= 0; i-- )
116: cr[i] = _chsgnsf(c2[i]);
117: return;
118: }
119: if ( DEG(p2) == -1 ) {
120: cpyum(p1,pr);
121: return;
122: }
123: c1 = COEF(p1); c2 = COEF(p2); cr = COEF(pr);
124: if ( DEG(p1) >= DEG(p2) ) {
125: dmax = DEG(p1); dmin = DEG(p2);
126: for ( i = 0; i <= dmin; i++ )
127: cr[i] = _subsf(c1[i],c2[i]);
128: for ( ; i <= dmax; i++ )
129: cr[i] = c1[i];
130: } else {
131: dmax = DEG(p2); dmin = DEG(p1);
132: for ( i = 0; i <= dmin; i++ )
133: cr[i] = _subsf(c1[i],c2[i]);
134: for ( ; i <= dmax; i++ )
135: cr[i] = _chsgnsf(c2[i]);
136: }
137: if ( dmax == dmin )
138: degum(pr,dmax);
139: else
140: DEG(pr) = dmax;
141: }
142:
1.11 noro 143: void gcdsfum(UM p1,UM p2,UM pr)
1.1 noro 144: {
145: int inv;
146: UM t1,t2,q,tum;
147: int drem;
148:
149: if ( DEG(p1) < 0 )
150: cpyum(p2,pr);
151: else if ( DEG(p2) < 0 )
152: cpyum(p1,pr);
153: else {
154: if ( DEG(p1) >= DEG(p2) ) {
155: t1 = p1; t2 = p2;
156: } else {
157: t1 = p2; t2 = p1;
158: }
159: q = W_UMALLOC(DEG(t1));
160: while ( ( drem = divsfum(t1,t2,q) ) >= 0 ) {
161: tum = t1; t1 = t2; t2 = tum; DEG(t2) = drem;
162: }
163: inv = _invsf(COEF(t2)[DEG(t2)]);
164: mulssfum(t2,inv,pr);
165: }
166: }
1.11 noro 167:
168: void mulsfum(UM p1,UM p2,UM pr)
1.1 noro 169: {
170: int *pc1,*pcr;
171: int *c1,*c2,*cr;
172: int mul;
173: int i,j,d1,d2;
174:
175: if ( ( (d1 = DEG(p1)) < 0) || ( (d2 = DEG(p2)) < 0 ) ) {
176: DEG(pr) = -1;
177: return;
178: }
179: c1 = COEF(p1); c2 = COEF(p2); cr = COEF(pr);
180: bzero((char *)cr,(int)((d1+d2+1)*sizeof(int)));
181: for ( i = 0; i <= d2; i++, cr++ )
182: if ( mul = *c2++ )
183: for ( j = 0, pc1 = c1, pcr = cr; j <= d1; j++, pc1++, pcr++ )
1.5 noro 184: if ( *pc1 )
185: *pcr = _ADDSF(_MULSF(*pc1,mul),*pcr);
1.1 noro 186: DEG(pr) = d1 + d2;
187: }
188:
1.11 noro 189: void mulssfum(UM p,int n,UM pr)
1.1 noro 190: {
191: int *sp,*dp;
192: int i;
193:
194: for ( i = DEG(pr) = DEG(p), sp = COEF(p)+i, dp = COEF(pr)+i;
195: i >= 0; i--, dp--, sp-- )
1.5 noro 196: *dp = _MULSF(*sp,n);
1.1 noro 197: }
198:
1.11 noro 199: void kmulsfum(UM n1,UM n2,UM nr)
1.5 noro 200: {
201: UM n,t,s,m,carry;
202: int d,d1,d2,len,i,l;
203: unsigned int *r,*r0;
204:
205: if ( !n1 || !n2 ) {
206: nr->d = -1; return;
207: }
208: d1 = DEG(n1)+1; d2 = DEG(n2)+1;
209: if ( (d1 < up_kara_mag) || (d2 < up_kara_mag) ) {
210: mulsfum(n1,n2,nr); return;
211: }
212: if ( d1 < d2 ) {
213: n = n1; n1 = n2; n2 = n;
214: d = d1; d1 = d2; d2 = d;
215: }
216: if ( d2 > (d1+1)/2 ) {
217: kmulsfummain(n1,n2,nr); return;
218: }
219: d = (d1/d2)+((d1%d2)!=0);
220: len = (d+1)*d2;
221: r0 = (unsigned int *)ALLOCA(len*sizeof(int));
222: bzero((char *)r0,len*sizeof(int));
223: m = W_UMALLOC(d2+1);
224: carry = W_UMALLOC(d2+1);
225: t = W_UMALLOC(d1+d2+1);
226: s = W_UMALLOC(d1+d2+1);
227: for ( DEG(carry) = -1, i = 0, r = r0; i < d; i++, r += d2 ) {
228: extractum(n1,i*d2,d2,m);
229: if ( m ) {
230: kmulsfum(m,n2,t);
231: addsfum(t,carry,s);
232: c_copyum(s,d2,r);
233: extractum(s,d2,d2,carry);
234: } else {
235: c_copyum(carry,d2,r);
236: carry = 0;
237: }
238: }
239: c_copyum(carry,d2,r);
240: for ( l = len - 1; !r0[l]; l-- );
241: l++;
242: DEG(nr) = l-1;
243: bcopy((char *)r0,(char *)COEF(nr),l*sizeof(int));
244: }
245:
1.11 noro 246: void kmulsfummain(UM n1,UM n2,UM nr)
1.5 noro 247: {
248: int d1,d2,h,len;
249: UM n1lo,n1hi,n2lo,n2hi,hi,lo,mid1,mid2,mid,s1,s2,t1,t2;
250:
251: d1 = DEG(n1)+1; d2 = DEG(n2)+1; h = (d1+1)/2;
252: n1lo = W_UMALLOC(d1+1); n1hi = W_UMALLOC(d1+1);
253: n2lo = W_UMALLOC(d2+1); n2hi = W_UMALLOC(d2+1);
254: lo = W_UMALLOC(d1+d2+1); hi = W_UMALLOC(d1+d2+1);
255: mid1 = W_UMALLOC(d1+d2+1); mid2 = W_UMALLOC(d1+d2+1);
256: mid = W_UMALLOC(d1+d2+1);
257: s1 = W_UMALLOC(d1+d2+1); s2 = W_UMALLOC(d1+d2+1);
258: extractum(n1,0,h,n1lo); extractum(n1,h,d1-h,n1hi);
259: extractum(n2,0,h,n2lo); extractum(n2,h,d2-h,n2hi);
260: kmulsfum(n1hi,n2hi,hi); kmulsfum(n1lo,n2lo,lo);
261: len = DEG(hi)+1+2*h; t1 = W_UMALLOC(len-1); DEG(t1) = len-1;
262: bzero((char *)COEF(t1),len*sizeof(int));
263: if ( lo )
264: bcopy((char *)COEF(lo),(char *)COEF(t1),(DEG(lo)+1)*sizeof(int));
265: if ( hi )
266: bcopy((char *)COEF(hi),(char *)(COEF(t1)+2*h),(DEG(hi)+1)*sizeof(int));
267:
268: addsfum(hi,lo,mid1);
269: subsfum(n1hi,n1lo,s1); subsfum(n2lo,n2hi,s2);
270: kmulsfum(s1,s2,mid2); addsfum(mid1,mid2,mid);
271: if ( mid ) {
272: len = DEG(mid)+1+h; t2 = W_UMALLOC(len-1); DEG(t2) = len-1;
273: bzero((char *)COEF(t2),len*sizeof(int));
274: bcopy((char *)COEF(mid),(char *)(COEF(t2)+h),(DEG(mid)+1)*sizeof(int));
275: addsfum(t1,t2,nr);
276: } else
277: copyum(t1,nr);
278: }
279:
1.11 noro 280: int divsfum(UM p1,UM p2,UM pq)
1.1 noro 281: {
282: int *pc1,*pct;
283: int *c1,*c2,*ct;
284: int inv,hd,tmp;
285: int i,j, d1,d2,dd;
286:
287: if ( (d1 = DEG(p1)) < (d2 = DEG(p2)) ) {
288: DEG(pq) = -1;
289: return d1;
290: }
291: c1 = COEF(p1); c2 = COEF(p2); dd = d1-d2;
292: if ( ( hd = c2[d2] ) != _onesf() ) {
293: inv = _invsf(hd);
294: for ( pc1 = c2 + d2; pc1 >= c2; pc1-- )
1.5 noro 295: *pc1 = _MULSF(*pc1,inv);
1.1 noro 296: } else
297: inv = _onesf();
298: for ( i = dd, ct = c1+d1; i >= 0; i-- )
299: if ( tmp = *ct-- ) {
300: tmp = _chsgnsf(tmp);
301: for ( j = d2-1, pct = ct, pc1 = c2+j; j >= 0; j--, pct--, pc1-- )
1.5 noro 302: *pct = _ADDSF(_MULSF(*pc1,tmp),*pct);
1.1 noro 303: }
304: if ( inv != _onesf() ) {
305: for ( pc1 = c1+d2, pct = c1+d1; pc1 <= pct; pc1++ )
1.5 noro 306: *pc1 = _MULSF(*pc1,inv);
1.1 noro 307: for ( pc1 = c2, pct = c2+d2; pc1 <= pct; pc1++ )
1.5 noro 308: *pc1 = _MULSF(*pc1,hd);
1.1 noro 309: }
310: for ( i = d2-1, pc1 = c1+i; i >= 0 && !(*pc1); pc1--, i-- );
311: for ( DEG(pq) = j = dd, pc1 = c1+d1, pct = COEF(pq)+j; j >= 0; j-- )
312: *pct-- = *pc1--;
313: return i;
314: }
315:
1.11 noro 316: void diffsfum(UM f,UM fd)
1.1 noro 317: {
318: int *dp,*sp;
319: int i;
320:
321: for ( i = DEG(f), dp = COEF(fd)+i-1, sp = COEF(f)+i;
322: i >= 1; i--, dp--, sp-- ) {
1.15 ! noro 323: *dp = _MULSF(*sp,_itosf(i%current_gfs_p));
1.1 noro 324: }
325: degum(fd,DEG(f) - 1);
326: }
327:
1.11 noro 328: void monicsfum(UM f)
1.1 noro 329: {
330: int *sp;
331: int i,inv;
332:
333: i = DEG(f); sp = COEF(f)+i;
334: inv = _invsf(*sp);
335: for ( ; i >= 0; i--, sp-- )
1.5 noro 336: *sp = _MULSF(*sp,inv);
1.10 noro 337: }
338:
1.11 noro 339: int compsfum(UM a,UM b)
1.10 noro 340: {
341: int i,da,db;
342:
343: if ( !a )
344: return !b?0:1;
345: else if ( !b )
346: return 1;
347: else if ( (da = DEG(a)) > (db = DEG(b)) )
348: return 1;
349: else if ( da < db )
350: return -1;
351: else {
352: for ( i = da; i >= 0 && COEF(a)[i] == COEF(b)[i]; i-- );
353: if ( i < 0 )
354: return 0;
355: else if ( (unsigned int)COEF(a)[i] > (unsigned int)COEF(b)[i] )
356: return 1;
357: else
358: return -1;
359: }
1.2 noro 360: }
361:
1.3 noro 362: void addsfarray(int,int *,int *);
363: void mulsfarray_trunc(int,int *,int *,int *);
1.2 noro 364:
1.4 noro 365: /* f1 = f1->c[0]+f1->c[1]*y+..., f2 = f2->c[0]+f2->c[1]*y+... mod y^n */
366:
1.11 noro 367: void mulsfbm(BM f1,BM f2,BM fr)
1.4 noro 368: {
369: UM mul,t,s;
1.11 noro 370: int i,j,d1,d2,dy;
1.4 noro 371:
1.8 noro 372: dy = MIN(DEG(f1),DEG(f2));
1.4 noro 373:
1.8 noro 374: d1 = degbm(f1);
375: d2 = degbm(f2);
1.4 noro 376: t = W_UMALLOC(d1+d2);
377: s = W_UMALLOC(d1+d2);
378:
1.8 noro 379: for ( i = 0; i <= dy; i++ ) {
1.4 noro 380: mul = COEF(f2)[i];
381: if ( DEG(mul) >= 0 )
1.8 noro 382: for ( j = 0; i+j <= dy; j++ ) {
1.4 noro 383: if ( COEF(f1)[j] ) {
1.7 noro 384: kmulsfum(COEF(f1)[j],mul,t);
1.4 noro 385: addsfum(t,COEF(fr)[i+j],s);
386: cpyum(s,COEF(fr)[i+j]);
387: }
388: }
389: }
1.8 noro 390: DEG(fr) = dy;
1.4 noro 391: }
392:
1.11 noro 393: int degbm(BM f)
1.6 noro 394: {
1.8 noro 395: int d,i,dy;
1.6 noro 396:
1.8 noro 397: dy = DEG(f);
1.6 noro 398: d = DEG(COEF(f)[0]);
1.8 noro 399: for ( i = 1; i <= dy; i++ )
1.6 noro 400: d = MAX(DEG(COEF(f)[i]),d);
401: return d;
402: }
403:
1.4 noro 404: /* g += f */
405:
1.11 noro 406: void addtosfbm(BM f,BM g)
1.4 noro 407: {
1.8 noro 408: int i,d1,d2,dy;
1.4 noro 409: UM t;
410:
1.8 noro 411: dy = DEG(g);
412: if ( DEG(f) > dy )
413: error("addtosfbm : invalid input");
414: dy = MIN(DEG(f),dy);
415: d1 = degbm(f);
416: d2 = degbm(g);
1.4 noro 417: t = W_UMALLOC(MAX(d1,d2));
1.8 noro 418: for ( i = 0; i <= dy; i++ ) {
1.4 noro 419: addsfum(COEF(f)[i],COEF(g)[i],t);
420: cpyum(t,COEF(g)[i]);
421: }
422: }
423:
1.11 noro 424: void eucsfum(UM f1,UM f2,UM a,UM b)
1.2 noro 425: {
426: UM g1,g2,a1,a2,a3,wm,q,tum;
427: int d,dr;
428:
429: /* XXX */
430: d = DEG(f1) + DEG(f2) + 10;
431: g1 = W_UMALLOC(d); g2 = W_UMALLOC(d); a1 = W_UMALLOC(d);
432: a2 = W_UMALLOC(d); a3 = W_UMALLOC(d); wm = W_UMALLOC(d);
433: q = W_UMALLOC(d);
1.3 noro 434: DEG(a1) = 0; COEF(a1)[0] = _onesf(); DEG(a2) = -1;
1.2 noro 435: cpyum(f1,g1); cpyum(f2,g2);
436: while ( 1 ) {
437: dr = divsfum(g1,g2,q); tum = g1; g1 = g2; g2 = tum;
438: if ( ( DEG(g2) = dr ) == -1 )
439: break;
440: mulsfum(a2,q,wm); subsfum(a1,wm,a3); dr = divsfum(a3,f2,q);
441: tum = a1; a1 = a2; a2 = a3; a3 = tum; DEG(a3) = dr;
442: }
1.3 noro 443: if ( COEF(g1)[0] != _onesf() )
1.2 noro 444: mulssfum(a2,_invsf(COEF(g1)[0]),a);
445: else
446: cpyum(a2,a);
447: mulsfum(a,f1,wm);
448: if ( DEG(wm) >= 0 )
449: COEF(wm)[0] = _subsf(COEF(wm)[0],_onesf());
450: else {
451: DEG(wm) = 0; COEF(wm)[0] = _chsgnsf(_onesf());
452: }
453: divsfum(wm,f2,q); mulssfum(q,_chsgnsf(_onesf()),b);
1.3 noro 454: }
455:
456: void shiftsfum(UM,int,UM);
457:
1.11 noro 458: void shiftsflum(int n,LUM f,int ev)
1.3 noro 459: {
460: int d,i,j;
461: UM w,w1;
462: int *coef;
463: int **c;
464:
465: d = f->d;
466: c = f->c;
467: w = W_UMALLOC(n);
468: w1 = W_UMALLOC(n);
469: for ( i = 0; i <= d; i++ ) {
470: coef = c[i];
471: for ( j = n-1; j >= 0 && coef[j] == 0; j-- );
472: if ( j <= 0 )
473: continue;
474: DEG(w) = j; bcopy(coef,COEF(w),(j+1)*sizeof(int));
475: shiftsfum(w,ev,w1);
476: bcopy(COEF(w1),coef,(j+1)*sizeof(int));
477: }
478: }
479:
480: /* f(x) -> g(x) = f(x+a) */
481:
1.11 noro 482: void shiftsfum(UM f,int a,UM g)
1.3 noro 483: {
484: int n,i;
485: UM pwr,xa,w,t;
486: int *c;
487:
488: n = DEG(f);
489: if ( n <= 0 )
490: cpyum(f,g);
491: else {
492: c = COEF(f);
493:
494: /* g = 0 */
495: DEG(g) = -1;
496:
497: /* pwr = 1 */
498: pwr = W_UMALLOC(n); DEG(pwr) = 0; COEF(pwr)[0] = _onesf();
499:
500: /* xa = x+a */
501: xa = W_UMALLOC(n); DEG(xa) = 1;
502: COEF(xa)[0] = a; COEF(xa)[1] = _onesf();
503:
504: w = W_UMALLOC(n);
505: t = W_UMALLOC(n);
506:
507: /* g += pwr*c[0] */
508: for ( i = 0; i <= n; i++ ) {
509: mulssfum(pwr,c[i],w); addsfum(g,w,t); cpyum(t,g);
510: if ( i < n ) {
511: mulsfum(pwr,xa,t); cpyum(t,pwr);
512: }
513: }
514: }
515: }
516:
1.4 noro 517: /* f(y) -> f(y+a) */
518:
1.11 noro 519: void shiftsfbm(BM f,int a)
1.4 noro 520: {
1.8 noro 521: int i,j,d,dy;
1.4 noro 522: UM pwr,ya,w,t,s;
523: UM *c;
524:
1.8 noro 525: dy = DEG(f);
526: c = COEF(f);
527: d = degbm(f);
528:
529: w = W_UMALLOC(d);
530: t = W_UMALLOC(d);
531: s = W_UMALLOC(dy);
532:
533: /* pwr = 1 */
534: pwr = W_UMALLOC(dy); DEG(pwr) = 0; COEF(pwr)[0] = _onesf();
535:
536: /* ya = y+a */
537: ya = W_UMALLOC(1); DEG(ya) = 1;
538: COEF(ya)[0] = a; COEF(ya)[1] = _onesf();
539:
540: for ( i = 0; i <= dy; i++ ) {
541: /* c[i] does not change */
542: for ( j = 0; j < i; j++ ) {
543: mulssfum(c[i],COEF(pwr)[j],w);
544: addsfum(w,c[j],t); cpyum(t,c[j]);
545: }
546: if ( i < dy ) {
547: mulsfum(pwr,ya,s); cpyum(s,pwr);
1.4 noro 548: }
549: }
550: }
551:
1.11 noro 552: void clearbm(int n,BM f)
1.4 noro 553: {
1.8 noro 554: int i,dy;
1.4 noro 555: UM *c;
556:
1.8 noro 557: dy = DEG(f);
558: for ( c = COEF(f), i = 0; i <= dy; i++ )
1.4 noro 559: clearum(c[i],n);
1.12 noro 560: }
561:
562: static void create_bmono(P c,V x,int i,V y,int j,P *mono);
563:
564: struct lb {
565: int pos,len;
566: int *r;
567: int *hist;
568: };
569:
570: static NODE insert_lb(NODE g,struct lb *a)
571: {
572: NODE prev,cur,n;
573:
574: prev = 0; cur = g;
575: while ( cur ) {
576: if ( a->pos < ((struct lb *)BDY(cur))->pos ) {
577: MKNODE(n,a,cur);
578: if ( !prev )
579: return n;
580: else {
581: NEXT(prev) = n;
582: return g;
583: }
584: } else {
585: prev = cur;
586: cur = NEXT(cur);
587: }
588: }
589: MKNODE(n,a,0);
590: NEXT(prev) = n;
591: return g;
592: }
593:
594: static void lnf(int *r,int *h,int n,int len,NODE g)
595: {
596: struct lb *t;
597: int pos,i,j,len1,c;
598: int *r1,*h1;
599:
600: for ( ; g; g = NEXT(g) ) {
601: t = (struct lb *)BDY(g);
602: pos = t->pos;
603: if ( c = r[pos] ) {
604: c = _chsgnsf(c);
605: r1 = t->r;
606: h1 = t->hist;
607: len1 = t->len;
608: for ( i = pos; i < n; i++ )
609: if ( r1[i] )
610: r[i] = _ADDSF(r[i],_MULSF(r1[i],c));
611: for ( i = 0; i < len1; i++ )
612: if ( h1[i] )
613: h[i] = _ADDSF(h[i],_MULSF(h1[i],c));
614: }
615: }
616: for ( i = 0; i < n && !r[i]; i++ );
617: if ( i < n ) {
618: c = _invsf(r[i]);
619: for ( j = i; j < n; j++ )
620: if ( r[j] )
621: r[j] = _MULSF(r[j],c);
622: for ( j = 0; j < len; j++ )
623: if ( h[j] )
624: h[j] = _MULSF(h[j],c);
625: }
626: }
627:
628: void sfmintdeg(VL vl,P fx,int dy,int c,P *fr)
629: {
630: V x,y;
631: int dx,dxdy,i,j,k,l,d,len,len0,u,dyk;
632: UP *rx;
633: DCP dc;
634: P t,f,mono,f1;
635: UP ut,h;
636: int ***nf;
637: int *r,*hist,*prev,*r1;
638: struct lb *lb;
639: GFS s;
640: NODE g;
641:
642: x = vl->v;
643: y = NEXT(vl)->v;
644: dx = getdeg(x,fx);
645: dxdy = dx*dy;
646: /* rx = -(fx-x^dx) */
647: rx = (UP *)CALLOC(dx,sizeof(UP));
648: for ( dc = DC(fx); dc; dc = NEXT(dc)) {
649: chsgnp(COEF(dc),&t);
650: ptoup(t,&ut);
651: rx[QTOS(DEG(dc))] = ut;
652: }
653: /* nf[d] = normal form table of monomials with total degree d */
654: nf = (int ***)CALLOC(dx+dy+1,sizeof(int **)); /* xxx */
655: nf[0] = (int **)CALLOC(1,sizeof(int *));
656:
657: /* nf[0][0] = 1 */
658: r = (int *)CALLOC(dxdy,sizeof(int));
659: r[0] = _onesf();
660: nf[0][0] = r;
661:
662: hist = (int *)CALLOC(1,sizeof(int));
663: hist[0] = _onesf();
664:
665: lb = (struct lb *)CALLOC(1,sizeof(struct lb));
666: lb->pos = 0;
667: lb->r = r;
668: lb->hist = hist;
669: lb->len = 1;
670:
671: /* g : table of normal form as linear form */
672: MKNODE(g,lb,0);
673:
674: len = 1;
675: h = UPALLOC(dy);
676: for ( d = 1; ; d++ ) {
677: if ( d > c ){
678: return;
679: }
680: nf[d] = (int **)CALLOC(d+1,sizeof(int *));
681: len0 = len;
682: len += d+1;
683:
684: for ( i = d; i >= 0; i-- ) {
685: /* nf(x^(d-i)*y^i) = nf(y*nf(x^(d-i)*y^(i-1))) */
686: /* nf(x^d) = nf(nf(x^(d-1))*x) */
687: r = (int *)CALLOC(dxdy,sizeof(int));
688: if ( i == 0 ) {
689: prev = nf[d-1][0];
690: bcopy(prev,r+dy,(dxdy-dy)*sizeof(int));
691:
692: /* create the head coeff */
693: for ( l = 0, k = dxdy-dy; l < dy; l++, k++ ) {
1.14 noro 694: iftogfs(prev[k],&s);
1.12 noro 695: COEF(h)[l] = (Num)s;
696: }
697: for ( l = dy-1; l >= 0 && !COEF(h)[l]; l--);
698: DEG(h) = l;
699:
700: for ( k = 0, dyk = 0; k < dx; k++, dyk += dy ) {
701: tmulup(rx[k],h,dy,&ut);
702: if ( ut )
703: for ( l = 0; l < dy; l++ ) {
704: s = (GFS)COEF(ut)[l];
705: if ( s ) {
706: u = CONT(s);
707: r[dyk+l] = _ADDSF(r[dyk+l],FTOIF(u));
708: }
709: }
710: }
711: } else {
712: prev = nf[d-1][i-1];
713: for ( k = 0, dyk = 0; k < dx; k++, dyk += dy ) {
714: for ( l = 1; l < dy; l++ )
715: r[dyk+l] = prev[dyk+l-1];
716: }
717: }
718: nf[d][i] = r;
719: hist = (int *)CALLOC(len,sizeof(int));
720: hist[len0+i] = _onesf();
721: r1 = (int *)CALLOC(dxdy,sizeof(int));
722: bcopy(r,r1,dxdy*sizeof(int));
723: lnf(r1,hist,dxdy,len,g);
724: for ( k = 0; k < dxdy && !r1[k]; k++ );
725: if ( k == dxdy ) {
726: f = 0;
727: for ( k = j = 0; k <= d; k++ )
728: for ( i = 0; i <= k; i++, j++ )
729: if ( hist[j] ) {
1.14 noro 730: iftogfs(hist[j],&s);
1.12 noro 731: /* mono = s*x^(k-i)*y^i */
732: create_bmono((P)s,x,k-i,y,i,&mono);
733: addp(vl,f,mono,&f1);
734: f = f1;
735: }
736: *fr = f;
737: return;
738: } else {
739: lb = (struct lb *)CALLOC(1,sizeof(struct lb));
740: lb->pos = k;
741: lb->r = r1;
742: lb->hist = hist;
743: lb->len = len;
744: g = insert_lb(g,lb);
745: }
746: }
747: }
748: }
749:
750: static void create_bmono(P c,V x,int i,V y,int j,P *mono)
751: {
752: P t,s;
753:
754: if ( !i )
755: if ( !j )
756: t = c;
757: else {
758: /* c*y^j */
759: MKV(y,t);
760: COEF(DC(t)) = c;
761: STOQ(j,DEG(DC(t)));
762: }
763: else if ( !j ) {
764: /* c*x^i */
765: MKV(x,t);
766: COEF(DC(t)) = c;
767: STOQ(i,DEG(DC(t)));
768: } else {
769: MKV(y,s);
770: COEF(DC(s)) = c;
771: STOQ(j,DEG(DC(s)));
772: MKV(x,t);
773: COEF(DC(t)) = s;
774: STOQ(i,DEG(DC(t)));
775: }
776: *mono = t;
1.1 noro 777: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>