source: git/Singular/LIB/spcurve.lib

spielwiese
Last change on this file was 594560, checked in by Hans Schoenemann <hannes@…>, 16 months ago
call std in many places only if attribute isSB is not set
  • Property mode set to 100644
File size: 31.1 KB
Line 
1//////////////////////////////////////////////////////////////////////////
2version="version spcurve.lib 4.3.1.3 Jan_2023 "; // $Id$
3category="Singularities";
4info="
5LIBRARY: spcurve.lib    Deformations and Invariants of CM-codim 2 Singularities
6AUTHOR:  Anne Fruehbis-Krueger, anne@mathematik.uni-kl.de
7
8PROCEDURES:
9 isCMcod2(i);            presentation matrix of the ideal i, if i is CM
10 CMtype(i);              Cohen-Macaulay type of the ideal i
11 matrixT1(M,n);          1st order deformation T1 in matrix description
12 semiCMcod2(M,T1);       semiuniversal deformation of maximal minors of M
13 discr(sem,n);           discriminant of semiuniversal deformation
14 qhmatrix(M);            weights if M is quasihomogeneous
15 relweight(N,W,a);       relative matrix weight of N w.r.t. weights (W,a)
16 posweight(M,T1,i);      deformation of coker(M) of non-negative weight
17 KSpencerKernel(M);      kernel of the Kodaira-Spencer map
18";
19
20LIB "elim.lib";
21LIB "homolog.lib";
22LIB "inout.lib";
23LIB "polylib.lib";
24/////////////////////////////////////////////////////////////////////////////
25
26proc isCMcod2(ideal kurve)
27"USAGE:   isCMcod2(i);   i an ideal
28RETURN:  presentation matrix of i, if i is Cohen-Macaulay of codimension 2 @*
29         a zero matrix otherwise
30EXAMPLE: example isCMcod2; shows an example"
31{
32  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
33//---------------------------------------------------------------------------
34// Compute a minimal free resolution of the ideal and check if the
35// resolution has the expected structure
36//---------------------------------------------------------------------------
37  list kurveres=mres(kurve,0);
38  matrix M=kurveres[2];
39  if ((size(kurveres)>3) &&
40         ((size(kurveres[3])>1) ||
41          ((size(kurveres[3])<=1) && (kurveres[3][1,1]!=0))))
42  {
43    dbprint(p,"//not Cohen-Macaulay, codim 2");
44    matrix ret=0;
45    return(ret);
46  }
47  return(M);
48}
49example
50{ "EXAMPLE:"; echo=2;
51  ring r=32003,(x,y,z),ds;
52  ideal i=xz,yz,x^3-y^4;
53  print(isCMcod2(i));
54}
55/////////////////////////////////////////////////////////////////////////////
56
57proc CMtype(ideal kurve)
58"USAGE:   CMtype(i);  i an ideal, CM of codimension 2
59RETURN:  Cohen-Macaulay type of i (integer)
60         (-1, if i is not Cohen-Macaulay of codimension 2)
61EXAMPLE: example CMtype; shows an example"
62{
63  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
64  int gt = -1;
65//---------------------------------------------------------------------------
66// Compute a minimal free resolution of the ideal and check if the
67// resolution has the expected structure
68//---------------------------------------------------------------------------
69  list kurveres;
70  kurveres=mres(kurve,0);
71  if ((size(kurveres)>3) &&
72         ((size(kurveres[3])>1) ||
73          ((size(kurveres[3])<=1) && (kurveres[3][1,1]!=0))))
74  {
75    dbprint(p,"//not Cohen-Macaulay, codim 2");
76    return(gt);
77  }
78//---------------------------------------------------------------------------
79// Return the Cohen-Macaulay type of i
80//---------------------------------------------------------------------------
81  matrix M = matrix(kurveres[2]);
82  gt = ncols(M);
83  return(gt);
84}
85example
86{ "EXAMPLE:"; echo=2;
87  ring r=32003,(x,y,z),ds;
88  ideal i=xy,xz,yz;
89  CMtype(i);
90}
91/////////////////////////////////////////////////////////////////////////////
92
93proc matrixT1(matrix M ,int n)
94"USAGE:   matrixT1(M,n);  M matrix, n integer
95ASSUME:  M is a presentation matrix of an ideal i, CM of codimension 2;
96         consider i as a family of ideals in a ring in the first n
97         variables where the remaining variables are considered as
98         parameters
99RETURN:  list consisting of the k x (k+1) matrix M and a module K_M such that
100         T1=Mat(k,k+1;R)/K_M is the space of first order deformations of i
101EXAMPLE: example matrixT1; shows an example"
102{
103  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
104//--------------------------------------------------------------------------
105// Initialization and sanity checks
106//--------------------------------------------------------------------------
107  int nr=nrows(M);
108  int nc=ncols(M);
109  if ( nr < nc )
110  {
111    M=transpose(M);
112    int temp=nc;
113    nc=nr;
114    nr=temp;
115    int tra=1;
116  }
117  if ( nr != (nc+1) )
118  {
119    ERROR("not a k x (k+1) matrix");
120  }
121//---------------------------------------------------------------------------
122// Construct the denominator - step by step
123// step 1: initialization
124//---------------------------------------------------------------------------
125  int gt=nc;
126  int i,j;
127  ideal m = M;
128  ideal dx;
129  ideal rv;
130  ideal lv;
131  matrix R[gt][gt]=0;
132  matrix L[gt+1][gt+1]=0;
133  matrix T1[n+gt*gt+(gt+1)*(gt+1)][gt*(gt+1)] = 0;
134//---------------------------------------------------------------------------
135// step 2: the derivatives of the matrix are generators of the denominator
136//---------------------------------------------------------------------------
137  for( i=1; i<= n; i++ )
138  {
139    dx=diff(m,var(i));
140    T1[i,1..gt*(gt+1)] = dx;
141  }
142//---------------------------------------------------------------------------
143// step 3: M*R is a generator as well
144//---------------------------------------------------------------------------
145  for( i=1; i <= gt; i++ )
146  {
147    for ( j=1 ; j <= gt ; j++ )
148    {
149      R[i,j]=1;
150      rv = M * R;
151      T1[n+(i-1)*gt+j,1..gt*(gt+1)] = rv;
152      R[i,j]=0;
153    }
154  }
155//---------------------------------------------------------------------------
156// step 4: so is L*M
157//---------------------------------------------------------------------------
158  for( i=1; i <= (gt+1); i++)
159  {
160    for( j=1 ; j <= (gt+1);j++ )
161    {
162      L[i,j]=1;
163      lv = L * M;
164      T1[n+gt*gt+(i-1)*(gt+1)+j,1..gt*(gt+1)] = lv;
165      L[i,j]=0;
166    }
167  }
168//---------------------------------------------------------------------------
169// Compute the vectorspace basis of T1
170//---------------------------------------------------------------------------
171  module t1 = module(transpose(T1));
172  list result=M,t1;
173  return(result);
174}
175example
176{ "EXAMPLE:"; echo = 2;
177  ring r=32003,(x(1),x(2),x(3)),ds;
178  ideal curve=x(1)*x(2),x(1)*x(3),x(2)*x(3);
179  matrix M=isCMcod2(curve);
180  matrixT1(M,3);
181}
182/////////////////////////////////////////////////////////////////////////////
183
184proc semiCMcod2(matrix M, module t1,list #)
185"USAGE:   semiCMcod2(M,t1[,s]); M matrix, t1 module, s any
186ASSUME:  M is a presentation matrix of an ideal i, CM of codimension 2,
187         and t1 is a presentation of the space of first order deformations
188         of i ((M,t1) as returned by the procedure matrixT1)
189RETURN:  new ring in which the ideal semi describing the semiuniversal
190         deformation of i;
191         if the optional third argument is given, the perturbation matrix
192         of the semiuniversal deformation is returned instead of the ideal.
193NOTE:    The current basering should not contain any variables named
194         A(j) where j is some integer!
195EXAMPLE: example semiCMcod2; shows an example"
196{
197  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
198//---------------------------------------------------------------------------
199// Initialization
200//---------------------------------------------------------------------------
201  if(!attrib(t1,"isSB")) { t1=std(t1); }
202  module t1erz=kbase(t1);
203  int tau=vdim(t1);
204  int gt=ncols(M);
205  int i;
206  def r=basering;
207  if(size(M)!=gt*(gt+1))
208  {
209    gt=gt-1;
210  }
211  for(i=1; i<=size(t1erz); i++)
212  {
213    if(rvar(A(i)))
214    {
215      int jj=-1;
216      break;
217    }
218  }
219  if (defined(jj)>1)
220  {
221    if (jj==-1)
222    {
223      ERROR("Your ring contains a variable T(i)!");
224    }
225  }
226//---------------------------------------------------------------------------
227// Definition of the new ring and the image of M and t1 in the new ring
228//---------------------------------------------------------------------------
229  ring rtemp=0,(A(1..tau)),dp;
230  def rneu=r+rtemp;
231  setring rneu;
232  matrix M=imap(r,M);
233  ideal m=M;
234  module t1erz=imap(r,t1erz);
235//---------------------------------------------------------------------------
236// Construction of the presentation matrix of the versal deformation
237//---------------------------------------------------------------------------
238  matrix N=matrix(m);
239  matrix Mtemp[gt*(gt+1)][1];
240  for( i=1; i<=tau; i++)
241  {
242    Mtemp=t1erz[i];
243    N=N+A(i)*transpose(Mtemp);
244  }
245  ideal n=N;
246  matrix O[gt+1][gt]=n;
247//---------------------------------------------------------------------------
248// Construction of the return value
249//---------------------------------------------------------------------------
250  if(size(#)>0)
251  {
252    matrix semi=O;
253  }
254  else
255  {
256    ideal semi=minor(O,gt);
257  }
258  export semi;
259  return(rneu);
260}
261example
262{ "EXAMPLE:"; echo=2;
263  ring r=32003,(x(1),x(2),x(3)),ds;
264  ideal curve=x(1)*x(2),x(1)*x(3),x(2)*x(3);
265  matrix M=isCMcod2(curve);
266  list l=matrixT1(M,3);
267  def rneu=semiCMcod2(l[1],std(l[2]));
268  setring rneu;
269  semi;
270}
271/////////////////////////////////////////////////////////////////////////////
272
273proc discr(ideal kurve, int n)
274"USAGE:   discr(sem,n);  sem ideal, n integer
275ASSUME:  sem is the versal deformation of an ideal of codimension 2. @*
276         The first n variables of the ring are treated as variables
277         all the others as parameters.
278RETURN:  ideal describing the discriminant
279NOTE:    This is not a powerful algorithm!
280EXAMPLE: example discr; shows an example"
281{
282  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
283//---------------------------------------------------------------------------
284// some sanity checks and initialization
285//---------------------------------------------------------------------------
286  int i;
287  ideal sem=std(kurve);
288  ideal semdiff;
289  ideal J2;
290  int ncol=ncols(matrix(sem));
291  matrix Jacob[n][ncol];
292//---------------------------------------------------------------------------
293// compute the Jacobian matrix
294//---------------------------------------------------------------------------
295  for (i=1; i<=n; i++)
296  {
297    semdiff=diff(sem,var(i));
298    Jacob[i,1..ncol]=semdiff;
299  }
300//---------------------------------------------------------------------------
301// eliminate the first n variables in the ideal generated by
302// the versal deformation and the 2x2 minors of the Jacobian
303//---------------------------------------------------------------------------
304  semdiff=minor(Jacob,2);
305  J2=sem,semdiff;
306  J2=std(J2);
307  poly eli=1;
308  for(i=1; i<=n; i++)
309  {
310    eli=eli*var(i);
311  }
312  ideal dis=eliminate(J2,eli);
313  return(dis);
314}
315example
316{ "EXAMPLE:"; echo=2;
317  ring r=32003,(x(1),x(2),x(3)),ds;
318  ideal curve=x(1)*x(2),x(1)*x(3),x(2)*x(3);
319  matrix M=isCMcod2(curve);
320  list l=matrixT1(M,3);
321  def rneu=semiCMcod2(l[1],std(l[2]));
322  setring rneu;
323  discr(semi,3);
324}
325/////////////////////////////////////////////////////////////////////////////
326
327proc qhmatrix(matrix M)
328"USAGE:   qhmatrix(M);   M a k x (k+1) matrix
329RETURN:  list, consisting of an integer vector containing the weights of
330         the variables of the basering and an integer matrix giving the
331         weights of the entries of M, if M is quasihomogeneous;
332         zero integer vector and zero integer matrix, if M is not
333         quasihomogeneous, i.e. does not allow row and column weights
334EXAMPLE: example qhmatrix; shows an example"
335{
336  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
337//---------------------------------------------------------------------------
338// Initialization and sanity checks
339//---------------------------------------------------------------------------
340  def r=basering;
341  int i,j,temp;
342  int tra=0;
343  int nr=nrows(M);
344  int nc=ncols(M);
345  if ( nr > nc )
346  {
347    M=transpose(M);
348    temp=nc;
349    nc=nr;
350    nr=temp;
351    tra=1;
352  }
353  if ( nc != (nr+1) )
354  {
355    ERROR("not a k x (k+1) matrix");
356  }
357  ideal m=minor(M,nr);
358//---------------------------------------------------------------------------
359// get the weight using the fact that the matrix is quasihomogeneous, if
360// its maximal minors are, and check, whether M is really quasihomogeneous
361//---------------------------------------------------------------------------
362  intvec a=weight(m);
363  list l1 = ring_list(r)[2];
364  ring rneu = create_ring(ring_list(r)[1], l1, "Ws(" + string(a) + ")", "no_minpoly");
365  def M=imap(r,M);
366  int difset=0;
367  list l;
368  int dif;
369  int donttest=0;
370  int comprow=0;
371  intmat W[nr][nc];
372//---------------------------------------------------------------------------
373// find a row not containing a 0
374//---------------------------------------------------------------------------
375  for(i=1; i<=nr; i++)
376  {
377    if(comprow==0)
378    {
379      comprow=i;
380      for(j=1; j<=nc; j++)
381      {
382        if(M[i,j]==0)
383        {
384          comprow=0;
385          break;
386        }
387      }
388    }
389  }
390//---------------------------------------------------------------------------
391// get the weights of the comprow'th row or use emergency exit
392//---------------------------------------------------------------------------
393  if(comprow==0)
394  {
395    intvec v=0;
396    intmat V=0
397    list ret=v,V;
398    return(ret);
399  }
400  else
401  {
402    for(j=1; j<=nc; j++)
403    {
404      l[j]=deg(lead(M[comprow,j]));
405    }
406  }
407//---------------------------------------------------------------------------
408// do the checks
409//---------------------------------------------------------------------------
410  for(i=1; i<=nr; i++)
411  {
412    if ( i==comprow )
413    {
414// this row should not be tested against itself
415      donttest=1;
416    }
417    else
418    {
419// initialize the difference of the rows, but ignore 0-entries
420      if (M[i,1]!=0)
421      {
422        dif=deg(lead(M[i,1]))-l[1];
423        difset=1;
424      }
425      else
426      {
427        list memo;
428        memo[1]=1;
429      }
430    }
431// check column by column
432    for(j=1; j<=nc; j++)
433    {
434      if(M[i,j]==0)
435      {
436        if(defined(memo)!=0)
437        {
438          memo[size(memo)+1]=j;
439        }
440        else
441        {
442          list memo;
443          memo[1]=j;
444        }
445      }
446      temp=deg(lead(M[i,j]));
447      if((difset!=1) && (donttest!=1) && (M[i,j]!=0))
448      {
449// initialize the difference of the rows, if necessary - still ignore 0s
450        dif=deg(lead(M[i,j]))-l[j];
451        difset=1;
452      }
453// is M[i,j] quasihomogeneous - else emergency exit
454      if(M[i,j]!=jet(M[i,j],temp,a)-jet(M[i,j],temp-1,a))
455      {
456        intvec v=0;
457        intmat V=0;
458        list ret=v,V;
459        return(ret);
460      }
461      if(donttest!=1)
462      {
463// check row and column weights - else emergency exit
464        if(((temp-l[j])!=dif) && (M[i,j]!=0) && (difset==1))
465        {
466          intvec v=0;
467          intmat V=0;
468          list ret=v,V;
469          return(ret);
470        }
471      }
472// set the weight matrix entry
473      W[i,j]=temp;
474    }
475// clean up the 0's we left out
476    if((difset==1) && (defined(memo)!=0))
477    {
478      for(j=1; j<=size(memo); j++)
479      {
480        W[i,memo[j]]=dif+l[memo[j]];
481      }
482      kill memo;
483    }
484    donttest=0;
485  }
486//---------------------------------------------------------------------------
487// transpose, if M was transposed during initialization, and return the list
488//---------------------------------------------------------------------------
489  if ( tra==1 )
490  {
491    W=transpose(W);
492  }
493  setring r;
494  list ret=a,W;
495  return(ret);
496}
497example
498{ "EXAMPLE:"; echo=2;
499  ring r=0,(x,y,z),ds;
500  matrix M[3][2]=z,0,y,x,x^3,y;
501  qhmatrix(M);
502  pmat(M);
503}
504/////////////////////////////////////////////////////////////////////////////
505
506proc relweight(matrix N, intmat W, intvec a)
507"USAGE:   relweight(N,W,a); N matrix, W intmat, a intvec
508ASSUME:  N is a non-zero matrix
509         W is an integer matrix of the same size as N
510         a is an integer vector giving the weights of the variables
511RETURN:  integer, max(a-weighted order(N_ij) - W_ij | all entries ij) @*
512         string \"ERROR\" if sizes do not match
513EXAMPLE: example relweight; shows an example
514"
515{
516  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
517//---------------------------------------------------------------------------
518// Initialization and sanity checks
519//---------------------------------------------------------------------------
520  if ((size(N)!=size(W)) || (ncols(N)!=ncols(W)))
521  {
522    ERROR("matrix size does not match");
523  }
524  if (size(a)!=nvars(basering))
525  {
526    ERROR("length of weight vector != number of variables");
527  }
528  int i,j,temp;
529  def r=basering;
530//---------------------------------------------------------------------------
531// Comparison entry by entry
532//---------------------------------------------------------------------------
533  for(i=1; i<=nrows(N); i++)
534  {
535    for(j=1; j<=ncols(N); j++)
536    {
537      if (N[i,j]!=0)
538      {
539        temp=mindeg1(N[i,j],a)-W[i,j];
540        if (defined(ret))
541        {
542          if(temp > ret)
543          {
544            ret=temp;
545          }
546        }
547        else
548        {
549          int ret=temp;
550        }
551      }
552    }
553  }
554  return(ret);
555}
556example
557{ "EXAMPLE:"; echo=2;
558  ring r=32003,(x,y,z),ds;
559  matrix N[2][3]=z,0,y,x,x^3,y;
560  intmat W[2][3]=1,1,1,1,1,1;
561  intvec a=1,1,1;
562  relweight(N,W,a);
563}
564/////////////////////////////////////////////////////////////////////////////
565
566proc posweight(matrix M, module t1, int choose, list #)
567"USAGE:   posweight(M,t1,n[,s]); M matrix, t1 module, n int, s string @*
568         n=0 : all deformations of non-negative weight @*
569         n=1 : only non-constant deformations of non-negative weight @*
570         n=2 : all deformations of positive weight @*
571ASSUME:  M is a presentation matrix of a Cohen-Macaulay codimension 2
572         ideal and t1 is its T1 space in matrix notation
573RETURN:  new ring containing a list posw, consisting of a presentation
574         matrix describing the deformation given by the generators of T1
575         of non-negative/positive weight and the weight vector for the new
576         variables
577NOTE:   The current basering should not contain any variables named
578         T(i) where i is some integer!
579EXAMPLE: example posweight; shows an example"
580{
581//---------------------------------------------------------------------------
582// Initialization and sanity checks
583//---------------------------------------------------------------------------
584  if (size(#)>0)
585  {
586    if (typeof(#[1])=="string")
587    {
588      string newname=#[1];
589    }
590  }
591  if (attrib(t1,"isSB"))
592  {
593    module t1erz=kbase(t1);
594    int tau=vdim(t1);
595  }
596  else
597  { module t1erz=kbase(std(t1));
598    int tau=vdim(std(t1));
599  }
600  for(int i=1; i<=size(t1erz); i++)
601  {
602    if(rvar(T(i)))
603    {
604      int jj=-1;
605      break;
606    }
607  }
608  kill i;
609  if (defined(jj))
610  {
611    if (jj==-1)
612    {
613      ERROR("Your ring contains a variable T(i)!");
614    }
615  }
616  int pw=0;
617  int i;
618  def r=basering;
619  list l=qhmatrix(M);
620  int gt=ncols(M);
621  if(size(M)!=gt*(gt+1))
622  {
623    gt=gt-1;
624  }
625  matrix erzmat[gt+1][gt];
626  list erz;
627  if ((size(l[1])==1) && (l[1][1]==0) && (size(l[2])==1) && (l[2][1,1]==0))
628  {
629    ERROR("Internal Error: Problem determining the weights.");
630  }
631//---------------------------------------------------------------------------
632// Find the generators of T1 of non-negative weight
633//---------------------------------------------------------------------------
634  int relw;
635  list rlw;
636  for(i=1; i<=tau; i++)
637  {
638    erzmat=t1erz[i];
639    kill relw;
640    def relw=relweight(erzmat,l[2],l[1]);
641    if(typeof(relw)=="int")
642    {
643      if (((choose==0) && (relw>=0))
644           || ((choose==1) && (relw>=0) && (CMtype(minor(M+erzmat,gt))==gt))
645           || ((choose==2) && (relw > 0)))
646      {
647        pw++;
648        rlw[pw]=relw;
649        erz[pw]=erzmat;
650      }
651    }
652    else
653    {
654      ERROR("Internal Error: Problem determining relative weight.");
655    }
656  }
657//---------------------------------------------------------------------------
658// Definition of the new ring and the image of M and erz in the new ring
659//---------------------------------------------------------------------------
660  if(size(rlw)==0)
661  {
662    ERROR("Internal Error: Problem determining relative weight.");
663  }
664  intvec iv=rlw[1..size(rlw)];
665  ring rtemp=0,(T(1..pw)),dp;
666  def rneu=r+rtemp;
667  setring rneu;
668  matrix M=imap(r,M);
669  ideal m=M;
670// we cannot imap erz, if its size=0
671  if(pw==0)
672  {
673    list erz1;
674  }
675  else
676  {
677    list erz1=imap(r,erz);
678  }
679//---------------------------------------------------------------------------
680// Construction of the presentation matrix of the deformation
681//---------------------------------------------------------------------------
682  matrix N=matrix(m);
683  ideal mtemp;
684  matrix Mtemp[gt*(gt+1)][1];
685  for( i=1; i<=pw; i++)
686  {
687    mtemp=erz1[i];
688    Mtemp=mtemp;
689    N=N+T(i)*transpose(Mtemp);
690  }
691  ideal n=N;
692  matrix O[gt+1][gt]=n;
693//---------------------------------------------------------------------------
694// Keep the matrix and return the ring in which it lives
695//---------------------------------------------------------------------------
696  list posw=O,iv;
697  export posw;
698  return(rneu);
699}
700example
701{ "EXAMPLE:"; echo=2;
702  ring r=32003,(x(1),x(2),x(3)),ds;
703  ideal curve=(x(3)-x(1)^2)*x(3),(x(3)-x(1)^2)*x(2),x(2)^2-x(1)^7*x(3);
704  matrix M=isCMcod2(curve);
705  list l=matrixT1(M,3);
706  def rneu=posweight(l[1],std(l[2]),0);
707  setring rneu;
708  pmat(posw[1]);
709  posw[2];
710}
711/////////////////////////////////////////////////////////////////////////////
712
713proc KSpencerKernel(matrix M,list #)
714"USAGE:     KSpencerKernel(M[,s][,v]);  M matrix, s string, v intvec @*
715           optional parameters (please specify in this order, if both are
716           present):
717           *  s = first of the names of the new rings
718              e.g. \"R\" leads to ring names R and R1
719           *  v of size n(n+1) leads to the following module ordering @*
720              gen(v[1]) > gen(v[2]) > ... > gen(v[n(n+1)]) where the matrix
721              entry ij corresponds to gen((i-1)*n+j)
722ASSUME:    M is a quasihomogeneous n x (n+1) matrix where the n minors define
723           an isolated space curve singularity
724RETURN:    new ring containing the coefficient matrix KS representing
725           the kernel of the Kodaira-Spencer map of the family of
726           non-negative deformations having the given singularity as
727           special fibre
728NOTE:      * the initial basering should not contain variables with name
729             e(i) or T(i), since those variable names will internally be
730             used by the script
731           * setting an intvec with 5 entries and name watchProgress
732             shows the progress of the computations: @*
733             watchProgress[1]>0  => option(prot) in groebner commands @*
734             watchProgress[2]>0  => trace output for highcorner @*
735             watchProgress[3]>0  => output of deformed matrix @*
736             watchProgress[4]>0  => result of elimination step @*
737             watchProgress[4]>1  => trace output of multiplications with xyz
738                                    and subsequent reductions @*
739             watchProgress[5]>0  => matrix representing the kernel using print
740EXAMPLE:   example KSpencerKernel; shows an example"
741{
742  int p = printlevel-voice+3;  // p=printlevel+1 (default: p=1)
743//---------------------------------------------------------------------------
744// Initialization and sanity checks
745//---------------------------------------------------------------------------
746  intvec optvec=option(get);
747  if (size(#)>0)
748  {
749    if (typeof(#[1])=="string")
750    {
751      string newname=#[1];
752    }
753    if (typeof(#[1])=="intvec")
754    {
755      intvec desiredorder=#[1];
756    }
757    if (size(#)>1)
758    {
759      if (typeof(#[2])=="intvec")
760      {
761        intvec desiredorder=#[2];
762      }
763    }
764  }
765  if (defined(watchProgress))
766  {
767    if ((typeof(watchProgress)!="intvec") || (size(watchProgress)<5))
768    {
769      "watchProgress should be an intvec with at least 5 entries";
770      "ignoring watchProgress";
771      def kksave=watchProgress;
772      kill watchProgress;
773    }
774  }
775  option(redTail);
776  if (nvars(basering) != 3 )
777  {
778    ERROR("It should be a curve in 3 space");
779  }
780//---------------------------------------------------------------------------
781// change to a basering with the correct weihted order
782//---------------------------------------------------------------------------
783  def rt=basering;
784  list wl=qhmatrix(M);
785  if ((size(wl)!=2) || ((wl[1]==0) && (wl[2]==0)))
786  {
787    ERROR("The matrix was not n x (n+1) or not quasihomogenous");
788  }
789  string orderKSK;
790  ring r = create_ring(ring_list(rt)[1], "(x,y,z)", "Ws(" + string(wl[1]) + ")", "no_minpoly");
791  matrix M=imap(rt,M);
792  int ne=size(M);
793  if (defined(desiredorder)>1)
794  {
795    intvec iv;
796    for(int i=1;i<=size(desiredorder);i++)
797    {
798      iv[desiredorder[i]]=i;
799    }
800  }
801  else
802  {
803    intvec iv=1..ne;
804  }
805  list l=matrixT1(M,3);
806  if (dim(std(l[2])) != 0)
807  {
808    ERROR("The matrix does not define an isolated space curve singularity");
809  }
810  module t1qh=l[2];
811//--------------------------------------------------------------------------
812// Passing to a new ring with extra variables e(i) corresponding to
813// the module generators gen(i) for weighted standard basis computation
814// accepting weights for the gen(i)
815//--------------------------------------------------------------------------
816  int jj=0;
817  for(int i=1; i<=ne; i++)
818  {
819    if(rvar(e(i)))
820    {
821      jj=-1;
822    }
823  }
824  if (jj==-1)
825  {
826    ERROR("Your ring contains a variable e(i)!");
827  }
828  if(defined(desiredorder)>1)
829  {
830    orderKSK ="Ws(";
831    intvec tempiv=intvec(wl[2]);
832    for(i=1;i<=ne;i++)
833    {
834      orderKSK = orderKSK + string((-1)*tempiv[desiredorder[i]]) + ",";
835    }
836    orderKSK = orderKSK  + string(wl[1]) + ");";
837    list l2;
838    for (int zz = 1; zz <= ne; zz++)
839    {
840     l2[zz] = "e("+string(zz)+")";
841    }
842    list l3 = ring_list(basering)[2];
843    l2 = l2+l3;
844    ring re = create_ring(ring_list(r)[1], l2, orderKSK, "no_minpoly");
845  }
846  else
847  {
848    list l4;
849    for (int zz = 1; zz <= ne; zz++)
850    {
851     l4[zz] = "e("+string(zz)+")";
852    }
853    list l5 = ring_list(basering)[2];
854    l4 = l4+l5;
855    ring re = create_ring(ring_list(r)[1], l4, "Ws(" + string((-1)*intvec(wl[2])) + ","+ string(wl[1]) + ")", "no_minpoly");
856  }
857  module temp=imap(r,t1qh);
858  ideal t1qh=mod2id(temp,iv);
859  if (defined(watchProgress))
860  {
861    if (watchProgress[1]!=0)
862    {
863      option(prot);
864      "Protocol output of the groebner computation (quasihomogenous case)";
865    }
866  }
867  ideal t1qhs=std(t1qh);
868  if (defined(watchProgress))
869  {
870    if (watchProgress[1]!=0)
871    {
872      "groebner computation finished";
873      option(noprot);
874    }
875  }
876  ideal t1qhsl=lead(t1qhs);
877  module mo=id2mod(t1qhsl,iv);
878//--------------------------------------------------------------------------
879// Return to the initial ring to compute the kbase and noether there
880// (in the new ring t1qh is of course not of dimension 0 but of dimension 3
881// so we have to go back)
882//--------------------------------------------------------------------------
883  setring r;
884  module mo=imap(re,mo);
885  attrib(mo,"isSB",1);                // mo is monomial ==> SB
886  attrib(mo,"isHomog",intvec(wl[2])); // highcorner has to respect the weights
887  vector noe=highcorner(mo);
888  if (defined(watchProgress))
889  {
890    if (watchProgress[2]!=0)
891    {
892      "weights corresponding to the entries of the matrix:";
893      wl;
894      "leading term of the groebner basis (quasihomogeneous case)";
895      mo;
896      "noether";
897      noe;
898    }
899  }
900//--------------------------------------------------------------------------
901// Define the family of curves with the same quasihomogeneous initial
902// matrix M, compute T1 and pass again to the ring with the variables e(i)
903//--------------------------------------------------------------------------
904  def rneu=posweight(M,mo,2);
905  setring rneu;
906  list li=posw;
907  if (size(li)<=1)
908  {
909    ERROR("Internal Error: Problem determining perturbations of weight > 0.")
910  }
911  if (defined(watchProgress))
912  {
913    if(watchProgress[3]!=0)
914    {
915      "perturbed matrix and weights of the perturbations:";
916      li;
917    }
918  }
919  list li2=matrixT1(li[1],3);
920  module Mpert=transpose(matrix(ideal(li2[1])));
921  module t1pert=li2[2];
922  int nv=nvars(rneu)-nvars(r);
923  ring rtemp=0,(T(1..nv)),wp(li[2]);
924  def reneu=re+rtemp;
925  setring reneu;
926  module noe=matrix(imap(r,noe));
927  ideal noet=mod2id(noe,iv);
928  module temp=imap(rneu,t1pert);
929  ideal t1pert=mod2id(temp,iv);
930//--------------------------------------------------------------------------
931// Compute the standard basis and select those generators with leading term
932// divisible by some T(i)
933//--------------------------------------------------------------------------
934  noether=noet[size(noet)];
935  if (defined(watchProgress))
936  {
937    if (watchProgress[1]!=0)
938    {
939      "protocol output of the groebner command (perturbed case)";
940      option(prot);
941    }
942  }
943  ideal t1perts=std(t1pert);
944  noether=noet[size(noet)];
945  t1perts=interred(t1perts);
946  if (defined(Debug))
947  {
948    if (watchProgress[1]!=0)
949    {
950      "groebner computation finished (perturbed case)";
951      option(noprot);
952    }
953  }
954  ideal templ=lead(t1perts);
955  for(int j=1;j<=nv;j++)
956  {
957    templ=subst(templ,T(j),0);
958  }
959  ideal mx;
960  ideal mt;
961  for(j=1;j<=size(t1perts);j++)
962  {
963    if(templ[j]!=0)
964    {
965      mx=mx,t1perts[j];
966    }
967    else
968    {
969      mt=mt,t1perts[j];
970    }
971  }
972//--------------------------------------------------------------------------
973// multiply by the initial ring variables to shift the generators with
974// leading term divisible by some T(i) and reduce afterwards
975//--------------------------------------------------------------------------
976                       // This is obviously no SB, but we have to reduce by
977  attrib(mx,"isSB",1); // it and setting isSB suppresses error messages
978  noether=noet[size(noet)];
979  ideal ker_gen=reduce(mt,mx);
980  ideal ovar=var(ne+1),var(ne+2),var(ne+3);
981  j=1;
982  noether=noet[size(noet)];
983  if (defined(watchProgress))
984  {
985    if (watchProgress[4]!=0)
986    {
987      "generators of the kernel as a C[T]{x} module:";
988      mt;
989      "noether:";
990      noether;
991    }
992  }
993  int zeros;
994  templ=ker_gen;
995  while(zeros==0)
996  {
997    zeros=1;
998    templ=templ*ovar;
999    templ=reduce(templ,mx);
1000    if(defined(watchProgress))
1001    {
1002      if(watchProgress[4]>1)
1003      {
1004        templ;
1005      }
1006    }
1007    if (size(templ)!= 0)
1008    {
1009      zeros=0;
1010      ker_gen=ker_gen,templ;
1011    }
1012  }
1013//-------------------------------------------------------------------------
1014// kill zero entries, keep only one of identical entries
1015//-------------------------------------------------------------------------
1016  ovar=var(1);
1017  for(i=2;i<=ne;i++)
1018  {
1019    ovar=ovar,var(i);
1020  }
1021  ker_gen=ker_gen,ovar^2;
1022  noether=noet[size(noet)];
1023  ker_gen=simplify(ker_gen,10);
1024//-------------------------------------------------------------------------
1025// interreduce ker_gen as a k[T]-module
1026//-------------------------------------------------------------------------
1027  intvec mgen=1..(ne+3);
1028  ideal Mpert=mod2id(imap(rneu,Mpert),iv);
1029  templ=0;
1030  for(i=1;i<=nv;i++)
1031  {
1032    templ[i]=diff(Mpert[size(Mpert)],T(i));
1033  }
1034  templ=templ,ovar^2;
1035  list retl=subrInterred(templ,ker_gen,mgen);
1036// Build up the matrix representing L
1037  module retlm=transpose(retl[2]);
1038  for(i=1;i<=size(retl[1]);i++)
1039  {
1040    if(reduce(retl[1][1,i],std(ovar^2))==0)
1041    {
1042      retlm[i]=0;
1043    }
1044  }
1045  retlm=simplify(transpose(simplify(transpose(retlm),10)),10);
1046  if(defined(watchProgress))
1047  {
1048    if(watchProgress[5]>0)
1049    {
1050      print(retlm);
1051    }
1052  }
1053  ker_gen=retl[3];
1054// we define ret=i(L),(delta_j(t_k))_jk
1055  list ret=id2mod(ker_gen,iv),matrix(retlm);
1056// cleanups - define what we previously killed
1057  if(defined(kksave)>1)
1058  {
1059    def watchProgress=kksave;
1060    export watch Progress;
1061  }
1062  option(set,optvec);
1063  def KS=ret[2];
1064  export KS;
1065  return(reneu);
1066}
1067example
1068{ "EXAMPLE:"; echo=2;
1069  ring r=0,(x,y,z),ds;
1070  matrix M[3][2]=z-x^7,0,y^2,z,x^9,y;
1071  def rneu=KSpencerKernel(M,"ar");
1072  setring rneu;
1073  basering;
1074  print(KS);
1075}
1076///////////////////////////////////////////////////////////////////////////
1077
Note: See TracBrowser for help on using the repository browser.