Annotation of OpenXM_contrib2/asir2018/lib/primdec_mod, Revision 1.2
1.2 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2018/lib/primdec_mod,v 1.1 2018/09/19 05:45:08 noro Exp $ */
1.1 noro 2:
1.2 ! noro 3: extern First_Component,Minipoly_SBA,NDGR$
1.1 noro 4: extern Hom,GBTime$
5: extern DIVLIST,INTIDEAL,ORIGINAL,ORIGINALDIMENSION,STOP,Trials,REM$
6: extern T_GRF,T_INT,T_PD,T_MP$
7: extern BuchbergerMinipoly,PartialDecompByLex,ParallelMinipoly$
8: extern B_Win,D_Win$
9: extern COMMONCHECK_SF,CID_SF$
10:
11: if (!module_definedp("fff")) load("fff"); else $
12: if (!module_definedp("gr")) load("gr"); else $
13: module primdec_mod $
14: /* Empty for now. It will be used in a future. */
15: endmodule $
16:
17: /*==============================================*/
18: /* prime decomposition of ideals over */
19: /* finite fields */
20: /* part 1 */
21: /* radical computation */
22: /* 28/12/2002 for Basic Small Finite Field */
23: /* 4/1/2003 for Arbitary Small Finite Field */
24: /*==============================================*/
25:
26: /*==============================================*/
27: /* radical computation of ideals over */
28: /* finite fields by Matsumoto's algorithm */
29: /* */
30: /* The radical of I is computed as the */
31: /* kernel of a power of Frobenius map. */
32: /* */
33: /* radical */
34: /* Input: a list P of polynomials */
35: /* Output: a list P1 of polynomials */
36: /* such that <P1>=rad(<P>) */
37: /* */
38: /* frobeniuskernel_main{2} */
39: /* Input: a list of polynomials P, */
40: /* a list of variables VSet, */
41: /* and a list of other variables WSet */
42: /* Output: a list of polynomials Q */
43: /* such that Q is the kernel of */
44: /* single Frobenius map: x--> x^q */
45: /* where q is the characteristic. */
46: /* version 2 uses successive kernel */
47: /* computation suggested by Matsumoto */
48: /* */
49: /* coefficientfrobeniuskernel */
50: /* Input: a list of polynomials P, */
51: /* Output: a list of polynomials Q */
52: /* such that Q is the kernel of */
53: /* single coefficient Frobenius */
54: /* map: a in GF(q) --> a^q */
55: /* where q is the characteristic. */
56: /* */
57: /* elimination */
58: /* Input: a list P of polynomials */
59: /* a list V of variables */
60: /* Output: a list P1 of polynomials */
61: /* such that P1={f\in P | */
62: /* vars(f)\cap V =\emptyset} */
63: /* */
64: /* checkequality */
65: /* Input: a list P of polynomials */
66: /* a list Q of polynomials */
67: /* Output: 1 if <P>=<Q> */
68: /* 0 otherwise */
69: /* */
70: /* */
71: /* */
72: /*==============================================*/
73:
74: def radicalideal(P,Choice,VSet)
75: {
76:
77: GBTime=0;
78: Ord=0;
79:
80: /* VSet=vars(P);*/
81: WSet=makecounterpart(VSet);
82:
83: T000=time()[0];
84: P1=dp_gr_f_main(P,VSet,Hom,Ord);
85: T001=time()[0];
86: GBTime +=T001-T000;
87:
88: if ( Choice == 3 )
89: {
90: P2=frobeniuskernel_main3(P1,VSet,WSet);
91: }
92: else if ( Choice == 2 )
93: {
94: P2=frobeniuskernel_main2(P1,VSet,WSet);
95: }
96: else if ( Choice == 4 )
97: {
98: P2=frobeniuskernel_main4(P1,VSet,WSet);
99: }
100: else
101: {
102: P2=frobeniuskernel_main(P1,VSet,WSet);
103: }
104:
105: M=checkequality(P1,P2,VSet);
106:
107: while ( M !=1 )
108: {
109: P1=P2;
110: P2=frobeniuskernel_main2(P2,VSet,WSet);
111: M=checkequality(P1,P2,VSet);
112: }
113:
114: return P1;
115: }
116:
117:
118: def frobeniuskernel_main(P,VSet,WSet)
119: {
120: NV=length(VSet);
121:
122: NewP=coefficientfrobeniuskernel(P);
123:
124: NW=length(NewP);
125:
126: TempP=NewP;
127:
128: for (K=NW-1;K>=0;K--)
129: {
130: Poly=TempP[K];
131: for (J=0;J<NV;J++)
132: {
133: Poly=subst(Poly,VSet[J],WSet[J]);
134: }
135: NewP=cons(Poly,NewP);
136: }
137:
138: XSet=append(VSet,WSet);
139: NewOrder=[[0,length(VSet)],[0,length(WSet)]];
140:
141: Char=characteristic_ff();
142:
143: for (I=0;I<NV;I++)
144: {
145: AddPoly=VSet[I]^Char-WSet[I];
146: NewP=cons(AddPoly,NewP);
147: }
148:
149: G=dp_gr_f_main(NewP,XSet,Hom,NewOrder);
150: PW=elimination(G,WSet);
151:
152: NW=length(PW);
153: ANS=[];
154: for (I=NW-1;I>=0;I--)
155: {
156: Poly=PW[I];
157: for (J=0;J<NV;J++)
158: {
159: Poly=subst(Poly,WSet[J],VSet[J]);
160: }
161: ANS=cons(Poly,ANS);
162: }
163: return ANS;
164: }
165:
166: def frobeniuskernel_main2(P,VSet,WSet)
167: {
168: NV=length(VSet);
169:
170: NewP=coefficientfrobeniuskernel(P);
171:
172: XSet=append(VSet,WSet);
173: NewOrder=[[0,NV],[0,NV]];
174:
175: Char=characteristic_ff();
176:
177: for (I=0;I<NV;I++)
178: {
179: for (J=0;J<NV;J++)
180: {
181: if ( I == J )
182: {
183: AddPoly=VSet[J]^Char-WSet[J];
184: }
185: else
186: {
187: AddPoly=VSet[J]-WSet[J];
188: }
189: NewP=cons(AddPoly,NewP);
190: }
191:
192: T000=time()[0];
193: GP=dp_gr_f_main(NewP,XSet,Hom,NewOrder);
194: T001=time()[0];
195: GBTime += T001-T000;
196:
197: PW=elimination(GP,WSet);
198: NW=length(PW);
199: NewP=[];
200: for (K=NW-1;K>=0;K--)
201: {
202: Poly=PW[K];
203: for (J=0;J<NV;J++)
204: {
205: Poly=subst(Poly,WSet[J],VSet[J]);
206: }
207: NewP=cons(Poly,NewP);
208: }
209: }
210: return NewP;
211: }
212:
213:
214: def frobeniuskernel_main4(P,VSet,WSet)
215: {
216: NV=length(VSet);
217:
218: NewP=coefficientfrobeniuskernel(P);
219:
220: XSet=append(VSet,WSet);
221: NewOrder=[[0,NV],[0,NV]];
222:
223: Char=characteristic_ff();
224:
225: for (I=0;I<NV;I++)
226: {
227: NW=length(NewP);
228: TempP=NewP;
229:
230: for (J=0;J<NV;J++)
231: {
232: if ( I == J )
233: {
234: AddPoly=VSet[J]^Char-WSet[J];
235: }
236: else
237: {
238: AddPoly=VSet[J]-WSet[J];
239: }
240: NewP=cons(AddPoly,NewP);
241: }
242:
243: /* for (K=NW-1;K>=0;K--)
244: {
245: Poly=TempP[K];
246: for (J=0;J<NV;J++)
247: {
248: if ( J == I )
249: {
250: Poly=subst(Poly,VSet[J],WSet[J]);
251: }
252: else
253: {
254: Poly=subst(Poly,VSet[J],WSet[J]^Char);
255: }
256: }
257: NewP=cons(Poly,NewP);
258: }*/
259: T000=time()[0];
260: GP=dp_gr_f_main(NewP,XSet,Hom,NewOrder);
261: T001=time()[0];
262: GBTime += T001-T000;
263:
264: PW=elimination(GP,WSet);
265: NW=length(PW);
266: NewP=[];
267: for (K=NW-1;K>=0;K--)
268: {
269: Poly=PW[K];
270: for (J=0;J<NV;J++)
271: {
272: Poly=subst(Poly,WSet[J],VSet[J]);
273: }
274: NewP=cons(Poly,NewP);
275: }
276: }
277: return NewP;
278: }
279:
280: def frobeniuskernel_main3(P,VSet,WSet)
281: {
282: NV=length(VSet);
283:
284: NewP=coefficientfrobeniuskernel(P);
285:
286: Char=characteristic_ff();
287:
288: for (I=0;I<NV;I++)
289: {
290: XWSet=[];
291: for (J=0;J<NV;J++)
292: {
293: if ( I == J )
294: {
295: AddPoly=VSet[I]^Char-WSet[I];
296: NewP=cons(AddPoly,NewP);
297: XWSet=append(XWSet,[WSet[I]]);
298: }
299: else
300: {
301: XWSet =append(XWSet,[VSet[J]]);
302: }
303: }
304:
305: XSet=cons(VSet[I],XWSet);
306:
307: NewOrder=[[0,1],[0,NV]];
308: T000=time()[0];
309: GP=dp_gr_f_main(NewP,XSet,Hom,NewOrder);
310: T001=time()[0];
311: GBTime += T001-T000;
312:
313: PW=elimination(GP,XWSet);
314: NW=length(PW);
315: NewP=[];
316: for (K=NW-1;K>=0;K--)
317: {
318: Poly=PW[K];
319: Poly=subst(Poly,WSet[I],VSet[I]);
320: NewP=cons(Poly,NewP);
321: }
322: }
323: return NewP;
324: }
325:
326: def coefficientfrobeniuskernel(P)
327: {
328: if ( setmod_ff()[1] == 0 )
329: {
330: return P;
331: }
332:
333: NP=length(P);
334: ANS=[];
335: for (I=0;I<NP;I++)
336: {
337: TEST=P[I];
338: Q=coefficientfrobeniuskernel_main(TEST);
339: ANS=append(ANS,[Q]);
340: }
341: return ANS;
342: }
343:
344: def coefficientfrobeniuskernel_main(Poly)
345: {
346: Vars=vars(Poly);
347: QP=dp_ptod(Poly,Vars);
348: ANS=0;
349: FOrd=extdeg_ff();
350: Char=characteristic_ff();
351: Pow=Char^(FOrd-1);
352:
353: while(QP !=0 )
354: {
355: Coef=dp_hc(QP);
356: HT=dp_ht(QP);
357:
358: ANS=ANS+Coef^Pow*dp_dtop(HT,Vars);
359:
360: QP=dp_rest(QP);
361: }
362: return ANS;
363: }
364:
365:
366: def elimination(G,V)
367: {
368: ANS=[];
369: NG=length(G);
370:
371: for (I=NG-1;I>=0;I--)
372: {
373: VSet=vars(G[I]);
374: DIFF=setminus(VSet,V);
375:
376: if ( DIFF ==[] )
377: {
378: ANS=cons(G[I],ANS);
379: }
380: }
381: return ANS;
382: }
383:
384: def setminus(A,B)
385: {
386: NA=length(A);
387: NB=length(B);
388:
389: ANS=[];
390:
391: for (I=0;I<NA;I++)
392: {
393: Flag =0;
394: for (J=0;J<NB;J++)
395: {
396: if (A[I] == B[J])
397: {
398: Flag=1;
399: break;
400: }
401: }
402:
403: if ( Flag == 0 )
404: {
405: ANS=append(ANS,[A[I]]);
406: }
407: }
408: return ANS;
409: }
410:
411: def makecounterpart(V)
412: {
413: NV=length(V);
414:
415: A="tmp";
416:
417: ANS=[];
418: for (I=NV-1;I>=0;I--)
419: {
420: T=strtov(A+rtostr(I));
421: ANS=cons(T,ANS);
422: }
423: return ANS;
424: }
425:
426: def checkequality(P,Q,VSet)
427: {
428: QQ=dp_gr_f_main(Q,VSet,Hom,Ord);
429: PP=dp_gr_f_main(P,VSet,Hom,Ord);
430:
431: NP=length(PP);
432: NQ=length(QQ);
433:
434: VarsP=vars(P);
435: VarsQ=vars(Q);
436: if ( NP != NQ || VarsP !=VarsQ )
437: {
438: return 0;
439: }
440:
441: for (I=0;I<NP;I++)
442: {
443: HCP=dp_hc(dp_ptod(PP[I],VSet));
444: HCQ=dp_hc(dp_ptod(QQ[I],VSet));
445:
446: if ( HCP*QQ[I]-HCQ*PP[I] != 0 )
447: {
448: return 0;
449: }
450: }
451:
452: return 1;
453: }
454:
455: /*==============================================*/
456: /* prime decomposition of ideals over */
457: /* finite fields */
458: /* part 2 */
459: /* ideal dimension */
460: /* 3/1/2003 */
461: /*==============================================*/
462:
463: /*==============================================*/
464: /* ideal dimension computation */
465: /* */
466: /* The dimension of I is computed as the */
467: /* maximal size of MSI sets. */
468: /* */
469: /* idealdimension */
470: /* Input: a list P of polynomials */
471: /* a list V of variables */
472: /* Output: the dimension of I */
473: /* and the MSI with max size */
474: /* */
475: /* findmsi */
476: /* Input: a list of head monomials */
477: /* and a list of variables */
478: /* Output: a list of all MSI sets */
479: /* and SI sets */
480: /* */
481: /* findmsi_main */
482: /* Input: a list P of polynomials */
483: /* a list V of variables */
484: /* Output: a list P1 of polynomials */
485: /* such that P1={f\in P | */
486: /* vars(f)\cap V =\emptyset} */
487: /* */
488: /* headtermset */
489: /* Input: a list P of polynomials */
490: /* a list V of variables */
491: /* Output: a list of head monomials */
492: /* */
493: /* */
494: /* */
495: /*==============================================*/
496:
497: def idealdimension(P,V,Ord)
498: {
499: GP=dp_gr_f_main(P,V,Hom,Ord);
500: HeadTermset=headtermset(GP,V,Ord);
501: MSIset=findmsi(HeadTermset,V);
502: if ( MSIset == [] )
503: {
504: return [0,[]];
505: }
506: Index=findmaxindex(MSIset);
507: MSI=MSIset[Index];
508: Dimension=length(MSI);
509: return [Dimension, MSI];
510: }
511:
512: def findmaxindex(S)
513: {
514: NS=length(S);
515: Index=0;
516: Defaultsize=length(S[0]);
517: for (I=1;I<NS;I++)
518: {
519: Targetsize=length(S[I]);
520:
521: if ( Targetsize > Defaultsize )
522: {
523: Index=I;
524: }
525: Defaultsize= Targetsize;
526: }
527: return Index;
528: }
529:
530: def headtermset(P,V,Ord)
531: {
532: ANS=[];
533: NP=length(P);
534: for ( I=NP-1;I>=0;I--)
535: {
536: Head=headterm(P[I],V,Ord);
537: ANS=cons(Head,ANS);
538: }
539: return ANS;
540: }
541:
542: def headterm(P,V,Ord)
543: {
544: dp_ord(Ord);
545: Q=dp_ptod(P,V);
546: Headdp=dp_hm(Q);
547: Head=dp_dtop(Headdp,V);
548: return Head;
549: }
550:
551: def findmsi_main(TermsetIndex,MSIsetIndex,Int,N)
552: {
553: ANS=[];
554: BNS=[];
555: TempMSIsetIndex=MSIsetIndex;
556:
557: if (Int == 0)
558: {
559: for ( I=0;I<N;I++)
560: {
561: TEST1=[I];
562: Check=intersection(TermsetIndex,TEST1);
563: if ( Check == 0 )
564: {
565: ANS=cons(TEST1,ANS);
566: }
567: }
568: }
569:
570: while( Int !=0 && TempMSIsetIndex != [] )
571: {
572: TEST=TempMSIsetIndex[0];
573: Flag=0;
574: for ( I=TEST[0]+1;I<N;I++)
575: {
576: TEST1=cons(I,TEST);
577: Check=intersection(TermsetIndex,TEST1);
578: if ( Check == 0 )
579: {
580: Flag=1;
581: ANS=cons(TEST1,ANS);
582: }
583: }
584: if ( Flag == 0 )
585: {
586: BNS=cons(TEST,BNS);
587: }
588: TempMSIsetIndex=cdr(TempMSIsetIndex);
589: }
590: return [ANS,BNS];
591: }
592:
593: def findmsi(Termset,Vset)
594: {
595: ANS=[];
596: MSIsetIndex=[];
597: N=length(Vset);
598: TermsetIndex=makeindex(Termset,Vset);
599:
600: for (I=0;I<N;I++)
601: {
602: Temp=findmsi_main(TermsetIndex,ANS,I,N);
603: ANS=Temp[0];
604: BNS=Temp[1];
605: MSIsetIndex=append(BNS,MSIsetIndex);
606: }
607:
608: MSIsetIndex=append(ANS,MSIsetIndex);
609: MSIset=makevarset(MSIsetIndex,Vset);
610: return MSIset;
611: }
612:
613: def makeindex(Termset,Vset)
614: {
615: ANS=[];
616:
617: N=length(Vset);
618:
619: TempTermset=Termset;
620: while( TempTermset !=[] )
621: {
622: TEST=TempTermset[0];
623: Index=[];
624: for (I=0;I<N;I++)
625: {
626: Q=srem(TEST,Vset[I]);
627: if ( Q == 0 )
628: {
629: Index=cons(I,Index);
630: }
631: }
632: ANS=cons(Index,ANS);
633: TempTermset=cdr(TempTermset);
634: }
635: return ANS;
636: }
637:
638: def makevarset(IndexSet,Vset)
639: {
640: ANS=[];
641: NI=length(IndexSet);
642:
643: for (I=0;I<NI;I++)
644: {
645: TEST=IndexSet[I];
646:
647: TestV=makevar(TEST,Vset);
648: ANS=append(ANS,[TestV]);
649: }
650: return ANS;
651: }
652:
653: def makevar(Index,Vset)
654: {
655: ANS=[];
656: TempIndex=Index;
657:
658: while( TempIndex !=[] )
659: {
660: ANS=cons(Vset[TempIndex[0]],ANS);
661: TempIndex=cdr(TempIndex);
662: }
663:
664: return ANS;
665: }
666:
667: def intersection(IndexSet,TestIndex)
668: {
669: TempIndexSet=IndexSet;
670:
671: while(TempIndexSet !=[] )
672: {
673: Sample=TempIndexSet[0];
674:
675: Inclusion=testinclusion(Sample,TestIndex);
676:
677: if ( Inclusion == 1 )
678: {
679: return 1;
680: }
681:
682: TempIndexSet=cdr(TempIndexSet);
683: }
684: return 0;
685: }
686:
687: def testinclusion(Sample,Test)
688: {
689: NS=length(Sample);
690: NT=length(Test);
691:
692: for (I=0;I<NS;I++)
693: {
694: Flag=0;
695: for (J=0;J<NT;J++)
696: {
697: if (Sample[I]==Test[J])
698: {
699: Flag=1;
700: break;
701: }
702: }
703: if ( Flag == 0 )
704: {
705: return 0;
706: }
707: }
708: return 1;
709: }
710:
711:
712: /*======================================================*/
713: /* prime decomposition of ideals over */
714: /* small finite fields */
715: /* part 3 */
716: /* prime decomposition */
717: /* 9/1/2003 1st Implementation */
718: /* 11/1/2003 Divid 3 cases in zeroprime */
719: /* decomposition (3a) */
720: /* 12/1/2003 Redundant elimination (3e) */
721: /* 13/1/2003 gr_fctr_sf version (3f) */
722: /* 14/1/2003 Flag on Early Termination */
723: /* 15/1/2002 drl version */
724: /* 17/1/2002 depth oriented search */
725: /* 17/1/2002 dimension oriented search */
726: /* */
727: /* global variables */
728: /* Hom: used in dp_gr_f_main */
729: /* DIVLIST: the set of prime ideals */
730: /* ORIGINAL: the GB of the original input ideal */
731: /* ORIGINALDIMENSION: the dimension */
732: /* STOP: the flag on terminatation */
733: /* Trials: a bound on the number of trials */
734: /* REM: the vector list of remaining ideals */
735: /* */
736: /*======================================================*/
737:
738: /*======================================================*/
739: /* prime decomposition */
740: /* */
741: /* */
742: /* primedec(P,V,Ord,F) */
743: /* Input: a list P of polynomials */
744: /* a list V of variables */
745: /* a term order Ord */
746: /* a flag F on Early Termination */
747: /* Output: 0 */
748: /* DVILIST: the set of prime divisors of <P> */
749: /* [subprocedure] */
750: /* o --gr_fctr_sf (mplex2) */
751: /* o --primedecomposition */
752: /* Remark: if F = 1, we empoly Early Termination */
753: /* */
754: /* */
755: /* primedecomposition(P,V,Ord,C,F) */
756: /* Input: a list P of polynomials */
757: /* a list V of variables */
758: /* a term order Ord */
759: /* a level C of recursive call */
760: /* a flag F on Early Termination */
761: /* Output: 0 */
762: /* DVILIST: the set of prime divisors of <P>^ec */
763: /* [subprocedure] */
764: /* o --idealdimension (part2) */
765: /* o --setminus (part1) */
766: /* o --zeroprimedecomposition */
767: /* o --extcont */
768: /* o --checkadd2 */
769: /* o --ideal_intersection_sfrat */
770: /* o --radical_equality */
771: /* */
772: /* zeroprimedecomposition(P,V,W) */
773: /* Input: a list P of polynomials */
774: /* lists V,W of variables */
775: /* such that <P> is 0-dimensional */
776: /* in K[V] and W is the original set */
777: /* of variables */
778: /* Output: the set of prime/primary */
779: /* divisors of <P> */
780: /* (P is a GB w.r.t. DRL) */
781: /* [subprocedure] */
782: /* o --partical_decomp (mplex2) */
783: /* o --checkgeneric */
784: /* o --separableclosure */
785: /* o --zerogenericprimedecomposition */
786: /* o --zeroseparableprimedecomposition */
787: /* o --convertdivisor */
788: /* o --contraction */
789: /* o --radicalideal (part1) */
790: /* */
791: /* extcont(P,V,Ord) */
792: /* Input: a list P of polynomials */
793: /* a set V of variables */
794: /* Output: a polynomial f */
795: /* such that \sqrt<P>^c=\sqrt(P:f) */
796: /* Then \sqrt<P>=\sqrt(P:f)\cap \sqrt(P+<f>) */
797: /* */
798: /* separableclosure([P,MP],V,W) */
799: /* Input: a pair [P,MP] of a list P of */
800: /* polynomials and a list MP of */
801: /* minimal polynomials of variables */
802: /* list V,W of variables */
803: /* such that <P> is 0-dimensional */
804: /* in K[V] and W is the original set */
805: /* of variables */
806: /* Output: [Q,E], a list Q of polynomials */
807: /* an exponent vector E */
808: /* such that <Q> is the separable */
809: /* closure of <P> */
810: /* [subprocedure] */
811: /* o --makecounterpart(part1) */
812: /* o --elimination(part1) */
813: /* o --checkseparable */
814: /* */
815: /* zeroseparableprimedecomposition(P,V,W) */
816: /* Input: a list P of polynomials */
817: /* lists V,W of variables */
818: /* such that <P> is 0-dimensional */
819: /* and all minimal polynomial */
820: /* are irreducible (i.e. <P> is an */
821: /* intermediate ideal in the paper */
822: /* or the output of partial_decomp) */
823: /* in K[V] and W is the original set */
824: /* of variables */
825: /* Output: the set of prime/primary */
826: /* divisors of <P> */
827: /* [subprocedure] */
828: /* o --findgeneric */
829: /* o --elimination(part1) */
830: /* */
831: /* zerogenericprimedecomposition([P,MP],M,V,W) */
832: /* Input: a pair [P,MP] of a list P of */
833: /* polynomials and a list MP of */
834: /* minimal polynomials of variables */
835: /* such that <P> is 0-dimensional */
836: /* and M is a minimal poly of a */
837: /* variable in generic position */
838: /* in K[V] and W is the original */
839: /* set of variables */
840: /* Output: the set of prime/primary */
841: /* divisors of <P> */
842: /* [subprocedure] */
843: /* */
844: /* convertdivisor(P,V,W,E) */
845: /* Input: a list P of polynomials */
846: /* list V,W of variables */
847: /* such that <P> is a primary/prime */
848: /* 0-dimensional ideal in K[V] and */
849: /* W is the original set */
850: /* of variables */
851: /* the exponent vector E */
852: /* Output: the corresponding prime ideal */
853: /* in K[W] */
854: /* [subprocedure] */
855: /* o --elimination(part1) */
856: /* */
857: /* contraction(P,V,W) */
858: /* Input: a list P of polynomials */
859: /* list V,W of variables */
860: /* such that <P> is a primary/prime */
861: /* 0-dimensional ideal in K[V] and */
862: /* W is the original set */
863: /* of variables */
864: /* Output: the contraction <P>^c in K[W] */
865: /* */
866: /* findgeneric(P,V) */
867: /* Input: a list P of polynomials */
868: /* a list V of variables */
869: /* such that <P> is a separable */
870: /* 0-dimensional ideal in K[V] */
871: /* Output: [F,Min,X], a polynomial F in */
872: /* generic position, its minimal */
873: /* polynomial Min in a new variable */
874: /* X */
875: /* [subprocedure] */
876: /* o --lineardimension */
877: /* o --makemagic */
878: /* o --minipoly_sf (mplex2) */
879: /* */
880: /*======================================================*/
881:
882: def primedec_mod(P,VSet,Ord,Mod,Strategy)
883: {
1.2 ! noro 884: First_Component = getopt(first);
! 885: if ( type(First_Component) == -1 ) First_Component = 0;
! 886: Minipoly_SBA = getopt(sba);
! 887: if ( type(Minipoly_SBA) == -1 ) Minipoly_SBA = 0;
! 888: NDGR = getopt(ndgr);
! 889: if ( type(NDGR) == -1 ) NDGR = 0;
1.1 noro 890: for ( Q = Mod, E = 1; Q < 2^14; Q *= Mod, E++ );
891: Q /= Mod;
892: E--;
893: if ( !(E%2) ) {
894: Q /= Mod;
895: E--;
896: }
897: setmod_ff(Mod,E);
898: Pq = map(simp_ff,P);
899: primedec_sf(Pq,VSet,Ord,Strategy);
900: R = convsf(DIVLIST,VSet,0,1);
901: return R;
902: }
903:
904:
905: def primedec_sf(P,VSet,Ord,Strategy)
906: {
907: /* DIVLIST = the set of all computed candidates for iredundant divisors */
908: /* INTIDEAL = the intersection of all computed candidates */
909: /* ORIGINAL = a Groebner basis of the input ideal <P> w.r.t. Ord */
910: /* ORIGINALDIMENSION = the dimension of the input ideal <P> */
911: /* STOP = the flag on termination */
912: /* REM = the list of remaining ideals */
913:
914: T0 = time();
915: T_GRF=0;
916: T_INT=0;
917: T_PD=0;
918: T_MP=0;
919: DIVLIST=[];
920: INTIDEAL=[];
921: STOP=0;
922: B_Win=0;
923: D_Win=0;
924:
925: ORIGINAL=dp_gr_f_main(P,VSet,Hom,Ord);
926:
927: Dimeset=idealdimension(ORIGINAL,VSet,Ord);
928: ORIGINALDIMENSION=Dimeset[0];
929:
930: /* REM0=newvect(ORIGINALDIMENSION+1);*/
931: REM=newvect(ORIGINALDIMENSION+1);
932:
933: for (I=0;I<ORIGINALDIMENSION+1;I++)
934: {
935: /* REM0[I]=[];*/
936: REM[I]=[];
937: }
938:
939: if ( dp_gr_print() ) {
940: print("The dimension of the ideal is ",2);print(ORIGINALDIMENSION,2);
941: print(". ");
942: }
943:
944: if ( ORIGINALDIMENSION == 0 )
945: {
946: Strategy = 0;
947: STOP = 0;
948: }
949:
950: ANS=gr_fctr_sf([ORIGINAL],VSet,Ord);
951: NANS=length(ANS);
952: if ( dp_gr_print() ) {
953: print("There are ",2);print(NANS,2);print(" partial components. ");
954: }
955: for (I=0;I<NANS;I++)
956: {
957: TempI=ANS[I];
958: DimI=idealdimension(TempI,VSet,Ord)[0];
959:
960: REM[ORIGINALDIMENSION-DimI]=cons(TempI,REM[ORIGINALDIMENSION-DimI]);
961: }
962:
963: REM[0]=ANS;
964:
965: INDEX=0;
966:
967: while ( INDEX != -1 )
968: {
969: /* print("We deal with the ",2);print(I,2);print("-th partial component. ");*/
970:
971: TESTIDEAL=car(REM[INDEX]);
972: REM[INDEX]=cdr(REM[INDEX]);
973: primedecomposition(TESTIDEAL,VSet,Ord,INDEX,Strategy);
974:
975: if (STOP == 1 )
976: {
977: DIVLIST = prime_irred_sf_by_first(DIVLIST,VSet,0);
978: DIVLIST = monic_sf_first(DIVLIST,VSet);
979: if ( dp_gr_print() ) {
980: print("We finish the computation. ");
981: T_TOTAL = time()[3]-T0[3];
982: print(["T_TOTAL",T_TOTAL,"T_GRF",T_GRF,"T_PD",T_PD,"T_MP",T_MP,"T_INT",T_INT,"B_Win",B_Win,"D_Win",D_Win]);
983: }
984: return 0;
985: }
986:
987: INDEX=findindex(REM);
988: }
989:
990: DIVLIST = prime_irred_sf_by_first(DIVLIST,VSet,0);
991: DIVLIST = monic_sf_first(DIVLIST,VSet);
992: T_TOTAL = time()[3]-T0[3];
993: if ( dp_gr_print() ) {
994: print(["T_TOTAL",T_TOTAL,"T_GRF",T_GRF,"T_PD",T_PD,"T_MP",T_MP,"T_INT",T_INT,"B_Win",B_Win,"D_Win",D_Win]);
995: }
996: return 0;
997: }
998:
999:
1000:
1001:
1002:
1003: def findindex(VECTORLIST)
1004: {
1005: NL=size(VECTORLIST)[0];
1006:
1007: for (I=0;I<NL;I++)
1008: {
1009: if ( VECTORLIST[I] == [] )
1010: {
1011: continue;
1012: }
1013: return I;
1014: }
1015: return -1;
1016: }
1017:
1018: #if 0
1019: def checkadd2(ADD,TESTADDLIST,VSet)
1020: {
1021: /* This function will be used for eliminating redundant divisors */
1022:
1023: NTESTADDLIST=length(TESTADDLIST);
1024: for (I=0;I<NTESTADDLIST;I++)
1025: {
1026: TESTLIST=TESTADDLIST[I][0];
1027:
1028: if ( setminus(TESTLIST,ADD) == [] )
1029: {
1030: return 1;
1031: }
1032: if ( inclusion_test(TESTLIST,ADD,VSet,Ord) == 1 )
1033: {
1034: return 1;
1035: }
1036: }
1037: return 0;
1038: }
1039: #endif
1040:
1041: def checkadd2a(ADD,DIM,TESTADDLIST,VSet)
1042: {
1043: /* This function will be used for eliminating redundant divisors */
1044:
1045: NTESTADDLIST=length(TESTADDLIST);
1046: for (I=0;I<NTESTADDLIST;I++)
1047: {
1048: TESTLIST=TESTADDLIST[I][0];
1049: TESTDIM=TESTADDLIST[I][1];
1050:
1051: if (DIM > TESTDIM )
1052: {
1053: continue;
1054: }
1055:
1056: if ( setminus(TESTLIST,ADD) == [] )
1057: {
1058: return 1;
1059: }
1060: if ( inclusion_test(TESTLIST,ADD,VSet,Ord) == 1 )
1061: {
1062: return 1;
1063: }
1064: }
1065: return 0;
1066: }
1067:
1068: def checkadd3(ADD,TESTADDLIST,VSet)
1069: {
1070: /* This function will be used for eliminating redundant divisors */
1071:
1072: NTESTADDLIST=length(TESTADDLIST);
1073: for (I=0;I<NTESTADDLIST;I++)
1074: {
1075: TESTLIST=TESTADDLIST[I];
1076:
1077: if ( setminus(TESTLIST,ADD) == [] )
1078: {
1079: return 1;
1080: }
1081:
1082:
1083: /* if ( inclusion_test(TESTLIST,ADD,VSet,0) == 1 )
1084: {
1085: return 1;
1086: }*/
1087: }
1088: return 0;
1089: }
1090:
1091: def radical_equality(A,B,VSet,Ord)
1092: {
1093: /* This function will be used for checking the termination. */
1094:
1095: NA=length(A);
1096:
1097: Ord1=[[0,1],[0,length(VSet)]];
1098: Vt=newt;
1099:
1100: for (I=0;I<NA;I++)
1101: {
1102: NewB=cons(1-newt*A[I],B);
1103: GB = dp_gr_f_main(NewB,cons(Vt,VSet),0,Ord1);
1104: K=elimination(GB,VSet);
1105:
1106: if ( vars(K) !=[] )
1107: {
1108: return 0;
1109: }
1110:
1111: }
1112:
1113: return 1;
1114: }
1115:
1116: def primedecomposition(P,VSet,Ord,COUNTER,Strategy)
1117: {
1118: /* DIVLIST = the set of all computed candidates for iredundant divisors */
1119: /* INTIDEAL = the intersection of all computed candidates */
1120: /* ORIGINAL = a Groebner basis of the input ideal <P> w.r.t. Ord */
1121: /* ORIGINALDIMENSION = the dimension of the input ideal <P> */
1122:
1123: RP=P;
1124: GP=dp_gr_f_main(RP,VSet,Hom,Ord);
1125:
1126: /* First we compute the MSI and the dimension of the */
1127: /* ideal <P> in K[Vset], where K is the ground field. */
1128:
1129: Dimeset=idealdimension(GP,VSet,Ord);
1130: Dimension=Dimeset[0];
1131: MSI=Dimeset[1];
1132:
1133: if ( dp_gr_print() ) {
1134: print("The dimension of the ideal is ",2); print(Dimension,2);
1135: print(".");
1136: }
1137: TargetVSet=setminus(VSet,MSI);
1138: NewGP=dp_gr_f_main(GP,TargetVSet,Hom,Ord);
1139:
1140: if ( vars(NewGP) == [] )
1141: {
1142: return [];
1143: }
1144:
1145: /* Then the ideal is 0-dimension in K[TargetVSet]. */
1146:
1147: if ( dp_gr_print() ) {
1148: print("We enter Zero-dimension Prime Decomposition. ",2);
1149: }
1150:
1151: QP=zeroprimedecomposition(NewGP,TargetVSet,VSet);
1152:
1153: ANS=[];
1154: NQP=length(QP);
1155:
1156: if ( dp_gr_print() ) {
1157: print("The number of the newly found component is ",2);
1158: print(NQP,2);print(". ",2);
1159: }
1160: for (I=0;I<NQP;I++)
1161: {
1162: ZPrimeideal=QP[I];
1163: Primedivisor=ZPrimeideal;
1164: CHECKADD=checkadd2a(Primedivisor,Dimension,DIVLIST,VSet);
1165: if (CHECKADD == 0 )
1166: {
1167: DIVLIST=append(DIVLIST,[[Primedivisor,Dimension]]);
1.2 ! noro 1168: if ( First_Component ) return 0;
1.1 noro 1169: if (Strategy != 1 )
1170: {
1171: /* NO-OPERATION */
1172: }
1173: else if ( COUNTER == 0 && Dimension == 0 && ORIGINALDIMENSION == 0 )
1174: {
1175: /* NO-OPERATION */
1176: }
1177: else if ( INTIDEAL == [] )
1178: {
1179: INTIDEAL=Primedivisor;
1180: }
1181: else
1182: {
1183: INTIDEAL=ideal_intersection_sfrat(Primedivisor,INTIDEAL,VSet);
1184: }
1185: }
1186: }
1187:
1188: /* We compute prime decomposition for remaining ideal */
1189: /* I+<ExtPoly> by recursive call. */
1190:
1191: if ( Strategy == 1 )
1192: {
1193: CHECK=radical_equality(INTIDEAL,ORIGINAL,VSet,Ord);
1194:
1195: if (CHECK==1)
1196: {
1197: if ( dp_gr_print() ) {
1198: print("We already obtain all divisor. ");
1199: }
1200: STOP = 1;
1201: return 0;
1202: }
1203: }
1204:
1205:
1206: if ( Dimension == 0 )
1207: {
1208: return 0;
1209: }
1210:
1211: Ord1 = [[0,length(TargetVSet)],[0,length(MSI)]];
1212: GP1 = dp_gr_f_main(GP,append(TargetVSet,MSI),Hom,Ord1);
1213: ExtpolyFactor=extcont_factor(GP1,TargetVSet,0);
1214:
1215: COUNTER=COUNTER+1;
1216:
1217: for ( Tmp = ExtpolyFactor; Tmp != []; Tmp = cdr(Tmp) )
1218: {
1219: AddPoly=car(Tmp);
1220:
1221: NewGP=cons(AddPoly,GP);
1222:
1223: GP1 = dp_gr_f_main(cons(AddPoly,GP),VSet,Hom,Ord);
1224:
1225: if ( Strategy == 1 )
1226: {
1227: CHECKADD=radical_equality(INTIDEAL,NewGP,VSet,Ord);
1228:
1229: if ( CHECKADD != 0 )
1230: {
1231: if ( dp_gr_print() ) {
1232: print("Avoid unnecessary computation. ",2);
1233: }
1234: continue;
1235: }
1236: }
1237:
1238:
1239: DimI=idealdimension(GP1,VSet,Ord)[0];
1240:
1241: if ( REM[ORIGINALDIMENSION-DimI] !=[] )
1242: {
1243: REM[ORIGINALDIMENSION-DimI]=cons(GP1,REM[ORIGINALDIMENSION-DimI]);
1244: }
1245: else
1246: {
1247: REM[ORIGINALDIMENSION-DimI]=[GP1];
1248: }
1249:
1250: /* primedecomposition(GP1,VSet,Ord,COUNTER,Strategy);
1251: if ( STOP == 1)
1252: {
1253: return 0;
1254: }*/
1255: }
1256: return 0;
1257: }
1258:
1259: /* returns 1 if Poly is a subset of Id(GB) */
1260: /* we assume GB is a gb wrt (V,Ord) */
1261:
1262: def inclusion_test(Poly,GB,V,Ord)
1263: {
1264: Len = length(GB);
1265: PS = newvect(Len);
1266: dp_ord(Ord);
1267: for ( J = 0, T = GB; T != []; T = cdr(T), J++ )
1268: PS[J] = dp_ptod(car(T),V);
1269: for ( J = Len-1, Ind = []; J >= 0; J-- )
1270: Ind = cons(J,Ind);
1271:
1272: for ( T = Poly; T != []; T = cdr(T) )
1273: if ( nf_sfrat(Ind,dp_ptod(car(T),V),1,PS)[0] )
1274: return 0;
1275: return 1;
1276: }
1277:
1278:
1279: def zeroprimedecomposition(P,TargetVSet,VSet)
1280: {
1281: /* We compute prime decomposition for an ideal <P> */
1282: /* such that <P> is 0-dimensional in K[TargetVSet]. */
1283:
1284: PD=partial_decomp(P,TargetVSet);
1285:
1286: /* each ideal in PD is an intermediate ideal, */
1287: /* i.e., all minimal polynomials are irreducible. */
1288: /* Thus, each ideal is very likely a prime ideal. */
1289: /* PD=[[P,MP],...], where P is a GB w.r.t. DRL and */
1290: /* MP is the set of all minimal polynomials. */
1291:
1292: NPD=length(PD);
1293: ANS=[];
1294:
1295: for (I=0;I<NPD;I++)
1296: {
1297: COMP=PD[I];
1298:
1299: /* check if the ideal has a variable in generic position*/
1300:
1301: CHECK=checkgeneric(COMP,TargetVSet,VSet);
1302:
1303: /* If there is a variable in generic position, then we apply a special */
1304: /* procedure (zerogenericprimedecomposition). Otherwise we apply a */
1305: /* general procedure (zeroseparableprimedecomposition). */
1306: /* */
1307: /* CHECK=[1,M], where M is the minimal polynomail of a variable x */
1308: /* such that x is in generic position, if there is such a variable x. */
1309: /* Otherwise, CHECK=0. */
1310:
1311: if (CHECK != 0 )
1312: {
1313: if ( TargetVSet != VSet )
1314: {
1315: PDiv=contraction(COMP[0],TargetVSet,VSet)[0];
1316: }
1317: else
1318: {
1319: PDiv=COMP[0];
1320: }
1321:
1322: ZDecomp=[PDiv];
1323:
1324: if ( dp_gr_print() ) {
1325: print("An intermediate ideal is of generic type. ");
1326: }
1327: }
1328: else
1329: {
1330: if ( dp_gr_print() ) {
1331: print("An intermediate ideal is not of generic type. ",2);
1332: }
1333:
1334: /* We compute the separable closure of <P> by using minimal polynomails.*/
1335: /* separableclosure outputs */
1336: /* [a GB Q of separable closure, the exponent vector]. */
1337: /* If <P> is already separable, then the exponent vector is 0. */
1338:
1339: Sep=separableclosure(COMP,TargetVSet,VSet);
1340:
1341: /* Then, we compute prime divisors of the separable closure by using */
1342: /* generic position. */
1343: /* If Sep[1]=0, COMP[0] is already separable ideal, and hence, */
1344: /* we do not apply radicalideal to its divisors. */
1345:
1346: if ( Sep[1] != 0 )
1347: {
1348: if ( dp_gr_print() ) {
1349: print("The ideal is inseparable. ",2);
1350: }
1351: CHECK2=checkgeneric2(Sep[2]);
1352: }
1353: else
1354: {
1355: if ( dp_gr_print() ) {
1356: print("The ideal is already separable. ",2);
1357: }
1358: }
1359:
1360: if ( Sep[1] !=0 && CHECK2 == 1 )
1361: {
1362: if ( dp_gr_print() ) {
1363: print("The separable closure is of generic type. ",2);
1364: print("So, the intermediate ideal is prime or primary. ",2);
1365: }
1366: PDiv=convertdivisor(Sep[0],TargetVSet,VSet,Sep[1]);
1367: if ( TargetVSet != VSet )
1368: {
1369: PDiv=contraction(PDiv,TargetVSet,VSet)[0];
1370: }
1371: Divisor=radicalideal(PDiv,2,VSet);
1372: ZDecomp=[Divisor];
1373: }
1374: else
1375: {
1376: #if 0
1377: ZSDecomp=zeroseparableprimedecomposition(Sep[0],TargetVSet,VSet);
1378: #else
1379: ZSDecomp=zerosepdec(Sep[0],TargetVSet,VSet,Ord);
1380: #endif
1381: /* We convert a prime separable ideal in K[TargetVSet] to its */
1382: /* corresponding prime ideal in K[VSet]. */
1383:
1384: NComp=length(ZSDecomp);
1385: ZDecomp=[];
1386:
1387: for (J=0;J<NComp;J++)
1388: {
1389: SDiv=ZSDecomp[J];
1390:
1391: /* First we convert a prime separable ideal in K[TargetVSet] to its */
1392: /* corresponding prime/primary ideal in K[TargetVSet] by computing the */
1393: /* image of Frobenius map. */
1394:
1395: PDiv=convertdivisor(SDiv,TargetVSet,VSet,Sep[1]);
1396:
1397: /* Then we compute the true prime divisor by contraction and radical */
1398: /* computation. */
1399:
1400: if ( TargetVSet != VSet )
1401: {
1402: PDiv=contraction(PDiv,TargetVSet,VSet)[0];
1403: }
1404:
1405: if (Sep[1] != 0 )
1406: {
1407: Divisor=radicalideal(PDiv,2,VSet);
1408: }
1409: else
1410: {
1411: Divisor=PDiv;
1412: }
1413:
1414:
1415: ZDecomp=append(ZDecomp,[Divisor]);
1416: }
1417: }
1418: }
1419:
1420: ANS=append(ANS, ZDecomp);
1421: }
1422: return map(monic_hc,ANS,VSet);
1423: }
1424:
1425: def monic_hc(Poly,V)
1426: {
1427: if ( type(Poly) == 4 )
1428: map(monic_hc,Poly,V);
1429: else {
1430: T = dp_ptod(Poly,V);
1431: return dp_dtop(T/dp_hc(T),V);
1432: }
1433: }
1434:
1435: def zeroseparableprimedecomposition(P,TargetVSet,VSet)
1436: {
1437: /* We compute prime decomposition for a separable */
1438: /* 0-dimensional ideal <P> in K[TargetVSet] by using */
1439: /* generic position. */
1440:
1441: ANS=[];
1442: Ord=0;
1443:
1444: NVSet=length(TargetVSet);
1445:
1446: /* The P is already a GB w.r.t. DRL. So, the following */
1447: /* must be replaced with NewP=P. */
1448:
1449: /* NewGP=dp_gr_f_main(P,TargetVSet,Hom,Ord); */
1450: NewGP = P;
1451:
1452: /* We search a polynomial f in generic position. */
1453: /* Generic=[f, minimal polynomial of f in newt, newt], */
1454: /* where newt (X) is a newly introduced variable. */
1455:
1456: if ( dp_gr_print() ) {
1457: print("We search for a linear sum of variables in generic position. ",2);
1458: }
1459: Generic=findgeneric(NewGP,TargetVSet,VSet);
1460:
1461: X=Generic[2]; /* newly introduced variable */
1462: Factors=sffctr(Generic[1]);
1463: NFactors=length(Factors);
1464: /* irreducible case */
1465: if ( NFactors == 2 && Factors[1][1] == 1 )
1466: return [NewGP];
1467: #if 0
1468: for (J=1;J<NFactors;J++)
1469: {
1470: AddPoly=Factors[J][0];
1471: AddPoly2=X-Generic[0];
1472:
1473: TestGP=append(NewGP,[AddPoly, AddPoly2]);
1474: VS=cons(X,TargetVSet);
1475: Q=dp_gr_f_main(TestGP,VS,Hom,[[0,1],[Ord,NVSet]]);
1476: QR=elimination(Q,VSet);
1477: ANS=append(ANS,[QR]);
1478: }
1479: #else
1480: /* noro */
1481: dp_ord([[0,1],[Ord,NVSet]]);
1482: XVSet = cons(X,TargetVSet);
1483: PS = newvect(length(NewGP)+1,map(dp_ptod,cons(X-Generic[0],NewGP),XVSet));
1484: for ( I = length(NewGP), Ind = [];I >= 0; I-- )
1485: Ind = cons(I,Ind);
1486: Ind = reverse(Ind);
1487: YSet = setminus(VSet,TargetVSet);
1488: NYSet = length(YSet);
1489: ElimVSet = append(TargetVSet,YSet);
1490: ElimOrd = [[Ord,NVSet],[0,NYSet]];
1491: for ( J = 1; J < NFactors; J++ ) {
1492: dp_ord([[0,1],[Ord,NVSet]]);
1493: Factor = dp_dtop(nf_sfrat(Ind,dp_ptod(Factors[J][0],XVSet),1,PS)[0],XVSet);
1494: #if 0
1495: Q = dp_gr_f_main(cons(Factor,NewGP),ElimVSet,Hom,ElimOrd);
1496: #else
1.2 ! noro 1497: if ( NDGR ) {
! 1498: Q0 = nd_gr(cons(Factor,NewGP),ElimVSet,-1,0);
! 1499: Q = nd_gr(Q0,ElimVSet,-1,ElimOrd);
! 1500: Q = nd_gr(Q,TargetVSet,-1,Ord);
! 1501: dp_ord(0);
! 1502: } else {
! 1503: Q0 = dp_gr_f_main(cons(Factor,NewGP),ElimVSet,Hom,0);
! 1504: Q = dp_gr_f_main(Q0,ElimVSet,Hom,ElimOrd);
! 1505: Q = dp_gr_f_main(Q,TargetVSet,Hom,Ord);
! 1506: }
1.1 noro 1507: #endif
1508: ANS = cons(Q,ANS);
1509: }
1510: #endif
1511: return ANS;
1512: }
1513:
1514: /* partial decomposition by sums of variables
1515: -> zeroseparableprimedecomposition */
1516:
1517: #if 0
1518: def zerosepdec(P,W,V,Ord)
1519: {
1520: /* P is GB wrt (W,Ord) */
1521: dp_ord(Ord);
1522: DIM = length(dp_mbase(map(dp_ptod,P,W)));
1523: /* preprocessing */
1524: N = length(W);
1525: C = newvect(N);
1526: C[0] = 1;
1527: Vt = ttttt;
1528: do {
1529: for ( I = 0, LF = 0; I < N; I++ )
1530: if ( C[I] ) LF += W[I];
1531: LF = simp_ff(LF);
1532: MP = minipoly_sf(P,W,Ord,LF,Vt);
1533: Factors = map(first,cdr(sffctr(MP)));
1534: if ( deg(MP,Vt) == DIM ) {
1535: if ( length(Factors) == 1 )
1536: return [P];
1537: else
1538: return zerosepdec_main(P,W,V,Ord,map(subst,Factors,Vt,LF));
1539: } else if ( length(Factors) > 1 ) {
1540: R = zerosepdec_main(P,W,V,Ord,map(subst,Factors,Vt,LF));
1541: S = [];
1542: for ( TR = R; TR != []; TR = cdr(TR) )
1543: S = append(zerosepdec(car(TR),W,V,Ord),S);
1544: return S;
1545: }
1546: } while ( !nextchoice(C) );
1547: /* we could not find any useful combination */
1548: R = zeroseparableprimedecomposition(P,W,V);
1549: return R;
1550: }
1551: #else
1552:
1553: /* we only search for useful poly among v[i]+v[j] */
1554: def zerosepdec(P,W,V,Ord)
1555: {
1556: /* P is GB wrt (W,Ord) */
1557: dp_ord(Ord);
1558: DIM = length(dp_mbase(map(dp_ptod,P,W)));
1559: /* preprocessing */
1560: N = length(W);
1561: C = newvect(N);
1562: C[0] = 1;
1563: Vt = ttttt;
1564: for ( I1 = 0; I1 < N; I1++ )
1565: for ( I2 = I1+1; I2 < N; I2++ ) {
1566: LF = simp_ff(W[I1]+W[I2]);
1567: MP = minipoly_sf(P,W,Ord,LF,Vt);
1568: Factors = map(first,cdr(sffctr(MP)));
1569: if ( deg(MP,Vt) == DIM ) {
1570: if ( length(Factors) == 1 )
1571: return [P];
1572: else
1573: return zerosepdec_main(P,W,V,Ord,map(subst,Factors,Vt,LF));
1574: } else if ( length(Factors) > 1 ) {
1575: R = zerosepdec_main(P,W,V,Ord,map(subst,Factors,Vt,LF));
1576: S = [];
1577: for ( TR = R; TR != []; TR = cdr(TR) )
1578: S = append(zerosepdec(car(TR),W,V,Ord),S);
1579: return S;
1580: }
1581: }
1582: /* we could not find any useful combination */
1583: R = zeroseparableprimedecomposition(P,W,V);
1584: return R;
1585: }
1586: #endif
1587:
1588: def zerosepdec_main(P,W,V,Ord,Factors)
1589: {
1590: dp_ord(Ord);
1591: N = length(P);
1592: NFactors = length(Factors);
1593: PS = newvect(length(P),map(dp_ptod,P,W));
1594: for ( I = length(P)-1, Ind = [];I >= 0; I-- )
1595: Ind = cons(I,Ind);
1596: Y= setminus(V,W);
1597: NW = length(W);
1598: NY = length(Y);
1599: ElimV = append(W,Y);
1600: ElimOrd = [[Ord,NW],[0,NY]];
1601: ANS = [];
1602: for ( J = 0; J < NFactors; J++ ) {
1603: Factor = dp_dtop(nf_sfrat(Ind,dp_ptod(Factors[J],W),1,PS)[0],W);
1.2 ! noro 1604: if ( NDGR ) {
! 1605: Q = nd_gr(cons(Factor,P),ElimV,-1,ElimOrd);
! 1606: Q = nd_gr(Q,W,-1,Ord);
! 1607: dp_ord(0);
! 1608: } else {
! 1609: Q = dp_gr_f_main(cons(Factor,P),ElimV,Hom,ElimOrd);
! 1610: Q = dp_gr_f_main(Q,W,Hom,Ord);
! 1611: }
1.1 noro 1612: ANS = cons(Q,ANS);
1.2 ! noro 1613: if ( First_Component ) break;
1.1 noro 1614: }
1615: return ANS;
1616: }
1617:
1618: def nextchoice(C)
1619: {
1620: N = size(C)[0];
1621: for ( I = N-1, Carry = 1; I >= 0; I-- ) {
1622: if ( C[I] ) {
1623: C[I] = !Carry;
1624: Carry = !C[I];
1625: } else {
1626: C[I] = Carry;
1627: Carry = 0;
1628: }
1629: }
1630: return Carry;
1631: }
1632:
1633: def separableclosure(CP,TargetVSet,VSet)
1634: {
1635: /* We compute a separable ideal <Q> from <P> by */
1636: /* computing inverse Frobenius map. */
1637:
1638: Ord=0;
1639:
1640: NVSet=length(TargetVSet);
1641: IndexVector=newvect(NVSet);
1642:
1643: /* First we check if <P> is already separable. */
1644: /* CHECK == 1 if <P> is already separable, */
1645: /* Otherwise, CHECK is the list of pairs of */
1646: /* the separable closure sc(m) of the minimal polynomial*/
1647: /* m and the exponent e, i.e. m=sc(m)(t^(q^e)). */
1648:
1649: CHECK=checkseparable(CP,TargetVSet,VSet);
1650:
1651: if ( CHECK == 1 )
1652: {
1653: if ( dp_gr_print() ) {
1654: print("This is already a separable ideal.", 2);
1655: }
1656: return [CP[0],0];
1657: }
1658:
1659: if ( dp_gr_print() ) {
1660: print("This is not a separable ideal, so we make its separable closure.", 2);
1661: }
1662: WSet=makecounterpart(TargetVSet);
1663: Char=characteristic_ff();
1664:
1665: NewP=CP[0];
1666: EXPVECTOR=newvect(NVSet);
1667: CHECKEXPVECTOR=newvect(NVSet);
1668:
1669: for (I=0;I<NVSet;I++)
1670: {
1671: EXPVECTOR[I]=CHECK[NVSet-I-1][0];
1672: CHECKEXPVECTOR[I]=deg(CHECK[NVSet-I-1][1],TargetVSet[I]);
1673:
1674: POW=Char^CHECK[NVSet-I-1][0];
1675:
1676: AddPoly=TargetVSet[I]^POW-WSet[I];
1677: /*SepClosure=subst(CHECK[I][0],TargetVSet[I],WSet[I]);*/
1678:
1679: NewP=cons(AddPoly,NewP);
1680: }
1681:
1682: NewOrder=[[Ord,NVSet],[Ord,NVSet]];
1683: XSet=append(TargetVSet,WSet);
1684: YSet=append(VSet,WSet);
1685:
1686: NewG=dp_gr_f_main(NewP,XSet,Hom,NewOrder);
1687:
1688: NWSet=setminus(YSet,TargetVSet);
1689:
1690: Q=elimination(NewG,NWSet);
1691:
1692: NQ=length(Q);
1693:
1694: ANS=[];
1695: for (I=NQ-1;I>=0;I--)
1696: {
1697: Poly=Q[I];
1698: for (J=0;J<NVSet;J++)
1699: {
1700: Poly=subst(Poly,WSet[J],TargetVSet[J]);
1701: }
1702: ANS=cons(Poly,ANS);
1703: }
1704: return [ANS,EXPVECTOR,CHECKEXPVECTOR];
1705: }
1706:
1707: def convertdivisor(P,TargetVSet,VSet,ExVector)
1708: {
1709: /* We compute a corresponding ideal <Q> from <P> by */
1710: /* computing Frobenius map. */
1711:
1712: if (ExVector == 0 )
1713: {
1714: return P;
1715: }
1716:
1717: NVSet=length(TargetVSet);
1718: WSet=makecounterpart(TargetVSet);
1719: Char=characteristic_ff();
1720: Ord=0;
1721:
1722: NewP=P;
1723:
1724: for (I=0;I<NVSet;I++)
1725: {
1726: POW=Char^ExVector[I];
1727:
1728: AddPoly=TargetVSet[I]-WSet[I]^POW;
1729: /*SepClosure=subst(CHECK[I][0],TargetVSet[I],WSet[I]);*/
1730:
1731: NewP=cons(AddPoly,NewP);
1732: }
1733:
1734: NewOrder=[[Ord,NVSet],[Ord,NVSet]];
1735:
1736: XSet=append(TargetVSet,WSet);
1737: YSet=append(VSet,WSet);
1738:
1739: NewG=dp_gr_f_main(NewP,XSet,Hom,NewOrder);
1740:
1741: NWSet=setminus(YSet,TargetVSet);
1742:
1743: Q=elimination(NewG,NWSet);
1744:
1745: NQ=length(Q);
1746:
1747: ANS=[];
1748: for (I=NQ-1;I>=0;I--)
1749: {
1750: Poly=Q[I];
1751: for (J=0;J<NVSet;J++)
1752: {
1753: Poly=subst(Poly,WSet[J],TargetVSet[J]);
1754: }
1755: ANS=cons(Poly,ANS);
1756: }
1757: return ANS;
1758: }
1759:
1760:
1761: def findgeneric(P,TargetVSet,VSet)
1762: {
1763: /* The number of trials is set as Trails. */
1764: NTargetVSet=length(TargetVSet);
1765: MNumber=0;
1766: /* Trials=100;*/
1767:
1768: if ( Trials == 0 )
1769: Trials = 2;
1770:
1771: Lineardimension=lineardimension(P,TargetVSet);
1772: NewVar=newt;
1773: Count=0;
1774: Ord=0;
1775:
1776: #if 0
1777: while(Count < Trials )
1778: {
1779: Candidate=0;
1780: MNumber=MNumber+1;
1781:
1782: MAGIC=makemagic(TargetVSet,MNumber);
1783:
1784: for (I=0;I<NTargetVSet;I++)
1785: {
1786: Candidate=Candidate+MAGIC[I]*TargetVSet[I];
1787: }
1788: MinPoly=minipoly_sf(P,TargetVSet,Ord,Candidate,NewVar);
1789: Deg=deg(MinPoly,NewVar);
1790: if ( Deg == Lineardimension )
1791: {
1792: return [Candidate,MinPoly,NewVar];
1793: }
1794: Count=Count+1;
1795: }
1796: #else
1797: YSet = setminus(VSet,TargetVSet);
1798: NYSet = length(YSet);
1799: Eval = newvect(NYSet);
1800: Q1 = field_order_ff()-1;
1801: HM = hmlist(P,TargetVSet,Ord);
1802: for ( Count = 0; Count < Trials; Count++ ) {
1803: Candidate = ptosfp(2)*TargetVSet[0];
1804: Candidate = 0;
1805: for ( I = 0; I < NTargetVSet; I++ )
1806: Candidate += random_ff()*TargetVSet[I];
1807: do {
1808: for ( I = 0; I < NYSet; I++ )
1809: Eval[I] = random()%Q1;
1810: } while ( !valid_modulus_sfrat(HM,YSet,Eval) );
1811: P0 = map(eval_sfrat,P,YSet,Eval);
1812: MinPoly0 = minipoly_sf(P0,TargetVSet,Ord,Candidate,NewVar);
1813: Deg = deg(MinPoly0,NewVar);
1814: if ( Deg == Lineardimension ) {
1815: MinPoly=minipoly_sf(P,TargetVSet,Ord,Candidate,NewVar);
1816: if ( deg(MinPoly,NewVar) != Deg )
1817: error("findgeneric : cannot happen");
1818: return [Candidate,MinPoly,NewVar];
1819: }
1820: }
1821: #endif
1822: if ( dp_gr_print() ) {
1823: print("Extend the ground field. ",2);
1824: }
1825: error();
1826: }
1827:
1828: def makemagic(VSet,MNumber)
1829: {
1830: NVSet=length(VSet);
1831: MAGIC=[1];
1832: for (I=1;I<NVSet;I++)
1833: {
1834: U=ptosfp(MNumber^I);
1835: MAGIC=append(MAGIC,[U]);
1836: }
1837: return MAGIC;
1838: }
1839:
1840: #if 0
1841: def zerogenericprimedecomposition(CP,MinP,TargetVSet,VSet)
1842: {
1843: P=CP[0];
1844:
1845: FACTORS=sffctr(MinP);
1846: NFACTORS=length(FACTORS);
1847:
1848: if ( NFACTORS == 2 )
1849: {
1850: return [P];
1851: }
1852:
1853: ANS=[];
1854:
1855: for (I=1;I<NFACTORS;I++)
1856: {
1857: AddPoly=NFACTORS[I][0];
1858: NewP=cos(AddPoly,P);
1859: NewG=dp_gr_f_main(NewP,TargetVSet,Hom,Ord);
1860: ANS=cons(NewG,ANS);
1861: }
1862: return ANS;
1863: }
1864: #endif
1865:
1866:
1867: def lineardimension(P,VSet)
1868: {
1869: Ord=0;
1870:
1871: PP=dp_gr_f_main(P,VSet,Hom,Ord);
1872: dp_ord(Ord);
1873: Dimension=length(dp_mbase(map(dp_ptod,PP,VSet)));
1874: return Dimension;
1875: }
1876:
1877: def checkgeneric(CP,TargetVSet,VSet)
1878: {
1879: Dimension=lineardimension(CP[0],TargetVSet);
1880: NVSet=length(TargetVSet);
1881: Flag=0;
1882:
1883: for (I=0;I<NVSet;I++)
1884: {
1885: MinP=CP[1][I];
1886:
1887: if ( deg(MinP,TargetVSet[NVSet-I-1]) == Dimension )
1888: {
1889: return [1,MinP];
1890: }
1891: }
1892: return 0;
1893: }
1894:
1895: def checkseparable(CP,TargetVSet,VSet)
1896: {
1897: NVSet=length(TargetVSet);
1898: EXPVector=newvect(NVSet);
1899: Flag=1;
1900:
1901: for (I=0;I<NVSet;I++)
1902: {
1903: MinP=CP[1][I];
1904: CHECK=checkseparablepoly(MinP,TargetVSet[NVSet-I-1]);
1905: if ( CHECK[0] != 0 )
1906: {
1907: Flag = 0;
1908: }
1909: EXPVector[I]=CHECK;
1910: }
1911: if ( Flag == 0 )
1912: {
1913: return EXPVector;
1914: }
1915: return 1;
1916: }
1917:
1918: def checkseparablepoly(F,V)
1919: {
1920: P = characteristic_ff();
1921: E = 0;
1922: Vt = newt;
1923: while ( 1 ) {
1924: if ( diff(F,V) != 0 )
1925: return [E,F];
1926: T = srem(F,V^P-Vt,V);
1927: F = subst(T,Vt,V);
1928: E++;
1929: }
1930: }
1931:
1932: def extcont(P,V,Ord)
1933: {
1934: /* We assume P is a Groebner Basis w.r.t. Ord. */
1935: /* We compute a polynomial f such that */
1936: /* \sqrt{<P>}=\sqrt{<P>+<f>}\cap \sqrt{(<P>)^{ec}} */
1937: /* by B.W. Proposition 8.96. */
1938: /* Remark: The square free part of f is also OK. */
1939:
1940: dp_ord(Ord);
1941: HC = map(dp_hc,map(dp_ptod,P,V));
1942: LCM = car(HC);
1943: for ( T = cdr(HC); T != []; T = cdr(T) )
1944: LCM = lcm_sfrat(LCM,car(T));
1945: return LCM;
1946: }
1947:
1948: def first(A)
1949: {
1950: return A[0];
1951: }
1952:
1953: def set_union(A,B)
1954: {
1955: for ( T = A; T != []; T = cdr(T) )
1956: B = insert_element(car(T),B);
1957: return B;
1958: }
1959:
1960: def insert_element(E,A)
1961: {
1962: for ( T = A; T != []; T = cdr(T) )
1963: if ( E == car(T) )
1964: break;
1965: if ( T == [] )
1966: return cons(E,A);
1967: else
1968: return A;
1969: }
1970:
1971: def extcont_factor(P,V,Ord)
1972: {
1973: /* We assume P is a Groebner Basis w.r.t. Ord. */
1974: /* We compute a polynomial f such that */
1975: /* \sqrt{<P>}=\sqrt{<P>+<f>}\cap \sqrt{(<P>)^{ec}} */
1976: /* by B.W. Proposition 8.96. */
1977: /* Remark: The square free part of f is also OK. */
1978:
1979: dp_ord(Ord);
1980: HC = map(dp_hc,map(dp_ptod,P,V));
1981: F = [];
1982: for ( T = HC; T != []; T = cdr(T) ) {
1983: F1 = map(first,cdr(sffctr(car(T))));
1984: F = set_union(F1,F);
1985: }
1986: return F;
1987: }
1988:
1989: def contraction(P,V,W)
1990: {
1991: /* We assume P is a Groebner Basis w.r.t. Ord. */
1992: /* We compute the contraction <P>^{c} by */
1993: /* <P>^c=(<G>:f^\infty) */
1994: /* by B.W. Proposition 8.91. */
1995: /* This procedure is called by zeroprimedecomposition. */
1996: /* So, P is supposed to be a GB w.r.t. DRL. */
1997:
1998: Ord0 = dp_ord();
1999: Ord=0;
2000: YSet=setminus(W,V);
2001:
2002: Ord1 = [[Ord,length(V)],[0,length(YSet)]];
2003: W1 = append(V,YSet);
2004: GP1 = dp_gr_f_main(P,W1,Hom,Ord1);
2005:
2006: Factor = extcont_factor(GP1,V,Ord);
2007: for ( F = 1, T = Factor; T != []; T = cdr(T) )
2008: F *= car(T);
2009: Vt = newt;
2010:
2011: G = dp_gr_f_main(cons(1-Vt*F,P),cons(Vt,W),0,[[0,1],[Ord,length(W)]]);
2012: R = [];
2013: for ( T = G; T != []; T = cdr(T) )
2014: if ( !member(Vt,vars(car(T))) )
2015: R = cons(car(T),R);
2016: dp_ord(Ord0);
2017: return [R,F];
2018: }
2019:
2020: def checkgeneric2(LIST)
2021: {
2022: NList=size(LIST)[0];
2023:
2024: FLAG=0;
2025:
2026: for (I=0;I<NList;I++)
2027: {
2028: if ( LIST[I] > 1 )
2029: {
2030: FLAG=FLAG+1;
2031: }
2032: }
2033:
2034: if (FLAG < 2 )
2035: {
2036: return 1;
2037: }
2038: return 0;
2039: }
2040:
2041: #if 0
2042: def checkseparablepoly(P,V)
2043: {
2044: TestP=P;
2045: CHECK=diff(TestP,V);
2046: Count=0;
2047:
2048: while ( CHECK !=0 )
2049: {
2050: if ( deg(TestP,V) != 0 )
2051: {
2052: break;
2053: }
2054: TestP=pdivide(TestP);
2055: CHECK=diff(TestP,V);
2056: Count=Count+1;
2057: }
2058:
2059: return [TestP,Count];
2060: }
2061:
2062: def pdivide(F,V)
2063: {
2064: Char=characteristic_ff();
2065: TestP=P;
2066:
2067: Deg=ideg(TestP,V);
2068: DegP=idiv(Deg,Char);
2069:
2070: if ( irem(Deg,Char) != 0 )
2071: {
2072: error;
2073: }
2074: ANS=0;
2075:
2076: for (I=O;I<DegP;I++)
2077: {
2078: TempDeg=I*Char;
2079: ANS=ANS+coeff(TestP,V,TempDeg)*X^I;
2080: }
2081: return ANS;
2082: }
2083: #endif
2084:
2085:
2086: def convsf(PP,VSet,Ord,Flag)
2087: {
2088: /* Flag = 0 or 1 */
2089: /* If Flag = 1, we compute the intersection */
2090: /* of the Galois orbit. */
2091:
2092: CHECK=checkgaloisorbit(PP,VSet,Ord,Flag);
2093:
2094: NewPP=CHECK[0];
2095:
2096: ANS=[];
2097:
2098: NPP=length(NewPP);
2099:
2100: for (I=0;I<NPP;I++)
2101: {
2102: NewComp=convertsmallfield(CHECK[Flag][I],VSet,Ord);
2103: ANS=cons(NewComp,ANS);
2104: }
2105: return ANS;
2106: }
2107:
2108: def convertsmallfield(PP,VSet,Ord)
2109: {
2110: dp_ord(Ord);
2111: NVSet=length(VSet);
2112: Char=characteristic_ff();
2113: ExtDeg=extdeg_ff();
2114:
2115: NewV=pgpgpgpgpgpgpg;
2116: MPP=map(monic_hc,PP,VSet);
2117: MPP=map(sfptopsfp,MPP,NewV);
2118:
2119: DefPoly=setmod_ff()[1];
2120: /* GF(p) case */
2121: if ( !DefPoly )
2122: return MPP;
2123:
2124: MinPoly=subst(DefPoly,var(DefPoly),NewV);
2125: XSet=cons(NewV,VSet);
2126:
2127: Ord1=[[0,1],[Ord,NVSet]];
2128:
2129: /* setmod_ff(Char,1);*/
2130:
2131: NewP=dp_gr_mod_main(cons(MinPoly,MPP),XSet,0,Char,Ord1);
2132:
2133: ANS=elimination(NewP,VSet);
2134:
2135: /* setmod_ff(Char,ExtDeg);*/
2136:
2137: return ANS;
2138: }
2139:
2140: def checkgaloisorbit(PP,VSet,Ord,Flag)
2141: {
2142: NPP=length(PP);
2143: TmpPP=PP;
2144: ExtDeg=extdeg_ff();
2145:
2146: ANS=[];
2147: BNS=[];
2148:
2149: while (TmpPP != [] )
2150: {
2151: TestP=car(TmpPP);
2152: Dim=TestP[1];
2153: TmpPP=cdr(TmpPP);
2154: NewP=TestP[0];
2155:
2156: ANS=cons(TestP[0],ANS);
2157:
2158: for (J=1;J<ExtDeg;J++)
2159: {
2160: G1=map(sf_galois_action,TestP[0],J);
2161:
2162: if ( setminus(G1,TestP[0]) == [] )
2163: {
2164: break;
2165: }
2166: if (Flag == 1 )
2167: {
2168: NewP=ideal_intersection_sfrat(NewP,G1,VSet);
2169: }
2170: TmpPP=deletecomponent(TmpPP,[G1,Dim]);
2171: }
2172: BNS=cons(NewP,BNS);
2173:
2174: }
2175: return [ANS,BNS];
2176: }
2177:
2178: def deletecomponent(PP,G)
2179: {
2180: TmpPP=PP;
2181:
2182: while( TmpPP !=[] )
2183: {
2184: Test=car(TmpPP)[0];
2185:
2186: if ( setminus(Test,G[0]) == [] )
2187: {
2188: ANS=setminus(PP,[G]);
2189: return ANS;
2190: }
2191:
2192: TmpPP=cdr(TmpPP);
2193: }
2194: error();
2195: }
2196:
2197:
2198: def pfctr(F)
2199: {
2200: if ( type(F) == 1 )
2201: return [[F,1]];
2202: P = characteristic_ff();
2203: E = extdeg_ff();
2204: F = sfptop(F);
2205: check_coef(F,P);
2206: D = modfctr(F,P);
2207: setmod_ff(P,E);
2208: return map(mapsf_first,D);
2209: }
2210:
2211: def check_coef(F,P)
2212: {
2213: V = vars(F);
2214: D = dp_ptod(F,V);
2215: for ( T = D; T; T = dp_rest(T) )
2216: if ( dp_hc(T) >= P )
2217: error("invalid coef");
2218: }
2219:
2220: def mapsf_first(D)
2221: {
2222: return [ptosfp(D[0]),D[1]];
2223: }
2224:
2225: def partial_decomp(B,V)
2226: {
2227: T0 = time();
2228: if ( ParallelMinipoly ) {
2229: map(ox_cmo_rpc,ParallelMinipoly,"setmod_ff",characteristic_ff(),extdeg_ff());
2230: map(ox_pop_cmo,ParallelMinipoly);
2231: }
2232: B = map(simp_ff,B);
2233: B = dp_gr_f_main(B,V,0,0);
2234: R = partial_decomp0(B,V,length(V)-1);
2235: if ( PartialDecompByLex ) {
2236: R0 = [];
2237: for ( TR = R; TR != []; TR = cdr(TR) ) {
2238: T = car(TR);
2239: S = dp_gr_f_main(T[0],V,0,0);
2240: R0 = cons([S,T[1]],R0);
2241: }
2242: R = reverse(R0);
2243: }
2244: T_PD += time()[3]-T0[3];
2245: return R;
2246: }
2247:
2248: def setintersection(A,B)
2249: {
2250: for ( L = []; A != []; A = cdr(A) )
2251: if ( member(car(A),B) )
2252: L = cons(car(A),L);
2253: return L;
2254: }
2255:
2256: /* returns [[Plist,Mlist],...] */
2257:
2258: def partial_decomp0(B,V,I)
2259: {
2260: N = length(V);
2261: if ( I < 0 )
2262: return [[B,[]]];
2263: Ord = PartialDecompByLex ? [[0,I],[2,N-I]] : 0;
2264: #if 0
2265: if ( setminus(vars(B),V) == [] )
2266: B = fglm_sf_0dim(B,V,Ord0,Ord);
2267: else
2268: #endif
2269: B = dp_gr_f_main(B,V,0,Ord);
2270: if ( type(B[0]) == 1 )
2271: return [];
2272: if ( !zero_dim(B,V,Ord) )
2273: error("non zero-dimensional ideal");
2274: /* XXX */
2275: Vt = ttttt;
2276: VI = V[I];
2277: if ( PartialDecompByLex ) {
2278: for ( J = 0, W = V; J < I; J++ )
2279: W = cdr(W);
2280: VW = setminus(V,W);
2281: for ( Bw = [], T = B; T != []; T = cdr(T) )
2282: if ( setintersection(vars(car(T)),VW) == [] )
2283: Bw = cons(car(T),Bw);
2284: MI = minipoly_sf(Bw,W,2,VI,Vt);
2285: } else
2286: MI = minipoly_sf(B,V,0,VI,Vt);
2287: MIF = sffctr(MI);
2288: /* if MI is irreducible, then process the next variable */
2289: if ( length(MIF) == 2 && MIF[1][1] == 1 ) {
2290: L = partial_decomp0(B,V,I-1);
2291: R = [];
2292: for ( S = L; S != []; S = cdr(S) ) {
2293: L = car(S);
2294: R = cons([L[0],cons(subst(MI,Vt,VI),L[1])],R);
2295: }
2296: return R;
2297: }
2298:
2299: /* for nf computation */
2300: Ord1 = PartialDecompByLex ? 2 : [[0,1],[0,N]];
2301: Len = length(B);
2302: PS = newvect(Len+1);
2303: dp_ord(Ord1);
2304: XV = cons(Vt,V);
2305: for ( J = 0, T = cons(Vt-VI,B); T != []; T = cdr(T), J++ )
2306: PS[J] = dp_ptod(car(T),XV);
2307: for ( J = 0, GI = []; J <= Len; J++ )
2308: GI = cons(J,GI);
2309: if ( PartialDecompByLex )
2310: GI = reverse(GI);
2311:
2312: R = [];
2313: for ( T = MIF; T != []; T = cdr(T) ) {
2314: Mt = car(car(T));
2315: if ( type(Mt) == 1 )
2316: continue;
2317: dp_ord(Ord1);
2318: NfMt = dp_dtop(nf_sfrat(GI,dp_ptod(Mt,XV),1,PS)[0],XV);
2319: if ( NfMt )
2320: B1 = dp_gr_f_main(cons(NfMt,B),V,0,Ord);
2321: else
2322: B1 = B;
2323: Rt = partial_decomp0(B1,V,I-1);
2324: for ( S = Rt; S != []; S = cdr(S) ) {
2325: L = car(S);
2326: R = cons([L[0],cons(subst(Mt,Vt,VI),L[1])],R);
2327: }
2328: }
2329: return R;
2330: }
2331:
2332:
2333: /* G is a gb wrt (V,O) */
2334:
2335: def minipoly_sf(G,V,O,F,V0)
2336: {
2337: T0 = time();
2338: Vc = cons(V0,setminus(vars(G),V));
2339: if ( ParallelMinipoly ) {
2340: Proc0 = ParallelMinipoly[0];
2341: Proc1 = ParallelMinipoly[1];
2342: if ( length(Vc) == 1 ) {
2343: ox_rpc(Proc0,"minipoly_sf_by_buchberger",G,V,O,F,V0,1);
2344: ox_rpc(Proc1,"minipoly_sf_0dim",G,V,O,F,V0,1);
2345: map(ox_get,ParallelMinipoly);
2346: /* 258=SM_popSerializedLocalObject */
2347: map(ox_push_cmd,ParallelMinipoly,258);
2348: F = ox_select(ParallelMinipoly);
2349: MP = ox_get(F[0]);
2350: if ( F[0] == Proc0 ) {
2351: if ( length(F) == 1 )
2352: B_Win++;
2353: else
2354: ox_get(Proc1);
2355: } else {
2356: if ( length(F) == 1 )
2357: D_Win++;
2358: else
2359: ox_get(Proc0);
2360: }
2361: ox_reset(Proc0);
2362: ox_reset(Proc1);
2363: } else if ( length(Vc) == 2 ) {
2364: ox_rpc(Proc0,"minipoly_sf_by_buchberger",G,V,O,F,V0,1);
2365: ox_rpc(Proc1,"minipoly_sfrat",G,V,O,F,V0,1);
2366: map(ox_get,ParallelMinipoly);
2367: /* 258=SM_popSerializedLocalObject */
2368: map(ox_push_cmd,ParallelMinipoly,258);
2369: F = ox_select(ParallelMinipoly);
2370: MP = ox_get(F[0]);
2371: if ( F[0] == Proc0 ) {
2372: if ( length(F) == 1 )
2373: B_Win++;
2374: else
2375: ox_get(Proc1);
2376: } else {
2377: if ( length(F) == 1 )
2378: D_Win++;
2379: else
2380: ox_get(Proc0);
2381: }
2382: ox_reset(Proc0);
2383: ox_reset(Proc1);
2384: } else
2385: MP = minipoly_sf_by_buchberger(G,V,O,F,V0,0);
2386: } else if ( BuchbergerMinipoly )
2387: MP = minipoly_sf_by_buchberger(G,V,O,F,V0,0);
2388: else {
2389: if ( length(Vc) == 1 )
2390: MP = minipoly_sf_0dim(G,V,O,F,V0,0);
2391: else if ( length(Vc) == 2 )
2392: MP = minipoly_sfrat(G,V,O,F,V0,0);
2393: else
2394: MP = minipoly_sf_by_buchberger(G,V,O,F,V0,0);
2395: }
2396: T_MP += time()[3]-T0[3];
2397: return MP;
2398: }
2399:
2400: def minipoly_sf_by_buchberger(G,V,O,F,V0,Server)
2401: {
2402: if ( Server )
2403: ox_sync(0);
2404: Vc = cons(V0,setminus(vars(G),V));
2405: Gf = cons(simp_ff(V0-F),G);
2406: Vf = append(V,Vc);
2407: Gelim = dp_gr_f_main(Gf,Vf,1,[[0,length(V)],[0,length(Vc)]]);
2408: for ( Gc = [], T = Gelim; T != []; T = cdr(T) ) {
2409: Vt = setminus(vars(car(T)),Vc);
2410: if ( Vt == [] )
2411: Gc = cons(car(T),Gc);
2412: }
2413: Gt = dp_gr_f_main(Gc,Vc,1,[[0,1],[0,length(Vc)-1]]);
2414: Pmin = car(Gt); Dmin = deg(Pmin,V0);
2415: for ( T = cdr(Gt); T != []; T = cdr(T) ) {
2416: Dt = deg(car(T),V0);
2417: if ( Dt < Dmin ) {
2418: Pmin = car(T); Dmin = Dt;
2419: }
2420: }
2421: Cont = sfcont(Pmin,V0);
2422: return sdiv(Pmin,Cont);
2423: }
2424:
2425: def minipoly_sf_0dim(G,V,O,F,V0,Server)
2426: {
2427: if ( Server )
2428: ox_sync(0);
1.2 ! noro 2429:
! 2430: if ( Minipoly_SBA ) {
! 2431: G1 = cons(simp_ff(V0-F),G);
! 2432: V1 = append(V,[V0]);
! 2433: G2 = nd_sba(G1,V1,-1,[[0,length(V)],[0,1]]|sba_modord=[[],0]);
! 2434: dp_ord(0);
! 2435: for ( T = G2; T != []; T = cdr(T) )
! 2436: if ( vars(car(T)) == [V0] ) break;
! 2437: if ( T == [] )
! 2438: error("minipoly does not exit");
! 2439: return car(T);
! 2440: }
! 2441:
1.1 noro 2442: N = length(V);
2443: Len = length(G);
2444: dp_ord(O);
2445: PS = newvect(Len);
2446: for ( I = 0, T = G; T != []; T = cdr(T), I++ )
2447: PS[I] = dp_ptod(car(T),V);
2448: for ( I = Len-1, HL = []; I >= 0; I-- )
2449: HL = cons(dp_ht(PS[I]),HL);
2450: for ( I = Len - 1, GI = []; I >= 0; I-- )
2451: GI = cons(I,GI);
2452: MB = dp_mbase(HL); DIM = length(MB); UT = newvect(DIM);
2453: U = dp_ptod(simp_ff(F),V);
2454: U = dp_nf_f(GI,U,PS,1);
2455: for ( I = 0; I < DIM; I++ )
2456: UT[I] = [MB[I],dp_nf_f(GI,U*MB[I],PS,1)];
2457:
2458: T = dp_ptod(simp_ff(1),[V0]);
2459: TT = dp_ptod(simp_ff(1),V);
2460: G = H = [[TT,T]];
2461:
2462: for ( I = 1; ; I++ ) {
2463: if ( dp_gr_print() )
2464: print(".",2);
2465: T = dp_ptod(simp_ff(V0^I),[V0]);
2466: TT = dp_nf_tab_f(H[0][0],UT);
2467: H = cons([TT,T],H);
2468: L = dp_lnf_f([TT,T],G);
2469: if ( !L[0] ) {
2470: if ( dp_gr_print() )
2471: print("");
2472: return dp_dtop(L[1],[V0]); /* XXX */
2473: } else
2474: G = insert(G,L);
2475: }
2476: }
2477:
2478: #if 1
2479: def minipoly_sf_rat(G,V,F,V0)
2480: {
2481: Vc = setminus(vars(G),V);
2482: Gf = cons(V0-F,G);
2483: Vf = append(V,[V0]);
2484: G3 = dp_gr_f_main(map(simp_ff,Gf),Vf,0,3);
2485: for ( T = G3; T != []; T = cdr(T) ) {
2486: Vt = setminus(vars(car(T)),Vc);
2487: if ( Vt == [V0] )
2488: return car(T);
2489: }
2490: }
2491:
2492: def minipoly_mod(G,V,Mod,F,V0)
2493: {
2494: Vc = setminus(vars(G),V);
2495: Gf = cons(V0-F,G);
2496: Vf = append(V,[V0]);
2497: G3 = dp_gr_mod_main(Gf,Vf,1,Mod,3);
2498: for ( T = G3; T != []; T = cdr(T) ) {
2499: Vt = setminus(vars(car(T)),Vc);
2500: if ( Vt == [V0] )
2501: return car(T);
2502: }
2503: }
2504: #endif
2505:
2506: /* find N/D s.t. F = N/D mod V^(2M), deg(N),deg(D)<M */
2507:
2508: def pade(F,M)
2509: {
2510: V = var(F);
2511: A = newvect(M);
2512: D = 0;
2513: for ( I = 0; I < M; I++ ) {
2514: A[I] = strtov("b"+rtostr(I));
2515: D += A[I]*V^I;
2516: }
2517: T = F*D;
2518: M2 = M*2;
2519: R = [];
2520: for ( I = M; I < M2; I++ )
2521: R = cons(coef(T,I,V),R);
2522: }
2523:
2524: def minipoly_sfrat(G0,V,O,P,V0,Server)
2525: {
2526: if ( Server )
2527: ox_sync(0);
2528: if ( !zero_dim(hmlist(G0,V,O),V,O) )
2529: error("minipoly_sfrat : ideal is not zero-dimensional!");
2530:
2531: G1 = cons(V0-P,G0);
2532: if ( type(O) <= 1 )
2533: O1 = [[0,1],[O,length(V)]];
2534: else
2535: O1 = cons([0,1],O);
2536: V1 = cons(V0,V);
2537: W = append(V,[V0]);
2538: Vc = setminus(vars(G0),V);
2539:
2540: N = length(V1);
2541: dp_ord(O1);
2542: HM = hmlist(G1,V1,O1);
2543: MB = dp_mbase(map(dp_ptod,HM,V1));
2544: dp_ord(O);
2545:
2546: Nc = length(Vc);
2547: Eval = newvect(Nc);
2548:
2549: /* heristic lower bound of deg(MP) */
2550: Q1 = field_order_ff()-1;
2551: do {
2552: for ( I = 0; I < Nc; I++ )
2553: Eval[I] = random()%Q1;
2554: } while ( !valid_modulus_sfrat(HM,Vc,Eval) );
2555: G0E = map(eval_sfrat,G0,Vc,Eval);
2556: P0 = eval_sfrat(P,Vc,Eval);
2557: MP = minipoly_sf(G0E,V,O,P0,V0);
2558: DMP = deg(MP,V0);
2559:
2560: for ( I = 0; I < Nc; I++ )
2561: Eval[I] = 0;
2562: while ( 1 ) {
2563: if ( valid_modulus_sfrat(HM,Vc,Eval) ) {
2564: G0E = map(eval_sfrat,G0,Vc,Eval);
2565: P0 = eval_sfrat(P,Vc,Eval);
2566: MP = minipoly_sf(G0E,V,O,P0,V0);
2567: D = deg(MP,V0);
2568: if ( D >= DMP ) {
2569: DMP = D;
2570: for ( TL = [], MPT = 0, J = 0; J <= D; J++ ) {
2571: TL = cons(V0^J,TL);
2572: MPT += car(TL);
2573: }
2574: NF = gennf_sfrat(G1,TL,V1,O1,V0,1)[0];
2575: R = tolex_sfrat_main(V1,O1,NF,[MPT],Vc,Eval,MB);
2576: if ( R )
2577: return sdiv(R[0],sfcont(R[0],V0));
2578: }
2579: }
2580: next_eval_sfrat(Eval);
2581: }
2582: }
2583:
2584: def next_eval_sfrat(Eval)
2585: {
2586: N = size(Eval)[0];
2587: for ( I = N-1; I >= 0; I-- )
2588: if ( Eval[I] ) break;
2589: if ( I < 0 ) Eval[N-1] = 1;
2590: else if ( I == 0 ) {
2591: T = Eval[0]; Eval[0] = 0; Eval[N-1] = T+1;
2592: } else {
2593: Eval[I-1]++; T = Eval[I];
2594: for ( J = I; J < N-1; J++ )
2595: Eval[J] = 0;
2596: Eval[N-1] = T-1;
2597: }
2598: }
2599:
2600: def eval_sfrat(F,V,Eval)
2601: {
2602: for ( I = 0; V != []; V = cdr(V), I++ )
2603: F = subst(F,car(V),ptosfp(Eval[I]));
2604: return F;
2605: }
2606:
2607: def valid_modulus_sfrat(HL,Vc,Eval) {
2608: for ( T = HL; T != []; T = cdr(T) ) {
2609: C = car(T);
2610: for ( S = Vc, I = 0; S != []; S = cdr(S), I++ )
2611: C = subst(C,car(S),ptosfp(Eval[I]));
2612: if ( !C )
2613: break;
2614: }
2615: return T == [] ? 1 : 0;
2616: }
2617:
2618: def gennf_sfrat(G,TL,V,O,V0,FLAG)
2619: {
2620: N = length(V); Len = length(G); dp_ord(O); PS = newvect(Len);
2621: for ( I = 0, T = G, HL = []; T != []; T = cdr(T), I++ ) {
2622: PS[I] = dp_ptod(car(T),V); HL = cons(dp_ht(PS[I]),HL);
2623: }
2624: for ( I = 0, DTL = []; TL != []; TL = cdr(TL) )
2625: DTL = cons(dp_ptod(car(TL),V),DTL);
2626: for ( I = Len - 1, GI = []; I >= 0; I-- )
2627: GI = cons(I,GI);
2628: T = car(DTL); DTL = cdr(DTL);
2629: H = [nf_sfrat(GI,T,T,PS)];
2630:
2631: USE_TAB = (FLAG != 0);
2632: if ( USE_TAB ) {
2633: T0 = time()[0];
2634: MB = dp_mbase(HL); DIM = length(MB);
2635: U = dp_ptod(V0,V);
2636: UTAB = newvect(DIM);
2637: for ( I = 0; I < DIM; I++ ) {
2638: UTAB[I] = [MB[I],remove_cont_sfrat(nf_sfrat(GI,U*MB[I],1,PS))];
2639: if ( dp_gr_print() )
2640: print(".",2);
2641: }
2642: if ( dp_gr_print() )
2643: print("");
2644: TTAB = time()[0]-T0;
2645: }
2646:
2647: T0 = time()[0];
2648: for ( LCM = 1; DTL != []; ) {
2649: if ( dp_gr_print() )
2650: print(".",2);
2651: T = car(DTL); DTL = cdr(DTL);
2652: if ( L = search_redble(T,H) ) {
2653: DD = dp_subd(T,L[1]);
2654: if ( USE_TAB && (DD == U) ) {
2655: NF = nf_tab_sfrat(L[0],UTAB);
2656: NF = [NF[0],dp_hc(L[1])*NF[1]*T];
2657: } else
2658: NF = nf_sfrat(GI,L[0]*dp_subd(T,L[1]),dp_hc(L[1])*T,PS);
2659: } else
2660: NF = nf_sfrat(GI,T,T,PS);
2661: NF = remove_cont_sfrat(NF);
2662: H = cons(NF,H);
2663: LCM = lcm_sfrat(LCM,dp_hc(NF[1]));
2664: }
2665: TNF = time()[0]-T0;
2666: if ( dp_gr_print() )
2667: print("gennf(TAB="+rtostr(TTAB)+" NF="+rtostr(TNF)+")");
2668: return [[map(adj_dn_sfrat,H,LCM),LCM],PS,GI];
2669: }
2670:
2671: def lcm_sfrat(A,B)
2672: {
2673: G = sfgcd(A,B);
2674: return sdiv(A,G)*B;
2675: }
2676:
2677: #define REDCONT(f) ((f)/sfcont(f))
2678:
2679: def remove_cont_sfrat(L)
2680: {
2681: if ( type(L[1]) <= 2 ) {
2682: T = remove_cont_sfrat([L[0],L[1]*<<0>>]);
2683: return [T[0],dp_hc(T[1])];
2684: } else if ( !L[0] )
2685: return [0,REDCONT(L[1])];
2686: else if ( !L[1] )
2687: return [REDCONT(L[0]),0];
2688: else {
2689: A0 = REDCONT(L[0]); A1 = REDCONT(L[1]);
2690: C0 = sdiv(dp_hc(L[0]),dp_hc(A0)); C1 = sdiv(dp_hc(L[1]),dp_hc(A1));
2691: GCD = sfgcd(C0,C1); M0 = sdiv(C0,GCD); M1 = sdiv(C1,GCD);
2692: return [M0*A0,M1*A1];
2693: }
2694: }
2695:
2696: def nf_sfrat(B,G,M,PS)
2697: {
2698: for ( D = 0; G; ) {
2699: for ( U = 0, L = B; L != []; L = cdr(L) ) {
2700: if ( dp_redble(G,R=PS[car(L)]) > 0 ) {
2701: GCD = sfgcd(dp_hc(G),dp_hc(R));
2702: CG = sdiv(dp_hc(R),GCD); CR = sdiv(dp_hc(G),GCD);
2703: U = CG*G-dp_subd(G,R)*CR*R;
2704: if ( !U )
2705: return [D,M];
2706: D *= CG; M *= CG;
2707: break;
2708: }
2709: }
2710: if ( U )
2711: G = U;
2712: else {
2713: D += dp_hm(G); G = dp_rest(G);
2714: }
2715: }
2716: return [D,M];
2717: }
2718:
2719: def nf_tab_sfrat(F,TAB)
2720: {
2721: for ( NM = 0, DN = 1, I = 0; F; F = dp_rest(F) ) {
2722: T = dp_ht(F);
2723: for ( ; TAB[I][0] != T; I++);
2724: NF = TAB[I][1]; N = NF[0]; D = NF[1];
2725: G = sfgcd(DN,D); DN1 = sdiv(DN,G); D1 = sdiv(D,G);
2726: NM = D1*NM + DN1*dp_hc(F)*N; DN *= D1;
2727: }
2728: return [NM,DN];
2729: }
2730:
2731: def adj_dn_sfrat(P,D)
2732: {
2733: return [(sdiv(D,dp_hc(P[1])))*P[0],dp_ht(P[1])];
2734: }
2735:
2736: def tolex_sfrat_main(V,O,NF,GM,Vc,Eval,MB)
2737: {
2738: if ( MB ) {
2739: PosDim = 0;
2740: DIM = length(MB);
2741: DV = newvect(DIM);
2742: } else
2743: PosDim = 1;
2744: for ( T = GM, SL = [], LCM = 1; T != []; T = cdr(T) ) {
2745: S = p_terms(car(T),V,2);
2746: if ( PosDim ) {
2747: MB = gather_nf_terms(S,NF,V,O);
2748: DV = newvect(length(MB));
2749: }
2750: dp_ord(O); RHS = termstomat_sfrat(NF,map(dp_ptod,cdr(S),V),MB,Vc,Eval);
2751: dp_ord(O); NHT = nf_tab_gsl_sfrat(dp_ptod(LCM*car(S),V),NF);
2752: dptov(NHT[0],DV,MB);
2753: dp_ord(O); B = hen_ttob_gsl_sfrat([DV,NHT[1]],RHS,cdr(S),Vc,Eval);
2754: if ( !B )
2755: return 0;
2756: Len = length(S);
2757: LCM *= B[1];
2758: for ( U = LCM*car(S), I = 1; I < Len; I++ )
2759: U += B[0][I-1]*S[I];
2760: SL = cons(U,SL);
2761: if ( dp_gr_print() )
2762: print(["DN",B[1]]);
2763: }
2764: return SL;
2765: }
2766:
2767: def termstomat_sfrat(NF,TERMS,MB,Vc,Eval)
2768: {
2769: DN = NF[1];
2770: NF = NF[0];
2771: N = length(MB);
2772: M = length(TERMS);
2773: MAT = newmat(N,M);
2774: W = newvect(N);
2775: Len = length(NF);
2776: for ( I = 0; I < M; I++ ) {
2777: T = TERMS[I];
2778: for ( K = 0; K < Len; K++ )
2779: if ( T == NF[K][1] )
2780: break;
2781: dptov(NF[K][0],W,MB);
2782: for ( J = 0; J < N; J++ )
2783: MAT[J][I] = W[J];
2784: }
2785: return [henleq_prep_sfrat(MAT,Vc,Eval),DN];
2786: }
2787:
2788: def henleq_prep_sfrat(A,Vc,Eval)
2789: {
2790: SIZE = size(A); ROW = SIZE[0]; COL = SIZE[1];
2791: L = geninv_sf_swap(map(eval_sfrat,A,Vc,Eval)); INV = L[0]; INDEX = L[1];
2792: AA = newmat(COL,COL);
2793: for ( I = 0; I < COL; I++ )
2794: for ( J = 0, T = AA[I], S = A[INDEX[I]]; J < COL; J++ )
2795: T[J] = S[J];
2796: if ( COL != ROW ) {
2797: RESTA = newmat(ROW-COL,COL);
2798: for ( ; I < ROW; I++ )
2799: for ( J = 0, T = RESTA[I-COL], S = A[INDEX[I]]; J < COL; J++ )
2800: T[J] = S[J];
2801: } else
2802: RESTA = 0;
2803: return [[A,AA,RESTA],L];
2804: }
2805:
2806: def hen_ttob_gsl_sfrat(LHS,RHS,TERMS,Vc,Eval)
2807: {
2808: LDN = LHS[1]; RDN = RHS[1]; LCM = lcm_sfrat(LDN,RDN);
2809: L1 = sdiv(LCM,LDN); R1 = sdiv(LCM,RDN);
2810: T0 = time()[0];
2811: S = henleq_gsl_sfrat(RHS[0],LHS[0]*L1,Vc,Eval);
2812: if ( dp_gr_print() )
2813: print(["henleq_gsl_sfrat",time()[0]-T0]);
2814: if ( !S )
2815: return 0;
2816: N = length(TERMS);
2817: return [S[0],S[1]*R1];
2818: }
2819:
2820: def nf_tab_gsl_sfrat(A,NF)
2821: {
2822: DN = NF[1];
2823: NF = NF[0];
2824: TLen = length(NF);
2825: for ( R = 0; A; A = dp_rest(A) ) {
2826: HM = dp_hm(A); C = dp_hc(HM); T = dp_ht(HM);
2827: for ( I = 0; I < TLen; I++ )
2828: if ( NF[I][1] == T )
2829: break;
2830: R += C*NF[I][0];
2831: }
2832: return remove_cont_sfrat([R,DN]);
2833: }
2834:
2835: def henleq_gsl_sfrat(L,B,Vc,Eval)
2836: {
2837: Nc = length(Vc);
2838: if ( Nc > 1 )
2839: return henleq_gsl_sfrat_higher(L,B,Vc,Eval);
2840:
2841: V0 = Vc[0]; E0 = ptosfp(Eval[0]);
2842:
2843: AL = L[0]; INVL = L[1];
2844: A = AL[0]; AA = AL[1]; RESTA = AL[2];
2845: INV = INVL[0]; INDEX = INVL[1];
2846:
2847: SIZE = size(A); ROW = SIZE[0]; COL = SIZE[1];
2848: BB = newvect(COL);
2849: for ( I = 0; I < COL; I++ )
2850: BB[I] = B[INDEX[I]];
2851: if ( COL != ROW ) {
2852: RESTB = newvect(ROW-COL);
2853: for ( ; I < ROW; I++ )
2854: RESTB[I-COL] = B[INDEX[I]];
2855: } else
2856: RESTB = 0;
2857:
2858: COUNT = 2;
2859: if ( !COUNT )
2860: COUNT = 2;
2861: X = newvect(size(AA)[0]);
2862: for ( I = 0, C = BB, CCC = 0, ITOR_FAIL = -1; ; I++ ) {
2863: if ( zerovector(C) ) {
2864: X = map(subst,X,V0,V0-E0);
2865: if ( zerovector(RESTA*X+RESTB) ) {
2866: if ( dp_gr_print() ) print("end",0);
2867: return [X,simp_ff(1)];
2868: } else
2869: return 0;
2870: } else if ( COUNT == CCC ) {
2871: CCC = 0;
2872: ND = polyvtoratv(X,V0,I);
2873: if ( ND ) {
2874: F = map(subst,ND[0],V0,V0-E0);
2875: LCM = subst(ND[1],V0,V0-E0);
2876: T = AA*F+LCM*BB;
2877: if ( zerovector(T) ) {
2878: T = RESTA*F+LCM*RESTB;
2879: if ( zerovector(T) ) {
2880: if ( dp_gr_print() ) print("end",0);
2881: return [F,LCM];
2882: } else
2883: return 0;
2884: }
2885: } else {
2886: }
2887: } else {
2888: if ( dp_gr_print() ) print(".",2);
2889: CCC++;
2890: }
2891: XT = -INV*map(subst,C,V0,E0);
2892: X += XT*V0^I;
2893: C += AA*XT;
2894: C = map(sdiv,C,V0-E0);
2895: }
2896: }
2897:
2898: def henleq_gsl_sfrat_higher(L,B,Vc,Eval)
2899: {
2900: Nc = length(Vc);
2901: E = map(ptosfp,Eval);
2902:
2903: AL = L[0]; INVL = L[1];
2904: A = AL[0]; AA0 = AL[1]; RESTA = AL[2];
2905: INV = INVL[0]; INDEX = INVL[1];
2906:
2907: SIZE = size(A); ROW = SIZE[0]; COL = SIZE[1];
2908:
2909: AA = map(mshift,AA0,Vc,E,1);
2910: BB = newvect(COL);
2911: for ( I = 0; I < COL; I++ )
2912: BB[I] = mshift(B[INDEX[I]],Vc,E,1);
2913:
2914: if ( COL != ROW ) {
2915: RESTB = newvect(ROW-COL);
2916: for ( ; I < ROW; I++ )
2917: RESTB[I-COL] = B[INDEX[I]];
2918: } else
2919: RESTB = 0;
2920:
2921: COUNT = 2;
2922: if ( !COUNT )
2923: COUNT = 2;
2924: X = newvect(size(AA)[0]);
2925: for ( I = 0, R = BB, CCC = 0, ITOR_FAIL = -1; ; I++ ) {
2926: if ( zerovector(R) ) {
2927: X = map(mshift,X,Vc,E,-1);
2928: if ( zerovector(RESTA*X+RESTB) ) {
2929: if ( dp_gr_print() ) print("end",0);
2930: return [X,simp_ff(1)];
2931: } else
2932: return 0;
2933: } else if ( COUNT == CCC ) {
2934: CCC = 0;
2935: ND = polyvtoratv_higher(X,Vc,I);
2936: if ( ND ) {
2937: F = map(mshift,ND[0],Vc,E,-1);
2938: LCM = mshift(ND[1],Vc,E,-1);
2939: T = AA*F+LCM*BB;
2940: if ( zerovector(T) ) {
2941: T = RESTA*F+LCM*RESTB;
2942: if ( zerovector(T) ) {
2943: if ( dp_gr_print() ) print("end",0);
2944: return [F,LCM];
2945: } else
2946: return 0;
2947: }
2948: } else {
2949: }
2950: } else {
2951: if ( dp_gr_print() ) print(".",2);
2952: CCC++;
2953: }
2954: RK = map(mtrunc,R,I+1);
2955: XT = -INV*RK;
2956: X += XT;
2957: R += AA*XT;
2958: }
2959: }
2960:
2961: /* V -> V+Sgn*E */
2962:
2963: def mshift(F,V,E,Sgn)
2964: {
2965: N = length(V);
2966: for ( I = 0; I < N; I++ )
2967: F = subst(F,V[I],V[I]+Sgn*E[I]);
2968: return F;
2969: }
2970:
2971: /* truncate terms whose degree are higher than or equal to D */
2972:
2973: def mtrunc(F,D)
2974: {
2975: if ( type(F) <= 1 )
2976: return F;
2977: else {
2978: R = 0;
2979: V = var(F);
2980: while ( F ) {
2981: K = deg(F,V);
2982: C = coef(F,K,V);
2983: if ( K < D )
2984: R += mtrunc(C,D-K)*V^K;
2985: F -= C*V^K;
2986: }
2987: return R;
2988: }
2989: }
2990:
2991: /* for 1-dim case */
2992:
2993: def polyvtoratv(Vect,V,K)
2994: {
2995: N = size(Vect)[0];
2996: R = newvect(N);
2997: K2 = idiv(K,2);
2998: Mat = newmat(K2,K2);
2999: for ( I = 0; I < N; I++ ) {
3000: T = polytorat(Vect[I],V,Mat,K2);
3001: if ( T )
3002: R[I] = T;
3003: else
3004: return 0;
3005: }
3006: LCM = R[0][1];
3007: for ( I = 1; I < N; I++ )
3008: LCM = lcm_sfrat(LCM,R[I][1]);
3009: for ( I = 0; I < N; I++ )
3010: R[I] = R[I][0]*sdiv(LCM,R[I][1]);
3011: return [R,LCM];
3012: }
3013:
3014: /* for higher dim case */
3015:
3016: def polyvtoratv_higher(Vect,Vc,K)
3017: {
3018: N = size(Vect)[0];
3019: R = newvect(N);
3020: K2 = idiv(K,2);
3021: for ( I = 0; I < N; I++ ) {
3022: T = polytorat_higher(Vect[I],Vc,K2);
3023: if ( T )
3024: R[I] = T;
3025: else
3026: return 0;
3027: }
3028: LCM = R[0][1];
3029: for ( I = 1; I < N; I++ )
3030: LCM = lcm_sfrat(LCM,R[I][1]);
3031: for ( I = 0; I < N; I++ )
3032: R[I] = R[I][0]*sdiv(LCM,R[I][1]);
3033: return [R,LCM];
3034: }
3035:
3036: /* find F = N/D mod V^(2K), deg(N), deg(D) < K */
3037: def polytorat_gcd(F,V,K)
3038: {
3039: if ( deg(F,V) < K )
3040: return [F,simp_ff(1)];
3041: F1 = Mod^(K*2); F2 = F;
3042: B1 = 0; B2 = 1;
3043: while ( 1 ) {
3044: Q = sdiv(F1,F2);
3045: F3 = F1-F2*Q;
3046: B3 = B1-B2*Q;
3047: if ( deg(F3,V) < K ) {
3048: if ( deg(B3,V) < K )
3049: return [F3,B3];
3050: else
3051: return 0;
3052: }
3053: F1 = F2; F2 = F3;
3054: B1 = B2; B2 = B3;
3055: }
3056: }
3057:
3058: /*
3059: * for 1-dim case
3060: *
3061: * solve
3062: *
3063: * [fk ... f1][ a0 ]
3064: * [f(k+1) ... f2][ a1 ] = 0
3065: * [ ... ][ ... ]
3066: * [f(2k-1) ... fk][a(k-1)]
3067: */
3068:
3069: def polytorat(F,V,Mat,K)
3070: {
3071: if ( deg(F,V) < K )
3072: return [F,simp_ff(1)];
3073: for ( I = 0; I < K; I++ )
3074: for ( J = 0; J < K; J++ )
3075: Mat[I][J] = coef(F,I+K-J);
3076: S = nullspace_ff(Mat);
3077: MT = S[0]; IND = S[1];
3078: for ( I = 0; I < K; I++ )
3079: if ( IND[I] )
3080: break;
3081: if ( I == K )
3082: return 0;
3083: D = null_to_poly_ff(MT,IND,V)[0];
3084: N = trunc(F*D,K-1);
3085: return [N,D];
3086: }
3087:
3088: /* find N,D s.t. tdeg(N), tdeg(D) < K, F = N/D mod <V0,...,VM>^(2K) */
3089:
3090: def polytorat_higher(F,V,K)
3091: {
3092: if ( K < 2 ) return 0;
3093: if ( homogeneous_deg(F) < K )
3094: return [F,simp_ff(1)];
3095: D = create_icpoly(V,K);
3096: C = extract_coef(D*F,V,K,2*K);
3097: Vc = vars(C);
3098: G = dp_gr_f_main(C,Vc,0,2);
3099: PS = newvect(length(G),map(dp_ptod,G,Vc));
3100: for ( I = length(G)-1, Ind = [];I >= 0; I-- )
3101: Ind = cons(I,Ind);
3102: D = dp_dtop(nf_sfrat(Ind,dp_ptod(D,Vc),1,PS)[0],Vc);
3103: if ( !D )
3104: return 0;
3105: Vp = setminus(vars(D),V);
3106: D = subst(D,car(Vp),1);
3107: for ( T = cdr(Vp); T != []; T = cdr(T) )
3108: D = subst(D,car(T),0);
3109: N = mtrunc(F*D,K);
3110: return [N,D];
3111: }
3112:
3113: def create_icpoly(V,K)
3114: {
3115: if ( V == [] )
3116: return uc();
3117: R = 0;
3118: for ( I = 0; I < K; I++ )
3119: R += create_icpoly(cdr(V),K-I)*V[0]^I;
3120: return R;
3121: }
3122:
3123: /* extract terms whose degrees are in [From,To) */
3124:
3125: def extract_coef(F,V,From,To)
3126: {
3127: if ( V == [] ) {
3128: if ( From == 0 )
3129: return [F];
3130: else
3131: return [];
3132: }
3133: R = [];
3134: V0 = V[0];
3135: for ( I = 0; I < To; I++ ) {
3136: C = coef(F,I,V0);
3137: if ( C ) {
3138: C = extract_coef(C,cdr(V),From>=I?From-I:0,To-I);
3139: R = append(C,R);
3140: }
3141: }
3142: return R;
3143: }
3144:
3145: def saturation_sfrat(F,G,V,Ord)
3146: {
3147: Vt = ttttt;
3148: G0 = dp_gr_f_main(cons(Vt*F-1,G),cons(Vt,V),0,[[0,1],[Ord,length(V)]]);
3149: return elimination(G0,V);
3150: }
3151:
3152: def ideal_list_intersection_sfrat(L,V)
3153: {
3154: R = car(L);
3155: for ( TL = cdr(L); TL != []; TL = cdr(TL) )
3156: R = ideal_intersection_sfrat(R,car(TL),V);
3157: return R;
3158: }
3159:
3160: def ideal_intersection_sfrat(A,B,V)
3161: {
3162: T0 = time();
3163: Vt = ttttt;
3164: C = [];
3165: for ( T = A; T != []; T = cdr(T) )
3166: C = cons(car(T)*Vt,C);
3167: for ( T = B; T != []; T = cdr(T) )
3168: C = cons(car(T)*(1-Vt),C);
3169: Ord = [[0,1],[0,length(V)]];
3170: #if 0
3171: G0 = dp_gr_f_main(C,cons(Vt,V),0,0);
3172: G = dp_gr_f_main(G0,cons(Vt,V),0,Ord);
3173: #else
3174: G = dp_gr_f_main(C,cons(Vt,V),0,Ord);
3175: #endif
3176: T_INT += time()[3]-T0[3];
3177: return elimination(G,V);
3178: }
3179:
3180: /* Shimoyama's gr_fctr */
3181:
3182: def idealsqfr_sf(G)
3183: {
3184: for(LL=[],I=length(G)-1;I>=0;I--) {
3185: for(A=1,L=sfsqfr(G[I]),J=1;J<length(L);J++)
3186: A*=L[J][0];
3187: LL=cons(A,LL);
3188: }
3189: return LL;
3190: }
3191:
3192: def ideal_uniq(L) /* sub procedure of welldec and normposdec */
3193: {
3194: for (R = [],I = 0,N=length(L); I < N; I++) {
3195: if ( R == [] )
3196: R = append(R,[L[I]]);
3197: else {
3198: for (J = 0; J < length(R); J++)
3199: if ( gb_comp_old(L[I],R[J]) )
3200: break;
3201: if ( J == length(R) )
3202: R = append(R,[L[I]]);
3203: }
3204: }
3205: return R;
3206: }
3207:
3208: def ideal_uniq_by_first(L) /* sub procedure of welldec and normposdec */
3209: {
3210: for (R = [],I = 0,N=length(L); I < N; I++) {
3211: if ( R == [] )
3212: R = append(R,[L[I]]);
3213: else {
3214: for (J = 0; J < length(R); J++)
3215: if ( gb_comp_old(L[I][0],R[J][0]) )
3216: break;
3217: if ( J == length(R) )
3218: R = append(R,[L[I]]);
3219: }
3220: }
3221: return R;
3222: }
3223:
3224: def prime_irred_sf(TP,VL,Ord)
3225: {
3226: TP = ideal_uniq(TP);
3227: N = length(TP);
3228: for (P = [], I = 0; I < N; I++) {
3229: for (J = 0; J < N; J++)
3230: if ( I != J && inclusion_test(TP[J],TP[I],VL,Ord) )
3231: break;
3232: if (J == N)
3233: P = append(P,[TP[I]]);
3234: }
3235: return P;
3236: }
3237:
3238: def prime_irred_sf_by_first(TP,VL,Ord)
3239: {
3240: TP = ideal_uniq_by_first(TP);
3241: N = length(TP);
3242: for (P = [], I = 0; I < N; I++) {
3243: for (J = 0; J < N; J++)
3244: if ( I != J && inclusion_test(car(TP[J]),car(TP[I]),VL,Ord) )
3245: break;
3246: if (J == N)
3247: P = append(P,[TP[I]]);
3248: }
3249: return P;
3250: }
3251:
3252: def monic_sf_first(L,V)
3253: {
3254: for ( R = [], T = L; T != []; T = cdr(T) )
3255: R = cons([monic_sf(car(T)[0],V),car(T)[1]],R);
3256: return reverse(R);
3257: }
3258:
3259: def monic_sf(P,V)
3260: {
3261: if ( type(P) == 4 )
3262: return map(monic_sf,P,V);
3263: else {
3264: D = dp_ptod(P,V);
3265: return dp_dtop(D/dp_hc(D),V);
3266: }
3267: }
3268:
3269: def gr_fctr_sf(FL,VL,Ord)
3270: {
3271: T0 = time();
3272: COMMONCHECK_SF = 1;
3273: for (TP = [],I = 0; I<length(FL); I++ ) {
3274: F = FL[I];
3275: SF = idealsqfr_sf(F);
3276: if ( !gb_comp_old(F,SF) )
3277: F = dp_gr_f_main(SF,VL,0,Ord);
3278: CID_SF=[1];
3279: SP = gr_fctr_sub_sf(F,VL,Ord);
3280: TP = append(TP,SP);
3281: }
3282: TP = prime_irred_sf(TP,VL,Ord);
3283: T_GRF += time()[3]-T0[3];
3284: return TP;
3285: }
3286:
3287: def gr_fctr_sub_sf(G,VL,Ord)
3288: {
3289: if ( length(G) == 1 && type(G[0]) == 1 )
3290: return [G];
3291: RL = [];
3292: for (I = 0; I < length(G); I++) {
3293: FL = sffctr(G[I]); L = length(FL); N = FL[1][1];
3294: if (L > 2 || N > 1) {
3295: TLL = [];
3296: for (J = 1; J < L; J++) {
3297: W = cons(FL[J][0],G);
3298: NG = dp_gr_f_main(W,VL,0,Ord);
3299: TNG = idealsqfr_sf(NG);
3300: if ( !gb_comp_old(NG,TNG) )
3301: NG = dp_gr_f_main(TNG,VL,0,Ord);
3302: if ( !inclusion_test(CID_SF,NG,VL,Ord) ) {
3303: DG = gr_fctr_sub_sf(NG,VL,Ord);
3304: RL = append(RL,DG);
3305: if ( J <= L-2
3306: && !inclusion_test(CID_SF,NG,VL,Ord)
3307: && COMMONCHECK_SF ) {
3308: CID_SF=ideal_intersection_sfrat(CID_SF,NG,VL);
3309: }
3310: }
3311: }
3312: break;
3313: }
3314: }
3315: if (I == length(G))
3316: RL = append([G],RL);
3317: return RL;
3318: }
3319:
3320: def gb_comp_old(A,B)
3321: {
3322: LA = length(A);
3323: LB = length(B);
3324: if ( LA != LB )
3325: return 0;
3326: A = newvect(LA,A);
3327: B = newvect(LB,B);
3328: A1 = qsort(A);
3329: B1 = qsort(B);
3330: for ( I = 0; I < LA; I++ )
3331: if ( A1[I] != B1[I] && A1[I] != -B1[I] )
3332: break;
3333: return I == LA ? 1 : 0;
3334: }
3335: end$
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>