source: git/Singular/LIB/integralbasis.lib @ 380a17b

spielwiese
Last change on this file since 380a17b was 380a17b, checked in by Hans Schoenemann <hannes@…>, 11 years ago
fix: new version numbers for libs
  • Property mode set to 100644
File size: 19.4 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2version="version integralbasis.lib 4.0.0.0 Jun_2013 ";
3category="Commutative Algebra";
4info="
5LIBRARY:  integralbasis.lib  Integral basis in algebraic function fields
6AUTHORS:  J. Boehm, j.boehm at mx.uni-saarland.de @*
7          W. Decker, decker at mathematik.uni-kl.de> @*
8          S. Laplagne, slaplagn at dm.uba.ar @*
9          F. Seelisch, seelisch at mathematik.uni-kl.de
10
11OVERVIEW:
12Given an irreducible polynomial f in two variables defining a plane curve,
13this library implements an algorithm to compute an integral basis of the
14integral closure of the affine coordinate ring in the algebraic function
15field via normalization.@*
16The user can choose whether the algorithm will do the computation globally
17or (this is the default) compute in the localization at each component of
18the singular locus and put everything together.
19
20PROCEDURES:
21 integralBasis(f, intVar);     Integral basis of an algebraic function field
22";
23
24LIB "normal.lib";
25
26///////////////////////////////////////////////////////////////////////////////
27
28proc integralBasis(poly f, int intVar, list #)
29"USAGE: integralBasis(f, intVar); f irreducible polynomial in two variables,
30        intVar integer indicating that the intVar-th variable of the ring is the
31        integral element.@*
32        The base ring must be a ring in two variables, and the polynomial f
33        must be monic as polynomial in the intVar-th variable.@*
34        Optional parameters in list choose (can be entered in any order):@*
35        Parameters for selecting the algorithm:@*
36        - \"global\" -> computes the integral basis by computing the
37        normalization of R/<f>, where R is the base ring.@*
38        - \"local\" -> computes the integral basis by computing the
39        normalization of R/<f> localized at each component of the singular
40        locus of R/<f>, and then putting everything together.
41        This is the default option.@*
42        Other parameters:@*
43        - \"isIrred\" -> assumes that the input polynomial f is irreducible,
44        and therefore will not check this. If this option is given but f is not
45        irreducible, the output might be wrong.@*
46        - list(\"inputJ\", ideal inputJ) -> takes as initial test ideal the
47        ideal inputJ. This option is only for use in other procedures. Using
48        this option, the result might not be the integral basis.@*
49        (When this option is given, the global option will be used.)@*
50        - list(\"inputC\", ideal inputC) -> takes as initial conductor the
51        ideal inputC. This option is only for use in other procedures. Using
52        this option, the result might not be the integral basis.@*
53        (When this option is given, the global option will be used.)@*
54RETURN: a list, say l, of size 2.
55        l[1] is an ideal I and l[2] is a polynomial D such that the integral
56        basis is b_0 = I[1] / D, b_1 = I[2] / D, ..., b_{n-1} = I[n] / D.@*
57        That is, the integral closure of k[x] in the algebraic function
58        field k(x,y) is @*
59        k[x] b_0 + k[x] b_1 + ... + k[x] b_{n-1},@*
60        where we assume that x is the transcendental variable, y is the integral
61        element (indicated by intVar), f gives the integral equation and n is
62        the degree of f as a polynomial in y.@*
63
64THEORY:  We compute the integral basis of the integral closure of k[x] in k(x,y)
65         by computing the normalization of the affine ring k[x,y]/<f> and
66         converting the k[x,y]-module generators into a k[x]-basis.@*
67KEYWORDS: integral basis; normalization.
68SEE ALSO: normal.
69EXAMPLE: example integralBasis; shows an example
70"
71{
72  int i;
73  ideal inputJ = 0;
74  ideal inputC = 0;
75  string algorithm = "local";     // The default option is "local"
76  int checkIrred = 1;
77
78//--------------------------- read the input options---------------------------
79  for ( i=1; i <= size(#); i++ )
80  {
81    if ( typeof(#[i]) == "string" )
82    {
83      if (#[i]=="local"){
84        algorithm = "local";
85      }
86      if (#[i]=="global"){
87        algorithm = "global";
88      }
89      if (#[i]=="isIrred"){
90        checkIrred = 0;
91      }
92    }
93    if(typeof(#[i]) == "list"){
94      if(size(#[i]) == 2){
95        if (#[i][1]=="inputJ"){
96          if((typeof(#[i][2]) == "ideal") or (typeof(#[i][2]) == "poly")){
97            inputJ = #[i][2];
98            algorithm = "global";
99          }
100        }
101      }
102      if (#[i][1]=="inputC"){
103        if(size(#[i]) == 2){
104          if((typeof(#[i][2]) == "ideal") or (typeof(#[i][2]) == "poly")){
105            inputC = #[i][2];
106            algorithm = "global";
107          }
108        }
109      }
110    }
111  }
112
113//--------------------------- preliminary checks ------------------------------
114  // The ring must have two variables.
115  if(nvars(basering) != 2){
116    ERROR("The base ring must be a ring in two variables.");
117  }
118
119  // intVar must be either 1 or 2.
120  if((intVar < 0) || (intVar > 2)){
121      ERROR("The second parameter intVar must be either 1 or 2, indicating the
122            integral variable.");
123  }
124
125  // No parameters or algebraic numbers are allowed.
126  if(npars(basering) >0){
127    ERROR("No parameters or algebraic extensions are allowed in the base ring.");
128  }
129
130  // The polynomial f must be monic in the intVar-th variable.
131  matrix cs = coeffs(f, var(intVar));
132  if(cs[size(cs),1] != 1){
133      ERROR("The input polynomial must be monic as a polynomial in the
134            intVar-th variable.");
135  }
136
137  // The polynomial f must be irreducible.
138  if(checkIrred == 1){
139    if(factorize(f)[2] != [1,1]){
140        ERROR("The input polynomial must be irreducible.");
141    }
142  }
143
144//--------------------- computing the integral basis --------------------------
145  return(cancelCF(integralBasisMain(f, algorithm, inputJ, inputC, intVar)));
146}
147example
148{ "EXAMPLE:";
149  printlevel = printlevel+1;
150  echo = 2;
151  ring s = 0,(x,y),dp;
152  poly f = y5-y4x+4y2x2-x4;
153  list l = integralBasis(f, 2);
154  l;
155// The integral basis of the integral closure of Q[x] in Q(x,y) consists
156// of the elements of l[1] divided by the polynomial l[2].
157  echo = 0;
158  printlevel = printlevel-1;
159}
160
161///////////////////////////////////////////////////////////////////////////////
162
163static proc integralBasisMain(poly f, string algorithm, ideal inputJ, ideal inputC, int intVar)
164// Computes the integral basis of R/<f>, from the normalizaiton of R/<f>.
165// inputC is the conductor ideal to be used in proc normal.
166// If inputC = < 0 >, then the default conductor ideal is used (the full
167// jacobian ideal).
168// inputJ is the test ideal to be used in proc normal.
169// If inputJ = < 0 >, then the default test ideal is used (the radical of the
170// conductor).
171{
172  int dbg = printlevel - voice + 2;
173  int i, j;
174  int newRing = 0;    // If = 1, a new ring with dp ordering was used.
175  def origR = basering;
176
177//--------------------- moving to a ring with dp ordering ---------------------
178  if(ordstr(origR) != "dp(2),C"){
179    // We change to dp ordering.
180    list rl = ringlist(origR);
181    list origOrd = rl[3];
182    list newOrd = list("dp", intvec(1:nvars(origR))), list("C", 0);
183    rl[3] = newOrd;
184    def R = ring(rl);
185    setring R;
186    poly f = fetch(origR, f);
187    ideal inputJ = fetch(origR, inputJ);
188    ideal inputC = fetch(origR, inputC);
189    newRing = 1;
190  } else {
191    def R = basering;
192  }
193
194//-------------------------------- basic data ---------------------------------
195  // The degree of f with respect to the variable intVar
196  ideal I = f;
197  int n = size(coeffs(f, var(intVar))) - 1;
198
199  // If the integral variable is the first, then the universal denominator
200  // must be a polynomial in the second variable (and viceversa).
201  string conduStr;
202  if(intVar == 1){
203    conduStr = "var2";
204  } else {
205    conduStr = "var1";
206  }
207  list opts = conduStr;
208
209//-------------------------- computes the normalization -----------------------
210  if(algorithm == "local"){
211    list nor = integralLocal(I, opts);
212  } else {
213    if(inputJ != 0){
214      opts = insert(opts, list("inputJ", inputJ));
215    }
216    if(inputC != 0){
217      opts = insert(opts, list("inputC", inputC));
218    }
219    list nor = normal(I, opts);
220  }
221  ideal normalGen = nor[2][1];
222  poly D = normalGen[size(normalGen)];  // The universal denominator
223
224  //Debug information
225  if(dbg >= 2){
226    "The universal denominator is: ", D;
227  }
228
229//--------------- computes the integral basis from the normalization ----------
230  // We define a new ring where the integral variable is the first (needed for
231  // reduction) and has the appropiate ordering.
232  list rl = ringlist(R);
233  rl[2] = list(var(intVar), var(3-intVar));
234  rl[3] = list(list("C", 0), list("lp", intvec(1,1)));
235  def S = ring(rl);
236  setring S;
237
238  // We map the elements in the previous ring to the new one
239  poly f = imap(R, f);
240  ideal normalGen = imap(R, normalGen);
241
242  // We create the system of generatos y^i*f_j.
243  list l;
244  ideal red = groebner(f);
245  for(j = 1; j <= size(normalGen); j++){
246    l[j] = reduce(normalGen[j], red);
247  }
248  for(i = 1; i <= n-1; i++){
249    for(j = 1; j <= size(normalGen); j++){
250      l[size(l)+1] = reduce(var(1)^i*normalGen[j], red);
251    }
252  }
253
254  // To eliminate the redundant elements, we look at the polynomials as
255  // elements of a free module where the coordinates are the coefficients
256  // of the polynomials regarded as polynomials in y.
257  // The groebner basis of the module generated by these elements
258  // gives the desired basis.
259  matrix vecs[n + 1][size(l)];
260  matrix coeffi[n + 1][2];
261
262  for(i = 1; i<= size(l); i++){
263    coeffi = coeffs(l[i], var(1));
264    vecs[1..nrows(coeffi), i] = coeffi[1..nrows(coeffi), 1];
265  }
266  module M = vecs;
267  M = std(M);
268
269  // We go back to the original ring.
270  setring origR;
271  module M = imap(S, M);
272  if(newRing == 1){
273    poly D = fetch(R, D);
274  }
275
276  // We go back from the module to the ring in two variables
277  ideal G;
278  poly g;
279  for(i = 1; i <= size(M); i++){
280    g = 0;
281    for(j = 0; j <= n; j++){
282      g = g + M[i][j+1] * var(intVar)^j;
283    }
284    G[i] = g;
285  }
286
287  // The first element in the output is the ideal of numerators.
288  // The second element is the denominator.
289  list outp = G, D;
290
291  return(outp);
292}
293
294///////////////////////////////////////////////////////////////////////////////
295
296static proc integralLocal(ideal I, list #){
297// Computes the integral basis  by localizing at the different components of
298// the singular locus.
299  int i;
300  int dbg = printlevel - voice + 4;
301  def R = basering;
302
303  list n;         // Output of proc normal
304  ideal norT;     // Temporary data.
305  poly denomT;    // Temporary data.
306
307  ideal nor;      // Output of normal with the denominator changed to the
308                  // common denominator.
309  ideal res;      // The full integral basis
310
311//--------------------------- read the input options---------------------------
312  int denomOption = 0;
313  for ( i=1; i <= size(#); i++ )
314  {
315    if ( typeof(#[i]) == "string" )
316    {
317      if (#[i]=="var1")
318      {denomOption = 1;}
319      if (#[i]=="var2")
320      {denomOption = 2;}
321    }
322  }
323
324//------------------------ singular locus computation -------------------------
325  // We use a general method that works for any ideal.
326  // For I defined by a single polynomial a simpler method could be used.
327  list IM = mstd(I);
328  I = IM[1];
329  int d = dim(I);
330  ideal IMin = IM[2];
331  qring Q = I;  // We work in the quotient by the Groebner basis of the ideal I
332  option("redSB");
333  option("returnSB");
334  ideal I = fetch(R, I);
335  attrib(I, "isSB", 1);
336  ideal IMin = fetch(R, IMin);
337  if(dbg >= 2){
338    int t = timer;
339  }
340  ideal J = minor(jacob(IMin), nvars(basering) - d, I);
341  if(dbg >= 2){
342    "singular locus time: ", timer - t;
343    t = timer;
344  }
345  setring R;
346  ideal J = fetch(Q, J);
347  J = J, I;
348  J = groebner(J);
349
350  if(dbg >= 2){
351    "groebner of the singular locus time: ", timer - t;
352    t = timer;
353  }
354
355  if(dbg >= 2){
356    "The original singular locus is";
357    J;
358  }
359
360//------------------------ universal denominator ------------------------------
361  // We could use the LCD of the denominators of each component, but we need
362  // a denominator in the required variable.
363  if(denomOption == 0){
364    poly condu = getSmallest(J);   // Choses the polynomial of smallest degree
365                                   // of J as universal denominator.
366  } else {
367    poly condu = getOneVar(J, denomOption);
368  }
369
370//------------------- components of the singular locus------------------------
371  list pd = primdecGTZ(J);
372  if(dbg >= 2){
373    "primary decomposition time:", timer - t;
374  }
375  if(dbg >= 1){
376    "The number of components of the Singular Locus is ", size(pd);
377  }
378
379  // The following commented lines are not needed for integral basis, since
380  // all components are maximal.
381  // Computes the maximal components and the components included in them
382  //list comps = maxComps(pd);
383  // For each maximal component, it intersects all the components included in it
384  //list locs = intersectList(comps);
385
386//------------------- normalization of each component--------------------------
387  list opts;
388  for(i = 1; i <= size(pd); i++){
389    //opts = #;
390    // We use the prime components as test ideals in the normalization.
391    //opts = list(list("inputJ", pd[i][2]));
392    // We use the primary components as conductor in the normalization.
393    opts = list(list("inputC", pd[i][1]));
394
395    if(dbg >= 2){
396      t = timer;
397    }
398    n = normal(I, opts);
399    if(dbg >= 2){
400      "normalization of component ", i, " time: ", timer - t;
401    }
402    if(size(n[2]) > 1){
403      ERROR("The input polynomial is not irreducible.");
404    }
405
406    // We add up the normalizations at each localization, to construct the
407    // normalization of the whole ideal.
408    norT = n[2][1];
409    denomT = norT[size(norT)];
410
411    // We change the denominator of the normalization of the localized ring,
412    // to have the same denominator for all the normalizations.
413    nor = changeDenominator(norT, denomT, condu, I);
414
415    // We sum the result to the previous results.
416    res = res, nor;
417  }
418  res = groebner(res);
419  res[size(res)+1] = condu;
420
421  // The output follows the output of proc normal, but we don't return the
422  // ring structure, only the generators. (We return 0 instead of the ring.)
423  return(list(0,list(res)));
424}
425
426///////////////////////////////////////////////////////////////////////////////
427
428static proc cancelCF(list IB)
429"USAGE:  cancelCF(IB); IB list of type returned by integralBasis
430RETURN:  list of same type with  common factor cancelled.
431KEYWORDS: greatest common divisor.
432"
433{
434  int l = size(IB[1]);
435  poly GrCoDi = IB[2];
436  int k = l;
437  while((GrCoDi != 1) && (k >=1))
438      {
439        GrCoDi = gcd(GrCoDi,IB[1][k]);
440        k = k-1;
441      }
442  if(GrCoDi != 1)
443    {
444      for(k = 1; k <= l; k++)
445         {
446           IB[1][k] = IB[1][k]/GrCoDi;
447         }
448      IB[2] = IB[2]/GrCoDi;
449    }
450  return(IB);
451}
452/////////////////////////////////////////////////////////////////////////////
453/////////////////////////////////////////////////////////////////////////////
454/////////////////////////////////////////////////////////////////////////////
455/*
456/////////////////////////////////////////////////////////////////////////////
457/// Examples for testing the main procedures
458/// Timings on wawa Sept 30
459/////////////////////////////////////////////////////////////////////////////
460LIB"integralbasis.lib";
461// -------------------------------------------------------
462// Example 1
463// -------------------------------------------------------
464ring r = 0, (x, y), dp;
465poly f = y5-y4x+4y2x2-x4;
466integralBasis(f, 2, "global");  // time 0
467integralBasis(f, 1);
468integralBasis(f, 2);  // local by default, time 0
469normal(f);
470kill r;
471// -------------------------------------------------------
472// Example 2
473// -------------------------------------------------------
474ring r = 0, (x, y), dp;
475poly f = y2-x2*(x+1)^2*(x+2);
476integralBasis(f, 2, "global");  // time 0
477integralBasis(f, 2);  // local by default, time 0
478integralBasis(f, 2, list(list("inputJ", ideal(x,y))));
479kill r;
480// -------------------------------------------------------
481// Example 3
482// -------------------------------------------------------
483ring RR = 0, (x,y), dp;
484poly f = 11y7+7y6x+8y5x2-3y4x3-10y3x4-10y2x5-x7-33y6-29y5x-13y4x2+26y3x3;
485f = f+30y2x4+10yx5+3x6+33y5+37y4x-8y3x2-33y2x3-20yx4-3x5-11y4-15y3x;
486f = f+13y2x2+10yx3+x4; // 3 OMPs of mult 3, 1 OMP of mult 4
487integralBasis(f, 2);
488f =1/11*f;
489integralBasis(f, 2, "global");  // time 2
490integralBasis(f, 2);  // local by default, time 0
491kill RR;
492// -------------------------------------------------------
493// Example 4
494// -------------------------------------------------------
495ring RR = 0, (x,y), dp;
496poly f = y^20+x*y^13+x^4*y^5+x^5+2*x^4+x^3;
497integralBasis(f, 2, "global");  // time 0
498integralBasis(f, 2);  // local by default,  time 0
499kill RR;
500// -------------------------------------------------------
501// Example 5
502// -------------------------------------------------------
503ring SS = 0, (u,v,z), dp;
504poly f = u^6+3*u^4*v^2+3*u^2*v^4+v^6-4*u^4*z^2-34*u^3*v*z^2-7*u^2*v^2*z^2;
505f = f+12*u*v^3*z^2+6*v^4*z^2+36*u^2*z^4+36*u*v*z^4+9*v^2*z^4;
506f = subst(f,z,1);
507ring RR = 0, (x,y), dp;
508poly f = fetch(SS,f);
509integralBasis(f, 2);  integralBasis(f, 2, "global");  // time 1
510integralBasis(f, 2);  // local by default, time 0
511kill RR, SS;
512// -------------------------------------------------------
513// Example 6
514// -------------------------------------------------------
515ring SS = 0, (u,v,z), dp;
516poly f = -24135/322*u^6-532037/6440*u^5*v+139459/560*u^4*v^2;
517f = f-1464887/12880*u^3*v^3+72187/25760*u^2*v^4+9/8*u*v^5+1/8*v^6;
518f = f-403511/3220*u^5*z-40817/920*u^4*v*z+10059/80*u^3*v^2*z;
519f = f-35445/1288*u^2*v^3*z+19/4*u*v^4*z+3/4*v^5*z-20743/805*u^4*z^2;
520f = f+126379/3220*u^3*v*z^2-423417/6440*u^2*v^2*z^2+11/2*u*v^3*z^2;
521f = f+3/2*v^4*z^2+3443/140*u^3*z^3+u^2*v*z^3+u*v^2*z^3+v^3*z^3;
522f = 8/27*subst(f,z,u+v+z);
523f = subst(f,z,1);
524ring RR = 0, (x,y), dp;
525poly f = fetch(SS,f);
526integralBasis(f, 2, "global");  // time 3
527integralBasis(f, 2);  // local by default, time 0
528kill RR, SS;
529// -------------------------------------------------------
530// Example 8
531// -------------------------------------------------------
532ring SS = 0, (u,v,z), dp;
533poly f = 25*u^8+184*u^7*v+518*u^6*v^2+720*u^5*v^3+576*u^4*v^4+282*u^3*v^5;
534f = f+84*u^2*v^6+14*u*v^7+v^8+244*u^7*z+1326*u^6*v*z+2646*u^5*v^2*z;
535f = f+2706*u^4*v^3*z+1590*u^3*v^4*z+546*u^2*v^5*z+102*u*v^6*z+8*v^7*z;
536f = f+854*u^6*z^2+3252*u^5*v*z^2+4770*u^4*v^2*z^2+3582*u^3*v^3*z^2;
537f = f+1476*u^2*v^4*z^2+318*u*v^5*z^2+28*v^6*z^2+1338*u^5*z^3+3740*u^4*v*z^3;
538f = f+4030*u^3*v^2*z^3+2124*u^2*v^3*z^3+550*u*v^4*z^3+56*v^5*z^3+1101*u^4*z^4;
539f = f+2264*u^3*v*z^4+1716*u^2*v^2*z^4+570*u*v^3*z^4+70*v^4*z^4+508*u^3*z^5;
540f = f+738*u^2*v*z^5+354*u*v^2*z^5+56*v^3*z^5+132*u^2*z^6+122*u*v*z^6;
541f = f+28*v^2*z^6+18*u*z^7+8*v*z^7+z^8;
542f = subst(f,z,1);
543ring RR = 0, (x,y), dp;
544poly f = fetch(SS,f);
545integralBasis(f, 2, "global");  // time 95
546integralBasis(f, 2);  // local by default, time  13
547kill RR, SS;
548// -------------------------------------------------------
549// Example 9
550// -------------------------------------------------------
551ring SS = 0, (u,v,z), dp;
552poly f = u^10+6*u^9*v-30*u^7*v^3-15*u^6*v^4+u^5*v^5+u^4*v^6+6*u^3*v^7+u^2*v^8;
553f = f+7*u*v^9+v^10+5*u^9*z+24*u^8*v*z-30*u^7*v^2*z-120*u^6*v^3*z-43*u^5*v^4*z;
554f = f+5*u^4*v^5*z+20*u^3*v^6*z+10*u^2*v^7*z+29*u*v^8*z+5*v^9*z;
555f = f+10*u^8*z^2+36*u^7*v*z^2-105*u^6*v^2*z^2-179*u^5*v^3*z^2;
556f = f-38*u^4*v^4*z^2+25*u^3*v^5*z^2+25*u^2*v^6*z^2+46*u*v^7*z^2;
557f = f+10*v^8*z^2+10*u^7*z^3+24*u^6*v*z^3-135*u^5*v^2*z^3;
558f = f-117*u^4*v^3*z^3-u^3*v^4*z^3+25*u^2*v^5*z^3+34*u*v^6*z^3;
559f = f+10*v^7*z^3+5*u^6*z^4+6*u^5*v*z^4-75*u^4*v^2*z^4-27*u^3*v^3*z^4;
560f = f+10*u^2*v^4*z^4+11*u*v^5*z^4+5*v^6*z^4+u^5*z^5;
561f = f-15*u^3*v^2*z^5+u^2*v^3*z^5+u*v^4*z^5+v^5*z^5;
562f = subst(f,z,1);
563ring RR = 0, (x,y), dp;
564poly f = fetch(SS,f);
565// integralBasis(f, 2, "global");  // fail
566integralBasis(f, 2);  //  local by default, time 2
567kill RR, SS;
568*/
569
570
Note: See TracBrowser for help on using the repository browser.