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

fieker-DuValspielwiese
Last change on this file since e27e47 was e27e47, checked in by Hans Schönemann <hannes@…>, 19 years ago
*** empty log message *** git-svn-id: file:///usr/local/Singular/svn/trunk@8246 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 40.1 KB
Line 
1// $Id: ehv.lib,v 1.1 2005-05-19 15:56:09 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.1 2005-05-19 15:56:09 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 K = normal(I);
903  if(printlevel > 2){"Leaving Normalisation.";}
904
905  //The normalization algorithm returns k factors.
906  int k = size(K);
907  if(printlevel > 1){"Normalization algorithm splits ideal in " + string(k) + " factors.";}
908
909  //Examine each factor of the normalization.
910  def P;
911  for(i=1; i<=k; i++)
912    {
913      P = K[i];
914      setring P;
915
916      //Use procedure idempotent to split the i-th factor of
917      //the normalization in a product of integral domains.
918      if(printlevel > 1){"Examining " + string(i) +". factor.";}
919      list l = idempotent(norid);
920      int leng = size(l);
921      if(printlevel > 1){"Idempotent algorithm splits factor " + string(i) + " in " + string(leng) + " factors.";}
922
923      //Intersect the minimal primes corresponding to the
924      //integral domains obtained from idempotent with the groundring,
925      //i.e. compute the preimages w.r.t. the corresponding normalization map
926      ideal J;
927      for(j=1; j<=leng; j++)
928        {
929          J = l[j];
930          setring base;
931          L[size(L)+1] = preimage(P,normap,J);
932          setring P;
933        }
934      kill l, leng, J;
935      setring base;
936    }
937
938  return(L);
939}
940
941
942/////////////////////////////////////////////////////////////////////
943proc AssEHV(ideal I, list #)
944"USAGE:  AssEHV(I [,Strategy]); I Ideal, Strategy list
945RETURN:  a list, the associated prime ideals of I
946NOTE:    Uses the algorithm of Eisenbud/Huneke/Vasconcelos.
947         The (optional) second argument determines the strategy used:
948         Strategy[1]        > strategy for the equidimensional part
949                     = 0    : uses equiMaxEHV
950                     = 1    : uses equidimMax
951         Strategy[2]        > strategy for the equidimensional radical
952                     = 0    : uses equiRadEHV
953                     = 1    : uses equiRadical
954         Strategy[3]        > strategy for equiRadEHV
955                     = 0    : combination of strategy 1 and 2
956                     = 1    : computation of the radical just with the
957                              help of regular sequences
958                     = 2    : does not try to find a regular sequence
959         Strategy[4]        > strategy for the computation of ideal quotients
960                     = n    : uses quot(.,.,n) for the ideal quotient computations
961         If no second argument is given, Strategy=(0,0,0,0) is used.
962EXAMPLE: example AssEHV; shows an example"
963{
964  if(ord_test(basering)!=1)
965    {
966      ERROR("// Not implemented for this ordering, please change to global ordering.");
967    }
968  if(printlevel > 2){"Entering AssEHV";}
969
970  //Specify the strategy to be used.
971  if(size(#)==0)
972    {
973      # = 0,0,0,0;
974    }
975  if(size(#)==1)
976    {
977      # = #[1],0,0,0;
978    }
979  if(size(#)==2)
980    {
981      # = #[1],#[2],0,0;
982    }
983  if(size(#)==3)
984    {
985      # = #[1],#[2],#[3],0;
986    }
987
988  list L;
989  ideal K;
990  def base = basering;
991  int m,j;
992  ideal J = groebner(I);
993  int n = nvars(basering);
994  int d = dim(J);
995
996  //Compute a resolution of I.
997  if(printlevel > 2){"Computing resolution.";}
998  if(homog(I)==1)
999    {
1000      list re = sres(J,0);
1001      re = minres(re);
1002    }
1003  else
1004    {
1005      list re = mres(I,0);
1006    }
1007  ideal ann;
1008  int cod;
1009
1010  //For 0<=i<= dim(I) compute the intersection of the i-dimensional associated primes of I
1011  for(int i=0; i<=d; i++)
1012    {
1013      if(printlevel > 1){"Are there components of dimension " + string(i) + "?";}
1014      ann = AnnExtEHV(n-i,re);
1015      cod = n - dim(groebner(ann));
1016
1017      //If there are associated primes of dimension i...
1018      if(cod == n-i)
1019        {
1020          if(printlevel > 1){"Yes. There are components of dimension " + string(i) + ".";}
1021          //...then compute the intersection K of all associated primes of I of dimension i
1022          if(#[2]==0)
1023            {
1024              if(size(#) > 3)
1025                {
1026                  K = equiRadEHV(ann,#[1],#[3],#[4]);
1027                }
1028              if(size(#) > 2)
1029                {
1030                  K = equiRadEHV(ann,#[1],#[3]);
1031                }
1032              else
1033                {
1034                  K = equiRadEHV(ann,#[1]);
1035                }
1036            }
1037          if(#[2]==1)
1038            {
1039              K = equiRadical(ann);
1040            }
1041          attrib(K,"isEquidimensional",1);
1042          attrib(K,"isRadical",1);
1043
1044          //If K is already homogeneous then use equiAssEHV to recover the associated primes of K...
1045           if(homog(K)==1)
1046            {
1047              if(printlevel > 2){"Input already homogeneous.";}
1048              L = L + equiAssEHV(K);
1049            }
1050
1051          //...else...
1052          else
1053            {
1054              //...homogenize K w.r.t. t,...
1055              if(printlevel > 2){"Input not homogeneous; must homogenize.";}
1056              changeord("homoR","dp");
1057              ideal homoJ = fetch(base,K);
1058              homoJ = groebner(homoJ);
1059              execute("ring newR = (" + charstr(base) + "),(x(1..n),t),dp;");
1060              ideal homoK = fetch(homoR,homoJ);
1061              homoK = homog(homoK,t);
1062              attrib(homoK,"isEquidimensional",1);
1063              attrib(homoK,"isRadical",1);
1064
1065              //...compute the associated primes of the homogenization using equiAssEHV,...
1066              list l = equiAssEHV(homoK);
1067
1068              //...and set t=1 in the generators of the associated primes just computed.
1069              ideal Z;
1070              for(j=1; j<=size(l); j++)
1071                {
1072                  Z = subst(l[j],t,1);
1073                  setring base;
1074                  L[size(L)+1] = fetch(newR,Z);
1075                  setring newR;
1076                }
1077              setring base;
1078              kill homoR;
1079              kill newR;
1080            }
1081        }
1082      else
1083        {
1084          if(printlevel > 1){"No. There are no components of dimension " + string(i) + ".";}
1085        }
1086    }
1087  return(L);
1088}
1089
1090example
1091{
1092  "EXAMPLE:";
1093  echo = 2;
1094  ring  r = 0,(x,y,z),dp;
1095  poly  p = z2+1;
1096  poly  q = z3+2;
1097  ideal i = p*q^2,y-z2;
1098  list pr = AssEHV(i);
1099  pr;
1100}
1101
1102/////////////////////////////////////////////////////////////////////
1103proc minAssEHV(ideal I, list #)
1104"USAGE:  minAssEHV(I [,Strategy]); I ideal, Strategy list
1105RETURN:  a list, the minimal associated prime ideals of I
1106NOTE:    Uses the algorithm of Eisenbud/Huneke/Vasconcelos.
1107         The (optional) second argument determines the strategy used:
1108         Strategy[1]        > strategy for the equidimensional part
1109                     = 0    : uses equiMaxEHV
1110                     = 1    : uses equidimMax
1111         Strategy[2]        > strategy for the equidimensional radical
1112                     = 0    : uses equiRadEHV, resp. radicalEHV
1113                     = 1    : uses equiRadical, resp. radical
1114         Strategy[3]        > strategy for equiRadEHV
1115                     = 0    : combination of strategy 1 and 2
1116                     = 1    : computation of the radical just with the
1117                              help of regular sequences
1118                     = 2    : does not try to find a regular sequence
1119         Strategy[4]        > strategy for the computation of ideal quotients
1120                     = n    : uses quot(.,.,n) for the ideal quotient computations
1121         If no second argument is given, Strategy=(0,0,0,0) is used.
1122EXAMPLE: example minAssEHV; shows an example"
1123{
1124  if(ord_test(basering)!=1)
1125    {ERROR("// Not implemented for this ordering, please change to global ordering.");}
1126
1127  //Specify the strategy to be used.
1128  if(size(#)==0)
1129    {
1130      # = 0,0,0,0;
1131    }
1132  if(size(#)==1)
1133    {
1134      # = #[1],0,0,0;
1135    }
1136  if(size(#)==2)
1137    {
1138      # = #[1],#[2],0,0;
1139    }
1140  if(size(#)==3)
1141    {
1142      # = #[1],#[2],#[3],0;
1143    }
1144
1145  //Compute the radical of I.
1146  if(#[2]==0)
1147    {
1148      I = radEHV(I,#);
1149    }
1150  if(#[2]==1)
1151    {
1152      I = radical(I);
1153    }
1154
1155  //Compute the associated primes of the radical.
1156  return(AssEHV(I,#));
1157}
1158
1159example
1160{
1161  "EXAMPLE:";
1162  echo = 2;
1163  ring  r = 0,(x,y,z),dp;
1164  poly  p = z2+1;
1165  poly  q = z3+2;
1166  ideal i = p*q^2,y-z2;
1167  list pr = minAssEHV(i);
1168  pr;
1169}
1170
1171
1172/////////////////////////////////////////////////////////////////////
1173//                                                                 //
1174//        P R I M A R Y   D E C O M P O S I T I O N                //
1175//                                                                 //
1176/////////////////////////////////////////////////////////////////////
1177
1178
1179/////////////////////////////////////////////////////////////////////
1180proc localize(ideal I, ideal P, list l)
1181"USAGE:   localize(I,P,l); I ideal, P an associated prime ideal of I,
1182         l list of all associated primes of I
1183RETURN:  ideal,  the contraction of the ideal generated by I
1184         in the localization w.r.t P
1185EXAMPLE: example localize; shows an example"
1186{
1187  if(ord_test(basering)!=1)
1188    {
1189      ERROR("// Not implemented for this ordering, please change to global ordering.");
1190    }
1191
1192  ideal Intersection = ideal(1);
1193  int s = size(l);
1194  if(attrib(P,"isSB")!=1)
1195    {
1196      P = groebner(P);
1197    }
1198
1199  //Compute the intersection of all associated primes of I that are not contained in P.
1200  for(int i=1; i<=s; i++)
1201    {
1202      if(isSubset(l[i],P)!=1)
1203        {
1204          Intersection = intersect(Intersection,l[i]);
1205        }
1206    }
1207  Intersection = groebner(Intersection);
1208
1209  //If the intersection is the entire ring...
1210  if(reduce(1,Intersection)==0)
1211    {
1212      //...then return I...
1213      return(I);
1214    }
1215  //...else try to find an element f that lies in the intersection but outside P...
1216  poly f = 0;
1217  while(reduce(f,P) == 0)
1218    {
1219      f = randomid(Intersection,1)[1];
1220    }
1221
1222  //...and saturate I w.r.t. f.
1223  I = sat(I,f)[1];
1224  return(I);
1225}
1226
1227/////////////////////////////////////////////////////////////////////
1228proc componentEHV(ideal I, ideal P, list L, list #)
1229"USAGE:   componentEHV(I,P,L [,Strategy]);
1230         I ideal, P associated prime of I,
1231         L list of all associated primes of I, Strategy list
1232RETURN:  ideal, a P-primary component Q for I
1233NOTE:    The (optional) second argument determines the strategy used:
1234         Strategy[1]        > strategy for equidimensional part
1235                     = 0    : uses equiMaxEHV
1236                     = 1    : uses equidimMax
1237         If no second argument is given then Strategy=0 is used.
1238EXAMPLE: example componentEHV; shows an example"
1239{
1240  if(printlevel > 2){"Entering componentEHV.";}
1241  if(ord_test(basering)!=1)
1242    {
1243      ERROR("// Not implemented for this ordering, please change to global ordering.");
1244    }
1245
1246  //If no strategy is specified use standard strategy.
1247  if(size(#)==0)
1248    {
1249      # = 0;
1250    }
1251
1252  ideal T = P;
1253  ideal Q;
1254
1255  //Compute the localization of I at P...
1256  ideal IP = groebner(localize(I,P,L));
1257
1258  //...and compute the saturation of the localization w.r.t. P.
1259  ideal IP2 = sat(IP,P)[1];
1260
1261  //As long as we have not found a primary component...
1262  int isPrimaryComponent = 0;
1263  while(isPrimaryComponent!=1)
1264    {
1265      //...compute the equidimensional part Q of I+P^n...
1266      if(#[1]==0)
1267        {
1268          Q = equiMaxEHV(I+T);
1269        }
1270      if(#[1]==1)
1271        {
1272          Q = equidimMax(I+T);
1273        }
1274      //...and check if it is a primary component for P.
1275      if(isSubset(intersect(IP2,Q),IP)==1)
1276        {
1277          isPrimaryComponent = 1;
1278        }
1279      else
1280        {
1281          T = T*P;
1282        }
1283    }
1284  if(printlevel > 2){"Leaving componentEHV.";}
1285  return(Q);
1286}
1287
1288example
1289{
1290  "EXAMPLE:";
1291  echo = 2;
1292  ring  r = 0,(x,y,z),dp;
1293  poly  p = z2+1;
1294  poly  q = z3+2;
1295  ideal i = p*q^2,y-z2;
1296  list pr = AssEHV(i);
1297  componentEHV(i,pr[1],pr);
1298}
1299
1300
1301/////////////////////////////////////////////////////////////////////
1302proc primdecEHV(ideal I, list #)
1303"USAGE:   primdecEHV(I [,Strategy]); I ideal, Strategy list
1304RETURN:  a list pr of primary ideals and their associated primes:
1305                pr[i][1]   the i-th primary component,
1306                pr[i][2]   the i-th prime component.
1307NOTE:    Algorithm of Eisenbud/Huneke/Vasconcelos.
1308         The (optional) second argument determines the strategy used:
1309         Strategy[1]        > strategy for equidimensional part
1310                     = 0    : uses equiMaxEHV
1311                     = 1    : uses equidimMax
1312         Strategy[2]        > strategy for equidimensional radical
1313                     = 0    : uses equiRadEHV, resp. radicalEHV
1314                     = 1    : uses equiRadical, resp. radical
1315         Strategy[3]        > strategy for equiRadEHV
1316                     = 0    : combination of strategy 1 and 2
1317                     = 1    : computation of the radical just with the
1318                              help of regular sequences
1319                     = 2    : does not try to find a regular sequence
1320         Strategy[4]        > strategy for the computation of ideal quotients
1321                     = n    : uses quot(.,.,n) for the ideal quotient computations
1322         If no second argument is given then Strategy=(0,0,0,0) is used.
1323EXAMPLE: example primdecEHV; shows an example"
1324{
1325  if(printlevel > 2){"Entering primdecEHV.";}
1326  if(ord_test(basering)!=1)
1327    {
1328      ERROR("// Not implemented for this ordering, please change to global ordering.");
1329    }
1330  list L,K;
1331
1332  //Specify the strategy to be used.
1333  if(size(#)==0)
1334    {
1335      # = 0,0,0,0;
1336    }
1337  if(size(#)==1)
1338    {
1339      # = #[1],0,0,0;
1340    }
1341  if(size(#)==2)
1342    {
1343      # = #[1],#[2],0,0;
1344    }
1345  if(size(#)==3)
1346    {
1347      # = #[1],#[2],#[3],0;
1348    }
1349
1350  //Compute the associated primes of I...
1351  L = AssEHV(I,#);
1352  if(printlevel > 0){"We have " + string(size(L)) + " prime components.";}
1353
1354  //...and compute for each associated prime of I a corresponding primary component.
1355  int l = size(L);
1356  for(int i=1; i<=l; i++)
1357    {
1358      K[i] = list();
1359      K[i][2] = L[i];
1360      K[i][1] = componentEHV(I,L[i],L,#[1]);
1361    }
1362  if(printlevel > 2){"Leaving primdecEHV.";}
1363  return(K);
1364
1365}
1366
1367example
1368{
1369  "EXAMPLE:";
1370  echo = 2;
1371  ring  r = 0,(x,y,z),dp;
1372  poly  p = z2+1;
1373  poly  q = z3+2;
1374  ideal i = p*q^2,y-z2;
1375  list pr = primdecEHV(i);
1376  pr;
1377}
1378
1379
1380/////////////////////////////////////////////////////////////////////
1381//                                                                 //
1382//        A L G O R I T H M S   F O R   T E S T I N G              //
1383//                                                                 //
1384/////////////////////////////////////////////////////////////////////
1385
1386
1387/////////////////////////////////////////////////////////////////////
1388proc compareLists(list L, list K)
1389"USAGE:   checkLists(L,K); L,K list of ideals
1390RETURN:  integer, 1 if the lists are the same up to ordering and 0 otherwise
1391EXAMPLE: example checkLists; shows an example"
1392{
1393  int s1 = size(L);
1394  int s2 = size(K);
1395  if(s1!=s2)
1396    {
1397      return(0);
1398    }
1399  list L1, K1;
1400  int i,j,t;
1401  list N;
1402  for(i=1; i<=s1; i++)
1403    {
1404      L1[i]=std(L[i][2]);
1405      K1[i]=std(K[i][2]);
1406    }
1407  for(i=1; i<=s1; i++)
1408    {
1409      for(j=1; j<=s1; j++)
1410        {
1411          if(isSubset(L1[i],K1[j]))
1412            {
1413              if(isSubset(K1[j],L1[i]))
1414                {
1415                  for(t=1; t<=size(N); t++)
1416                    {
1417                      if(N[t]==j)
1418                        {
1419                          return(0);
1420                        }
1421                    }
1422                  N[size(N)+1]=j;
1423                }
1424
1425            }
1426        }
1427    }
1428  return(1);
1429}
1430
1431example
1432{
1433  "EXAMPLE:";
1434  echo = 2;
1435  ring  r = 0,(x,y),dp;
1436  ideal i = x2,xy;
1437  list L1 = primdecGTZ(i);
1438  list L2 = primdecEHV(i);
1439  compareLists(L1,L2);
1440}
1441
Note: See TracBrowser for help on using the repository browser.