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