Annotation of OpenXM_contrib2/asir2000/engine/F.c, Revision 1.2
1.2 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2000/engine/F.c,v 1.1.1.1 1999/12/03 07:39:08 noro Exp $ */
1.1 noro 2: #include "ca.h"
3: #include <math.h>
4:
5: void homfctr();
6:
7: void fctrp(vl,f,dcp)
8: VL vl;
9: P f;
10: DCP *dcp;
11: {
12: VL nvl;
13: DCP dc;
14:
15: if ( !f || NUM(f) ) {
16: NEWDC(dc); COEF(dc) = f; DEG(dc) = ONE;
17: NEXT(dc) = 0; *dcp = dc;
18: return;
19: } else if ( !qpcheck((Obj)f) )
20: error("fctrp : invalid argument");
21: else {
22: clctv(vl,f,&nvl);
23: if ( !NEXT(nvl) )
24: ufctr(f,1,dcp);
25: else
26: mfctr(nvl,f,dcp);
27: }
28: }
29:
30: void homfctr(vl,g,dcp)
31: VL vl;
32: P g;
33: DCP *dcp;
34: {
35: P s,t,u,f,h,x;
36: Q e;
37: int d,d0;
38: DCP dc,dct;
39:
40: substp(vl,g,vl->v,(P)ONE,&t); fctrp(vl,t,&dc); MKV(vl->v,x);
41: for ( dct = dc; dct; dct = NEXT(dct) )
42: if ( !NUM(dc->c) ) {
43: for ( s = 0, f = dc->c, d = d0 = homdeg(f); f; d = homdeg(f) ) {
44: exthp(vl,f,d,&h); STOQ(d0-d,e); pwrp(vl,x,e,&t);
45: mulp(vl,t,h,&u); addp(vl,s,u,&t); s = t;
46: subp(vl,f,h,&u); f = u;
47: }
48: dc->c = s;
49: }
50: *dcp = dc;
51: }
52:
53: void mfctr(vl,f,dcp)
54: VL vl;
55: P f;
56: DCP *dcp;
57: {
58: DCP dc,dc0,dct,dcs,dcr;
59: P p,pmin,ppmin,cmin,t;
60: VL mvl;
61: Q c;
62:
63: ptozp(f,1,&c,&p);
64: NEWDC(dc0); dc = dc0; COEF(dc) = (P)c; DEG(dc) = ONE; NEXT(dc) = 0;
65: msqfr(vl,p,&dct);
66: for ( ; dct; dct = NEXT(dct) ) {
67: mindegp(vl,COEF(dct),&mvl,&pmin);
68: #if 0
69: minlcdegp(vl,COEF(dct),&mvl,&pmin);
70: min_common_vars_in_coefp(vl,COEF(dct),&mvl,&pmin);
71: #endif
72: pcp(mvl,pmin,&ppmin,&cmin);
73: if ( !NUM(cmin) ) {
74: mfctrmain(mvl,cmin,&dcs);
75: for ( dcr = dcs; dcr; dcr = NEXT(dcr) ) {
76: DEG(dcr) = DEG(dct);
77: reorderp(vl,mvl,COEF(dcr),&t); COEF(dcr) = t;
78: }
79: for ( ; NEXT(dc); dc = NEXT(dc) );
80: NEXT(dc) = dcs;
81: }
82: mfctrmain(mvl,ppmin,&dcs);
83: for ( dcr = dcs; dcr; dcr = NEXT(dcr) ) {
84: DEG(dcr) = DEG(dct);
85: reorderp(vl,mvl,COEF(dcr),&t); COEF(dcr) = t;
86: }
87: for ( ; NEXT(dc); dc = NEXT(dc) );
88: NEXT(dc) = dcs;
89: }
90: adjsgn(f,dc0); *dcp = dc0;
91: }
92:
1.2 ! noro 93: #if 0
1.1 noro 94: void adjsgn(p,dc)
95: P p;
96: DCP dc;
97: {
98: int sgn;
99: DCP dct;
100: P c;
101:
102: for ( dct = dc, sgn = headsgn(p); dct; dct = NEXT(dct) )
103: if ( !EVENN(NM(dct->d)) )
104: sgn *= headsgn(COEF(dct));
105: if ( sgn < 0 ) {
106: chsgnp(COEF(dc),&c); COEF(dc) = c;
107: }
108: }
1.2 ! noro 109: #else
! 110: void adjsgn(p,dc)
! 111: P p;
! 112: DCP dc;
! 113: {
! 114: int sgn;
! 115: DCP dct;
! 116: P c;
! 117:
! 118: if ( headsgn(COEF(dc)) != headsgn(p) ) {
! 119: chsgnp(COEF(dc),&c); COEF(dc) = c;
! 120: }
! 121: for ( dct = NEXT(dc); dct; dct = NEXT(dct) )
! 122: if ( headsgn(COEF(dct)) < 0 ) {
! 123: chsgnp(COEF(dct),&c); COEF(dct) = c;
! 124: }
! 125: }
! 126: #endif
1.1 noro 127:
128: int headsgn(p)
129: P p;
130: {
131: if ( !p )
132: return 0;
133: else {
134: while ( !NUM(p) )
135: p = COEF(DC(p));
136: return SGN((Q)p);
137: }
138: }
139:
140: void fctrwithmvp(vl,f,v,dcp)
141: VL vl;
142: P f;
143: V v;
144: DCP *dcp;
145: {
146: VL nvl;
147: DCP dc;
148:
149: if ( NUM(f) ) {
150: NEWDC(dc); COEF(dc) = f; DEG(dc) = ONE;
151: NEXT(dc) = 0; *dcp = dc;
152: return;
153: }
154:
155: clctv(vl,f,&nvl);
156: if ( !NEXT(nvl) )
157: ufctr(f,1,dcp);
158: else
159: mfctrwithmv(nvl,f,v,dcp);
160: }
161:
162: void mfctrwithmv(vl,f,v,dcp)
163: VL vl;
164: P f;
165: V v;
166: DCP *dcp;
167: {
168: DCP dc,dc0,dct,dcs,dcr;
169: P p,pmin,ppmin,cmin,t;
170: VL mvl;
171: Q c;
172:
173: ptozp(f,1,&c,&p);
174: NEWDC(dc0); dc = dc0; COEF(dc) = (P)c; DEG(dc) = ONE; NEXT(dc) = 0;
175: msqfr(vl,p,&dct);
176: for ( ; dct; dct = NEXT(dct) ) {
177: if ( !v )
178: mindegp(vl,COEF(dct),&mvl,&pmin);
179: else {
180: reordvar(vl,v,&mvl); reorderp(mvl,vl,COEF(dct),&pmin);
181: }
182: pcp(mvl,pmin,&ppmin,&cmin);
183: if ( !NUM(cmin) ) {
184: mfctrmain(mvl,cmin,&dcs);
185: for ( dcr = dcs; dcr; dcr = NEXT(dcr) ) {
186: DEG(dcr) = DEG(dct);
187: reorderp(vl,mvl,COEF(dcr),&t); COEF(dcr) = t;
188: }
189: for ( ; NEXT(dc); dc = NEXT(dc) );
190: NEXT(dc) = dcs;
191: }
192: mfctrmain(mvl,ppmin,&dcs);
193: for ( dcr = dcs; dcr; dcr = NEXT(dcr) ) {
194: DEG(dcr) = DEG(dct);
195: reorderp(vl,mvl,COEF(dcr),&t); COEF(dcr) = t;
196: }
197: for ( ; NEXT(dc); dc = NEXT(dc) );
198: NEXT(dc) = dcs;
199: }
200: *dcp = dc0;
201: }
202:
203: void ufctr(f,hint,dcp)
204: P f;
205: int hint;
206: DCP *dcp;
207: {
208: P p,c;
209: DCP dc,dct,dcs,dcr;
210:
211: ptozp(f,SGN((Q)UCOEF(f)),(Q *)&c,&p);
212: NEWDC(dc); COEF(dc) = c; DEG(dc) = ONE; NEXT(dc) = 0;
213: usqp(p,&dct);
214: for ( *dcp = dc; dct; dct = NEXT(dct) ) {
215: ufctrmain(COEF(dct),hint,&dcs);
216: for ( dcr = dcs; dcr; dcr = NEXT(dcr) )
217: DEG(dcr) = DEG(dct);
218: for ( ; NEXT(dc); dc = NEXT(dc) );
219: NEXT(dc) = dcs;
220: }
221: }
222:
223: void mfctrmain(vl,p,dcp)
224: VL vl;
225: P p;
226: DCP *dcp;
227: {
228: int i,j,k,*win,np;
229: VL nvl,tvl;
230: VN vn,vnt,vn1;
231: P p0,f,g,f0,g0,s,t,lp,m;
232: P *fp0,*fpt,*l,*tl;
233: DCP dc,dc0,dcl;
234: int count,nv;
235:
236: if ( !cmpq(DEG(DC(p)),ONE) ) {
237: NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
238: *dcp = dc; return;
239: }
240: lp = LC(p); fctrp(vl,lp,&dcl); clctv(vl,p,&nvl);
241: for ( nv = 0, tvl = nvl; tvl; tvl = NEXT(tvl), nv++);
242: W_CALLOC(nv,struct oVN,vn); W_CALLOC(nv,struct oVN,vnt);
243: W_CALLOC(nv,struct oVN,vn1);
244: for ( i = 0, tvl = NEXT(nvl); tvl; tvl = NEXT(tvl), i++ )
245: vn1[i].v = vn[i].v = tvl->v;
246: vn1[i].v = vn[i].v = 0;
247: count = 0;
248: while ( 1 ) {
249: while ( 1 ) {
250: count++;
251: for ( i = 0, j = 0; vn[i].v; i++ )
252: if ( vn[i].n )
253: vnt[j++].v = (V)i;
254: vnt[j].n = 0; mulsgn(vn,vnt,j,vn1);
255: for ( i = 0; vn1[i].v; i++ )
256: if ( vn1[i].n ) {
257: if ( vn1[i].n > 0 )
258: vn1[i].n = sprime[vn1[i].n];
259: else
260: vn1[i].n = -sprime[-vn1[i].n];
261: }
262: if ( valideval(nvl,dcl,vn1) ) {
263: substvp(nvl,p,vn1,&p0);
264: if ( sqfrchk(p0) ) {
265: ufctr(p0,1,&dc0);
266: if ( NEXT(NEXT(dc0)) == 0 ) {
267: NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
268: *dcp = dc;
269: return;
270: } else
271: goto MAIN;
272: }
273: }
274: if ( nextbin(vnt,j) )
275: break;
276: }
277: next(vn);
278: }
279: MAIN :
280: #if 0
281: for ( i = 0; vn1[i].v; i++ )
282: fprintf(stderr,"%d ",vn1[i].n);
283: fprintf(stderr,"\n");
284: #endif
285: for ( np = 0, dc = NEXT(dc0); dc; dc = NEXT(dc), np++ );
286: fp0 = (P *)ALLOCA((np + 1)*sizeof(P));
287: fpt = (P *)ALLOCA((np + 1)*sizeof(P));
288: l = tl = (P *)ALLOCA((np + 1)*sizeof(P));
289: for ( i = 1, dc = NEXT(dc0); dc; i++, dc = NEXT(dc) )
290: fp0[i-1] = COEF(dc);
291: #if 0
292: sort_by_deg(np,fp0,fpt);
293: sort_by_deg_rev(np-1,fpt+1,fp0+1);
294: #endif
295: #if 0
296: sort_by_deg_rev(np,fp0,fpt); fp0[0] = fpt[0];
297: sort_by_deg(np-1,fpt+1,fp0+1); fp0[np] = 0;
298: #endif
299: fp0[np] = 0;
300: win = W_ALLOC(np + 1); f = p; divsp(vl,p0,COEF(dc0),&f0);
301: for ( k = 1, win[0] = 1, --np; ; ) {
302: P h0,lcg,lch;
303: Q c;
304:
305: g0 = fp0[win[0]];
306: for ( i = 1; i < k; i++ ) {
307: mulp(vl,g0,fp0[win[i]],&m); g0 = m;
308: }
309: mulq((Q)LC(g0),(Q)COEF(dc0),&c); estimatelc(nvl,c,dcl,vn1,&lcg);
310: divsp(nvl,f0,g0,&h0);
311: mulq((Q)LC(h0),(Q)COEF(dc0),&c); estimatelc(nvl,c,dcl,vn1,&lch);
312: mfctrhen2(nvl,vn1,f,f0,g0,h0,lcg,lch,&g);
313: if ( g ) {
314: *tl++ = g; divsp(vl,f,g,&t);
315: f = t; divsp(vl,f0,g0,&t); ptozp(t,1,(Q *)&s,&f0);
316: for ( i = 0; i < k - 1; i++ )
317: for ( j = win[i] + 1; j < win[i + 1]; j++ )
318: fp0[j - i - 1] = fp0[j];
319: for ( j = win[k - 1] + 1; j <= np; j++ )
320: fp0[j - k] = fp0[j];
321: if ( ( np -= k ) < k ) break;
322: if ( np - win[0] + 1 < k )
323: if ( ++k <= np ) {
324: for ( i = 0; i < k; i++ ) win[i] = i + 1;
325: continue;
326: } else
327: break;
328: else for ( i = 1; i < k; i++ ) win[i] = win[0] + i;
329: } else {
330: if ( ncombi(1,np,k,win) == 0 )
331: if ( k == np ) break;
332: else for ( i = 0, ++k; i < k; i++ ) win[i] = i + 1;
333: }
334: }
335: *tl++ = f; *tl = 0;
336: for ( dc0 = 0; *l; l++ ) {
337: NEXTDC(dc0,dc); DEG(dc) = ONE; COEF(dc) = *l;
338: }
339: NEXT(dc) = 0; *dcp = dc0;
340: }
341:
342: void ufctrmain(p,hint,dcp)
343: P p;
344: int hint;
345: DCP *dcp;
346: {
347: ML list;
348: DCP dc;
349:
350: if ( NUM(p) || (UDEG(p) == 1) ) {
351: NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
352: *dcp = dc;
353: } else if ( iscycm(p) )
354: cycm(VR(p),UDEG(p),dcp);
355: else if ( iscycp(p) )
356: cycp(VR(p),UDEG(p),dcp);
357: else {
358: hensel(5,5,p,&list);
359: if ( list->n == 1 ) {
360: NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
361: *dcp = dc;
362: } else
363: dtest(p,list,hint,dcp);
364: }
365: }
366:
367: struct oMF {
368: int m;
369: P f;
370: };
371:
372: void calcphi();
373:
374: void cycm(v,n,dcp)
375: V v;
376: register int n;
377: DCP *dcp;
378: {
379: register int i,j;
380: struct oMF *mfp;
381: DCP dc,dc0;
382:
383: if ( n == 1 ) {
384: NEWDC(dc); mkssum(v,1,1,-1,&COEF(dc)); DEG(dc) = ONE;
385: } else {
386: mfp = (struct oMF *) ALLOCA((n+1)*sizeof(struct oMF));
387: bzero((char *)mfp,(int)(sizeof(struct oMF)*(n+1)));
388: for ( i = 1, j = 0; i <= n; i++ )
389: if ( !(n%i) ) mfp[j++].m = i;
390: mkssum(v,1,1,-1,&mfp[0].f);
391: for ( i = 1; i < j; i++ )
392: calcphi(v,i,mfp);
393: for ( dc0 = 0, i = 0; i < j; i++ ) {
394: NEXTDC(dc0,dc); COEF(dc) = mfp[i].f; DEG(dc) = ONE;
395: }
396: }
397: NEXT(dc) = 0; *dcp = dc0;
398: }
399:
400: void cycp(v,n,dcp)
401: V v;
402: register int n;
403: DCP *dcp;
404: {
405: register int i,j;
406: int n0;
407: struct oMF *mfp;
408: DCP dc,dc0;
409:
410: if ( n == 1 ) {
411: NEWDC(dc); mkssum(v,1,1,1,&COEF(dc)); DEG(dc) = ONE;
412: } else {
413: n0 = n; n *= 2;
414: mfp = (struct oMF *) ALLOCA((n+1)*sizeof(struct oMF));
415: bzero((char *)mfp,(int)(sizeof(struct oMF)*(n+1)));
416: for ( i = 1, j = 0; i <= n; i++ )
417: if ( !(n%i) ) mfp[j++].m = i;
418: mkssum(v,1,1,-1,&mfp[0].f);
419: for ( i = 1; i < j; i++ )
420: calcphi(v,i,mfp);
421: for ( dc0 = 0, i = 0; i < j; i++ )
422: if ( n0 % mfp[i].m ) {
423: NEXTDC(dc0,dc); COEF(dc) = mfp[i].f; DEG(dc) = ONE;
424: }
425: }
426: NEXT(dc) = 0; *dcp = dc0;
427: }
428:
429: void calcphi(v,n,mfp)
430: V v;
431: int n;
432: register struct oMF *mfp;
433: {
434: register int i,m;
435: P t,s,tmp;
436:
437: for ( t = (P)ONE, i = 0, m = mfp[n].m; i < n; i++ )
438: if ( !(m%mfp[i].m) ) {
439: mulp(CO,t,mfp[i].f,&s); t = s;
440: }
441: mkssum(v,m,1,-1,&s); udivpz(s,t,&mfp[n].f,&tmp);
442: if ( tmp )
443: error("calcphi: cannot happen");
444: }
445:
446: void mkssum(v,e,s,sgn,r)
447: V v;
448: int e,s,sgn;
449: P *r;
450: {
451: register int i,sgnt;
452: DCP dc,dc0;
453: Q q;
454:
455: for ( dc0 = 0, i = s, sgnt = 1; i >= 0; i--, sgnt *= sgn ) {
456: if ( !dc0 ) {
457: NEWDC(dc0); dc = dc0;
458: } else {
459: NEWDC(NEXT(dc)); dc = NEXT(dc);
460: }
461: STOQ(i*e,DEG(dc)); STOQ(sgnt,q),COEF(dc) = (P)q;
462: }
463: NEXT(dc) = 0; MKP(v,dc0,*r);
464: }
465:
466: int iscycp(f)
467: P f;
468: {
469: DCP dc;
470: dc = DC(f);
471:
472: if ( !UNIQ((Q)COEF(dc)) )
473: return ( 0 );
474: dc = NEXT(dc);
475: if ( NEXT(dc) || DEG(dc) || !UNIQ((Q)COEF(dc)) )
476: return ( 0 );
477: return ( 1 );
478: }
479:
480: int iscycm(f)
481: P f;
482: {
483: DCP dc;
484:
485: dc = DC(f);
486: if ( !UNIQ((Q)COEF(dc)) )
487: return ( 0 );
488: dc = NEXT(dc);
489: if ( NEXT(dc) || DEG(dc) || !MUNIQ((Q)COEF(dc)) )
490: return ( 0 );
491: return ( 1 );
492: }
493:
494: void sortfs(dcp)
495: DCP *dcp;
496: {
497: int i,k,n,k0,d;
498: DCP dc,dct,t;
499: DCP *a;
500:
501: dc = *dcp;
502: for ( n = 0, dct = dc; dct; dct = NEXT(dct), n++ );
503: a = (DCP *)ALLOCA((n+1)*(sizeof(DCP)));
504: for ( i = 0, dct = dc; dct; dct = NEXT(dct), i++ )
505: a[i] = dct;
506: a[n] = 0;
507:
508: for ( i = 0; i < n; i++ ) {
509: for ( k0 = k = i, d = UDEG(COEF(a[i])); k < n; k++ )
510: if ( (int)UDEG(COEF(a[k])) < d ) {
511: k0 = k;
512: d = UDEG(COEF(a[k]));
513: }
514: if ( i != k0 ) {
515: t = a[i]; a[i] = a[k0]; a[k0] = t;
516: }
517: }
518: for ( *dcp = dct = a[0], i = 1; i < n; i++ )
519: dct = NEXT(dct) = a[i];
520: NEXT(dct) = 0;
521: }
522:
523: void sortfsrev(dcp)
524: DCP *dcp;
525: {
526: int i,k,n,k0,d;
527: DCP dc,dct,t;
528: DCP *a;
529:
530: dc = *dcp;
531: for ( n = 0, dct = dc; dct; dct = NEXT(dct), n++ );
532: a = (DCP *)ALLOCA((n+1)*(sizeof(DCP)));
533: for ( i = 0, dct = dc; dct; dct = NEXT(dct), i++ )
534: a[i] = dct;
535: a[n] = 0;
536:
537: for ( i = 0; i < n; i++ ) {
538: for ( k0 = k = i, d = UDEG(COEF(a[i])); k < n; k++ )
539: if ( (int)UDEG(COEF(a[k])) > d ) {
540: k0 = k;
541: d = UDEG(COEF(a[k]));
542: }
543: if ( i != k0 ) {
544: t = a[i]; a[i] = a[k0]; a[k0] = t;
545: }
546: }
547: for ( *dcp = dct = a[0], i = 1; i < n; i++ )
548: dct = NEXT(dct) = a[i];
549: NEXT(dct) = 0;
550: }
551:
552: void nthrootchk(f,dc,fp,dcp)
553: P f;
554: struct oDUM *dc;
555: ML fp;
556: DCP *dcp;
557: {
558: register int i,k;
559: int e,n,dr,tmp,t;
560: int *tmpp,**tmppp;
561: int **pp,**wpp;
562: LUM fpa,tpa,f0l;
563: UM wt,wq,ws,dvr,f0,fe;
564: N lc;
565: int lcm;
566: int m,b;
567:
568: m = fp->mod; b = fp->bound; fe = *((UM *)fp->c);
569: e = dc->n; f0 = dc->f; nthrootn(NM((Q)COEF(DC(f))),e,&lc);
570: if ( !lc ) {
571: *dcp = 0;
572: return;
573: }
574: lcm = rem(lc,m); W_LUMALLOC(DEG(f0),b,f0l);
575: for ( i = DEG(f0), tmppp = COEF(f0l), tmpp = COEF(f0);
576: i >= 0; i-- )
577: *(tmppp[i]) = dmb(m,tmpp[i],lcm,&tmp);
578: dtestroot(m,1,f,f0l,dc,dcp);
579: if ( *dcp )
580: return;
581: n = UDEG(f); W_LUMALLOC(n,b,fpa); W_LUMALLOC(n,b,tpa);
582: ptolum(m,b,f,fpa);
583: dvr = W_UMALLOC(n); wq = W_UMALLOC(n);
584: wt = W_UMALLOC(n); ws = W_UMALLOC(n);
585: cpyum(fe,dvr); divum(m,dvr,f0,wq);
586: t = dmb(m,pwrm(m,lcm,e-1),e,&tmp); DEG(dvr) = DEG(wq);
587: for ( k = 0; k <= DEG(wq); k++ )
588: COEF(dvr)[k] = dmb(m,COEF(wq)[k],t,&tmp);
589: for ( i = 1; i < b; i++ ) {
590: pwrlum(m,i+1,f0l,e,tpa);
591: for ( k = 0, pp = COEF(fpa), wpp = COEF(tpa);
592: k <= n; k++ )
593: COEF(wt)[k] = (pp[k][i]-wpp[k][i]+m)%m;
594: degum(wt,n); dr = divum(m,wt,dvr,ws);
595: if ( dr >= 0 ) {
596: *dcp = 0;
597: return;
598: }
599: for ( k = 0, pp = COEF(f0l); k <= DEG(ws); k++ )
600: pp[k][i] = COEF(ws)[k];
601: dtestroot(m,i+1,f,f0l,dc,dcp);
602: if ( *dcp )
603: return;
604: }
605: }
606:
607: void sqfrp(vl,f,dcp)
608: VL vl;
609: P f;
610: DCP *dcp;
611: {
612: P c,p;
613: DCP dc,dc0;
614:
615: if ( !f || NUM(f) ) {
616: NEWDC(dc0); *dcp = dc0; DEG(dc0) = ONE;
617: COEF(dc0) = f; NEXT(dc0) = 0;
618: } else if ( !qpcheck((Obj)f) )
619: error("sqfrp : invalid argument");
620: else {
621: NEWDC(dc0); *dcp = dc0; DEG(dc0) = ONE;
622: ptozp(f,1,(Q *)&c,&p); msqfr(vl,p,&dc);
623: COEF(dc0) = c; NEXT(dc0) = dc;
624: adjsgn(f,dc0);
625: }
626: }
627:
628: /*
629: * f : must be a poly with int coef, ignore int content
630: */
631: void msqfr(vl,f,dcp)
632: VL vl;
633: P f;
634: DCP *dcp;
635: {
636: DCP dc,dct,dcs;
637: P c,p,t,s,pc;
638: VL mvl;
639:
640: ptozp(f,1,(Q *)&c,&t); monomialfctr(vl,t,&p,&dc);
641: if ( NUM(p) ) {
642: *dcp = dc;
643: return;
644: }
645: mindegp(vl,p,&mvl,&s);
646: #if 0
647: minlcdegp(vl,p,&mvl,&s);
648: min_common_vars_in_coefp(vl,p,&mvl,&s);
649: #endif
650: pcp(mvl,s,&p,&pc);
651: if ( !NUM(pc) ) {
652: msqfr(mvl,pc,&dcs);
653: if ( !dc )
654: dc = dcs;
655: else {
656: for ( dct = dc; NEXT(dct); dct = NEXT(dct) );
657: NEXT(dct) = dcs;
658: }
659: }
660: msqfrmain(mvl,p,&dcs);
661: for ( dct = dcs; dct; dct = NEXT(dct) ) {
662: reorderp(vl,mvl,COEF(dct),&t); COEF(dct) = t;
663: }
664: if ( !dc )
665: *dcp = dcs;
666: else {
667: for ( dct = dc; NEXT(dct); dct = NEXT(dct) );
668: NEXT(dct) = dcs; *dcp = dc;
669: }
670: }
671:
672: void usqp(f,dcp)
673: P f;
674: DCP *dcp;
675: {
676: int index,nindex;
677: P g,c,h;
678: DCP dc;
679:
680: ptozp(f,1,(Q *)&c,&h);
681: if ( SGN((Q)LC(h)) < 0 )
682: chsgnp(h,&g);
683: else
684: g = h;
685: for ( index = 0, dc = 0; !dc; index = nindex )
686: hsq(index,5,g,&nindex,&dc);
687: *dcp = dc;
688: }
689:
690: void msqfrmain(vl,p,dcp)
691: VL vl;
692: P p;
693: DCP *dcp;
694: {
695: int i,j;
696: VL nvl,tvl;
697: VN vn,vnt,vn1;
698: P gg,tmp,p0,g;
699: DCP dc,dc0,dcr,dcr0;
700: int nv,d,d1;
701: int found;
702: VN svn1;
703: P sp0;
704: DCP sdc0;
705:
706: if ( deg(VR(p),p) == 1 ) {
707: NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
708: *dcp = dc;
709: return;
710: }
711: clctv(vl,p,&nvl);
712: for ( nv = 0, tvl = nvl; tvl; tvl = NEXT(tvl), nv++);
713: if ( nv == 1 ) {
714: usqp(p,dcp);
715: return;
716: }
717: #if 0
718: if ( heusqfrchk(nvl,p) ) {
719: NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
720: *dcp = dc;
721: return;
722: }
723: #endif
724: W_CALLOC(nv,struct oVN,vn);
725: W_CALLOC(nv,struct oVN,vnt);
726: W_CALLOC(nv,struct oVN,vn1);
727: W_CALLOC(nv,struct oVN,svn1);
728: for ( i = 0, tvl = NEXT(nvl); tvl; tvl = NEXT(tvl), i++ )
729: vn1[i].v = vn[i].v = tvl->v;
730: vn1[i].v = vn[i].v = 0;
731:
732: for ( dcr0 = 0, g = p, d = deg(VR(g),g), found = 0; ; ) {
733: while ( 1 ) {
734: for ( i = 0, j = 0; vn[i].v; i++ )
735: if ( vn[i].n ) vnt[j++].v = (V)i;
736: vnt[j].n = 0;
737:
738: mulsgn(vn,vnt,j,vn1);
739: substvp(nvl,LC(g),vn1,&tmp);
740: if ( tmp ) {
741: substvp(nvl,g,vn1,&p0);
742: usqp(p0,&dc0);
743: for ( d1 = 0, dc = dc0; dc; dc = NEXT(dc) )
744: if ( DEG(dc) )
745: d1 += (QTOS(DEG(dc))-1)*UDEG(COEF(dc));
746:
747: if ( d1 == 0 ) {
748: NEWDC(dc); DEG(dc) = ONE; COEF(dc) = g; NEXT(dc) = 0;
749: if ( !dcr0 )
750: dcr0 = dc;
751: else
752: NEXT(dcr) = dc;
753: *dcp = dcr0;
754: return;
755: }
756:
757: if ( d < d1 )
758: goto END;
759: if ( d > d1 ) {
760: d = d1;
761: found = 1;
762: bcopy((char *)vn1,(char *)svn1,(int)(sizeof(struct oVN)*nv));
763: sp0 = p0; sdc0 = dc0;
764: goto END;
765: }
766: /* d1 == d */
767: if ( found ) {
768: found = 0;
769: #if 0
770: if ( d > d1 ) {
771: d = d1;
772: /*} */
773: #endif
774: msqfrmainmain(nvl,g,svn1,sp0,sdc0,&dc,&gg); g = gg;
775: if ( dc ) {
776: if ( !dcr0 )
777: dcr0 = dc;
778: else
779: NEXT(dcr) = dc;
780: for ( dcr = dc; NEXT(dcr); dcr = NEXT(dcr) );
781: if ( NUM(g) ) {
782: NEXT(dcr) = 0; *dcp = dcr0;
783: return;
784: }
785: d = deg(VR(g),g);
786: }
787: }
788: }
789: END:
790: if ( nextbin(vnt,j) )
791: break;
792: }
793: next(vn);
794: }
795: }
796:
797: void msqfrmainmain(vl,p,vn,p0,dc0,dcp,pp)
798: VL vl;
799: P p;
800: VN vn;
801: P p0;
802: DCP dc0;
803: DCP *dcp;
804: P *pp;
805: {
806: int i,j,k,np;
807: DCP *a;
808: DCP dc,dcr,dcr0,dct;
809: P g,t,s,u,t0,f,f0,d,d0,g0,h0,x,xx;
810: Q q;
811: V v;
812:
813: for ( np = 0, dc = dc0; dc; dc = NEXT(dc), np++ );
814: a = (DCP *)ALLOCA((np + 1)*sizeof(DCP));
815: for ( i = 0, dc = dc0; dc; i++, dc = NEXT(dc) )
816: a[np-i-1] = dc;
817:
818: for ( i = 0, dcr0 = 0, f = p, f0 = p0, v = VR(p);
819: i < np; i++ ) {
820: if ( (i == (np-1))&&UNIQ(DEG(a[i])) ) {
821: NEXTDC(dcr0,dcr);
822: DEG(dcr) = DEG(a[i]);
823: COEF(dcr) = f;
824: f = (P)ONE;
825: } else if ( (i == (np-1))&&UNIQ(DEG(DC(COEF(a[i])))) ) {
826: diffp(vl,f,v,&s); pcp(vl,s,&t,&u);
827: if ( divtpz(vl,f,t,&s) ) {
828: NEXTDC(dcr0,dcr);
829: DEG(dcr) = DEG(a[i]);
830: COEF(dcr) = s;
831: f = (P)ONE;
832: } else
833: break;
834: } else {
835: for ( t = f, t0 = f0,
836: j = 0, k = QTOS(DEG(a[i]))-1; j < k; j++ ) {
837: diffp(vl,t,v,&s); t = s;
838: diffp(vl,t0,v,&s); t0 = s;
839: }
840: factorial(k,&q);
841: divsp(vl,t,(P)q,&s);
842: for ( dct = DC(s); NEXT(dct); dct = NEXT(dct) );
843: if ( DEG(dct) ) {
844: MKV(VR(s),x); pwrp(vl,x,DEG(dct),&xx);
845: divsp(vl,s,xx,&d);
846: } else {
847: xx = (P)ONE; d = s;
848: }
849: divsp(vl,t0,xx,&t);
850: divsp(vl,t,(P)q,&s);
851: ptozp(s,1,(Q *)&t,&d0);
852:
853: for ( dct = DC(COEF(a[i])); NEXT(dct); dct = NEXT(dct) );
854: if ( DEG(dct) )
855: divsp(vl,COEF(a[i]),xx,&g0);
856: else {
857: xx = (P)ONE; g0 = COEF(a[i]);
858: }
859:
860: pcp(vl,d,&t,&u); d = t;
861: ptozp(g0,1,(Q *)&u,&t); g0 = t;
862:
863: {
864: DCP dca,dcb;
865:
866: fctrp(vl,LC(d),&dca);
867: for ( dcb = dca, u = (P)ONE; dcb; dcb = NEXT(dcb) ) {
868: if ( NUM(COEF(dcb)) ) {
869: mulp(vl,u,COEF(dcb),&t); u = t;
870: } else {
871: Q qq;
872: P tt;
873:
874: pwrp(vl,COEF(dcb),DEG(a[i]),&s);
875: for ( t = LC(f), j = 0; divtpz(vl,t,s,&tt); j++, t = tt );
876: STOQ(j,qq);
877: if ( cmpq(qq,DEG(dcb)) > 0 )
878: qq = DEG(dcb);
879: pwrp(vl,COEF(dcb),qq,&t); mulp(vl,u,t,&s); u = s;
880: }
881: }
882: divsp(vl,d0,g0,&h0);
883: }
884: mfctrhen2(vl,vn,d,d0,g0,h0,u,LC(d),&s);
885: if ( s ) {
886: mulp(vl,s,xx,&g);
887: pwrp(vl,g,DEG(a[i]),&t);
888: if ( divtpz(vl,f,t,&s) ) {
889: NEXTDC(dcr0,dcr);
890: DEG(dcr) = DEG(a[i]); COEF(dcr) = g;
891: f = s; substvp(vl,f,vn,&f0);
892: } else
893: break;
894: } else
895: break;
896: }
897: }
898: *pp = f;
899: if ( dcr0 )
900: NEXT(dcr) = 0;
901: *dcp = dcr0;
902: }
903:
904: void mfctrhen2(vl,vn,f,f0,g0,h0,lcg,lch,gp)
905: VL vl;
906: VN vn;
907: P f;
908: P f0,g0,h0,lcg,lch;
909: P *gp;
910: {
911: V v;
912: P f1,lc,lc0,lcg0,lch0;
913: P m,ff0,gg0,hh0,gk,hk,ggg,gggr,hhh,ak,bk,tmp;
914: Q bb,qk,s;
915: Q cbd;
916: int dbd;
917: int d;
918:
919: if ( NUM(g0) ) {
920: *gp = (P)ONE;
921: return;
922: }
923:
924: v = VR(f); d = deg(v,f);
925: if ( d == deg(v,g0) ) {
926: pcp(vl,f,gp,&tmp);
927: return;
928: }
929:
930: mulp(vl,lcg,lch,&lc);
931: if ( !divtpz(vl,lc,LC(f),(P *)&s) ) {
932: *gp = 0;
933: return;
934: }
935: mulp(vl,(P)s,f,&f1);
936: dbd = dbound(VR(f1),f1) + 1; cbound(vl,f1,&cbd);
937:
938: substvp(vl,lc,vn,&lc0);
939: divq((Q)lc0,(Q)LC(f0),(Q *)&m); mulp(vl,f0,m,&ff0);
940: substvp(vl,lcg,vn,&lcg0);
941: divq((Q)lcg0,(Q)LC(g0),(Q *)&m); mulp(vl,g0,m,&gg0);
942: substvp(vl,lch,vn,&lch0);
943: divq((Q)lch0,(Q)LC(h0),(Q *)&m); mulp(vl,h0,m,&hh0);
944: addq(cbd,cbd,&bb);
945: henzq1(gg0,hh0,bb,&bk,&ak,&qk); gk = gg0; hk = hh0;
946: henmv(vl,vn,f1,gk,hk,ak,bk,
947: lcg,lch,lcg0,lch0,qk,dbd,&ggg,&hhh);
948:
949: if ( divtpz(vl,f1,ggg,&gggr) )
950: pcp(vl,ggg,gp,&tmp);
951: else
952: *gp = 0;
953: }
954:
955: int sqfrchk(p)
956: P p;
957: {
958: Q c;
959: P f;
960: DCP dc;
961:
962: ptozp(p,SGN((Q)UCOEF(p)),&c,&f); usqp(f,&dc);
963: if ( NEXT(dc) || !UNIQ(DEG(dc)) )
964: return ( 0 );
965: else
966: return ( 1 );
967: }
968:
969: int cycchk(p)
970: P p;
971: {
972: Q c;
973: P f;
974:
975: ptozp(p,SGN((Q)UCOEF(p)),&c,&f);
976: if ( iscycp(f) || iscycm(f) )
977: return 0;
978: else
979: return 1;
980: }
981:
982: int zerovpchk(vl,p,vn)
983: VL vl;
984: P p;
985: VN vn;
986: {
987: P t;
988:
989: substvp(vl,p,vn,&t);
990: if ( t )
991: return ( 0 );
992: else
993: return ( 1 );
994: }
995:
996: int valideval(vl,dc,vn)
997: VL vl;
998: DCP dc;
999: VN vn;
1000: {
1001: DCP dct;
1002: Q *a;
1003: int i,j,n;
1004: N q,r;
1005:
1006: for ( dct = NEXT(dc), n = 0; dct; dct = NEXT(dct), n++ );
1007: W_CALLOC(n,Q,a);
1008: for ( dct = NEXT(dc), i = 0; dct; dct = NEXT(dct), i++ ) {
1009: substvp(vl,COEF(dct),vn,(P *)&a[i]);
1010: if ( !a[i] )
1011: return ( 0 );
1012:
1013: for ( j = 0; j < i; j++ ) {
1014: divn(NM(a[j]),NM(a[i]),&q,&r);
1015: if ( !r )
1016: return ( 0 );
1017: divn(NM(a[i]),NM(a[j]),&q,&r);
1018: if ( !r )
1019: return ( 0 );
1020: }
1021: }
1022: return ( 1 );
1023: }
1024:
1025: void estimatelc(vl,c,dc,vn,lcp)
1026: VL vl;
1027: Q c;
1028: DCP dc;
1029: VN vn;
1030: P *lcp;
1031: {
1032: int i;
1033: DCP dct;
1034: P r,s,t;
1035: Q c0,c1,c2;
1036:
1037: for ( dct = dc, r = (P)ONE; dct; dct = NEXT(dct) ) {
1038: if ( NUM(COEF(dct)) ) {
1039: mulp(vl,r,COEF(dct),&s); r = s;
1040: } else {
1041: substvp(vl,COEF(dct),vn,(P *)&c0);
1042: for ( i = 0, c1 = c; i < (int)QTOS(DEG(dct)); i++ ) {
1043: divq(c1,c0,&c2);
1044: if ( !INT(c2) )
1045: break;
1046: else
1047: c1 = c2;
1048: }
1049: if ( i ) {
1050: STOQ(i,c1);
1051: pwrp(vl,COEF(dct),c1,&s); mulp(vl,r,s,&t); r = t;
1052: }
1053: }
1054: }
1055: *lcp = r;
1056: }
1057:
1058: void monomialfctr(vl,p,pr,dcp)
1059: VL vl;
1060: P p;
1061: P *pr;
1062: DCP *dcp;
1063: {
1064: VL nvl,avl;
1065: Q d;
1066: P f,t,s;
1067: DCP dc0,dc;
1068:
1069: clctv(vl,p,&nvl);
1070: for ( dc0 = 0, avl = nvl, f = p; avl; avl = NEXT(avl) ) {
1071: getmindeg(avl->v,f,&d);
1072: if ( d ) {
1073: MKV(avl->v,t); NEXTDC(dc0,dc); DEG(dc) = d; COEF(dc) = t;
1074: pwrp(vl,t,d,&s); divsp(vl,f,s,&t); f = t;
1075: }
1076: }
1077: if ( dc0 )
1078: NEXT(dc) = 0;
1079: *pr = f; *dcp = dc0;
1080: }
1081:
1082: void afctr(vl,p0,p,dcp)
1083: VL vl;
1084: P p,p0;
1085: DCP *dcp;
1086: {
1087: DCP dc,dc0,dcr,dct,dcs;
1088: P t;
1089: VL nvl;
1090:
1091: if ( VR(p) == VR(p0) ) {
1092: NEWDC(dc);
1093: DEG(dc) = ONE;
1094: COEF(dc) = p;
1095: NEXT(dc) = 0;
1096: *dcp = dc;
1097: return;
1098: }
1099:
1100: clctv(vl,p,&nvl);
1101: if ( !NEXT(nvl) )
1102: ufctr(p,1,&dc);
1103: else {
1104: sqa(vl,p0,p,&dc);
1105: for ( dct = dc; dct; dct = NEXT(dct) ) {
1106: pmonic(vl,p0,COEF(dct),&t); COEF(dct) = t;
1107: }
1108: }
1109: if ( NUM(COEF(dc)) )
1110: dcr = NEXT(dc);
1111: else
1112: dcr = dc;
1113: for ( dc0 = 0; dcr; dcr = NEXT(dcr) ) {
1114: afctrmain(vl,p0,COEF(dcr),1,&dcs);
1115:
1116: for ( dct = dcs; dct; dct = NEXT(dct) )
1117: DEG(dct) = DEG(dcr);
1118: if ( !dc0 )
1119: dc0 = dcs;
1120: else {
1121: for ( dct = dc0; NEXT(dct); dct = NEXT(dct) );
1122: NEXT(dct) = dcs;
1123: }
1124: }
1125: *dcp = dc0;
1126: }
1127:
1128: void afctrmain(vl,p0,p,init,dcp)
1129: VL vl;
1130: P p,p0;
1131: int init;
1132: DCP *dcp;
1133: {
1134: P x,y,s,m,a,t,u,pt,pt1,res,g;
1135: Q q;
1136: DCP dc,dc0,dcsq0,dcr0,dcr,dct,dcs;
1137: V v,v0;
1138:
1139: if ( !cmpq(DEG(DC(p)),ONE) ) {
1140: NEWDC(dc); DEG(dc) = ONE; NEXT(dc) = 0;
1141: pmonic(vl,p0,p,&COEF(dc)); *dcp = dc;
1142: return;
1143: }
1144:
1145: v = VR(p); MKV(v,x);
1146: v0 = VR(p0); MKV(v0,y);
1147: STOQ(init,q),s = (P)q;
1148: mulp(vl,s,y,&m); subp(vl,x,m,&t); addp(vl,x,m,&a);
1149: substp(vl,p,v,t,&pt);
1150: remsdcp(vl,pt,p0,&pt1);
1151:
1152: /*
1153: if ( ( deg(v0,p0) <= 3 ) || ( TCPQ(p0) <= 2 ) )
1154: resultp(vl,v0,p0,pt1,&res);
1155: else
1156: srcrnorm(vl,v0,pt1,p0,&res);
1157: */
1158: #if 0
1159: srcr(vl,v0,pt1,p0,&res);
1160: #endif
1161: resultp(vl,v0,p0,pt1,&res);
1162: usqp(res,&dcsq0);
1163: for ( dc0 = 0, dct = dcsq0; dct; dct = NEXT(dct) ) {
1164: if ( UNIQ(DEG(dct)) )
1165: ufctr(COEF(dct),deg(v0,p0),&dcs);
1166: else
1167: ufctr(COEF(dct),1,&dcs);
1168: for ( dcr = dcs; dcr; dcr = NEXT(dcr) )
1169: DEG(dcr) = DEG(dct);
1170: if ( !dc0 ) {
1171: dc0 = NEXT(dcs);
1172: dc = dc0;
1173: } else {
1174: for ( ; NEXT(dc); dc = NEXT(dc) );
1175: NEXT(dc) = NEXT(dcs);
1176: }
1177: }
1178: sortfs(&dc0);
1179:
1180: for ( g = p, dcr = dcr0 = 0, dc = dc0; dc; dc = NEXT(dc) ) {
1181: if ( !UNIQ(DEG(dc)) ) {
1182: substp(vl,COEF(dc),v,a,&pt); remsdcp(vl,pt,p0,&s);
1183: gcda(vl,p0,s,g,&u);
1184: if ( !NUM(u) && (VR(u) == v)) {
1185: afctrmain(vl,p0,u,init+1,&dct);
1186: for ( dcs = dct, t = (P)ONE; dcs; dcs = NEXT(dcs) ) {
1187: mulp(vl,t,COEF(dcs),&s); remsdcp(vl,s,p0,&t);
1188: }
1189: pdiva(vl,p0,g,t,&s); g = s;
1190: if ( !dcr0 )
1191: dcr0 = dct;
1192: else
1193: NEXT(dcr) = dct;
1194: for ( dcr = dct; NEXT(dcr); dcr = NEXT(dcr) );
1195: }
1196: } else {
1197: substp(vl,COEF(dc),v,a,&pt); remsdcp(vl,pt,p0,&s);
1198: gcda(vl,p0,s,g,&u);
1199: if ( !NUM(u) && (VR(u) == v)) {
1200: NEXTDC(dcr0,dcr);
1201: DEG(dcr) = ONE;
1202: COEF(dcr) = u;
1203: pdiva(vl,p0,g,u,&t); g = t;
1204: }
1205: }
1206: }
1207: if ( dcr0 )
1208: NEXT(dcr) = 0;
1209: *dcp = dcr0;
1210: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>