source: git/Singular/LIB/ehv.lib @ 7f9ca3

spielwiese
Last change on this file since 7f9ca3 was 7f9ca3, checked in by Sachin <sachinkm308@…>, 4 years ago
replacing execute with create_ring(13)
  • Property mode set to 100644
File size: 41.0 KB
Line 
1////////////////////////////////////////////////////////////////////
2version="version ehv.lib 4.1.2.0 Feb_2019 "; // $Id$
3category="Commutative Algebra";
4
5info="
6LIBRARY: EHV.lib      PROCEDURES FOR PRIMARY DECOMPOSITION OF IDEALS
7AUTHORS: Kai Dehmann, dehmann@mathematik.uni-kl.de;
8
9OVERVIEW:
10  Algorithms for primary decomposition and radical-computation
11  based on the ideas of Eisenbud, Huneke, and Vasconcelos.
12
13PROCEDURES:
14  equiMaxEHV(I);                      equidimensional part of I
15  removeComponent(I,e);               intersection of the primary components
16                                      of I of dimension >= e
17  AssOfDim(I,e);                      an ideal such that the associated primes
18                                      are exactly the associated primes of I
19                                      having dimension e
20  equiRadEHV(I [,Strategy]);          equidimensional radical of I
21  radEHV(I [,Strategy]);              radical of I
22  IntAssOfDim1(I,e);                  intersection of the associated primes of I
23                                      having dimension e
24  IntAssOfDim2(I,e);                  another way of computing the intersection
25                                      of the associated primes of I
26                                      having dimension e
27  decompEHV(I);                       decomposition of a zero-dimensional
28                                      radical ideal I
29  AssEHV(I [,Strategy]);              associated primes of I
30  minAssEHV(I [,Strategy]);           minimal associated primes of I
31  localize(I,P,l);                    the contraction of the ideal generated by I
32                                      in the localization w.r.t P
33  componentEHV(I,P,L [,Strategy]);    a P-primary component for I
34  primdecEHV(I [,Strategy]);          a minimal primary decomposition of I
35  primDecsAreEquivalent(L, K);        procedure for comparing the output of
36                                      primary decomposition algorithms (checks
37                                      if the computed associated primes coincide)
38";
39
40LIB "ring.lib";
41LIB "general.lib";
42LIB "elim.lib";
43LIB "poly.lib";
44LIB "random.lib";
45LIB "inout.lib";
46LIB "matrix.lib";
47LIB "algebra.lib";
48LIB "normal.lib";
49
50
51/////////////////////////////////////////////////////////////////////
52//                                                                 //
53//             G E N E R A L   A L G O R I T H M S                 //
54//                                                                 //
55/////////////////////////////////////////////////////////////////////
56
57/////////////////////////////////////////////////////////////////////
58static proc AnnExtEHV(int n,list re)
59"USAGE:   AnnExtEHV(n,re); n integer, re resolution
60RETURN:  ideal, the annihilator of Ext^n(R/I,R) with given
61         resolution re of I"
62{
63  if(printlevel > 2){"Entering AnnExtEHV.";}
64
65  if(n < 0)
66    {
67      ideal ann = ideal(1);
68      if(printlevel > 2){"Leaving AnnExtEHV.";}
69      return(ann);
70    }
71  int l = size(re);
72
73  if(n < l)
74    {
75      matrix f = transpose(re[n+1]);
76      if(n == 0)
77        {
78          matrix g = 0*gen(ncols(f));
79        }
80      else
81        {
82          matrix g = transpose(re[n]);
83        }
84      module k = syz(f);
85      ideal ann = quotient1(g,k);
86      if(printlevel > 2){"Leaving AnnExtEHV.";}
87      return(ann);
88    }
89
90  if(n == l)
91    {
92      ideal ann = Ann(transpose(re[n]));
93      if(printlevel > 2){"Leaving AnnExtEHV.";}
94      return(ann);
95    }
96
97  ideal ann = ideal(1);
98  if(printlevel > 2){"Leaving AnnExtEHV.";}
99  return(ann);
100}
101
102
103/////////////////////////////////////////////////////////////////////
104//static
105proc isSubset(ideal I,ideal J)
106"USAGE:   isSubset(I,J); I, J ideals
107RETURN:  integer, 1 if I is a subset of J and 0 otherwise
108"
109{
110  if ( attrib(J,"isSB") == 0) { J = groebner(J); }
111  int s = ncols(I);
112  for(int i=1; i<=s; i++)
113    {
114      if(reduce(I[i],J)!=0)
115        {
116          return(0);
117        }
118    }
119  return(1);
120}
121
122
123/////////////////////////////////////////////////////////////////////
124//                                                                 //
125//         T H E   E Q U I D I M E N S I O N A L   P A R T         //
126//                                                                 //
127/////////////////////////////////////////////////////////////////////
128
129/////////////////////////////////////////////////////////////////////
130proc equiMaxEHV(ideal I)
131"USAGE:   equiMaxEHV(I); I ideal
132RETURN:  ideal, the equidimensional part of I.
133NOTE:    Uses algorithm of Eisenbud, Huneke, and Vasconcelos.
134EXAMPLE: example equiMaxEHV; shows an example
135"
136{
137  if(printlevel > 2){"Entering equiMaxEHV.";}
138  if(attrib(basering,"global")==0)
139    {
140      ERROR("// Not implemented for this ordering, please change to global ordering.");
141    }
142  ideal J = groebner(I);
143  int cod = nvars(basering)-dim(J);
144
145  //If I is the entire ring...
146  if(cod > nvars(basering))
147    {
148      //...then return the ideal generated by 1.
149      return(ideal(1));
150    }
151
152  //Compute a resolution of I.
153  if(printlevel > 2){"Computing resolution.";}
154  if(homog(I)==1)
155    {
156      list re = sres(J,cod+1);
157      re = minres(re);
158    }
159  else
160    {
161      list re = mres(I,cod+1);
162    }
163  if(printlevel > 2){"Finished computing resolution.";}
164
165  //Compute the annihilator of the cod-th EXT-module.
166  ideal ann = AnnExtEHV(cod,re);
167  attrib(ann,"isEquidimensional",1);
168  if(printlevel > 2){"Leaving equiMaxEHV.";}
169  return(ann);
170}
171
172example
173{
174  "EXAMPLE:";
175  echo = 2;
176  ring  r = 0,(x,y,z),dp;
177  ideal I = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
178  equiMaxEHV(I);
179}
180
181
182/////////////////////////////////////////////////////////////////////
183proc removeComponent(ideal I, int e)
184"USAGE:   removeComponent(I,e); I ideal, e integer
185RETURN:  ideal, the intersection of the primary components
186         of I of dimension >= e
187EXAMPLE: example removeComponent; shows an example"
188{
189  if(attrib(basering,"global")==0)
190    {
191      ERROR("// Not implemented for this ordering, please change to global ordering.");
192    }
193
194  ideal J = groebner(I);
195
196  //Compute a resolution of I
197  if(homog(I)==1)
198    {
199      list re = sres(J,0);
200      re = minres(re);
201    }
202  else
203    {
204      list re = mres(I,0);
205    }
206
207  int f = nvars(basering);
208  int cod;
209  ideal ann;
210  int g = nvars(basering) - e;
211  while(f > g)
212    {
213      ann = AnnExtEHV(f,re);
214      cod = nvars(basering) - dim(groebner(ann));
215      if( cod == f )
216        {
217          I = quotient(I,ann);
218        }
219      f = f-1;
220    }
221  return(I);
222}
223
224example
225{
226  "EXAMPLE:";
227  echo = 2;
228  ring  r = 0,(x,y,z),dp;
229  ideal I = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
230  removeComponent(I,1);
231}
232
233
234/////////////////////////////////////////////////////////////////////
235proc AssOfDim(ideal I, int e)
236"USAGE:   AssOfDim(I,e); I ideal, e integer
237RETURN:  ideal, such that the associated primes are exactly
238         the associated primes of I having dimension e
239EXAMPLE: example AssOfDim; shows an example"
240{
241  if(attrib(basering,"global")==0)
242    {
243      ERROR("// Not implemented for this ordering, please change to global ordering.");
244    }
245  int g = nvars(basering) - e;
246
247  //Compute a resolution of I.
248  ideal J = std(I);
249  if(homog(I)==1)
250    {
251      list re = sres(J,g+1);
252      re = minres(re);
253    }
254  else
255    {
256      list re = mres(I,g+1);
257    }
258
259  ideal ann = AnnExtEHV(g,re);
260  int cod = nvars(basering) - dim(std(ann));
261
262  //If the codimension of I_g:=Ann(Ext^g(R/I,R)) equals g...
263  if(cod == g)
264    {
265      //...then return the equidimensional part of I_g...
266      ann = equiMaxEHV(ann);
267      attrib(ann,"isEquidimensional",1);
268      return(ann);
269    }
270  //...otherwise...
271  else
272    {
273      //...I has no associated primes of dimension e.
274      return(ideal(1));
275    }
276}
277
278example
279{
280  "EXAMPLE:";
281  echo = 2;
282  ring  r = 0,(x,y,z),dp;
283  ideal I = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
284  AssOfDim(I,1);
285}
286
287/////////////////////////////////////////////////////////////////////
288//                                                                 //
289//                      T H E   R A D I C A L                      //
290//                                                                 //
291/////////////////////////////////////////////////////////////////////
292
293/////////////////////////////////////////////////////////////////////
294static proc aJacob(ideal I, int a)
295"USAGE:   aJacob(I,a); I ideal, a integer
296RETURN:  ideal, the ath-Jacobian ideal of I"
297{
298  matrix M = jacob(I);
299  int n = nvars(basering);
300  if(n-a <= 0)
301    {
302      return(ideal(1));
303    }
304  if(n-a > nrows(M) or n-a > ncols(M))
305    {
306      return(ideal(0));
307    }
308  ideal J = minor(M,n-a);
309  return(J);
310}
311
312
313/////////////////////////////////////////////////////////////////////
314proc equiRadEHV(ideal I, list #)
315"USAGE:   equiRadEHV(I [,Strategy]); I ideal, Strategy list
316RETURN:  ideal, the equidimensional radical of I,
317         i.e. the intersection of the minimal associated primes of I
318         having the same dimension as I
319NOTE:    Uses the algorithm of Eisenbud/Huneke/Vasconcelos,
320         Works only in characteristic 0 or p large.
321         The (optional) second argument determines the strategy used:
322         Strategy[1]        > strategy for the equidimensional part
323                     = 0    : uses equiMaxEHV
324                     = 1    : uses equidimMax
325         Strategy[2]        > strategy for the radical
326                     = 0    : combination of strategy 1 and 2
327                     = 1    : computation of the radical just with the
328                              help of regular sequences
329                     = 2    : does not try to find a regular sequence
330         If no second argument is given then Strategy=(0,0,0) is used.
331EXAMPLE: example equiRadEHV; shows an example"
332{
333  if(printlevel > 2){"Entering equiRadEHV.";}
334  if(attrib(basering,"global")==0)
335    {
336      ERROR("// Not implemented for this ordering, please change to global ordering.");
337    }
338  if((char(basering)<100)&&(char(basering)!=0))
339    {
340      "WARNING: The characteristic is too small, the result may be wrong";
341    }
342
343  //Define the Strategy to be used.
344  if(size(#) > 0)
345    {
346      if(#[1]!=1)
347        {
348          int equStr = 0;
349        }
350      else
351        {
352          int equStr = 1;
353        }
354      if(size(#) > 1)
355        {
356          if(#[2]!=1 and #[2]!=2)
357            {
358              int strategy = 0;
359            }
360          else
361            {
362              int strategy = #[2];
363            }
364        }
365      else
366        {
367          int strategy = 0;
368        }
369    }
370  else
371    {
372      int equStr = 0;
373      int strategy = 0;
374    }
375
376  ideal J,I0,radI0,L,radI1,I2,radI2;
377  int l,n;
378  intvec op = option(get);
379  matrix M;
380
381  option(redSB);
382  list m = mstd(I);
383  option(set,op);
384
385  int d = dim(m[1]);
386  if(d==-1)
387    {
388      return(ideal(1));
389    }
390
391  if(strategy != 2)
392    {
393      /////////////////////////////////////////////
394      // Computing the equidimensional radical   //
395      // via regular sequenves                   //
396      /////////////////////////////////////////////
397
398      if(printlevel > 2){"Trying to find a regular sequence.";}
399      int cod = nvars(basering)-d;
400
401      //Complete intersection case:
402      if(cod==size(m[2]))
403        {
404          J = aJacob(m[2],d);
405          if(printlevel > 2){"Leaving equiRadEHV.";}
406          return(quotient(m[2],J));
407        }
408
409      //First codim elements of I are a complete intersection:
410      for(l=1; l<=cod; l++)
411        {
412          I0[l] = m[2][l];
413        }
414      n = dim(groebner(I0))+cod-nvars(basering);
415
416      //Last codim elements of I are a complete intersection:
417      if(n!=0)
418              {
419          for(l=1; l<=cod; l++)
420            {
421              I0[l] = m[2][size(m[2])-l+1];
422            }
423          n = dim(groebner(I0))+cod-nvars(basering);
424        }
425
426      //Taking a generic linear combination of the input:
427      if(n!=0)
428              {
429          M = transpose(sparsetriag(size(m[2]),cod,95,1));
430          I0 = ideal(M*transpose(m[2]));
431          n = dim(groebner(I0))+cod-nvars(basering);
432        }
433
434      //Taking a more generic linear combination of the input:
435      if(n!=0)
436        {
437          while(strategy == 1 and n!=0)
438            {
439              M = transpose(sparsetriag(size(m[2]),cod,0,100));
440              I0 = ideal(M*transpose(m[2]));
441              n = dim(groebner(I0))+cod-nvars(basering);
442            }
443        }
444
445      if(n==0)
446        {
447          J = aJacob(I0,d);
448          if(printlevel > 2){"1st quotient.";}
449          radI0 = quotient(I0,J);
450          if(printlevel > 2){"2nd quotient.";}
451          L = quotient(radI0,m[2]);
452          if(printlevel > 2){"3rd quotient.";}
453          radI1 = quotient(radI0,L);
454          attrib(radI1,"isEquidimensional",1);
455          attrib(radI1,"isRadical",1);
456          if(printlevel > 2){"Leaving equiRadEHV.";}
457          return(radI1);
458        }
459    }
460
461  ////////////////////////////////////////////////////
462  // Computing the equidimensional radical directly //
463  ////////////////////////////////////////////////////
464
465  if(printlevel > 2){"Computing the equidimensional radical directly";}
466
467  //Compute the equidimensional part depending on the chosen strategy
468  if(equStr == 0)
469    {
470      I = equiMaxEHV(I);
471    }
472  if(equStr == 1)
473    {
474      I = equidimMax(I);
475    }
476  int a = nvars(basering)-1;
477
478  while(a > d)
479    {
480      if(printlevel > 2){"While-Loop: "+string(a);}
481      J = aJacob(I,a);
482      while(dim(groebner(J+I))==d)
483        {
484          if(printlevel > 2){"Quotient-Computation.";}
485          I = quotient(I,J);
486          if(printlevel > 2){"Computing the a-th Jacobian";}
487            J = aJacob(I,a);
488        }
489      a = a-1;
490    }
491  if(printlevel > 2){"We left While-Loop.";}
492  if(printlevel > 2){"Computing the a-th Jacobian";}
493  J = aJacob(I,d);
494  if(printlevel > 2){"Quotient-Computation.";}
495  I = quotient(I,J);
496  attrib(I,"isEquidimensional",1);
497  attrib(I,"isRadical",1);
498  if(printlevel > 2){"Leaving equiRadEHV.";}
499  return(I);
500}
501
502example
503{
504  "EXAMPLE:";
505  echo = 2;
506  ring  r = 0,(x,y,z),dp;
507  poly  p = z2+1;
508  poly  q = z3+2;
509  ideal i = p*q^2,y-z2;
510  ideal pr= equiRadEHV(i);
511  pr;
512}
513
514/////////////////////////////////////////////////////////////////////
515proc radEHV(ideal I, list #)
516"USAGE:   radEHV(I [,Strategy]); ideal I, Strategy list
517RETURN:  ideal, the radical of I
518NOTE:    uses the algorithm of Eisenbud/Huneke/Vasconcelos
519         Works only in characteristic 0 or p large.
520         The (optional) second argument determines the strategy used:
521         Strategy[1]        > strategy for the equidimensional part
522                     = 0    : uses equiMaxEHV
523                     = 1    : uses equidimMax
524         Strategy[2]        > strategy for the radical
525                     = 0    : combination of strategy 1 and 2
526                     = 1    : computation of the radical just with the
527                              help of regular sequences
528                     = 2    : does not try to find a regular sequence
529         Strategy[3]        > strategy for the computation of ideal quotients
530                     = n    : uses quot(.,.,n) for the ideal quotient computations
531         If no second argument is given then Strategy=(0,0,0) is used.
532EXAMPLE: example radEHV; shows an example"
533{
534  if(printlevel > 2){"Entering radEHV.";}
535  if(attrib(basering,"global")==0)
536    {
537      ERROR("// Not implemented for this ordering, please change to global ordering.");
538    }
539  if (size(I) == 0)  { return( ideal(0) ); }
540  //Compute the equidimensional radical J of I.
541  ideal J = equiRadEHV(I,#);
542
543  //If I is the entire ring...
544  if(deg(J[1]) <= 0)
545    {
546      //...then return the ideal generated by 1...
547      return(ideal(1));
548    }
549
550  //...else remove the maximal dimensional components and
551  //compute the radical K of the lower dimensional components ...
552  ideal K = radEHV(sat(I,J)[1],#);
553
554  //..and intersect it with J.
555  K = intersect(J,K);
556  attrib(K,"isRadical",1);
557  return(K);
558}
559
560example
561{
562  "EXAMPLE:";
563  echo = 2;
564  ring  r = 0,(x,y,z),dp;
565  poly  p = z2+1;
566  poly  q = z3+2;
567  ideal i = p*q^2,y-z2;
568  ideal pr= radical(i);
569  pr;
570}
571
572/////////////////////////////////////////////////////////////////////
573proc IntAssOfDim1(ideal I, int e)
574"USAGE:   IntAssOfDim1(I,e); I idea, e integer
575RETURN:  ideal, the intersection of the associated primes of I having dimension e
576EXAMPLE: example IntAssOfDim1; shows an example"
577{
578  if(attrib(basering,"global")==0)
579    {
580      ERROR("// Not implemented for this ordering, please change to global ordering.");
581    }
582  int g = nvars(basering) - e;
583
584  //Compute a resolution of I.
585  ideal J = groebner(I);
586  if(homog(I)==1)
587    {
588      list re = sres(J,g+1);
589      re = minres(re);
590    }
591  else
592    {
593      list re = mres(I,g+1);
594    }
595
596  ideal ann = AnnExtEHV(g,re);
597  int cod = nvars(basering) - dim(groebner(ann));
598  //If the codimension of I_g:=Ann(Ext^g(R/I,I)) equals g...
599  if(cod == g)
600    {
601      //...then return the equidimensional radical of I_g...
602      ann = equiRadEHV(ann);
603      attrib(ann,"isEquidimensional",1);
604      attrib(ann,"isRadical",1);
605      return(ann);
606    }
607  else
608    {
609      //...else I has no associated primes of dimension e.
610      return(ideal(1));
611    }
612}
613
614example
615{
616  "EXAMPLE:";
617  echo = 2;
618  ring  r = 0,(x,y,z),dp;
619  ideal I = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
620  IntAssOfDim1(I,1);
621}
622
623/////////////////////////////////////////////////////////////////////
624proc IntAssOfDim2(ideal I, int e)
625"USAGE:   IntAssOfDim2(I,e); I ideal, e integer
626RETURN:  ideal, the intersection of the associated primes of I having dimension e
627EXAMPLE: example IntAssOfDim2; shows an example"
628{
629  if(attrib(basering,"global")==0)
630    {
631      ERROR("// Not implemented for this ordering, please change to global ordering.");
632    }
633  ideal I1 = removeComponent(I,e);
634  ideal I2 = removeComponent(I,e+1);
635  ideal b = quotient(I1,I2);
636  b = equiRadEHV(b);
637  return(b);
638}
639
640example
641{
642  "EXAMPLE:";
643  echo = 2;
644  ring  r = 0,(x,y,z),dp;
645  ideal I = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
646  IntAssOfDim2(I,1);
647}
648
649
650/////////////////////////////////////////////////////////////////////
651//                                                                 //
652//   Z E R O - D I M E N S I O N A L   D E C O M P O S I T I O N   //
653//                                                                 //
654/////////////////////////////////////////////////////////////////////
655
656/////////////////////////////////////////////////////////////////////
657proc decompEHV(ideal I)
658"USAGE:   decompEHV(I); I zero-dimensional radical ideal
659RETURN:  list, the associated primes of I
660EXAMPLE: example decompEHV; shows an example"
661{
662  if(printlevel > 2){"Entering decompEHV.";}
663  if(attrib(basering,"global")==0)
664    {
665      ERROR("// Not implemented for this ordering, please change to global ordering.");
666    }
667
668  int e,m,vd,nfact;
669  list l,k,L;
670  poly f,h;
671  ideal J;
672  def base = basering;
673
674  if( attrib(I,"isSB")!=1 )
675    {
676      I = groebner(I);
677    }
678
679  while(1)
680    {
681      //Choose a random polynomial f from R.
682      e = random(0,100);
683      f = sparsepoly(e);
684
685      //Check if f lies not in I.
686      if(reduce(f,I)!=0)
687        {
688          J = quotient1(I,f);
689
690          //If f is a zerodivisor modulo I...
691          if( isSubset(J,I) == 0 )
692            {
693              //...then use recursion...
694              if(printlevel > 2){"We found a zerodivisor -- recursion";}
695              l = decompEHV(J) + decompEHV(I+f);
696              return(l);
697            }
698          if(printlevel > 2){"We found a non-zero-divisor.";}
699
700          //...else compute the vectorspace dimension vd of I and...
701          vd = vdim(I);
702
703          //...compute m minimal such that 1,f,f^2,...,f^m are linearly dependent.
704          qring Q = I;
705          poly g = fetch(base,f);
706          k = algDependent(g);
707          def R = k[2];
708          setring R;
709          if(size(ker)!=1)
710            {
711              //Calculate a generator for ker.
712              ker = mstd(ker)[2];
713            }
714          poly g = ker[1];
715          m = deg(g);
716
717          //If m and vd coincide...
718          if(m==vd)
719            {
720              if(printlevel > 2){"We have a good candidate.";}
721              //...then factorize g.
722              if(printlevel > 2){"Factorizing.";}
723              L = factorize(g,2);    //returns non-constant factors and multiplicities
724              nfact = size(L[1]);
725
726              //If g is irreducible...
727              if(nfact==1 and L[2][1]==1)
728                {
729                  if(printlevel > 2){"The element is irreducible.";}
730                  setring base;
731                  //..then I is a maximal ideal...
732                  l[1] = I;
733                  kill R,Q;
734                  return(l);
735                }
736              //...else...
737              else
738                {
739
740                  if(printlevel > 2){"The element is not irreducible -- recursion.";}
741                  //...take a non-trivial factor g1 of g ...
742                  poly g1 = L[1][1];
743                  //..and insert f in g1...
744                  ring newR = create_ring(ringlist(R)[1], "(y(1))", "(" + ordstr(R) + ")", "no_minpoly");
745                  poly g2 = imap(R,g1);
746                  setring base;
747                  h = fetch(newR,g2);
748                  h = subst(h,var(1),f);
749                  //...and use recursion...
750                  kill R,Q,newR;
751                  l = l + decompEHV(quotient1(I,h));
752                  l = l + decompEHV(I+h);
753                  return(l);
754                }
755            }
756          setring base;
757          kill R,Q;
758          }
759    }
760}
761
762example
763{
764  "EXAMPLE:";
765  echo = 2;
766  ring r = 32003,(x,y),dp;
767  ideal i = x2+y2-10,x2+xy+2y2-16;
768  decompEHV(i);
769}
770
771
772/////////////////////////////////////////////////////////////////////
773//                                                                 //
774//           A S S O C I A T E D   P R I M E S                     //
775//                                                                 //
776/////////////////////////////////////////////////////////////////////
777
778
779/////////////////////////////////////////////////////////////////////
780static proc idempotent(ideal I)
781"USAGE:   idempotent(I); ideal I (weighted) homogeneous radical ideal,
782         I intersected K[x(1),...,x(k)] zero-dimensional
783         where deg(x(i))=0 for all i <= k and deg(x(i))>0 for all i>k.
784RETURN:  a list of ideals I(1),...,I(t) such that
785         K[x]/I = K[x]/I(1) x ... x K[x]/I(t)"
786{
787  if(printlevel > 2){"Entering idempotent.";}
788  if(attrib(basering,"global")==0)
789    {
790      ERROR("// Not implemented for this ordering, please change to global ordering.");
791    }
792  int n = nvars(basering);
793  poly f,g;
794  string j;
795  int i,k,splits;
796  list l;
797
798  //Collect all variables of degree 0.
799  for(i=1; i<=n; i++)
800    {
801      if(deg(var(i)) > 0)
802        {
803          f = f*var(i);
804        }
805      else
806        {
807          splits = 1;
808          j = j +  string(var(i)) + "," ;
809        }
810    }
811  //If there are no variables of degree 0
812  //then there are no idempotents and we are done...
813  if(splits == 0)
814    {
815      l[1]=I;
816      return(l);
817    }
818
819  //...else compute J = I intersected K[x(1),...,x(k)]...
820  ideal J = eliminate(I,f);
821  def base = basering;
822  j = j[1,size(j)-1];
823  ring @r = create_ring(ringlist(basering)[1], (" + j + "), "(" + ordstr(basering) + ")", "no_minpoly");
824  ideal J = imap(base,J);
825
826  //...and compute the associated primes of the zero-dimensional ideal J.
827  list L = decompEHV(J);
828  int s = size(L);
829  ideal K,Z;
830  poly g;
831  //For each associated prime ideal P_i of J...
832  for(i=1; i<=s; i++)
833    {
834      K = ideal(1);
835      //...comnpute the intersection K of the other associated prime ideals...
836      for(k=1; k<=s; k++)
837        {
838          if(i!=k)
839            {
840              K = intersect(K,L[k]);
841            }
842        }
843
844      //...and find an element that lies in K but not in P_i...
845      g = randomid(K,1)[1];
846      Z = L[i];
847      Z = std(Z);
848      while(reduce(g,Z)==0)
849        {
850          g = randomid(K,1)[1];
851        }
852      setring base;
853      g = imap(@r,g);
854      //...and compute the corresponding ideal I(i)
855      l[i] = quotient(I,g);
856      setring @r;
857
858    }
859  setring base;
860  return(l);
861}
862
863
864/////////////////////////////////////////////////////////////////////
865static proc equiAssEHV(ideal I)
866"USAGE:   equiAssEHV(I); I equidimensional, radical, and homogeneous ideal
867RETURN:  a list, the associated prime ideals of I"
868{
869  if(printlevel > 2){"Entering equiAssEHV.";}
870  if(attrib(basering,"global")==0)
871    {
872      ERROR("// Not implemented for this ordering, please change to global ordering.");
873    }
874  list L;
875  def base = basering;
876  int n = nvars(basering);
877  int i,j;
878
879  //Compute the normalization of I.
880  if(printlevel > 2){"Entering Normalization.";}
881  list norOut = normal(I, "noDeco");
882  list K = norOut[1];
883  if(printlevel > 2){"Leaving Normalisation.";}
884
885  //The normalization algorithm returns k factors.
886  int k = size(K);
887  if(printlevel > 1){"Normalization algorithm splits ideal in " + string(k) + " factors.";}
888
889  //Examine each factor of the normalization.
890  def P;
891  for(i=1; i<=k; i++)
892    {
893      P = K[i];
894      setring P;
895
896      //Use procedure idempotent to split the i-th factor of
897      //the normalization in a product of integral domains.
898      if(printlevel > 1){"Examining " + string(i) +". factor.";}
899      list l = idempotent(norid);
900      int leng = size(l);
901      if(printlevel > 1){"Idempotent algorithm splits factor " + string(i) + " in " + string(leng) + " factors.";}
902
903      //Intersect the minimal primes corresponding to the
904      //integral domains obtained from idempotent with the groundring,
905      //i.e. compute the preimages w.r.t. the corresponding normalization map
906      ideal J;
907      for(j=1; j<=leng; j++)
908        {
909          J = l[j];
910          setring base;
911          L[size(L)+1] = preimage(P,normap,J);
912          setring P;
913        }
914      kill l, leng, J;
915      setring base;
916    }
917
918  return(L);
919}
920
921
922/////////////////////////////////////////////////////////////////////
923proc AssEHV(ideal I, list #)
924"USAGE:  AssEHV(I [,Strategy]); I Ideal, Strategy list
925RETURN:  a list, the associated prime ideals of I
926NOTE:    Uses the algorithm of Eisenbud/Huneke/Vasconcelos.
927         The (optional) second argument determines the strategy used:
928         Strategy[1]        > strategy for the equidimensional part
929                     = 0    : uses equiMaxEHV
930                     = 1    : uses equidimMax
931         Strategy[2]        > strategy for the equidimensional radical
932                     = 0    : uses equiRadEHV
933                     = 1    : uses equiRadical
934         Strategy[3]        > strategy for equiRadEHV
935                     = 0    : combination of strategy 1 and 2
936                     = 1    : computation of the radical just with the
937                              help of regular sequences
938                     = 2    : does not try to find a regular sequence
939         Strategy[4]        > strategy for the computation of ideal quotients
940                     = n    : uses quot(.,.,n) for the ideal quotient computations
941         If no second argument is given, Strategy=(0,0,0,0) is used.
942EXAMPLE: example AssEHV; shows an example"
943{
944  if(attrib(basering,"global")==0)
945    {
946      ERROR("// Not implemented for this ordering, please change to global ordering.");
947    }
948  if(printlevel > 2){"Entering AssEHV";}
949
950  //Specify the strategy to be used.
951  if(size(#)==0)
952    {
953      # = 0,0,0,0;
954    }
955  if(size(#)==1)
956    {
957      # = #[1],0,0,0;
958    }
959  if(size(#)==2)
960    {
961      # = #[1],#[2],0,0;
962    }
963  if(size(#)==3)
964    {
965      # = #[1],#[2],#[3],0;
966    }
967
968  list L;
969  ideal K;
970  def base = basering;
971  int m,j;
972  ideal J = groebner(I);
973  int n = nvars(basering);
974  int d = dim(J);
975
976  //Compute a resolution of I.
977  if(printlevel > 2){"Computing resolution.";}
978  if(homog(I)==1)
979    {
980      list re = sres(J,0);
981      re = minres(re);
982    }
983  else
984    {
985      list re = mres(I,0);
986    }
987  ideal ann;
988  int cod;
989
990  //For 0<=i<= dim(I) compute the intersection of the i-dimensional associated primes of I
991  for(int i=0; i<=d; i++)
992    {
993      if(printlevel > 1){"Are there components of dimension " + string(i) + "?";}
994      ann = AnnExtEHV(n-i,re);
995      cod = n - dim(groebner(ann));
996
997      //If there are associated primes of dimension i...
998      if(cod == n-i)
999        {
1000          if(printlevel > 1){"Yes. There are components of dimension " + string(i) + ".";}
1001          //...then compute the intersection K of all associated primes of I of dimension i
1002          if(#[2]==0)
1003            {
1004              if(size(#) > 3)
1005                {
1006                  K = equiRadEHV(ann,#[1],#[3],#[4]);
1007                }
1008              if(size(#) > 2)
1009                {
1010                  K = equiRadEHV(ann,#[1],#[3]);
1011                }
1012              else
1013                {
1014                  K = equiRadEHV(ann,#[1]);
1015                }
1016            }
1017          if(#[2]==1)
1018            {
1019              K = equiRadical(ann);
1020            }
1021          attrib(K,"isEquidimensional",1);
1022          attrib(K,"isRadical",1);
1023
1024          //If K is already homogeneous then use equiAssEHV to recover the associated primes of K...
1025           if(homog(K)==1)
1026            {
1027              if(printlevel > 2){"Input already homogeneous.";}
1028              L = L + equiAssEHV(K);
1029            }
1030
1031          //...else...
1032          else
1033            {
1034              //...homogenize K w.r.t. t,...
1035              if(printlevel > 2){"Input not homogeneous; must homogenize.";}
1036              def homoR=changeord(list(list("dp",1:nvars(basering))));
1037              setring homoR;
1038              ideal homoJ = fetch(base,K);
1039              homoJ = groebner(homoJ);
1040              list l2;
1041              for (int ii = 1; ii <= n; ii++)
1042              {
1043                l2[i] = "x("+string(ii)+")";
1044              }
1045              l2[size(l2)+1] = "t";
1046              ring newR = create_ring(ringlist(base)[1], l2, "dp", "no_minpoly");
1047              ideal homoK = fetch(homoR,homoJ);
1048              homoK = homog(homoK,t);
1049              attrib(homoK,"isEquidimensional",1);
1050              attrib(homoK,"isRadical",1);
1051
1052              //...compute the associated primes of the homogenization using equiAssEHV,...
1053              list l = equiAssEHV(homoK);
1054
1055              //...and set t=1 in the generators of the associated primes just computed.
1056              ideal Z;
1057              for(j=1; j<=size(l); j++)
1058                {
1059                  Z = subst(l[j],t,1);
1060                  setring base;
1061                  L[size(L)+1] = fetch(newR,Z);
1062                  setring newR;
1063                }
1064              setring base;
1065              kill homoR;
1066              kill newR;
1067            }
1068        }
1069      else
1070        {
1071          if(printlevel > 1){"No. There are no components of dimension " + string(i) + ".";}
1072        }
1073    }
1074  return(L);
1075}
1076
1077example
1078{
1079  "EXAMPLE:";
1080  echo = 2;
1081  ring  r = 0,(x,y,z),dp;
1082  poly  p = z2+1;
1083  poly  q = z3+2;
1084  ideal i = p*q^2,y-z2;
1085  list pr = AssEHV(i);
1086  pr;
1087}
1088
1089/////////////////////////////////////////////////////////////////////
1090proc minAssEHV(ideal I, list #)
1091"USAGE:  minAssEHV(I [,Strategy]); I ideal, Strategy list
1092RETURN:  a list, the minimal associated prime ideals of I
1093NOTE:    Uses the algorithm of Eisenbud/Huneke/Vasconcelos.
1094         The (optional) second argument determines the strategy used:
1095         Strategy[1]        > strategy for the equidimensional part
1096                     = 0    : uses equiMaxEHV
1097                     = 1    : uses equidimMax
1098         Strategy[2]        > strategy for the equidimensional radical
1099                     = 0    : uses equiRadEHV, resp. radicalEHV
1100                     = 1    : uses equiRadical, resp. radical
1101         Strategy[3]        > strategy for equiRadEHV
1102                     = 0    : combination of strategy 1 and 2
1103                     = 1    : computation of the radical just with the
1104                              help of regular sequences
1105                     = 2    : does not try to find a regular sequence
1106         Strategy[4]        > strategy for the computation of ideal quotients
1107                     = n    : uses quot(.,.,n) for the ideal quotient computations
1108         If no second argument is given, Strategy=(0,0,0,0) is used.
1109EXAMPLE: example minAssEHV; shows an example"
1110{
1111  if(attrib(basering,"global")==0)
1112    {ERROR("// Not implemented for this ordering, please change to global ordering.");}
1113
1114  //Specify the strategy to be used.
1115  if(size(#)==0)
1116    {
1117      # = 0,0,0,0;
1118    }
1119  if(size(#)==1)
1120    {
1121      # = #[1],0,0,0;
1122    }
1123  if(size(#)==2)
1124    {
1125      # = #[1],#[2],0,0;
1126    }
1127  if(size(#)==3)
1128    {
1129      # = #[1],#[2],#[3],0;
1130    }
1131
1132  //Compute the radical of I.
1133  if(#[2]==0)
1134    {
1135      I = radEHV(I,#);
1136    }
1137  if(#[2]==1)
1138    {
1139      I = radical(I);
1140    }
1141
1142  //Compute the associated primes of the radical.
1143  return(AssEHV(I,#));
1144}
1145
1146example
1147{
1148  "EXAMPLE:";
1149  echo = 2;
1150  ring  r = 0,(x,y,z),dp;
1151  poly  p = z2+1;
1152  poly  q = z3+2;
1153  ideal i = p*q^2,y-z2;
1154  list pr = minAssEHV(i);
1155  pr;
1156}
1157
1158
1159/////////////////////////////////////////////////////////////////////
1160//                                                                 //
1161//        P R I M A R Y   D E C O M P O S I T I O N                //
1162//                                                                 //
1163/////////////////////////////////////////////////////////////////////
1164
1165
1166/////////////////////////////////////////////////////////////////////
1167proc localize(ideal I, ideal P, list l)
1168"USAGE:   localize(I,P,l); I ideal, P an associated prime ideal of I,
1169         l list of all associated primes of I
1170RETURN:  ideal,  the contraction of the ideal generated by I
1171         in the localization w.r.t P
1172EXAMPLE: example localize; shows an example"
1173{
1174  if(attrib(basering,"global")==0)
1175    {
1176      ERROR("// Not implemented for this ordering, please change to global ordering.");
1177    }
1178
1179  ideal Intersection = ideal(1);
1180  int s = size(l);
1181  if(attrib(P,"isSB")!=1)
1182    {
1183      P = groebner(P);
1184    }
1185
1186  //Compute the intersection of all associated primes of I that are not contained in P.
1187  for(int i=1; i<=s; i++)
1188    {
1189      if(isSubset(l[i],P)!=1)
1190        {
1191          Intersection = intersect(Intersection,l[i]);
1192        }
1193    }
1194  Intersection = groebner(Intersection);
1195
1196  //If the intersection is the entire ring...
1197  if(reduce(1,Intersection)==0)
1198    {
1199      //...then return I...
1200      return(I);
1201    }
1202  //...else try to find an element f that lies in the intersection but outside P...
1203  poly f = 0;
1204  while(reduce(f,P) == 0)
1205    {
1206      f = randomid(Intersection,1)[1];
1207    }
1208
1209  //...and saturate I w.r.t. f.
1210  I = sat(I,f)[1];
1211  return(I);
1212}
1213
1214/////////////////////////////////////////////////////////////////////
1215proc componentEHV(ideal I, ideal P, list L, list #)
1216"USAGE:   componentEHV(I,P,L [,Strategy]);
1217         I ideal, P associated prime of I,
1218         L list of all associated primes of I, Strategy list
1219RETURN:  ideal, a P-primary component Q for I
1220NOTE:    The (optional) second argument determines the strategy used:
1221         Strategy[1]        > strategy for equidimensional part
1222                     = 0    : uses equiMaxEHV
1223                     = 1    : uses equidimMax
1224         If no second argument is given then Strategy=0 is used.
1225EXAMPLE: example componentEHV; shows an example"
1226{
1227  if(printlevel > 2){"Entering componentEHV.";}
1228  if(attrib(basering,"global")==0)
1229    {
1230      ERROR("// Not implemented for this ordering, please change to global ordering.");
1231    }
1232
1233  //If no strategy is specified use standard strategy.
1234  if(size(#)==0)
1235    {
1236      # = 0;
1237    }
1238
1239  ideal T = P;
1240  ideal Q;
1241
1242  //Compute the localization of I at P...
1243  ideal IP = groebner(localize(I,P,L));
1244
1245  //...and compute the saturation of the localization w.r.t. P.
1246  ideal IP2 = sat(IP,P)[1];
1247
1248  //As long as we have not found a primary component...
1249  int isPrimaryComponent = 0;
1250  while(isPrimaryComponent!=1)
1251    {
1252      //...compute the equidimensional part Q of I+P^n...
1253      if(#[1]==0)
1254        {
1255          Q = equiMaxEHV(I+T);
1256        }
1257      if(#[1]==1)
1258        {
1259          Q = equidimMax(I+T);
1260        }
1261      //...and check if it is a primary component for P.
1262      if(isSubset(intersect(IP2,Q),IP)==1)
1263        {
1264          isPrimaryComponent = 1;
1265        }
1266      else
1267        {
1268          T = T*P;
1269        }
1270    }
1271  if(printlevel > 2){"Leaving componentEHV.";}
1272  return(Q);
1273}
1274
1275example
1276{
1277  "EXAMPLE:";
1278  echo = 2;
1279  ring  r = 0,(x,y,z),dp;
1280  poly  p = z2+1;
1281  poly  q = z3+2;
1282  ideal i = p*q^2,y-z2;
1283  list pr = AssEHV(i);
1284  componentEHV(i,pr[1],pr);
1285}
1286
1287
1288/////////////////////////////////////////////////////////////////////
1289proc primdecEHV(ideal I, list #)
1290"USAGE:   primdecEHV(I [,Strategy]); I ideal, Strategy list
1291RETURN:  a list pr of primary ideals and their associated primes:
1292                pr[i][1]   the i-th primary component,
1293                pr[i][2]   the i-th prime component.
1294NOTE:    Algorithm of Eisenbud/Huneke/Vasconcelos.
1295         The (optional) second argument determines the strategy used:
1296         Strategy[1]        > strategy for equidimensional part
1297                     = 0    : uses equiMaxEHV
1298                     = 1    : uses equidimMax
1299         Strategy[2]        > strategy for equidimensional radical
1300                     = 0    : uses equiRadEHV, resp. radicalEHV
1301                     = 1    : uses equiRadical, resp. radical
1302         Strategy[3]        > strategy for equiRadEHV
1303                     = 0    : combination of strategy 1 and 2
1304                     = 1    : computation of the radical just with the
1305                              help of regular sequences
1306                     = 2    : does not try to find a regular sequence
1307         Strategy[4]        > strategy for the computation of ideal quotients
1308                     = n    : uses quot(.,.,n) for the ideal quotient computations
1309         If no second argument is given then Strategy=(0,0,0,0) is used.
1310EXAMPLE: example primdecEHV; shows an example"
1311{
1312  if(printlevel > 2){"Entering primdecEHV.";}
1313  if(attrib(basering,"global")==0)
1314    {
1315      ERROR("// Not implemented for this ordering, please change to global ordering.");
1316    }
1317  list L,K;
1318
1319  //Specify the strategy to be used.
1320  if(size(#)==0)
1321    {
1322      # = 0,0,0,0;
1323    }
1324  if(size(#)==1)
1325    {
1326      # = #[1],0,0,0;
1327    }
1328  if(size(#)==2)
1329    {
1330      # = #[1],#[2],0,0;
1331    }
1332  if(size(#)==3)
1333    {
1334      # = #[1],#[2],#[3],0;
1335    }
1336
1337  //Compute the associated primes of I...
1338  L = AssEHV(I,#);
1339  if(printlevel > 0){"We have " + string(size(L)) + " prime components.";}
1340
1341  //...and compute for each associated prime of I a corresponding primary component.
1342  int l = size(L);
1343  for(int i=1; i<=l; i++)
1344    {
1345      K[i] = list();
1346      K[i][2] = L[i];
1347      K[i][1] = componentEHV(I,L[i],L,#[1]);
1348    }
1349  if(printlevel > 2){"Leaving primdecEHV.";}
1350  return(K);
1351
1352}
1353
1354example
1355{
1356  "EXAMPLE:";
1357  echo = 2;
1358  ring  r = 0,(x,y,z),dp;
1359  poly  p = z2+1;
1360  poly  q = z3+2;
1361  ideal i = p*q^2,y-z2;
1362  list pr = primdecEHV(i);
1363  pr;
1364}
1365
1366
1367/////////////////////////////////////////////////////////////////////
1368//                                                                 //
1369//        A L G O R I T H M S   F O R   T E S T I N G              //
1370//                                                                 //
1371/////////////////////////////////////////////////////////////////////
1372proc removeRedundantComponents(list primdecResult)
1373"USAGE:   removeRedundantComponents(L); L a primary decomposition
1374RETURN:  an irredundant primary decomposition.
1375EXAMPLE: example removeRedundantComponents; shows an example"
1376proc removeRedundantComponents(list primdecResult)
1377{
1378   int i,j;
1379
1380   i = 1;
1381   j = 1;
1382   while  ( i<=size(primdecResult) )
1383   {
1384     ASSUME(1, i>0 &&  i<=size(primdecResult) );
1385     ASSUME(1, j>0 &&  j<=size(primdecResult) );
1386
1387      if (i!=j)
1388      {
1389          if ( isSubset( std(primdecResult[j][1]) , std(primdecResult[i][1]) ) )
1390          {
1391              primdecResult[i] =  primdecResult[j];
1392              primdecResult = delete(primdecResult,j);
1393              j = j - 1; /*correct j due to deletion */
1394              if ( j<i )  {    i = i -1;   } /*correct i */
1395          }
1396      }
1397      j = j + 1;
1398      if ( j > size(primdecResult) )
1399      {
1400         i = i + 1;
1401         j = 1;
1402      }
1403   }
1404
1405   return (primdecResult);
1406}
1407example
1408{
1409  "EXAMPLE:";
1410  ring rng = 0,(x,y),dp;
1411  def L1 = list(list(ideal(x-1),ideal(x-1)),list(ideal(x-1),ideal(x-1)),list(ideal(y-2),ideal(y-2)));
1412  def L2 = list(list(ideal(x-1),ideal(x-1)),list(ideal(y-2),ideal(y-2)));
1413  L1;
1414  L2;
1415  ASSUME(0, primDecsAreEquivalent( L1, L2 ) );
1416}
1417
1418/////////////////////////////////////////////////////////////////////
1419proc primDecsAreEquivalent(list L, list K)
1420"USAGE:   primDecsAreEquivalent(L,K); L,K list of ideals
1421RETURN:  integer, 1 if the lists are the same up to ordering and redundant components; 0 otherwise
1422EXAMPLE: example primDecsAreEquivalent; shows an example"
1423{
1424  L = removeRedundantComponents(L);
1425  K = removeRedundantComponents(K);
1426  int s1 = size(L);
1427  int s2 = size(K);
1428  if(s1!=s2)
1429    {
1430      return(0);
1431    }
1432  list L1, K1;
1433  int i,j,t;
1434  list N;
1435  for(i=1; i<=s1; i++)
1436    {
1437      L1[i]=std(L[i][2]);
1438      K1[i]=std(K[i][2]);
1439    }
1440  for(i=1; i<=s1; i++)
1441    {
1442      for(j=1; j<=s1; j++)
1443        {
1444          if(isSubset(L1[i],K1[j]))
1445            {
1446              if(isSubset(K1[j],L1[i]))
1447                {
1448                  for(t=1; t<=size(N); t++)
1449                    {
1450                      if(N[t]==j)
1451                        {
1452                          return(0);
1453                        }
1454                    }
1455                  N[size(N)+1]=j;
1456                }
1457
1458            }
1459        }
1460    }
1461  if ( size(N) != s1 )
1462  {
1463     return(0);
1464  }
1465  return(1);
1466}
1467
1468example
1469{
1470  "EXAMPLE:";
1471  echo = 2;
1472  ring  r = 0,(x,y),dp;
1473  ideal i = x2,xy;
1474  list L1 = primdecGTZ(i);
1475  list L2 = primdecEHV(i);
1476  primDecsAreEquivalent(L1,L2);
1477}
Note: See TracBrowser for help on using the repository browser.