source: git/Singular/LIB/ehv.lib @ a6606e6

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