source: git/Singular/LIB/reesclos.lib @ b9b906

spielwiese
Last change on this file since b9b906 was b9b906, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: lib format revisited git-svn-id: file:///usr/local/Singular/svn/trunk@5078 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 17.5 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="$id reesclos.lib,v 1.30 2000/12/5 hirsch Exp $";
3category="Commutative Algebra";
4info="
5LIBRARY:     reesclos.lib Rees Algebra and Integral Closure of Ideals
6AUTHOR:      Tobias Hirsch, email: hirsch@math.tu-cottbus.de
7
8OVERVIEW:
9 A library to compute the integral closure of an ideal I in a polynomial ring
10 R=k[x(1),...,x(n)] using the Rees Algebra R[It] of I. It computes the integral
11 closure of R[It] (in the same manner as done in the library 'normal.lib');
12 which is a graded subalgebra of R[t]. The degree-k-component is the integral
13 closure of the k-th power of I.
14
15PROCEDURES:
16 ReesAlgebra(I);        computes the Rees Algebra of an ideal I
17 NormalI(I[,p[,r]]);    computes the integral closure of an ideal I using R[It]
18";
19
20LIB "normal.lib";       // for HomJJ
21LIB "standard.lib";     // for groebner
22
23///////////////////////////////////////////////////////////////////////////////
24
25proc ReesAlgebra (ideal I)
26"USAGE:    ReesAlgebra (I); I = ideal
27COMPUTE:  The Rees algebra R[I*t] as an affine ring, where I is an ideal in R
28RETURN:   a list containing two rings:
29          [1]: a ring, say RR; in the ring an ideal ker such that R[I*t]=RR/ker
30          [2]: a ring, say Kxt; the basering with additional variable t con-
31               taining an ideal mapI defining the map RR-->Kxt
32EXAMPLE:  example ReesAlgebra; shows an example
33"
34{
35  // remember the data of the basering
36
37  def oldring = basering;
38  string oldchar = charstr(basering);
39  string oldvar  = varstr(basering);
40  string oldord  = ordstr(basering);
41  int n = ncols(I);
42  ideal m = maxideal(1);
43
44
45  // Create a new ring with variables for each generator of I
46
47  execute ("ring Rees = "+oldchar+",("+oldvar+",U(1.."+string(n)+")),dp");
48
49
50  // Kxt is the old ring with additional variable t
51  // Here I -> t*I, so the generators of I generate the subalgebra R[It] in Kxt
52
53  execute ("ring Kxt = "+oldchar+",("+oldvar+",t),dp");
54  ideal I = fetch(oldring,I);
55  ideal m = fetch(oldring,m);
56  int k;
57  for (k=1;k<=n;k++)
58  {
59    I[k]=t*I[k];
60  }
61
62
63  // Now we map from Rees to Kxt, identity on the original variables, and
64  // U(k) -> I[k]
65
66  ideal mapI = m,I;
67  map phi = Rees,mapI;
68  ideal zero = 0;
69  export (mapI);
70
71  // Now the Rees-Algebra is Rees/ker(phi)
72
73  setring Rees;
74  ideal ker = preimage(Kxt,phi,zero);
75  export (ker);
76
77  list result = Rees,Kxt;
78
79  return(result);
80
81}
82example
83{
84  "EXAMPLE:"; echo=2;
85  ring R = 0,(x,y),dp;
86  ideal I = x2,xy4,y5;
87  list L = ReesAlgebra(I);
88  def Rees = L[1];       // defines the ring Rees, containing the ideal ker
89  setring Rees;          // passes to the ring Rees
90  Rees;
91  ker;                   // R[I*t] is isomorphic to Rees/ker
92}
93
94
95////////////////////////////////////////////////////////////////////////////
96
97static proc ClosureRees (list L)
98"USAGE:    ClosureRees (L); L a list containing
99          - a ring L[1], inside L[1] an ideal ker such that L[1]/ker is
100            isomorphic to the Rees Algebra R[It] of an ideal I in k[x]
101          - a ring L[2]=k[x,t], inside L[1] an ideal mapI defining the
102            map L[1] --> L[2] with image R[It]
103COMPUTE:  quotients of elements of k[x,t] representing generators of the
104          integral closure of R[It]
105RETURN:   a list images, the first size(images)-1 entries are the nu-
106          merators of the generators, the last one is the universal deno-
107          minator
108"
109{
110  int dblvl=printlevel-voice+2;   // toggles how much data is printed
111                                  // during the procedure
112
113  def Kxt = basering;
114  def R(1) = L[1];
115  setring R(1);                   // declaration of variables used later
116  ideal ker(1)=ker;               // in STEP 2
117  poly p;
118
119  // some auxiliary variables
120
121  int i=1;         // counts the number of steps to reach the closure of R(1)
122  int check=0;     // a 'boolean' variable for several checks
123  int isIsoSing=0; // '1' in case of an isolated singularity
124
125  /////// STEP 1: ///////////////////////////////////////////////////////////
126  // construct R(i) step by step as done in normal.lib; 2 differences:     //
127  //  - since the input is a prime ideal, no splitting will occur          //
128  //  - the intermediate rings and nonzerodivisors for J are remembered    //
129  ///////////////////////////////////////////////////////////////////////////
130
131  if (dblvl>0)
132  {
133    "// STEP 1: Compute the integral closure of R[It]";
134  }
135
136  list RS;
137
138  while (check==0)  // repeat until the closure is reached
139  {
140    // construction of HomJJ, J an ideal containing the non-normal locus
141    // of R(i)/ker(i), as done in normalizationPrimes in normal.lib for
142    // the special case that we are working with a prime ideal
143
144    if (dblvl>0)
145    {
146      "";
147      "// We are in step",i;
148      pause();
149    }
150
151    if (homog(ker(i))==1)
152    {
153      list SM=mstd(ker(i));
154    }
155    else
156    {
157      list SM=groebner(ker(i)),ker(i);
158    }
159
160    if (dblvl>0)
161    {
162      "// Standard basis of the current ideal:";
163      SM[1];
164    }
165
166    // In the first iteration, we have to compute the singular locus and
167    // to check whether it is an isolated singularity (this makes things
168    // much easier: for further iterations, we just take the max. ideal).
169    // If not, we still fetch the singular locus but have to compute
170    // its radical.
171
172    if (i==1)
173    {
174      ideal J=minor(jacob(SM[2]),nvars(basering)-dim(SM[1]));
175      ideal sin=J+SM[2];
176      if (homog(SM[2])==1)
177      {
178        list JM=mstd(sin);
179      }
180      else
181      {
182        list JM=groebner(sin),sin;
183      }
184
185      if (dim(JM[1])==0 && homog(SM[2])==1)
186      {
187        isIsoSing=1;
188      }
189      J=equiRadical(JM[2]);
190    }
191    else
192    {
193      if (isIsoSing==0)
194      {
195        ideal J=equiRadical(JM[2]);
196      }
197      else
198      {
199        ideal J=maxideal(1);
200      }
201    }
202
203    if (dblvl>0)
204    {
205      "// Radical of the singular locus:";
206      J;
207    }
208
209    ideal SL=simplify(reduce(JM[2],SM[1]),2);
210    JM =J,J;
211    poly nzd=SL[1];           // universal denominator for HomJJ
212
213    if (dblvl>0)
214    {
215      "// The non-zerodivisor";
216      nzd;
217      pause();
218    }
219
220    list RR=SM[1],SM[2],JM[2],SL[1];
221    RS=HomJJ(RR);
222
223    if (RS[2]==1)             // we've reached the integral closure
224    {
225      if (dblvl>0)
226      {
227        "";
228        "// We've reached the integral closure after",i,"iterations";
229        pause();
230      }
231      check=1;
232    }
233    else                      // prepare the next iteration with new
234    {                         // ring R(i+1)
235      ideal MJ=JM[2];
236
237      def R(i+1)=RS[1];       // the data of and some variable decla-
238      setring R(i+1);         // rations in R(i+1) needed in STEP 2
239      ideal ker(i+1)=endid;
240      map phi=R(i),endphi;
241      poly p;
242
243      if (isIsoSing==0)       // fetch the singular locus if it is not
244      {                       // an isolated singularity
245        list JM=mstd(simplify(phi(MJ)+ker(i+1),4));
246      }
247      i++;
248    }
249  }
250
251  if (i==1)                     // R[It] (and thus I) was integrally
252  {                             // closed ==> we're already done
253        list result="closed";
254        return(result);
255  }
256
257
258  /////// STEP 2: ////////////////////////////////////////////////////////
259  // compute representations of the ring variables of R(i) as fractions //
260  // of elements of R(1);                                               //
261  ////////////////////////////////////////////////////////////////////////
262
263  int length=nvars(R(i));  // the number of variables of the last ring
264  int j,k,n;               // some counters
265  string mapstr;           // will be used while constructing preimages
266
267  list preimages;          // here the fractions are stored in the
268                           // form var(j)=preimages[j]/preimages[length+1]
269                           // ('=' means identification via the inclusion)
270                           // the last entry corresponds to nzd in R(i)
271
272  // For each variable (counter j) and for each intermediate ring (k):
273  // find preimages of var(j)*endphi(nzd_k-1) in R(k-1).
274  // Finally, do the same for nzd.
275
276  if (dblvl>0)
277  {
278    "// STEP 2: Compute fractions representing the ring variables of";
279    "           the last ring";
280  }
281
282  for (j=1;j<=length+1;j++)
283  {
284    setring R(i);
285
286    if (j<=length)          // do it with for ring variables...
287    {
288      p=var(j);
289    }
290    else                   // ...and finally for nzd in R(i)
291    {
292      p=1;
293    }
294
295    // get back from R(i) to R(1) step by step
296
297    for (k=i;k>1;k--)
298    {
299      // clear the fraction in the representation in R(i)
300
301      p=p*phi(nzd);
302
303      // compute the preimage of [p mod ker(k)] under phi in R(k-1):
304      // as p is an element of im(phi), there is a poly h such that
305      // h(vars(R(k-1)) is mapped to [p mod ker (k)], and h can be com-
306      // puted as the normal form of a w.r.t <ker(k),Z(n)-phi(k)(n)> in R(k)[Z]
307
308         // compute this normal form h...
309
310      if (j==1)    // in the first iteration: construct S(k)=R(k)[Z], fetch
311                   // endphi (the ideal defining phi) and ker(k) and construct
312                   // the ideal from above
313      {
314        execute ("ring S(k) = "+charstr(R(k))+",("+varstr(R(k))+",Z(1.."+string(ncols(endphi))+")),(dp("+string(nvars(R(k)))+"),dp("+string(ncols(endphi))+"));");
315        ideal endphi = imap(R(k),endphi);
316        ideal J = imap(R(k),ker(k));
317        for (n=1;n<=ncols(endphi);n++)
318        {
319          J=J+(Z(n)-endphi[n]);
320        }
321        J=groebner(J);
322        poly h=NF(imap(R(k),p),J);
323      }
324      else
325      {
326        setring S(k);
327        h=NF(imap(R(k),p),J);
328      }
329
330         // and compute h(vars(R(k-1)))
331
332      setring R(k-1);
333      if (j==1)  // in the first iteration: compute backmap:S(k)-->R(k-1)
334      {
335        mapstr="map backmap = S(k),";
336        for (n=1;n<=nvars(R(k));n++)
337        {
338          mapstr=mapstr+"0,";
339        }
340        execute (mapstr+"maxideal(1);");
341      }
342
343      p=NF(backmap(h),std(ker(k-1)));
344    }
345
346    // when down to R(1), store the result in the list preimages
347
348    preimages=insert(preimages,p,j-1);
349    if (dblvl>0)
350    {
351      if (j<=length)
352      {
353        "numerator of variable ",j,":",p;
354      }
355      else
356      {
357        "";
358        "and finally the 'universal' denominator:",p;
359      }
360    }
361  }
362
363  // at the end: go back to the original basering and construct gene-
364  // rators of the closure of I
365
366  setring Kxt;
367  map psi=R(1),mapI;              // from ReesAlgebra: the map Rees->Kxt
368
369  list images=psi(preimages);
370
371  if (dblvl>-1)
372  {
373    pause();
374    "";
375    "// Get back to the original basering and construct the";
376    "// generators of the closure of I";
377    "";
378    "// Back in k[x,t], the fractions, stored in the list images:";
379    for (int j=1;j<=size(images);j++)
380    {
381      if (j<size(images))
382      {
383        "numerator",j,":",images[j];
384      }
385      else
386      {
387        "";
388        "denominator:  ",images[j];
389      }
390    }
391    pause();
392  }
393  return (images);
394}
395
396
397////////////////////////////////////////////////////////////////////////////
398
399static proc ClosurePower(list images, list #)
400"USAGE:    ClosurePower (L [,#]);
401          - L a list containing generators of the closure of R[It] in k[x,t]
402            (the first size(L)-1 elements are the numerators, the last one
403            is the denominator)
404          - if # is given: #[1] is an integer, compute generators for the
405                           closure of I, I^2, ..., I^#[1]
406COMPUTE:  the integral closure of I, ... I^#[1]. If # is not given, compute
407          the closure of all powers up to the maximum degree in t occurring
408          in the closure of R[It] (so this is the last one that is not just
409          the sum/product of the above ones).
410RETURN:   a list containing generators of the closure of the desired powers
411          of I as elements of k[x,t].
412"
413{
414  int dblvl=printlevel-voice+2;   // toggles how much data is printed
415                                  // during the procedure
416
417  int j,k,d,computepow;                    // some counters
418  int pow=0;
419  int length = size(images)-1;             // the number of generators
420  poly image;
421  poly denominator = images[length+1];     // the universal denominator
422
423  if (size(#)>0)
424  {
425    pow=#[1];
426  }
427  computepow=pow;
428
429  if (dblvl>0)
430  {
431    "";
432    "// The generators of the closure of R[It]:";
433  }
434
435  intmat m[nvars(basering)-1][1];  // an intvec used for jet and maxdeg1
436  intvec tw=m,1;                   // such that t has weight 1 and all
437                                   // other variables have weight 0
438
439  // Construct the generators of the closure of R[It] as elements of k[x,t]
440  // If # is not given, determine the highest degree pow in t that occurs.
441
442  for (j=1;j<=length;j++)
443  {
444    images[j] = (images[j]/denominator); // construct the fraction
445    image = images[j];
446    if (dblvl>0)
447    {
448      "generator",j,":",image;
449    }
450
451    if (computepow==0)              // #[1] not given or ==0 => compute pow
452    {
453      if (maxdeg1(image,tw)>pow)    // from poly.lib
454      {
455        pow=maxdeg1(image,tw);
456      }
457    }
458  }
459
460  if (dblvl>0)
461  {
462    "";
463    if (computepow==0)
464    {
465      "// Compute the closure up to the given powers of I";
466    }
467    else
468    {
469     "// Compute the closure up to the maximal power of t that occured:",pow;
470    }
471  }
472
473  // Construct a list consisting of #[1] resp. pow times the zero ideal
474
475  ideal CurrentPower=0;
476  list result;
477  for (k=1;k<=pow;k++)
478  {
479    result=insert(result,CurrentPower);
480  }
481
482  // For each generator and each k, add its degree-k-coefficient to the #
483  // closure of I^k
484
485  for (j=1;j<=length;j++)
486  {
487    for (k=1;k<=pow;k++)
488    {
489      image=images[j]-jet(images[j],k-1,tw);
490      if (image<>0)
491      {
492        image=subst(image/t^k,t,0);
493        if (image<>0)
494        {
495          result[k]=result[k]+image;
496        }
497      }
498    }
499  }
500
501  if (dblvl>0)
502  {
503    "";
504    "// The 'pure' parts of degrees 1..pow:";
505    result;
506    "";
507  }
508
509  // finally, add the suitable products of generators in lower degrees
510
511  for (k=2;k<=pow;k++)
512  {
513    for (j=1;j<=(k div 2);j++)
514    {
515      result[k]=result[k]+result[j]*result[k-j];
516    }
517  }
518
519  return(result);
520}
521
522////////////////////////////////////////////////////////////////////////////
523
524proc normalI(ideal I, list #)
525"USAGE:    normalI (I [,p[,r]]); I an ideal, p and r optional integers
526COMPUTE:  the integral closure of I, ..., I^p. If p is not given, or p==0,
527          compute the closure of all powers up to the maximum degree in t
528          occurring in the closure of R[It] (so this is the last one that
529          is not just the sum/product of the above ones).
530          If r is given and <>1, the check whether the input ideal is
531          already a radical ideal is omitted.
532RETURN:   a list containing the closure of the desired powers of I as ideals
533          of the basering.
534DISPLAY:  The procedure displays more comments for higher printlevel
535EXAMPLE:  example normalI; shows an example
536"
537{
538  int dblvl=printlevel-voice+2;   // toggles how much data is printed
539                                  // during the procedure
540
541  def BAS=basering;               // remember the basering
542
543  // two simple cases: principal ideals and radical ideals are always
544  // integrally closed
545
546  if (size(I)<=1)        // includes the case I=(0)
547  {
548    if (dblvl>0)
549    {
550      "// Trivial case: I is a principal ideal";
551    }
552    list result=I;
553    if (size(#)>0)
554    {
555      for (int k=1;k<=#[1]-1;k++)
556      {
557        result=insert(result,I*result[k],k);
558      }
559    }
560    return(result);
561  }
562
563  int testrad=1;      // do the radical check?
564  if (size(#)>1)
565  {
566    if (#[2]<>1)
567    {
568      testrad=0;
569    }
570  }
571  if (testrad==1)
572  {
573    if (dblvl>0)
574    {
575      "//Check whether I is radical";
576    }
577
578    if (size(reduce(radical(I),std(I)))==0)
579    {
580      if (dblvl>0)
581      {
582        "//Trivial case: I is a radical ideal";
583      }
584      list result=I;
585      if (size(#)>0)
586      {
587        for (int k=1;k<=#[1]-1;k++)
588        {
589          result=insert(result,I*result[k],k);
590        }
591      }
592      return(result);
593    }
594  }
595
596  // start with the computation of the Rees Algebra R[It] of I
597
598  if (dblvl>0)
599  {
600    "// We start with the Rees Algebra of I:";
601  }
602
603  list Rees = ReesAlgebra(I);
604  def R(1)=Rees[1];
605  def Kxt=Rees[2];
606  setring R(1);
607
608  if (dblvl>0)
609  {
610    R(1);
611    ker;
612    "";
613    "// Now ClosureRees computes generators for the integral closure";
614    "// of R[It] step by step";
615  }
616
617  // ClosureRees computes fractions in R[x,t] representing the generators
618  // of the closure of R[It] in k[x,t], which is the same as the closure
619  // in Q(R[It]).
620  // the first size(images)-1 entries are the numerators of the gene-
621  // rators, the last entry is the 'universal' denominator
622
623  setring Kxt;
624  list images = ClosureRees(Rees);
625
626  // ClosureRees was done after the first HomJJ-call
627  // ==> I is integrally closed, and images consists of the only entry "closed"
628
629  if ((size(images)==1) && (typeof(images[1])=="string"))
630  {
631    if (dblvl>0)
632    {
633      "//I is integrally closed!";
634    }
635
636    setring BAS;
637    list result=I;
638    if (size(#)>0)
639    {
640      for (int k=1;k<=#[1]-1;k++)
641      {
642        result=insert(result,I*result[k],k);
643      }
644    }
645    return(result);
646  }
647
648  // construct the fractions corresponding to the generators of the
649  // closure of I and its powers, depending on # (in fact, they will
650  // not be real fractions, of course). This is done in ClosurePower.
651
652  list result = ClosurePower(images,#);
653
654  // finally fetch the result to the old basering
655
656  setring BAS;
657  list result=fetch(Kxt,result);
658  return(result);
659}
660example
661{
662  "EXAMPLE:"; echo=2;
663  ring R=0,(x,y),dp;
664  ideal I = x2,xy4,y5;
665  list J = normalI(I);
666  I;
667  J;                             // J is the integral closure of I
668}
669///////////////////////////////////////////////////////////////////////////////
670/*
671  BEISPIELE
672*/
Note: See TracBrowser for help on using the repository browser.