source: git/Singular/LIB/graal.lib @ e480be8

spielwiese
Last change on this file since e480be8 was e480be8, checked in by Sachin <sachinkm308@…>, 5 years ago
replacing execute with create_ring (5)
  • Property mode set to 100644
File size: 34.2 KB
Line 
1////////////////////////////////////////////////////////////////////////////
2version="version graal.lib 4.1.2.0 Feb_2019 "; // $Id$
3category="Commutative Algebra";
4info="
5LIBRARY:  graal.lib          localization at prime ideals and their associated graded rings
6AUTHOR:   Magdaleen Marais,  magdaleen@aims.ac.za
7          Yue Ren,           ren@mathematik.uni-kl.de
8
9OVERVIEW:
10This library is on a computational treatment of localizations at prime ideals
11and their associated graded rings based on a work of Mora.
12Not only does it construct a ring isomorphic to the localization of an affine
13coordinate ring at a prime ideal,
14the algorithms in this library aim to exploit the topology in the localization
15by computing first and foremost in the associated graded ring and lifting
16the result to the localization afterwards.
17Features include a check for regularity and the resolution of ideals.
18
19REFERENCES:
20Mora, Teo: La queste del Saint Gr_a(A_L): A computational approach to local algebra
21Marais, Magdaleen and Ren, Yue: Mora's holy graal: Algorithms for computing in localizations at prime ideals
22
23PROCEDURES:
24graalMixed(ideal L[,int t]);              contruct graalBearer
25dimensionOfLocalization(def L);           dimension of the localization A_L of A at L
26systemOfParametersOfLocalization(def L);  system of parameter of the localization A_L of A at L
27isLocalizationRegular(def L);             test if localization A_L of A at L is regular
28warkedPreimageStd(warkedModule wM);       std for warkedModule
29resolutionInLocalization(ideal I, def L); the resolution of I*A_L
30";
31
32LIB "general.lib";  // for watchdog
33LIB "poly.lib";     // for hilbPoly
34LIB "standard.lib"; // for res
35
36proc mod_init()
37{
38  /***
39   * graalBearer is a structure that contains those objects
40   * of the intermediate steps to computing the associated graded algebra
41   * that are worth saving for future computations. These are:
42   *
43   * ring A      affine coordinate ring
44   * ideal L     ideal cutting out the subvariety
45   * int s       number of generators of L
46   * ring Q      polynomial ring of the ambient space
47   * ideal H     ideal such that A=Q/H
48   * ideal J     preimage of L
49   * ring Q0y    Q^0[Y1,...,Ys]
50   * ideal scriptI <Y1-f1,...,Ys-fs>, where f1,...,fs are the generators of L
51   * ring Al     the ring A_L = Q0y/scriptI
52   * ring Ky     K[Y1,...,Ys], where K quotient field of A/L
53   * ideal scriptIin I_in
54   * ring Graal associated graded ring, isomorphic to Ky/scriptIin
55   * map ina     Al -> Graal, maps standard basis of ideals
56   *               to standard basis of their respective initial ideals
57   **/
58  newstruct("graalBearer","int s, ring A, ideal L, ring Q, ideal H, ideal J, ring Q0, ideal J0, ring Q0y, ideal scriptI, ring Al, ring Ky, ideal scriptIin, map Q0yToKy, ring Graal, map ina");
59  system("install","graalBearer","print",graalBearer_print,1);
60
61  /***
62   * warkedModule is a structure built to hold two corresponding modules in Ay and Ky respectively.
63   * More precisely, it contains space for:
64   * graalBearer Gr   a graalBearer containing all relevant global structures
65   * module modQ0y      a module M over Q0y
66   * module stdmodQ0y   a standard basis of M with respect to the weight w
67   * matrix qQ0y        a transformation matrix over Q0y such that
68   *                      stdmodAy = qQ0y*modQ0y
69   * module modKy       a module M_in over Ky
70   * module stdmodKy    a standard basis of M_in
71   * matrix qKy         a transformation Matrix over Ky such that
72   *                      stdmodKy = qKy*modKy
73   * intvec w           an intvec containing the weights on M
74   * Note: "wark" is a scots noun for building
75   **/
76  newstruct("warkedModule","graalBearer Gr, module modQ0y, module stdmodQ0y, matrix qQ0y, module modKy, module stdmodKy, matrix qKy, intvec w");
77  system("install","warkedModule","print",warkedModule_print,1);
78
79  /***
80   * markedResolution is a structure built to hold two corresponding resolutions in Al and Graal respectively.
81   * More precisely, it contains space for:
82   * graalBearer Gr      a graalBearer containing all relevant global structures
83   * ideal idealAl         a standard basis of an ideal I in Al
84   * resolution resAl      a resolution of I over Al
85   * resolution resGraal   a resolution of inI, the initial ideal of I over Graal
86   * list weight           a list containing weights on the modules in resAl
87   **/
88  newstruct("markedResolution","graalBearer Gr, ideal idealAl, resolution resAl, resolution resGraal, list weight");
89  system("install","markedResolution","print",markedResolution_print,1);
90}
91
92///////////////////////////////////////////////////////////////////////////////
93
94
95/***
96 * returns the number of Y, each of them corresponding to a generator of J.
97 * we assume that the Ys are written in the first non-"c" block of our ordering,
98 * for example (Y(1..s),X(1..n)),(c,ds(s),dp(n))
99 * or (Y(1..s),X(1..n)),(ds(s),c,dp(n))
100 * but not (X(1..n),Y(1..s)),(c,dp(s),ds(n)).
101 **/
102static proc numberOfYs()
103{
104  list L = ringlist(basering);
105  if (L[3][1][1]!="c")
106  {
107    return(size(ringlist(basering)[3][1][2]));
108  }
109  else
110  {
111    return(size(ringlist(basering)[3][2][2]));
112  }
113}
114
115
116static proc yinitial(def F, list #)
117{
118  int s;
119  if (size(#)>0 && typeof(#[1])=="int")
120    { s = #[1]; }
121  else
122    { s = numberOfYs(); }
123  if (typeof(F)=="poly")
124  {
125    int k = size(F);
126    poly inF = F[1];
127    intvec expv = leadexp(F);
128    int d = sum(intvec(expv[1..s]));
129    for (int i=2; i<=k; i++)
130    {
131      expv = leadexp(F[i]);
132      if (sum(intvec(expv[1..s])) == d)
133        { inF = inF + F[i]; }
134      else
135        { break; }
136    }
137    return(inF);
138  }
139  if (typeof(F)=="ideal")
140  {
141    int k = size(F);
142    ideal inF = yinitial(F[1]);
143    for (int i=2; i<=k; i++)
144      { inF[i] = yinitial(F[i],s); }
145    return(inF);
146  }
147}
148
149
150/***
151 * suppose X(1),...,X(n) are the variables in the ring containing g,
152 * checks whether g contains the variables X(1),...,X(n-1).
153 **/
154static proc containsVariablesApartFromLast(poly g)
155{
156  intvec expv; int d; int s = nvars(basering)-1;
157  int i,j;
158  for (j=1; j<=size(g); j++)
159  {
160    expv = leadexp(g[j]);
161    for (i=1; i<=s; i++)
162    {
163      if (expv[i] > 0)
164        { return(i); }
165    }
166  }
167  return(0);
168}
169
170
171/***
172 * assuming that the ordering is lexicographical,
173 * checks whether m is in general position with repect to it.
174 **/
175static proc isInGeneralPosition(ideal m)
176{
177  int n = nvars(basering);
178  if (n == 1)
179    { return(1); }
180
181  int k = size(m);
182  if (k == n)
183  {
184    m = sort(m)[1]; poly g;
185    for (int i=2; i<=k; i++)
186    {
187      g = m[i];
188      if (leadmonom(g)!=var(k-i+1) || containsVariablesApartFromLast(g-lead(g)))
189        { return(0); }
190    }
191    g = m[1];
192    if (containsVariablesApartFromLast(g))
193      { return(0); }
194    return(1);
195  }
196  return(0);
197}
198
199
200/***
201 * finds a transformation of the last variable
202 * which maps m into general position with respect to the lexicographical ordering lp.
203 * returns the image of the last variable under the transformation and the image of m.
204 **/
205static proc findGeneralPosition(ideal m)
206{
207  list L = ringlist(basering);
208  int newRing = 0;
209  if (L[3][1][1]!="lp" || L[3][1][2]!=nvars(basering))
210  {
211    def origin = basering;
212    ring ringForGeneralPosition = create_ring(ringlist(basering)[1], "("+varstr(basering)+")", "lp", "no_minpoly");
213    ideal m = fetch(origin,m);
214    newRing = 1;
215  }
216  ideal mGeneralPosition = std(m);
217  int n = nvars(basering); poly p = var(n);
218  while (!isInGeneralPosition(mGeneralPosition))
219  { // apply generic coordinate change to the last variable,
220    //   m -> mGeneralPosition, X_n |-> p
221    // until mGeneraliPosition is indeed in general position.
222    p = randomLast(5)[n];
223    mGeneralPosition = subst(m,var(n),p);
224    mGeneralPosition = std(mGeneralPosition);
225  }
226  if (newRing == 1)
227  {
228    setring origin;
229    ideal mGeneralPosition = fetch(ringForGeneralPosition,mGeneralPosition);
230    poly p = fetch(ringForGeneralPosition,p);
231  }
232  return(p,mGeneralPosition);
233}
234
235
236/***
237 * tries for t seconds to find a transformation of the last variable,
238 * which maps m into general position with respect to the lexicographical ordering lp.
239 * if successful, returns the image of the last variable as well as the image of m.
240 * if unsuccessful, returns (0,0) instead.
241 **/
242static proc tryFindingGeneralPosition(ideal m, int t)
243{
244  def p, mgp;
245  p, mgp = watchdog(t,"findGeneralPosition(ideal("+string(m)+"))");
246  if (typeof(p)=="string")
247    { return(0,0); }
248  return(p,mgp);
249}
250
251
252/***
253 * if mgp is in general position with respect to the lexicographical ordering lp,
254 * sorts the generators such that their order is
255 * X(1) - g(1)
256 * X(2) - g(2)
257 * ...
258 * X(n-1) - g(n-1)
259 * g(n),
260 * where g(1),...,g(n-1) are polynomials in X(n).
261 **/
262static proc sortIdealInGeneralPosition(ideal mgp)
263{
264  int k = size(mgp);
265  ideal sortedMgp; sortedMgp[k]=0;
266  ASSUME(1,size(mgp)==nvars(basering));
267  for (int i=1; i<=k; i++)
268  {
269    poly g = mgp[i];
270    int j = containsVariablesApartFromLast(g);
271    if (j>0)
272      { sortedMgp[j] = g; }
273    else
274      { sortedMgp[k] = g; }
275    kill g;
276    kill j;
277  }
278  return(sortedMgp);
279}
280
281
282/***
283 * if mgp is in general position with respect to the lexicographical ordering lp,
284 * and sorted (see above), returns g(1),...,g(n-1).
285 **/
286static proc getImagesOfPreviousX(ideal mgp)
287{
288  def origin = basering;
289  def getImagesRing = changeord(list(list("lp",nvars(basering))));
290  setring getImagesRing;
291
292  ideal mgp = fetch(origin,mgp);
293  int k = size(mgp);
294  ideal imagesOfPreviousX; imagesOfPreviousX[k]=0;
295
296  for (int i=1; i<=k; i++)
297  {
298    poly g = mgp[i];
299    ASSUME(1,leadexp(g)[i]==1);
300    if (g!=0)
301      { g = (lead(g)-g)/leadcoef(g); }
302    imagesOfPreviousX[i] = g;
303    kill g;
304  }
305
306  setring origin;
307  ideal imagesOfPreviousX = fetch(getImagesRing,imagesOfPreviousX);
308  return (imagesOfPreviousX);
309}
310
311
312proc graalMixed(ideal L, list #)
313"
314USAGE:    graalMixed(L,t); L ideal, t int (optional)
315RETURN:   graalBearer with all the necessary structures for our machinery
316          if t specified and t>0, puts an upper time limit
317            on finding a necessary transformation to map an intermediate ideal into general position.
318NOTE:     assumes that the current basering is a domain and that L is a prime ideal.
319EXAMPLE:  example graalMixed; shows an example
320"
321{
322  graalBearer Gr;
323
324  /***
325   * store ring A and ideal L
326   **/
327  Gr.A = basering; Gr.L = L;
328  int s = size(L); Gr.s = s;
329
330  /***
331   * construct ring Q and ideals H,J
332   **/
333  ideal H = ringlist(Gr.A)[4];
334  execute("ring Q = "+string(Gr.A)+";");
335  ideal H = fetch(Gr.A,H); H = sort(std(H))[1];
336  ideal J = fetch(Gr.A,L) + H; J = sort(std(J))[1];
337  Gr.Q = Q; Gr.H = H; Gr.J = J;
338
339  /***
340   * construct ring Q0 and ideal J0
341   **/
342  intvec maxIndepSet = indepSet(std(J));
343  int trdeg = sum(maxIndepSet);
344  int i; int n = nvars(Q);
345  if (trdeg > 0)
346  {
347    string pars = ","; string vars;
348    for (i=1; i<=n; i++)
349    {
350      if (maxIndepSet[i]>0)
351        { pars = pars + string(var(i)) + ","; }
352      else
353        { vars = vars + string(var(i)) + ","; }
354    }
355    pars = pars[1..size(pars)-1];
356    vars = vars[1..size(vars)-1];
357  }
358  else
359    { string pars; string vars = varstr(basering); }
360  ring Q0 = create_ring("("+charstr(basering)+pars+")", "("+vars+")", "dp");
361  ideal J0 = imap(Q,J);
362  Gr.Q0 = Q0;
363  Gr.J0 = J0;
364
365  /***
366   * push J0 into general position
367   **/
368  if (size(#)==0)
369  {
370    poly p; ideal mgp;
371    p, mgp = findGeneralPosition(J0);
372  }
373  else
374  {
375    if ((#[1]==1) && (typeof(#[1])=="int"))
376    {
377      polg p; ideal mgp;
378      p, mgp = tryFindingGeneralPosition(J0,#[1]);
379      if (p == 0)
380      {
381        ERROR("timeout during computation of minimal polynomial");
382        return(Gr);
383      }
384    }
385    else
386    {
387      ERROR("graal: unexpected optional paramemters");
388      return(Gr);
389    }
390  }
391  n = nvars(Q0);
392  mgp = sortIdealInGeneralPosition(mgp);
393  ideal imageOfX = getImagesOfPreviousX(mgp);
394  imageOfX[n] = p;
395  for (i=1; i<n; i++)
396  {
397    imageOfX[n] = subst(imageOfX[n],var(i),imageOfX[i]);
398  }
399  poly g(n) = mgp[n];
400
401  /***
402   * construct Q0y, scriptI and Al
403   **/
404  string ostring = ordstr(basering);
405  ostring = ostring[1..size(ostring)-2];
406  execute("ring Q0y = ("+charstr(basering)+"),(Y(1..s),"+varstr(basering)+"),(ds(s),c,"+ostring+")");
407  setring Q0y;
408  ideal H = imap(Gr.A,H);
409  ideal J = imap(Gr.A,L);
410  ideal scriptI = H;
411  for (i=1; i<=s; i++)
412    { scriptI = scriptI + poly(J[i]-Y(i)); }
413  scriptI = std(scriptI);
414  Gr.Q0y = Q0y;
415  Gr.scriptI = scriptI;
416  ideal inI = yinitial(scriptI,s);
417  attrib(inI,"isSB",1);
418  qring Al = scriptI;
419  Gr.Al = Al;
420
421  /***
422   * construct Ky and sigmainI
423   **/
424  execute("ring KKy = ("+charstr(Q0)+"),(Y(1..s),"+varstr(Q0,nvars(Q0))+"),(c,dp(s),dp(1));");
425  poly minpolyOfK = imap(Q0,g(n));
426  qring Ky = std(minpolyOfK);
427
428  ideal G = Y(1..s); ideal imageOfX = imap(Q0,imageOfX);
429  int j1=1;
430  for (i=1; i<=nvars(Q); i++)
431  {
432    if (maxIndepSet[i]==0)
433      { G = G, imageOfX[j1]; j1++; }
434    // if (maxIndepSet[i]>0)
435    //   { G = G, par(j2); j2++; }
436    // else
437    //   { G = G, imageOfX[j1]; j1++; }
438  }
439  map Q0yToKy = Q0y,G;
440  Gr.Q0yToKy = Q0yToKy;
441  ideal scriptIin = Q0yToKy(inI);
442  ASSUME(2,isStandardBasis(scriptIin));
443  scriptIin = std(scriptIin);
444  Gr.Ky = Ky;
445  Gr.scriptIin = scriptIin;
446
447  /***
448   * construct Graal
449   **/
450  qring Graal = scriptIin;
451  Gr.Graal = Graal;
452  map in_a = Al,imap(Ky,G);
453  Gr.ina = in_a;
454
455  return(Gr);
456}
457example
458{ "EXAMPLE:"; echo = 2;
459  // see [Mora] Example 6.5
460  ring Q = 0,(x,y,z),dp;
461  ideal H = y2-xz;
462  qring A = std(H);
463  ideal L = x3-yz,x2y-z2;
464  graalBearer Gr = graalMixed(L); Gr;
465}
466
467/***
468 * a print routine for graalBearers,
469 * will overwrite the default print routine for newstructs
470 **/
471proc graalBearer_print(graalBearer Gr)
472{
473  def A=Gr.A; setring A;
474  "affine coordinate ring: ";
475  "   "+string(Gr.A);
476  ideal quotientIdeal = ringlist(Gr.A)[4];
477  if (quotientIdeal != 0)
478    { "     mod <"+string(quotientIdeal)+">"; }
479  "";
480  "ideal defining the subvariety: ";
481  "   <"+string(Gr.L)+">";"";
482  def Al = Gr.Al; setring Al;
483  "Al: ";
484  "   "+string(Gr.Al);
485  ideal quotientIdeal = ringlist(basering)[4];
486  if (quotientIdeal != 0)
487    { "     mod <"+string(quotientIdeal)+">"; }
488  kill quotientIdeal;
489  def Graal = Gr.Graal; setring Graal;
490  "graal: ";
491  "   "+string(Gr.Graal);
492  ideal quotientIdeal = ringlist(basering)[4];
493  if (quotientIdeal != 0)
494    { "     mod <"+string(quotientIdeal)+">"; }
495  kill quotientIdeal;
496  "   where ";
497  setring Gr.A;
498  for (int i=1; i<=Gr.s; i++)
499  { "     Y("+string(i)+") represents generator "+string(Gr.L[i]); }
500  setring Al;
501  list L = ringlist(basering);
502  int yEnd = size(L[3][1][2]);
503  ideal xAll; int n = nvars(basering);
504  for (i=1; yEnd+i<=n; i++)
505    { xAll[i] = var(yEnd+i); }
506  string inaPrint = "   and "+string(xAll)+" in Al are mapped to ";
507  kill L;
508  kill xAll;
509  setring Graal;
510  map ina = Gr.ina;
511  ideal xAllImages;
512  for (i=1; yEnd+i<=n; i++)
513    { xAllImages[i] = ina[yEnd+i]; }
514  inaPrint + string(xAllImages)+" in Graal";
515  kill ina;
516  kill xAllImages;
517}
518
519/***
520 * a print routine for warkedModules,
521 * will overwrite the default print routine for newstructs
522 **/
523proc warkedModule_print(warkedModule wM)
524{
525  graalBearer Gr = wM.Gr;
526  def Q0y = Gr.Q0y; setring Q0y;
527  ideal quotientIdeal = ringlist(basering)[4];
528  "module over Q^0[Y] = "+string(basering)+" / <"+string(quotientIdeal)+">:";
529  print(matrix(wM.modQ0y));
530  "standard basis:";
531  print(matrix(wM.stdmodQ0y));
532  def Ky = Gr.Ky; setring Ky;
533  ideal quotientIdeal = ringlist(basering)[4];
534  "module over K[Y] = "+string(basering)+" / <"+string(quotientIdeal)+">:";
535  print(matrix(wM.modKy));
536  "weights on the unit vectors: "+string(wM.w);
537}
538
539/***
540 * a print routine for markedModules,
541 * will overwrite the default print routine for newstructs
542 **/
543proc markedModule_print(markedModule M)
544{
545  graalBearer Gr = M.Gr;
546  def Ay = Gr.Ky; setring Ay;
547  module G = M.G;
548  "module over Ay:";
549  print(G);
550  def Ky = Gr.Graal; setring Ky;
551  module H = M.H;
552  "module over Ky:";
553  print(H);
554}
555
556
557proc dimensionOfLocalization(def L)
558"
559USAGE:    dimensionOfLocalization(L); L ideal or graalBearer
560RETURN:   int, the dimension of the localization A_L of A at L.
561EXAMPLE:  example dimensionOfLocalization; shows an example
562"
563{
564  if (typeof(L)=="ideal")
565  {
566    graalBearer Gr = graalMixed(L);
567    return(dimensionOfLocalization(Gr));
568  }
569  if (typeof(L)=="graalBearer")
570  {
571    graalBearer Gr = L;
572    def Ky = Gr.Ky; setring Ky;
573    ideal scriptIin = Gr.scriptIin;
574    return(dim(scriptIin));
575  }
576  ERROR("dimensionOfLocalization: unexpected parameters");
577  return(0);
578}
579example
580{
581  "EXAMPLE:"; echo = 2;
582  ring Q = 0,(X(1),X(2)),dp;
583  ideal H = X(2)^2-(X(1)-1)*X(1)*(X(1)+1);
584  ideal J = std(X(1),X(2));
585  qring A = std(H);
586  ideal L = fetch(Q,J);
587  graalBearer Gr = graalMixed(L);
588  // def fA = Gr.fA; setring fA;
589  dimensionOfLocalization(Gr); // = 1
590}
591
592proc systemOfParametersOfLocalization(def L)
593"
594USAGE:    systemOfParametersOfLocalization(def L); L ideal or graalBearer
595RETURN:   ideal, a system of parameter of the localization A_L of A at L.
596EXAMPLE:  example systemOfParameterOfLocalization; shows an example
597"
598{
599  if (typeof(L)=="ideal")
600  {
601    graalBearer Gr = graalMixed(L);
602    return(systemOfParametersOfIdealInLocalization(I, Gr));
603  }
604  if (typeof(L)=="graalBearer")
605  {
606    graalBearer Gr = L;
607    def Ky = Gr.Ky; setring Ky;
608    int delta = dimensionOfLocalization(Gr);
609    int s = Gr.s;
610    int i,j;
611    ideal H1 = Gr.scriptIin;
612    for (i=1; i<=delta; i++)
613    {
614      poly lambda(i);
615      for (j=1; j<=s; j++)
616      {
617        int c(i)(j) = random(0,10000);
618        lambda(i) = lambda(i) + c(i)(j)*Y(j);
619      }
620      H1 = H1 + lambda(i);
621    }
622    H1 = std(H1);
623    while (dim(H1) != 0)
624    {
625      H1 = Gr.scriptIin;
626      for (i=1; i<=delta; i++)
627      {
628        for (j=1; j<=s; j++)
629        {
630          c(i)(j) = random(0,10000);
631          lambda(i) = lambda(i) + c(i)(j)*Y(j);
632        }
633        H1 = H1 + lambda(i);
634      }
635      H1 = std(H1);
636    }
637    def Q = Gr.Q; setring Q;
638    ideal J = Gr.J; ideal ret;
639    for (i=1; i<=delta; i++)
640    {
641      poly a(i);
642      for (j=1; j<=s; j++)
643        { a(i) = a(i)+c(i)(j)*J[i]; }
644      ret = ret + a(i);
645    }
646    def A = Gr.A; setring A;
647    return(std(fetch(Q,ret)));
648  }
649  ERROR("systemOfParametersOfLocalization: unexpected parameters");
650  return(0);
651}
652example
653{
654  "EXAMPLE:"; echo = 2;
655  ring Q = 0,(X(1),X(2)),dp;
656  ideal H = X(2)^2-(X(1)-1)*X(1)*(X(1)+1);
657  ideal J = X(1),X(2);
658  qring A = std(H);
659  ideal L = fetch(Q,J);
660  graalBearer Gr = graalMixed(L);
661  systemOfParametersOfLocalization(Gr); // = 1
662}
663
664
665/***
666 * returns true, if g only contains the last variuable.
667 * returns false otherwise.
668 **/
669static proc isPolyInLastVariable(poly g)
670{
671  int k = size(g);
672  int n = nvars(basering);
673  for (int i=1; i<=k; i++)
674  {
675    intvec v = leadexp(g[i]);
676    v = v[1..n-1];
677    if (sum(v)>0)
678    {
679      return (0);
680    }
681  }
682  return (1);
683}
684
685proc isLocalizationRegular(def L)
686"
687USAGE:    isLocalizationRegular(def L); L ideal or graalBearer
688RETURN:   int, 1 if the localization A_L of A at L is regular,
689               0 otherwise.
690EXAMPLE:  example isLocalizationRegular; shows an example
691"
692{
693  if (typeof(L)=="ideal")
694  {
695    graalBearer Gr = graalMixed(L);
696    return(isLocalizationRegular(Gr));
697  }
698  if (typeof(L)=="graalBearer")
699  {
700    graalBearer Gr = L;
701    def Ky = Gr.Ky; setring Ky;
702    ideal sscriptIin = Gr.scriptIin;
703    option(redSB);
704    sscriptIin = std(sscriptIin);
705    option(noredSB);
706    int i,j; poly gi; intvec expv;
707    int s = Gr.s;
708    for (i=1; i<=size(sscriptIin); i++)
709    {
710      gi = sscriptIin[i];
711      if (!isPolyInLastVariable(gi))
712      {
713        for (j=1; j<=size(gi); j++)
714        {
715          expv = leadexp(gi[i]);
716          if (sum(intvec(expv[1..s])) != 1)
717          { return(0); }
718        }
719      }
720    }
721    return(1);
722  }
723  ERROR("isLocalizationRegular: unexpected parameters");
724  return(0);
725}
726example
727{
728  "EXAMPLE:"; echo = 2;
729  ring Q = 0,(X(1),X(2)),dp;
730  ideal H = X(2)^2-(X(1)-1)*X(1)*(X(1)+1);
731  ideal J = X(1),X(2);
732  qring A = std(H);
733  ideal L = fetch(Q,J);
734  graalBearer Gr = graalMixed(L);
735  isLocalizationRegular(Gr); // = 1
736}
737
738
739/***
740 * returns the degree in Y
741 **/
742static proc yDeg(poly g, list #)
743{
744  int s;
745  if (size(#)>0 && typeof(#[1])=="int")
746    { s = #[1]; }
747  else
748    { s = numberOfYs(); }
749
750  intvec v = leadexp(g);
751  int d = 0;
752  for (int i=1; i<=s; i++)
753    { d = d+v[i]; }
754  return (d);
755}
756
757
758/***
759 * normalizes g such that LT_>(g)=Y^\alpha for some \alpha\in\NN^n.
760 **/
761static proc normalizeInY(vector g, graalBearer Gr, list #)
762{
763  def origin = basering;
764  int s;
765  if (size(#)>0 && typeof(#[1])=="int")
766    { s = #[1]; }
767  else
768    { s = numberOfYs(); }
769
770  // get the coefficient before Y in the leading term
771  // first isolate the first non-zero component and computes its degree in Y
772  poly cg;
773  for (int i = 1; i<=nrows(g); i++)
774  {
775    if (g[i]!=0)
776    {
777      cg = g[i];
778      break;
779    }
780  }
781  int d = yDeg(cg,s);
782  // next, sum all terms with the same degree in Y
783  poly c = cg[1];
784  for (i = 2; i<=size(g); i++)
785  {
786    if (yDeg(cg[i],s)==d)
787      { c = c+cg[i]; }
788  }
789  // and substitute all Y with 1
790  for (i=1; i<=s; i++)
791    { c = subst(c,var(i),1); }
792
793  def Q0 = Gr.Q0;
794  setring Q0;
795  ideal J0 = Gr.J0;
796  ideal J0withC = imap(origin,c), J0;
797  list L = division(1,J0withC);
798
799  ASSUME(1,L[2]==0);
800  poly a = L[1][1,1];
801
802  kill J0;
803  kill J0withC;
804  kill L;
805  setring origin;
806  poly a = imap(Q0,a);
807
808  ideal scriptI = Gr.scriptI;
809  g = reduce(a*g,scriptI);
810
811  return (a,g);
812}
813
814
815/***
816 * removes all zero columns in matrix(G),
817 * and removes the corresponding columns in Q, if they exist.
818 **/
819static proc removeZeroColumns(module G, matrix Q)
820{
821  ASSUME(1,ncols(G)>ncols(Q));
822  module Gprime;
823  matrix Qprime[nrows(Q)][ncols(Q)];
824  int newSizeG = 0;
825  int newSizeQ = 0;
826
827  for (int i=1; i<=ncols(G); i++)
828  {
829    if (G[i]!=0)
830    {
831      newSizeG++;
832      Gprime[newSizeG] = G[i];
833      if (i<=ncols(Q))
834      {
835        newSizeQ++;
836        Qprime[1..nrows(Q),newSizeQ] = Q[1..nrows(Q),i];
837      }
838    }
839  }
840  matrix QQprime[nrows(Q)][newSizeQ] = Qprime[1..nrows(Q),1..newSizeQ];
841  return (Gprime,QQprime);
842}
843
844
845proc warkedPreimageStd(warkedModule wM)
846"
847USAGE:    warkedPreimageStd(wM); M warkedModule
848RETURN:   given wM consisting of:
849          - wM.Gr        a graalBearer containing all relevant global structures
850          - wM.modQ0y      generating set G of a module M over Q0y
851          - wM.stdmodQ0y   empty
852          - wM.qQ0y        empty
853          - wM.modKy       corresponding generating set H of M_in over Ky
854          - wM.stdmodKy    empty
855          - wM.qKy         empty
856          - wM.w           weights on M
857          returns the same warkedModule, except following differences:
858          - wM.stdmodQ0y   contains a subset G such that for any standard basis L of the kernel
859                           G + L is a standard basis of modQ0y + kernel
860          - wM.qQ0y        contains a transformation matrix such that
861                             stdmodAy = QAy*modQ0y
862          - wM.stdmodKy    contains a standardbasis of modKy
863          - wM.qKy         contains a transformation matrix such that
864                             stdmodKy = QKy*modKy
865NOTE:     the standard basis of modAy is computed by lifting a corresponding
866          Groebner basis of modKy
867EXAMPLE:  example warkedPreimageStd; shows an example
868"
869{
870  ASSUME(1,checkCorrespondence(wM));
871
872  graalBearer Gr = wM.Gr;
873  // intvec w = wM.w;
874
875  def Ky = Gr.Ky; setring Ky;
876  module H = wM.modKy;
877
878  /* add generators of the kernel to H */
879  int l = ncols(H);
880  int k = nrows(H);
881  int i,j;
882  ideal scriptIin = Gr.scriptIin;
883  H = H+freemodule(k)*scriptIin;
884
885  /* compute a standard basis of H
886   * and a corresponding transformation matrix */
887  matrix Qdash;
888  module Hdash = liftstd(H,Qdash);
889
890  /* drop factors before elements of scriptIin
891   * and single out all elements of Hdash
892   * whose leading monomial does not lie in scriptIin */
893  matrix QQ[l][size(Hdash)];
894  int ncolsQQ = 0;
895  module redLHdash = reduce(lead(Hdash),lead(scriptIin));
896  for (i=1; i<=size(Hdash); i++)
897  {
898    if (redLHdash[i] != 0)
899    {
900      ncolsQQ++;
901      QQ[1..l,ncolsQQ] = Qdash[1..l,i];
902    }
903  }
904  matrix Q[l][ncolsQQ] = QQ[1..l,1..ncolsQQ];
905  wM.qKy = Q;
906  wM.stdmodKy = Hdash;
907
908  def Q0y = Gr.Q0y; setring Q0y;
909  module G = wM.modQ0y;
910  matrix Q = imap(Ky,Q);
911  ideal scriptI = Gr.scriptI;
912  module Gdash = reduce(matrix(G)*Q,scriptI);
913  poly a;
914  for (i=1; i<=size(Gdash); i++)
915  {
916    a,Gdash[i] = normalizeInY(Gdash[i],Gr);
917    Q[1..l,i] = a*Q[1..l,i];
918  }
919  ASSUME(1,isStandardBases(Gdash));
920  Gdash = Gdash + freemodule(k)*scriptI;
921
922  Gdash = simplify(Gdash,32);
923  Gdash,Q = removeZeroColumns(Gdash,Q);
924
925
926  wM.qQ0y = Q;
927  wM.stdmodQ0y = Gdash;
928
929  return(wM);
930}
931example
932{ "EXAMPLE:"; echo = 2;
933  ring Q = 0,(x,y,z),dp;
934  ideal H = y2-xz;
935  qring A = std(H);
936  ideal L = x3-yz,x2y-z2;
937  graalBearer Gr = graalMixed(L);
938  def Q0y = Gr.Q0y; setring Q0y;
939
940  module M = (Y(1)*y+y^2-1)*gen(1)+(Y(2)*z+z^2-1)*gen(2), Y(1)*y*gen(1)+Y(2)*z*gen(2);
941  /* This is M: */
942  print(matrix(M));
943  intvec w = 1,1,1;
944  warkedModule wM;
945  wM.Gr = Gr;
946  wM.modQ0y = M;
947  wM.w = w;
948
949  def Ky = Gr.Ky; setring Ky;
950  module Min = (y^2-1)*gen(1)+(z^2-1)*gen(2),Y(1)*y*gen(1)+Y(2)*z*gen(2);
951  /* This is M_in: */
952  print(matrix(Min));
953  wM.modKy = Min;
954
955  /* warkedPreimageStd yields the same standard basis as std: */
956  warkedModule wN = warkedPreimageStd(wM); wN;
957  setring Q0y;
958  module stdM = std(M);
959  print(matrix(stdM));
960}
961
962proc markedResolution_print(markedResolution mr)
963{
964  graalBearer Gr = mr.Gr;
965
966  "resolution over Al:";
967  def Al = Gr.Al; setring Al;
968  resolution resAl = mr.resAl;
969  resAl;
970  for (int i=1; i<=ressize(resAl); i++)
971  {
972    "k="+string(i);
973    print(module(resAl[i]));
974    "";
975  }
976
977  "resolution over Graal:";
978  def Graal = Gr.Graal; setring Graal;
979  resolution resGraal = mr.resGraal;
980  resGraal;
981  for (i=1; i<=ressize(resGraal); i++)
982  {
983    "k="+string(i);
984    print(module(resGraal[i]));
985    "";
986  }
987}
988
989
990/***
991 * returns the size of a resolution.
992 **/
993static proc ressize(resolution res)
994{
995  for (int i=1; i<=size(res); i++)
996  {
997    if (res[i]==0)
998    {
999      return (i-1);
1000    }
1001  }
1002  return (size(res));
1003}
1004
1005
1006/***
1007 * given rh consisting of:
1008 *  - rh.Gr          a graalBearer containing all relevant global structures
1009 *  - rh.idealAl     a standard basis of an ideal I in Al
1010 *  - rh.resAl       a resolution with only a single entry,
1011 *                     generators of I corresponding to the generators of inI
1012 *  - rh.resGraal    a resolution of inI, the initial ideal inI of I over Graal
1013 *  - rh.weights     an empty list of weights for the modules in resAl
1014 * liftRes lifts the given resolution of inI to a resolution of I
1015 **/
1016static proc liftRes(markedResolution rh)
1017{
1018  graalBearer Gr = rh.Gr;
1019
1020  /* before anything initiate a list with the generators of I
1021     for the resolution over Al
1022     and read out the resolution over Graal */
1023  def Al = Gr.Al; setring Al;
1024  ideal I = rh.idealAl;
1025  list resAl = I;
1026
1027  def Graal = Gr.Graal; setring Graal;
1028  resolution resGraal = rh.resGraal;
1029  int k = ressize(resGraal);
1030  ideal inI = resGraal[1];
1031
1032  /* before lifting the first segment of the resolution,
1033     find suitable preimages of the generators of I and inI */
1034  int i = 1;
1035  def Ky = Gr.Ky; setring Ky;
1036  ideal scriptIin = Gr.scriptIin;
1037  ASSUME(1,reduce(std(scriptIin),scriptIin)==0); // check whether it is standard basis
1038  attrib(scriptIin,"isSB",1);                    // and set corresponding flag to 1
1039  ideal H(i) = imap(Graal,inI);
1040  ASSUME(1,lead(H(i))==lead(reduce(H(i),scriptIin))); // H(i) should already be in reduced form,
1041                                                      // since inI was a standard basis
1042
1043  def Q0y = Gr.Q0y; setring Q0y;
1044  ideal scriptI = Gr.scriptI;
1045  ASSUME(1,reduce(std(scriptI),scriptI)==0); // check whether it is standard basis
1046  attrib(scriptI,"isSB",1);                  // and set corresponding flag to 1
1047  ideal G(i) = imap(Al,I);
1048  ASSUME(1,lead(G(i))==lead(reduce(G(i),scriptI))); // G(i) should already be in reduced form,
1049                                                    // since I was a standard basis
1050
1051  /* lifting the first segment of the resolution,
1052   * i.e. syzygies of the generators Theta of inI to
1053   * syzygies of the generators Delta of I */
1054
1055  /* note that I already is already in standard bases form,
1056   * which is why G(i)+scriptI is a standard bases */
1057  /* next, we need a standard basis of the preimage of I */
1058  setring Q0y;
1059  ideal Gdash(i) = G(i) + scriptI;
1060  ASSUME(2,isStandardBasis(Gdash(i)));
1061  attrib(Gdash(i),"isSB",1);
1062  matrix Q(i)[size(G(i))][size(Gdash(i))];
1063  for (int j=1; j<=size(G(i)); j++)
1064    { Q(i)[j,j]=1; }
1065
1066  for (i=2; i<=k; i++)
1067  {
1068    setring Graal;
1069    module syzTheta = resGraal[i];
1070
1071    // pick homogeneous representatives of hs eta in syzTheta
1072    setring Ky;
1073    module H(i) = imap(Graal,syzTheta);
1074    H(i) = reduce(H(i),scriptIin);
1075
1076    // lift them to gs in Q0y, substitute elements of G for the unit vectors
1077    // and reduce the result
1078    setring Q0y;
1079    module G(i) = imap(Ky,H(i));
1080    module R = matrix(G(i-1))*matrix(G(i));
1081    R = reduce(R,scriptI);
1082
1083    // compute a standard representation of the remainder
1084    // with respect to G'
1085    list L = division(R,Gdash(i-1));
1086    matrix D = L[1];
1087    ASSUME(1,L[2]==0);
1088    ASSUME(1,isDiagonalMatrixOfOnes(L[3]));
1089
1090    // correct the gs by our result
1091    matrix QD = Q(i-1)*D;
1092    G(i) = module(matrix(G(i))-QD);
1093    setring Al;
1094    resAl[i] = imap(Q0y,G(i));
1095
1096    // extend it to standard basis GDash(i)
1097    // and transformation matrix for next step
1098    warkedModule wM;
1099    wM.Gr = Gr;
1100
1101    setring Ky;
1102    wM.modKy = H(i);
1103
1104    setring Q0y;
1105    wM.modQ0y = G(i);
1106
1107    wM = warkedPreimageStd(wM);
1108    matrix Q(i) = wM.qQ0y;
1109    module Gdash(i) = wM.modQ0y;
1110
1111    // cleanup
1112    setring Graal;
1113    kill syzTheta;
1114    setring Q0y;
1115    kill R;
1116    kill L;
1117    kill D;
1118    kill QD;
1119  }
1120
1121  setring Al;
1122  rh.resAl = resolution(resAl);
1123  return(rh);
1124}
1125
1126
1127/***
1128 * Given two ideals with the same generators modulo ordering
1129 * returns an intvec that respresents a permutation of the generators
1130 **/
1131static proc getPermutation(ideal I1, ideal I2)
1132{
1133  ASSUME(1,size(I1)==size(I2));
1134  int i,j;
1135  intvec perm;
1136  for (i=1; i<=size(I1); i++)
1137  {
1138    for (j=1; j<=size(I2); j++)
1139    {
1140      if (I1[i]==I2[j])
1141      {
1142        perm[i] = j;
1143      }
1144    }
1145  }
1146  for (i=1; i<=size(perm); i++)
1147  {
1148    ASSUME(1,perm[i]>0);
1149  }
1150  return(perm);
1151}
1152
1153
1154/***
1155 * Given an intvec representing a permutation,
1156 * permutes the generators of the ideal.
1157 **/
1158static proc permuteGenerators(ideal I, intvec perm)
1159{
1160  ASSUME(1,size(I)==size(perm));
1161  ideal J;
1162  for (int i=1; i<=size(perm); i++)
1163  {
1164    J[i]=I[perm[i]];
1165  }
1166  return (J);
1167}
1168
1169
1170proc resolutionInLocalization(ideal I, def L)
1171"
1172USAGE:    resolutionInLocalization(I,L); I ideal, L ideal or graalBearer
1173RETURN:   the resolution of I*A_L, where
1174            A_L is the localization of the current basering (possibly a quotient ring)
1175            at a prime ideal L.
1176EXAMPLE:  example resolutionInLocalization; shows an example
1177"
1178{
1179  if (typeof(L)=="ideal")
1180  {
1181    graalBearer Gr = graalMixed(L);
1182    return(resolutionInLocalization(I,Gr));
1183  }
1184  if (typeof(L)=="graalBearer")
1185  {
1186    graalBearer Gr = L;
1187    def origin = basering;
1188    def Al = Gr.Al; setring Al;
1189    ideal I = imap(origin,I);
1190    I = std(I);
1191    int s = Gr.s;
1192    markedResolution mr;
1193    mr.idealAl = I;
1194    ideal inI = yinitial(I,s);
1195    def Graal = Gr.Graal;
1196    setring Graal;
1197    ideal inI = Gr.ina(inI);
1198    ASSUME(1,isStandardBasis(inI));
1199    attrib(inI,"isSB",1);
1200    resolution resInI = res(inI,0);
1201    resInI = minres(resInI);
1202    mr.Gr = Gr;
1203    mr.resGraal = resInI;
1204    ideal inJ = resInI[1];
1205    intvec perm = getPermutation(inI,inJ);
1206    setring Al;
1207    mr.idealAl = permuteGenerators(I,perm);
1208    mr = liftRes(mr);
1209    return(mr);
1210  }
1211  ERROR("resolutionInLocalization: unexpected parameters");
1212  return(0);
1213}
1214example
1215{ "EXAMPLE:"; echo = 2;
1216  ring Q = 0,(x,y,z,w),dp;
1217  ideal circle = (x-1)^2+y^2-3,z;
1218  ideal twistedCubic = xz-y2,yw-z2,xw-yz,z;
1219  ideal I = std(intersect(circle,twistedCubic));
1220
1221  // the resolution is more complicated due to the twisted cubic
1222  res(I,0);
1223
1224  // however if we localize outside of the twisted cubic,
1225  // it should become very easy again.
1226  ideal L = std(I+ideal(x-1));
1227  graalBearer Gr = graalMixed(L); Gr;
1228  markedResolution mr = resolutionInLocalization(I,Gr);
1229  mr;
1230}
1231
1232
1233/***
1234 * debug code
1235 **/
1236static proc isConstantUnit(poly p)
1237{
1238  return(cleardenom(p)==1);
1239}
1240static proc isConstantMultiple(vector v, vector w)
1241{
1242  module M = v,w;
1243  M = simplify(M,8);
1244  if (M[2]!=0)
1245    { return(0); }
1246  return(1);
1247}
1248static proc checkColumnsUpToUnits(matrix M, matrix N)
1249{
1250  if ((ncols(M)!=ncols(N)) && (nrows(M)!=nrows(N)))
1251    { return(0); }
1252  if (nrows(M)==0)
1253    { return(1); }
1254  int i,j;
1255  vector v,w;
1256  poly p,q;
1257  for (i=ncols(M); i>0; i--)
1258  {
1259    v = M[i];
1260    w = N[i];
1261    if (!isConstantMultiple(v,w))
1262      { return(0); }
1263  }
1264  return(1);
1265}
1266/***
1267 * returns 1, if wM.modAy and wM.modKy correspond to each other
1268 *   and wm.stdmodAy and wm.stdmodKy correspond to each other.
1269 * returns 0 otherwise.
1270 **/
1271static proc checkCorrespondence(warkedModule wM)
1272{
1273  return (1);
1274  graalBearer Gr = wM.Gr;
1275  intvec w = wM.w;
1276  def Ky = Gr.Ky;
1277  setring Ky;
1278  map Q0yToKy = Gr.Q0yToKy;
1279  def Q0y = Gr.Q0y;
1280  setring Q0y;
1281
1282  module G1 = wM.modQ0y;
1283  if (G1 != 0)
1284  {
1285    G1 = vectorInitial(G1,w);
1286    setring Ky;
1287    module H10 = wM.modKy;
1288    if (H10 != 0)
1289    {
1290      module H11 = Q0yToKy(G1);
1291      if (matrix(H10)!=matrix(H11))
1292      { return(0); }
1293    }
1294    setring Q0y;
1295  }
1296
1297  module G2 = wM.stdmodQ0y;
1298  if (G2 != 0)
1299  {
1300    G2 = vectorInitial(G2,w);
1301    setring Ky;
1302    module H20 = wM.stdmodKy;
1303    if (H20 != 0)
1304    {
1305      module H21 = Q0yToKy(G2);
1306      if (matrix(H20)!=matrix(H21))
1307      { return(0); }
1308    }
1309  }
1310
1311  return(1);
1312}
1313/***
1314 * checks whether U is a diagonal matrix consisting of 1's
1315 **/
1316static proc isDiagonalMatrixOfOnes(matrix U)
1317{
1318  if (nrows(U)!=ncols(U))
1319    { return(0); }
1320  int j,j;
1321  for (i=1; i<=nrows(U); i++)
1322  {
1323    for (j=1; j<=ncols(U); j++)
1324    {
1325      if (i==j && U[i,j]!=number(1))
1326        { return(0); }
1327      if (i!=j && U[i,j]!=number(0))
1328        { return(0); }
1329    }
1330  }
1331  return(1);
1332}
1333/***
1334 * returns 1 if I is a standard basis, returns 0 otherwise,
1335 **/
1336static proc isStandardBasis(ideal I)
1337{
1338  ideal LI = lead(std(I));
1339  attrib(LI,"isSB",1);
1340  ideal LII = lead(I);
1341  attrib(LII,"isSB",1);
1342  /* checks whether lead(I) generates the leading ideal */
1343  if (simplify(reduce(LI,LII),2)!=0)
1344  {
1345    ERROR("isStandardBasis: input ideal no standard basis!");
1346    return(0);
1347  }
1348  /* the following case should never happen mathematically,
1349   * left the check for sake of completeness */
1350  if (simplify(reduce(LII,LI),2)!=0)
1351  {
1352    ERROR("isStandardBasis: input ideal no standard basis!");
1353    return(0);
1354  }
1355  return(1);
1356}
Note: See TracBrowser for help on using the repository browser.