source: git/Singular/LIB/gaussman.lib @ 409dbae

spielwiese
Last change on this file since 409dbae was 409dbae, checked in by Mathias Schulze <mschulze@…>, 22 years ago
*mschulze: bug fixed git-svn-id: file:///usr/local/Singular/svn/trunk@5580 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 38.6 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="$Id: gaussman.lib,v 1.50 2001-08-13 11:40:58 mschulze Exp $";
3category="Singularities";
4
5info="
6LIBRARY:  gaussman.lib  Gauss-Manin Connection of a Singularity
7
8AUTHOR:   Mathias Schulze, email: mschulze@mathematik.uni-kl.de
9
10OVERVIEW: A library to compute invariants related to the Gauss-Manin connection
11          of a an isolated hypersurface singularity
12
13PROCEDURES:
14 gmsring(t,s);              Brieskorn lattice in Gauss-Manin system of t
15 gmsnf(p,K[,Kmax]);         Gauss-Manin system normal form
16 gmscoeffs(p,K[,Kmax]);     Gauss-Manin system basis representation
17 monodromy(t[,opt]);        Jordan data or eigenvalues of monodromy of t
18 spectrum(t);               spectrum of t
19 sppairs(t[,opt]);          spectral pairs or spectrum of t
20 vfilt(t[,opt]);            V-filtration on H''/H' or spectrum of t
21 endfilt(t,V);              endomorphism filtration of V-filtration V
22 spgen(a);                  generate spectrum defined by a
23 sppgen(a,w);               generate spectral pairs defined by a and w
24 spprint(list Sp);          print spectrum or spectral pairs Sp
25 spadd(list Sp1,list Sp2);  sum of spectra Sp1 and Sp2
26 spsub(list Sp1,list Sp2);  difference of spectra Sp1 and Sp2
27 spmul(list Sp,int k);      product of spectrum Sp and integer k
28 spmul(list Sp,intvec k);   linear combination of spectra Sp with coeffs k
29 spissemicont(list Sp[,opt]);         test spectrum Sp for semicontinuity
30 spsemicont(list Sp0,list Sp[,opt]);  semicontinuity of spectra Sp0 and Sp
31 spmilnor(list Sp);         milnor number of spectrum Sp
32 spgeomgenus(list Sp);      geometrical genus of spectrum Sp
33 spgamma(list Sp);          gamma invariant of spectrum Sp
34
35SEE ALSO: mondromy_lib, spectrum_lib
36
37KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice;
38          monodromy; spectrum; spectral pairs;
39          Hodge filtration; V-filtration; weight filtration
40";
41
42LIB "linalg.lib";
43
44///////////////////////////////////////////////////////////////////////////////
45
46static proc stdtrans(ideal I)
47{
48  def R=basering;
49
50  string os=ordstr(R);
51  int j=find(os,",C");
52  if(j==0)
53  {
54    j=find(os,"C,");
55  }
56  if(j==0)
57  {
58    j=find(os,",c");
59  }
60  if(j==0)
61  {
62    j=find(os,"c,");
63  }
64  if(j>0)
65  {
66    os[j..j+1]="  ";
67  }
68
69  execute("ring S="+charstr(R)+",(gmspoly,"+varstr(R)+"),(c,dp,"+os+");");
70
71  ideal I=homog(imap(R,I),gmspoly);
72  module M=transpose(transpose(I)+freemodule(ncols(I)));
73  M=std(M);
74
75  setring(R);
76  execute("map h=S,1,"+varstr(R)+";");
77  module M=h(M);
78
79  for(int i=ncols(M);i>=1;i--)
80  {
81    for(j=ncols(M);j>=1;j--)
82    {
83      if(M[i][1]==0)
84      {
85        M[i]=0;
86      }
87      if(i!=j&&M[j][1]!=0)
88      {
89        if(lead(M[i][1])/lead(M[j][1])!=0)
90        {
91          M[i]=0;
92        }
93      }
94    }
95  }
96
97  M=transpose(simplify(M,2));
98  I=M[1];
99  attrib(I,"isSB",1);
100  M=M[2..ncols(M)];
101  module U=transpose(M);
102
103  return(list(I,U));
104}
105///////////////////////////////////////////////////////////////////////////////
106
107proc gmsring(poly t,string s)
108"USAGE:    gmsring(t,s); poly t, string s;
109ASSUME:   basering with characteristic 0 and local degree ordering,
110          t with isolated singularity at 0
111RETURN:
112@format
113ring G: C{{s}}*basering,
114  poly gmspoly: image of t
115  ideal gmsjacob: image of Jacobian ideal
116  ideal gmsstd: image of standard basis of Jacobian ideal
117  matrix gmsmatrix: matrix(gmsjacob)*gmsmatrix=matrix(gmsstd)
118  ideal gmsbasis: image of monomial vector space basis of Jacobian algebra
119  int gmsmaxweight: maximal weight of variables of basering
120@end format
121NOTE:     do not modify gms variables if you want to use gms procedures
122KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice
123EXAMPLE:  example gms; shows examples
124"
125{
126  def R=basering;
127  if(charstr(R)!="0")
128  {
129    ERROR("characteristic 0 expected");
130  }
131  for(int i=nvars(R);i>=1;i--)
132  {
133    if(var(i)>1)
134    {
135      ERROR("local ordering expected");
136    }
137  }
138
139  ideal dt=jacob(t);
140  list l=stdtrans(dt);
141  ideal g=l[1];
142  if(vdim(g)<=0)
143  {
144    if(vdim(g)==0)
145    {
146      ERROR("singularity at 0 expected");
147    }
148    else
149    {
150      ERROR("isolated singularity at 0 expected");
151    }
152  } 
153  matrix a=l[2];
154  ideal m=kbase(g);
155
156  int gmsmaxweight;
157  for(i=nvars(R);i>=1;i--)
158  {
159    if(deg(var(i))>gmsmaxweight)
160    {
161      gmsmaxweight=deg(var(i));
162    }
163  }
164
165  string os=ordstr(R);
166  int j=find(os,",C");
167  if(j==0)
168  {
169    j=find(os,"C,");
170  }
171  if(j==0)
172  {
173    j=find(os,",c");
174  }
175  if(j==0)
176  {
177    j=find(os,"c,");
178  }
179  if(j>0)
180  {
181    os[j..j+1]="  ";
182  }
183
184  execute("ring G="+string(charstr(R))+",("+s+","+varstr(R)+"),(ws("+
185    string(deg(highcorner(g))+2*gmsmaxweight)+"),"+os+",c);");
186
187  poly gmspoly=imap(R,t);
188  ideal gmsjacob=imap(R,dt);
189  ideal gmsstd=imap(R,g);
190  matrix gmsmatrix=imap(R,a);
191  ideal gmsbasis=imap(R,m);
192
193  attrib(gmsstd,"isSB",1);
194  export gmspoly,gmsjacob,gmsstd,gmsmatrix,gmsbasis,gmsmaxweight;
195
196  return(G);
197}
198example
199{ "EXAMPLE:"; echo=2;
200  ring R=0,(x,y),ds;
201  poly t=x5+x2y2+y5;
202  def G=gmsring(t,"s");
203  setring(G);
204  gmspoly;
205  print(gmsjacob);
206  print(gmsstd);
207  print(gmsmatrix);
208  print(gmsbasis);
209  gmsmaxweight;
210}
211///////////////////////////////////////////////////////////////////////////////
212
213proc gmsnf(ideal p,int K,list #)
214"USAGE:    gmsnf(p,K[,Kmax]); poly p, int K[, int Kmax];
215ASSUME:   basering constructed by gmsring, K<=Kmax
216RETURN:
217@format
218list l:
219  ideal l[1]: projection of p to H''=C{{s}}*gmsbasis mod s^{K+1}
220  ideal l[2]: p=l[1]+l[2] mod s^(Kmax+1)
221@end format
222NOTE:     by setting p=l[2] the computation can be continued up to order
223          at most Kmax, by default Kmax=infinity
224KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice
225EXAMPLE:  example gmsnf; shows examples
226"
227{
228  int Kmax=-1;
229  if(size(#)>0)
230  {
231    if(typeof(#[1])=="int")
232    {
233      Kmax=#[1];
234      if(K>Kmax)
235      {
236        Kmax=K;
237      }
238    }
239  }
240
241  intvec v=1;
242  v[nvars(basering)]=0;
243
244  int k;
245  if(Kmax>=0)
246  {
247    p=jet(jet(p,K,v),(Kmax+1)*deg(var(1))-2*gmsmaxweight);
248  }
249
250  ideal r,q;
251  r[ncols(p)]=0;
252  q[ncols(p)]=0;
253
254  poly s;
255  int i,j;
256  for(k=ncols(p);k>=1;k--)
257  {
258    while(p[k]!=0&&deg(lead(p[k]),v)<=K)
259    {
260      i=1;
261      s=lead(p[k])/lead(gmsstd[i]);
262      while(i<ncols(gmsstd)&&s==0)
263      {
264        i++;
265        s=lead(p[k])/lead(gmsstd[i]);
266      }
267      if(s!=0)
268      {
269        p[k]=p[k]-s*gmsstd[i];
270        for(j=1;j<=nrows(gmsmatrix);j++)
271        {
272          if(Kmax>=0)
273          {
274            p[k]=p[k]+
275              jet(jet(diff(s*gmsmatrix[j,i],var(j+1))*var(1),Kmax,v),
276                (Kmax+1)*deg(var(1))-2*gmsmaxweight);
277          }
278          else
279          {
280            p[k]=p[k]+diff(s*gmsmatrix[j,i],var(j+1))*var(1);
281          }
282        }
283      }
284      else
285      {
286        r[k]=r[k]+lead(p[k]);
287        p[k]=p[k]-lead(p[k]);
288      }
289      while(deg(lead(p[k]))>(K+1)*deg(var(1))-2*gmsmaxweight&&
290        deg(lead(p[k]),v)<=K)
291      {
292        q[k]=q[k]+lead(p[k]);
293        p[k]=p[k]-lead(p[k]);
294      }
295    }
296    q[k]=q[k]+p[k];
297  }
298
299  return(list(r,q));
300}
301example
302{ "EXAMPLE:"; echo=2;
303  ring R=0,(x,y),ds;
304  poly t=x5+x2y2+y5;
305  def G=gmsring(t,"s");
306  setring(G);
307  list l0=gmsnf(gmspoly,0);
308  print(l0[1]);
309  list l1=gmsnf(gmspoly,1);
310  print(l1[1]);
311  list l=gmsnf(l0[2],1);
312  print(l[1]);
313}
314///////////////////////////////////////////////////////////////////////////////
315
316proc gmscoeffs(ideal p,int K,list #)
317"USAGE:    gmscoeffs(p,K[,Kmax]); poly p, int K[, int Kmax];
318ASSUME:   basering constructed by gmsring, K<=Kmax
319RETURN:
320@format
321list l:
322  matrix l[1]: projection of p to H''=C{{s}}*gmsbasis=C{{s}}^mu mod s^(K+1)
323  ideal l[2]: p=matrix(gmsbasis)*l[1]+l[2] mod s^(Kmax+1)
324@end format
325NOTE:     by setting p=l[2] the computation can be continued up to order
326          at most Kmax, by default Kmax=infinity
327KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice
328EXAMPLE:  example gmscoeffs; shows examples
329"
330{
331  list l=gmsnf(p,K,#);
332  ideal r,q=l[1..2];
333  poly v=1;
334  for(int i=2;i<=nvars(basering);i++)
335  {
336    v=v*var(i);
337  }
338  matrix C=coeffs(r,gmsbasis,v);
339  return(C,q);
340}
341example
342{ "EXAMPLE:"; echo=2;
343  ring R=0,(x,y),ds;
344  poly t=x5+x2y2+y5;
345  def G=gmsring(t,"s");
346  setring(G);
347  list l0=gmscoeffs(gmspoly,0);
348  print(l0[1]);
349  list l1=gmscoeffs(gmspoly,1);
350  print(l1[1]);
351  list l=gmscoeffs(l0[2],1);
352  print(l[1]);
353}
354///////////////////////////////////////////////////////////////////////////////
355
356static proc maxintdif(ideal e)
357{
358  int i,j,d;
359  int d0=0;
360  for(i=ncols(e);i>=1;i--)
361  {
362    for(j=i-1;j>=1;j--)
363    {
364      d=int(e[i]-e[j]);
365      if(d<0)
366      {
367        d=-d;
368      }
369      if(d>d0)
370      {
371        d0=d;
372      }
373    }
374  }
375  return(d0);
376}
377///////////////////////////////////////////////////////////////////////////////
378
379proc monodromy(poly t,list #)
380"USAGE:    monodromy(t[,opt]); poly t, int opt
381ASSUME:   basering with characteristic 0 and local degree ordering,
382          t with isolated singularity at 0
383RETURN:
384@format
385if opt<=0:
386list l:
387  ideal l[1]: exp(-2*pi*i*l[1]) are the eigenvalues of the monodromy
388if opt>=1:
389list l: Jordan data jordan(M) of a monodromy matrix exp(-2*pi*i*M)
390default: opt=1
391@end format
392SEE ALSO: mondromy_lib
393KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice; monodromy
394EXAMPLE:  example monodromy; shows examples
395"
396{
397  int opt=1;
398  if(size(#)>0)
399  {
400    if(typeof(#[1])=="int")
401    {
402      opt=#[1];
403    }
404  }
405
406  def R=basering;
407  int n=nvars(R)-1;
408  def G=gmsring(t,"s");
409  setring G;
410
411  int mu=ncols(gmsbasis);
412  ideal r=gmspoly*gmsbasis;
413  list l;
414  matrix A0[mu][mu],C;
415  module H,H1=freemodule(mu),freemodule(mu);
416  module H0;
417  int k=-1;
418  while(size(reduce(H,std(H0*s)))>0)
419  {
420    k++;
421    dbprint(printlevel-voice+2,"// k="+string(k));
422    dbprint(printlevel-voice+2,"// compute matrix A of t");
423    if(opt<=0)
424    {
425      l=gmscoeffs(r,k,mu);
426    }
427    else
428    {
429      l=gmscoeffs(r,k,mu+n);
430    }
431    C,r=l[1..2];
432    A0=A0+C;
433
434    dbprint(printlevel-voice+2,"// compute saturation of H''");
435    H0=H;
436    H1=jet(module(A0*H1+s^2*diff(matrix(H1),s)),k);
437    H=H*s+H1;
438  }
439  A0=A0-k*s;
440
441  dbprint(printlevel-voice+2,"// compute basis of saturation of H''");
442  H=std(H0);
443  int d0=maxdeg1(H);
444  dbprint(printlevel-voice+2,"// k="+string(d0+1));
445  dbprint(printlevel-voice+2,"// compute matrix A of t");
446  if(opt<=0)
447  {
448    l=gmscoeffs(r,d0+1,d0+1);
449  }
450  else
451  {
452    l=gmscoeffs(r,d0+1,d0+n+1);
453  }
454  C,r=l[1..2];
455  A0=A0+C;
456  dbprint(printlevel-voice+2,"// transform A to saturation of H''");
457  l=division(H*s,A0*H+s^2*diff(matrix(H),s));
458  matrix A=jet(l[1],l[2],0);
459
460  dbprint(printlevel-voice+2,
461    "// compute eigenvalues e with multiplicities m of A");
462  l=eigenval(jet(A,0));
463  def e,m=l[1..2];
464  dbprint(printlevel-voice+2,"// e="+string(e));
465  dbprint(printlevel-voice+2,"// m="+string(m));
466
467  if(opt<=0)
468  {
469    setring(R);
470    ideal e=imap(G,e);
471    return(list(e));
472  }
473
474  dbprint(printlevel-voice+2,"// compute maximal integer difference d1 of e");
475  int d1=maxintdif(e);
476  dbprint(printlevel-voice+2,"// d1="+string(d1));
477
478  module U;
479  if(d1>0)
480  {
481    dbprint(printlevel-voice+2,"// k="+string(d0+d1+1));
482    dbprint(printlevel-voice+2,"// compute matrix A of t");
483    l=gmscoeffs(r,d0+d1+1,d0+d1+1);
484    C,r=l[1..2];
485    A0=A0+C;
486    dbprint(printlevel-voice+2,"// transform A to saturation of H''");
487    l=division(H*s,A0*H+s^2*diff(matrix(H),s));
488    A=jet(l[1],l[2],d1);
489
490    intvec d;
491    d[mu]=0;
492    int i,j;
493    for(i=ncols(e);i>=1;i--)
494    {
495      for(j=i-1;j>=1;j--)
496      {
497        k=int(e[j]-e[i]);
498        if(k>d[j])
499        {
500          d[j]=k;
501        }
502        if(-k>d[i])
503        {
504          d[i]=-k;
505        }
506      }
507    }
508    for(j,k=ncols(e),mu;j>=1;j--)
509    {
510      for(i=m[j];i>=1;i--)
511      {
512        d[k]=d[j];
513        k--;
514      }
515    }
516
517    while(d1>0)
518    {
519      dbprint(printlevel-voice+2,"// transform basis to reduce d1 by 1");
520
521      A0=jet(A,0);
522      U=0;
523      for(i=ncols(e);i>=1;i--)
524      {
525        U=syz(power(A0-e[i],n+1))+U;
526      }
527      A=lift(U,A*U);
528
529      for(i=mu;i>=1;i--)
530      {
531        for(j=mu;j>=1;j--)
532        {
533          if(d[i]==0&&d[j]>0)
534          {
535            A[i,j]=A[i,j]/s;
536          }
537          else
538          {
539            if(d[i]>0&&d[j]==0)
540            {
541              A[i,j]=A[i,j]*s;
542            }
543          }
544        }
545      }
546      for(i=mu;i>=1;i--)
547      {
548        if(d[i]>0)
549        {
550          A[i,i]=A[i,i]-1;
551          d[i]=d[i]-1;
552        }
553      }
554
555      d1--;
556      dbprint(printlevel-voice+2,"// d1="+string(d1));
557    }
558
559    A=jet(A,0);
560  }
561
562  setring(R);
563  matrix A=imap(G,A);
564  return(jordan(A));
565}
566example
567{ "EXAMPLE:"; echo=2;
568  ring R=0,(x,y),ds;
569  poly f=x5+x2y2+y5;
570  print(monodromy(f));
571}
572///////////////////////////////////////////////////////////////////////////////
573
574proc spectrum(poly t)
575"USAGE:    spectrum(t); poly t
576ASSUME:   basering with characteristic 0 and local degree ordering,
577          t with isolated singularity at 0
578RETURN:
579@format
580list Sp: spectrum of t
581  ideal Sp[1]: spectral numbers in increasing order
582  intvec Sp[2]:
583    int Sp[2][i]: multiplicity of spectral number Sp[1][i]
584@end format
585SEE ALSO: spectrum_lib
586KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice; spectrum
587EXAMPLE:  example spnumbers; shows examples
588"
589{
590  return(sppairs(t,0));
591}
592example
593{ "EXAMPLE:"; echo=2;
594  ring R=0,(x,y),ds;
595  poly t=x5+x2y2+y5;
596  spprint(spectrum(t));
597}
598///////////////////////////////////////////////////////////////////////////////
599
600proc sppairs(poly t,list #)
601"USAGE:    sppairs(t[,opt]); poly t, int opt
602ASSUME:   basering with characteristic 0 and local degree ordering,
603          t with isolated singularity at 0
604RETURN: list l:
605@format
606  ideal l[1]: spectral numbers in increasing order
607if opt<=0:
608  intvec l[2]:
609    int l[2][i]: multiplicity of spectral number l[1][i]
610if opt>=1:
611  intvec l[2]: weight filtration indices in decreasing order
612  intvec l[3]:
613    int l[3][i]: multiplicity of spectral pair (l[1][i],l[2][i])
614default: opt=1
615@end format
616SEE ALSO: spectrum_lib
617KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice;
618          spectrum; spectral pairs
619EXAMPLE:  example sppairs; shows examples
620"
621{
622  int opt=1;
623  if(size(#)>0)
624  {
625    if(typeof(#[1])=="int")
626    {
627      opt=#[1];
628    }
629  }
630
631  def R=basering;
632  int n=nvars(R)-1;
633  def G=gmsring(t,"s");
634  setring(G);
635
636  int mu=ncols(gmsbasis);
637  ideal r=gmspoly*gmsbasis;
638  list l;
639  matrix A0[mu][mu],C;
640  module H0;
641  module H,H1=freemodule(mu),freemodule(mu);
642  int k=-1;
643  while(size(reduce(H,std(H0*s)))>0)
644  {
645    k++;
646    dbprint(printlevel-voice+2,"// k="+string(k));
647    dbprint(printlevel-voice+2,"// compute matrix A of t");
648    if(opt<=0)
649    {
650      l=gmscoeffs(r,k,mu);
651    }
652    else
653    {
654      l=gmscoeffs(r,k,mu+n);
655    }
656    C,r=l[1..2];
657    A0=A0+C;
658
659    dbprint(printlevel-voice+2,"// compute saturation of H''");
660    H0=H;
661    H1=jet(module(A0*H1+s^2*diff(matrix(H1),s)),k);
662    H=H*s+H1;
663  }
664  A0=A0-k*s;
665
666  dbprint(printlevel-voice+2,"// compute basis of saturation of H''");
667  H=std(H0);
668  int d0=maxdeg1(H);
669  dbprint(printlevel-voice+2,"// transform H'' to saturation of H''");
670  l=division(H,freemodule(mu)*s^k);
671  H0=l[1];
672
673  dbprint(printlevel-voice+2,"// k="+string(d0+1));
674  dbprint(printlevel-voice+2,"// compute matrix A of t");
675  if(opt<=0)
676  {
677    l=gmscoeffs(r,d0+1,d0+1);
678  }
679  else
680  {
681    l=gmscoeffs(r,d0+1,d0+n+1);
682  }
683  C,r=l[1..2];
684  A0=A0+C;
685  dbprint(printlevel-voice+2,"// transform A to saturation of H''");
686  l=division(H*s,A0*H+s^2*diff(matrix(H),s));
687  matrix A=jet(l[1],l[2],0);
688
689  int i,j;
690  module U,V;
691  if(opt<=0)
692  {
693    dbprint(printlevel-voice+2,"// transform to Jordan basis");
694    U=jordanbasis(A)[1];
695    V=lift(U,freemodule(mu));
696    A=V*A*U;
697    dbprint(printlevel-voice+2,"// compute normal form of H''");
698    H0=std(V*H0);
699
700    dbprint(printlevel-voice+2,"// compute spectral numbers");
701    ideal a;
702    for(i=1;i<=mu;i++)
703    {
704      j=leadexp(H0[i])[nvars(basering)+1];
705      a[i]=A[j,j]+deg(lead(H0[i]))/deg(s)-1;
706    }
707
708    setring(R);
709    return(spgen(imap(G,a)));
710  }
711
712  dbprint(printlevel-voice+2,
713    "// compute eigenvalues e with multiplicities m of A");
714  l=eigenval(A);
715  def e,m=l[1..2];
716  dbprint(printlevel-voice+2,"// e="+string(e));
717  dbprint(printlevel-voice+2,"// m="+string(m));
718  dbprint(printlevel-voice+2,"// compute maximal integer difference d1 of e");
719  int d1=maxintdif(e);
720  dbprint(printlevel-voice+2,"// d1="+string(d1));
721
722  if(d1>0)
723  {
724    dbprint(printlevel-voice+2,"// k="+string(d0+d1+1));
725    dbprint(printlevel-voice+2,"// compute matrix A of t");
726    l=gmscoeffs(r,d0+d1+1,d0+d1+1);
727    C,r=l[1..2];
728    A0=A0+C;
729    dbprint(printlevel-voice+2,"// transform A to saturation of H''");
730    l=division(H*s,A0*H+s^2*diff(matrix(H),s));
731    A=jet(l[1],l[2],d1);
732
733    intvec d;
734    d[mu]=0;
735    for(i=ncols(e);i>=1;i--)
736    {
737      for(j=i-1;j>=1;j--)
738      {
739        k=int(e[j]-e[i]);
740        if(k>d[j])
741        {
742          d[j]=k;
743        }
744        if(-k>d[i])
745        {
746          d[i]=-k;
747        }
748      }
749    }
750    for(j,k=ncols(e),mu;j>=1;j--)
751    {
752      for(i=m[j];i>=1;i--)
753      {
754        d[k]=d[j];
755        k--;
756      }
757    }
758
759    while(d1>0)
760    {
761      dbprint(printlevel-voice+2,"// transform to separate eigenvalues");
762      A0=jet(A,0);
763      U=0;
764      for(i=ncols(e);i>=1;i--)
765      {
766        U=syz(power(A0-e[i],n+1))+U;
767      }
768      V=lift(U,freemodule(mu));
769      A=V*A*U;
770      H0=V*H0;
771
772      dbprint(printlevel-voice+2,"// transform to reduce d1 by 1");
773      for(i=mu;i>=1;i--)
774      {
775        for(j=mu;j>=1;j--)
776        {
777          if(d[i]==0&&d[j]>0)
778          {
779            A[i,j]=A[i,j]/s;
780          }
781          else
782          {
783            if(d[i]>0&&d[j]==0)
784            {
785              A[i,j]=A[i,j]*s;
786            }
787          }
788        }
789      }
790      H0=transpose(H0);
791      for(i=mu;i>=1;i--)
792      {
793        if(d[i]>0)
794        {
795          A[i,i]=A[i,i]-1;
796          d[i]=d[i]-1;
797          H0[i]=H0[i]*s;
798        }
799      }
800      H0=transpose(H0);
801
802      d1--;
803      dbprint(printlevel-voice+2,"// d1="+string(d1));
804    }
805
806    A=jet(A,0);
807  }
808
809  dbprint(printlevel-voice+2,"// compute weight filtration basis");
810  intvec w0;
811  l=jordanbasis(A);
812  U,w0=l[1..2];
813  V=lift(U,freemodule(mu));
814  A0=jet(V*A*U,0);
815  vector u;
816  i=1;
817  while(i<ncols(A0))
818  {
819    j=i+1;
820    while(j<ncols(A0)&&A0[i,i]==A0[j,j])
821    {
822      if(w0[i]<w0[j])
823      {
824        k=w0[i];
825        w0[i]=w0[j];
826        w0[i]=k;
827        u=U[i];
828        U[i]=U[j];
829        U[j]=u;
830      }
831      j++;
832    }
833    if(j==ncols(A0)&&A0[i,i]==A0[j,j]&&w0[i]<w0[j])
834    {
835      k=w0[i];
836      w0[i]=w0[j];
837      w0[i]=k;
838      u=U[i];
839      U[i]=U[j];
840      U[j]=u;
841    }
842    i=j;
843  }
844
845  dbprint(printlevel-voice+2,"// transform to weight filtration basis");
846  V=lift(U,freemodule(mu));
847  A=V*A*U;
848  dbprint(printlevel-voice+2,"// compute normal form of H''");
849  H0=std(V*H0);
850
851  dbprint(printlevel-voice+2,"// compute spectral pairs");
852  ideal a;
853  intvec w;
854  for(i=1;i<=mu;i++)
855  {
856    j=leadexp(H0[i])[nvars(basering)+1];
857    a[i]=A[j,j]+deg(lead(H0[i]))/deg(s)-1;
858    w[i]=w0[j]+n;
859  }
860  setring(R);
861  return(sppgen(imap(G,a),w));
862}
863example
864{ "EXAMPLE:"; echo=2;
865  ring R=0,(x,y),ds;
866  poly t=x5+x2y2+y5;
867  spprint(sppairs(t));
868}
869///////////////////////////////////////////////////////////////////////////////
870
871proc vfilt(poly t,list #)
872"USAGE:    vfilt(t[,opt]); poly t, int opt
873ASSUME:   basering with characteristic 0 and local degree ordering,
874          t with isolated singularity at 0
875RETURN:
876@format
877list V: V-filtration of t on H''/H'
878  intvec V[1]: spectral numbers in increasing order
879  intvec V[2]:
880    int V[2][i]: multiplicity of spectral number V[1][i]/V[2][i]
881if opt>=1:
882  list V[4]:
883    module V[3][i]: vector space basis of V[1][i]/V[2][i]-th graded part
884                    in terms of V[5]
885  ideal V[4]: monomial vector space basis of H''/H'
886  ideal V[5]: standard basis of Jacobian ideal
887default: opt=1
888@end format
889NOTE:     H' and H'' denote the Brieskorn lattices
890SEE ALSO: spectrum_lib
891KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice;
892          Hodge filtration; V-filtration; spectrum
893EXAMPLE:  example vfilt; shows examples
894"
895{
896  int opt=1;
897  if(size(#)>0)
898  {
899    if(typeof(#[1])=="int")
900    {
901      opt=#[1];
902    }
903  }
904
905  def R=basering;
906  int n=nvars(R)-1;
907  def G=gmsring(t,"s");
908  setring G;
909
910  int mu=ncols(gmsbasis);
911  ideal r=gmspoly*gmsbasis;
912  list l;
913  matrix A[mu][mu],C;
914  module H,H1=freemodule(mu),freemodule(mu);
915  module H0;
916  int k=-1;
917  int N=n+1;
918
919  while(size(reduce(H,std(H0*s)))>0)
920  {
921    k++;
922    dbprint(printlevel-voice+2,"// k="+string(k));
923    dbprint(printlevel-voice+2,"// compute matrix A of t");
924    l=gmscoeffs(r,k);
925    C,r=l[1..2];
926    A=A+C;
927
928    dbprint(printlevel-voice+2,"// compute saturation of H''");
929    H0=H;
930    H1=jet(module(A*H1+s^2*diff(matrix(H1),s)),k);
931    H=H*s+H1;
932  }
933  A=A-k*s;
934
935  dbprint(printlevel-voice+2,"// compute basis of saturation of H''");
936  H=std(H0);
937  int d0=maxdeg1(H);
938  dbprint(printlevel-voice+2,"// k="+string(d0+N));
939  dbprint(printlevel-voice+2,"// compute matrix A of t");
940  l=gmscoeffs(r,d0+N,d0+N);
941  C,r=l[1..2];
942  A=A+C;
943
944  dbprint(printlevel-voice+2,"// transform H'' to saturation of H''");
945  l=division(H,freemodule(mu)*s^k);
946  H0=jet(l[1],l[2],N-1);
947
948  dbprint(printlevel-voice+2,"// compute vector spaces");
949  poly p;
950  int i0,j0,i1,j1;
951  matrix V0[mu*N][mu*N];
952  matrix V1[mu*N][mu*(N-1)];
953  for(i0=mu;i0>=1;i0--)
954  {
955    for(i1=mu;i1>=1;i1--)
956    {
957      p=H0[i1,i0];
958      while(p!=0)
959      {
960        j1=leadexp(p)[1];
961        for(j0=N-j1-1;j0>=0;j0--)
962        {
963          V0[i1+(j1+j0)*mu,i0+j0*mu]=V0[i1+(j1+j0)*mu,i0+j0*mu]+leadcoef(p);
964          if(j1+j0+1<N)
965          {
966            V1[i1+(j1+j0+1)*mu,i0+j0*mu]=
967            V1[i1+(j1+j0+1)*mu,i0+j0*mu]+leadcoef(p);
968          }
969        }
970        p=p-lead(p);
971      }
972    }
973  }
974
975  dbprint(printlevel-voice+2,"// transform A to saturation of H''");
976  l=division(H*s,A*H+s^2*diff(matrix(H),s));
977  A=jet(l[1],l[2],N-1);
978
979  dbprint(printlevel-voice+2,"// compute matrix M of A");
980  matrix M[mu*N][mu*N];
981  for(i0=mu;i0>=1;i0--)
982  {
983    for(i1=mu;i1>=1;i1--)
984    {
985      p=A[i1,i0];
986      while(p!=0)
987      {
988        j1=leadexp(p)[1];
989        for(j0=N-j1-1;j0>=0;j0--)
990        {
991          M[i1+(j0+j1)*mu,i0+j0*mu]=leadcoef(p);
992        }
993        p=p-lead(p);
994      }
995    }
996  }
997  for(i0=mu;i0>=1;i0--)
998  {
999    for(j0=N-1;j0>=0;j0--)
1000    {
1001      M[i0+j0*mu,i0+j0*mu]=M[i0+j0*mu,i0+j0*mu]+j0;
1002    }
1003  }
1004
1005  dbprint(printlevel-voice+2,"// compute eigenvalues eA of A");
1006  ideal eA=eigenval(jet(A,0))[1];
1007  dbprint(printlevel-voice+2,"// eA="+string(eA));
1008
1009  dbprint(printlevel-voice+2,"// compute eigenvalues eM of M");
1010  ideal eM;
1011  k=0;
1012  intvec u;
1013  for(int i=N;i>=1;i--)
1014  {
1015    u[i]=1;
1016  }
1017  i0=1;
1018  while(u[N]<=ncols(eA))
1019  {
1020    for(i,i1=i0+1,i0;i<=N;i++)
1021    {
1022      if(eA[u[i]]+i<eA[u[i1]]+i1)
1023      {
1024        i1=i;
1025      }
1026    }
1027    k++;
1028    eM[k]=eA[u[i1]]+i1-1;
1029    u[i1]=u[i1]+1;
1030    if(u[i1]>ncols(eA))
1031    {
1032      i0=i1+1;
1033    }
1034  }
1035  dbprint(printlevel-voice+2,"// eM="+string(eM));
1036
1037  dbprint(printlevel-voice+2,"// compute V-filtration on H''/sH''");
1038  ideal a;
1039  k=0;
1040  list V;
1041  V[ncols(eM)+1]=interred(V1);
1042  intvec d;
1043  if(opt<=0)
1044  {
1045    for(i=ncols(eM);number(eM[i])-1>number(n-1)/2;i--)
1046    {
1047      dbprint(printlevel-voice+2,"// compute V["+string(i)+"]");
1048      V1=module(V1)+syz(power(M-eM[i],n+1));
1049      V[i]=interred(intersect(V1,V0));
1050
1051      if(size(V[i])>size(V[i+1]))
1052      {
1053        k++;
1054        a[k]=eM[i]-1;
1055        d[k]=size(V[i])-size(V[i+1]);
1056      }
1057    }
1058
1059    dbprint(printlevel-voice+2,"// symmetry index found");
1060    int j=k;
1061
1062    if(number(eM[i])-1==number(n-1)/2)
1063    {
1064      dbprint(printlevel-voice+2,"// compute V["+string(i)+"]");
1065      V1=module(V1)+syz(power(M-eM[i],n+1));
1066      V[i]=interred(intersect(V1,V0));
1067
1068      if(size(V[i])>size(V[i+1]))
1069      {
1070        k++;
1071        a[k]=eM[i]-1;
1072        d[k]=size(V[i])-size(V[i+1]);
1073      }
1074    }
1075
1076    dbprint(printlevel-voice+2,"// apply symmetry");
1077    while(j>=1)
1078    {
1079      k++;
1080      a[k]=a[j];
1081      a[j]=n-1-a[k];
1082      d[k]=d[j];
1083      j--;
1084    }
1085
1086    setring(R);
1087    ideal a=imap(G,a);
1088    return(list(a,d));
1089  }
1090  else
1091  {
1092    list v;
1093    int j=-1;
1094    for(i=ncols(eM);i>=1;i--)
1095    {
1096      dbprint(printlevel-voice+2,"// compute V["+string(i)+"]");
1097      V1=module(V1)+syz(power(M-eM[i],n+1));
1098      V[i]=interred(intersect(V1,V0));
1099
1100      if(size(V[i])>size(V[i+1]))
1101      {
1102        if(number(eM[i]-1)>=number(n-1)/2)
1103        {
1104          k++;
1105          a[k]=eM[i]-1;
1106          v[k]=matrix(freemodule(ncols(V[i])),mu,mu*N)*division(V0,V[i])[1];
1107        }
1108        else
1109        {
1110          if(j<0)
1111          {
1112            if(a[k]==number(n-1)/2)
1113            {
1114              j=k-1;
1115            }
1116            else
1117            {
1118              j=k;
1119            }
1120          }
1121          k++;
1122          a[k]=a[j];
1123          a[j]=eM[i]-1;
1124          v[k]=v[j];
1125          v[j]=matrix(freemodule(ncols(V[i])),mu,mu*N)*division(V0,V[i])[1];
1126          j--;
1127        }
1128      }
1129    }
1130
1131    dbprint(printlevel-voice+2,"// compute graded parts");
1132    for(k=1;k<size(v);k++)
1133    {
1134      v[k]=interred(reduce(v[k],std(v[k+1])));
1135      d[k]=size(v[k]);
1136    }
1137    v[k]=interred(v[k]);
1138    d[k]=size(v[k]);
1139
1140    setring(R);
1141    ideal a=imap(G,a);
1142    list v=imap(G,v);
1143    ideal m=imap(G,gmsbasis);
1144    ideal g=imap(G,gmsstd);
1145    attrib(g,"isSB",1);
1146    return(list(a,d,v,m,g));
1147  }
1148}
1149example
1150{ "EXAMPLE:"; echo=2;
1151  ring R=0,(x,y),ds;
1152  poly t=x5+x2y2+y5;
1153  vfilt(t);
1154}
1155///////////////////////////////////////////////////////////////////////////////
1156
1157proc endfilt(list V)
1158"USAGE:   endfilt(V); list V
1159ASSUME:  V computed by vfilt
1160RETURN:
1161@format
1162list V1: endomorphim filtration of V on the Jacobian algebra
1163  ideal V1[1]: spectral numbers in increasing order
1164  intvec V1[2]:
1165    int V1[2][i]: multiplicity of spectral number V1[1][i]
1166  list V1[3]:
1167    module V1[3][i]: vector space basis of the V1[1][i]-th graded part
1168                     in terms of V1[4]
1169  ideal V1[4]: monomial vector space basis
1170@end format
1171SEE ALSO: spectrum_lib
1172KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice; spectrum;
1173          Hodge filtration; V-filtration
1174EXAMPLE: example endfilt; shows examples
1175"
1176{
1177  def a,d,v,m,g=V[1..5];
1178  int mu=ncols(m);
1179
1180  module V0=v[1];
1181  for(int i=2;i<=size(v);i++)
1182  {
1183    V0=V0,v[i];
1184  }
1185
1186  dbprint(printlevel-voice+2,"// compute multiplication in Jacobian algebra");
1187  list M;
1188  module U=freemodule(ncols(m));
1189  for(i=ncols(m);i>=1;i--)
1190  {
1191    M[i]=lift(V0,coeffs(reduce(m[i]*m,U,g),m)*V0);
1192  }
1193
1194  int j,k,i0,j0,i1,j1;
1195  number b0=number(a[1]-a[ncols(a)]);
1196  number b1,b2;
1197  matrix M0;
1198  module L;
1199  list v0=freemodule(ncols(m));
1200  ideal a0=b0;
1201
1202  while(b0<number(a[ncols(a)]-a[1]))
1203  {
1204    dbprint(printlevel-voice+2,"// find next possible index");
1205    b1=number(a[ncols(a)]-a[1]);
1206    for(j=ncols(a);j>=1;j--)
1207    {
1208      for(i=ncols(a);i>=1;i--)
1209      {
1210        b2=number(a[i]-a[j]);
1211        if(b2>b0&&b2<b1)
1212        {
1213          b1=b2;
1214        }
1215        else
1216        {
1217          if(b2<=b0)
1218          {
1219            i=0;
1220          }
1221        }
1222      }
1223    }
1224    b0=b1;
1225
1226    list l=ideal();
1227    for(k=ncols(m);k>=2;k--)
1228    {
1229      l=l+list(ideal());
1230    }
1231
1232    dbprint(printlevel-voice+2,"// collect conditions for V1["+string(b0)+"]");
1233    j=ncols(a);
1234    j0=mu;
1235    while(j>=1)
1236    {
1237      i0=1;
1238      i=1;
1239      while(i<ncols(a)&&a[i]<a[j]+b0)
1240      {
1241        i0=i0+d[i];
1242        i++;
1243      }
1244      if(a[i]<a[j]+b0)
1245      {
1246        i0=i0+d[i];
1247        i++;
1248      }
1249      for(k=1;k<=ncols(m);k++)
1250      {
1251        M0=M[k];
1252        if(i0>1)
1253        {
1254          l[k]=l[k],M0[1..i0-1,j0-d[j]+1..j0];
1255        }
1256      }
1257      j0=j0-d[j];
1258      j--;
1259    }
1260
1261    dbprint(printlevel-voice+2,"// compose condition matrix");
1262    L=transpose(module(l[1]));
1263    for(k=2;k<=ncols(m);k++)
1264    {
1265      L=L,transpose(module(l[k]));
1266    }
1267
1268    dbprint(printlevel-voice+2,"// compute kernel of condition matrix");
1269    v0=v0+list(syz(L));
1270    a0=a0,b0;
1271  }
1272
1273  dbprint(printlevel-voice+2,"// compute graded parts");
1274  option(redSB);
1275  for(i=1;i<size(v0);i++)
1276  {
1277    v0[i+1]=std(v0[i+1]);
1278    v0[i]=std(reduce(v0[i],v0[i+1]));
1279  }
1280
1281  dbprint(printlevel-voice+2,"// remove trivial graded parts");
1282  i=1;
1283  while(size(v0[i])==0)
1284  {
1285    i++;
1286  }
1287  list v1=v0[i];
1288  intvec d1=size(v0[i]);
1289  ideal a1=a0[i];
1290  i++;
1291  while(i<=size(v0))
1292  {
1293    if(size(v0[i])>0)
1294    {
1295      v1=v1+list(v0[i]);
1296      d1=d1,size(v0[i]);
1297      a1=a1,a0[i];
1298    }
1299    i++;
1300  }
1301  return(list(a1,d1,v1,m));
1302}
1303example
1304{ "EXAMPLE:"; echo=2;
1305  ring R=0,(x,y),ds;
1306  poly t=x5+x2y2+y5;
1307  endfilt(vfilt(t));
1308}
1309///////////////////////////////////////////////////////////////////////////////
1310
1311proc spgen(ideal a)
1312"USAGE:   spgen(a); ideal a
1313RETURN:
1314@format
1315list Sp: numbers in a with multiplicities
1316  ideal Sp[1]: numbers in a in increasing order
1317  intvec Sp[2]:
1318    int Sp[2][i]: multiplicity of number Sp[1][i] in a
1319@end format
1320EXAMPLE: example spgen; shows examples
1321"
1322{
1323  ideal a0=jet(a,0);
1324  int i,j;
1325  poly p;
1326  for(i=1;i<=ncols(a0);i++)
1327  {
1328    for(j=i+1;j<=ncols(a0);j++)
1329    {
1330      if(number(a0[i])>number(a0[j]))
1331      {
1332        p=a0[i];
1333        a0[i]=a0[j];
1334        a0[j]=p;
1335      }
1336    }
1337  }
1338  j=1;
1339  a=a0[1];
1340  intvec m=1;
1341  for(i=2;i<=ncols(a0);i++)
1342  {
1343    if(a0[i]==a[j])
1344    {
1345      m[j]=m[j]+1;
1346    }
1347    else
1348    {
1349      j++;
1350      a[j]=a0[i];
1351      m[j]=1;
1352    }
1353  }
1354  return(list(a,m));
1355}
1356example
1357{ "EXAMPLE:"; echo=2;
1358  ring R=0,(x,y),ds;
1359  ideal a=-1/2,-3/10,-3/10,-1/10,-1/10,0,1/10,1/10,3/10,3/10,1/2;
1360  spprint(spgen(a));
1361}
1362///////////////////////////////////////////////////////////////////////////////
1363
1364proc sppgen(ideal a,intvec w)
1365"USAGE:   sppgen(a,w); ideal a, intvec w
1366RETURN:
1367@format
1368list Spp: pairs in a and w with multiplicities
1369  ideal Spp[1]: numbers in a in increasing order
1370  intvec Spp[2]: integers in w in decreasing order
1371  intvec Spp[3]:
1372    int Spp[3][i]: multiplicity of pair (Spp[1][i],Spp[2][i]) in a,w
1373@end format
1374EXAMPLE: example sppgen; shows examples
1375"
1376{
1377  ideal a0=jet(a,0);
1378  intvec w0=w;
1379  int i,j,k;
1380  poly p;
1381  for(i=1;i<=ncols(a0);i++)
1382  {
1383    for(j=i+1;j<=ncols(a0);j++)
1384    {
1385      if(number(a0[i])>number(a0[j])||a0[i]==a0[j]&&w0[i]>w0[j])
1386      {
1387        p=a0[i];
1388        a0[i]=a0[j];
1389        a0[j]=p;
1390        k=w0[i];
1391        w0[i]=w0[j];
1392        w0[j]=k;
1393      }
1394    }
1395  }
1396  j=1;
1397  a=a0[1];
1398  w=w0[1];
1399  intvec m=1;
1400  for(i=2;i<=ncols(a0);i++)
1401  {
1402    if(a0[i]==a[j]&&w0[i]==w[j])
1403    {
1404      m[j]=m[j]+1;
1405    }
1406    else
1407    {
1408      j++;
1409      a[j]=a0[i];
1410      w[j]=w0[i];
1411      m[j]=1;
1412    }
1413  }
1414  return(list(a,w,m));
1415}
1416example
1417{ "EXAMPLE:"; echo=2;
1418  ring R=0,(x,y),ds;
1419  ideal a=-1/2,-3/10,-3/10,-1/10,-1/10,0,1/10,1/10,3/10,3/10,1/2;
1420  intvec w=2,1,1,1,1,1,1,1,1,1,0;
1421  spprint(sppgen(a,w));
1422}
1423///////////////////////////////////////////////////////////////////////////////
1424
1425proc spprint(list Sp)
1426"USAGE:   spprint(Sp); list Sp
1427RETURN:  string: spectrum or spectral pairs Sp
1428EXAMPLE: example spprint; shows examples
1429"
1430{
1431  string s;
1432  if(size(Sp)==2)
1433  {
1434    for(int i=1;i<size(Sp[2]);i++)
1435    {
1436      s=s+"("+string(Sp[1][i])+","+string(Sp[2][i])+"),";
1437    }
1438    s=s+"("+string(Sp[1][i])+","+string(Sp[2][i])+")";
1439  }
1440  else
1441  {
1442    for(int i=1;i<size(Sp[3]);i++)
1443    {
1444      s=s+"(("+string(Sp[1][i])+","+string(Sp[2][i])+"),"+string(Sp[3][i])+"),";
1445    }
1446    s=s+"(("+string(Sp[1][i])+","+string(Sp[2][i])+"),"+string(Sp[3][i])+")";
1447  }
1448  return(s);
1449}
1450example
1451{ "EXAMPLE:"; echo=2;
1452  ring R=0,(x,y),ds;
1453  list Sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
1454  spprint(Sp);
1455}
1456///////////////////////////////////////////////////////////////////////////////
1457
1458proc spadd(list Sp1,list Sp2)
1459"USAGE:   spadd(Sp1,Sp2); list Sp1,Sp2
1460RETURN:  list: sum of spectra Sp1 and Sp2
1461EXAMPLE: example spadd; shows examples
1462"
1463{
1464  ideal s;
1465  intvec m;
1466  int i,i1,i2=1,1,1;
1467  while(i1<=size(Sp1[2])||i2<=size(Sp2[2]))
1468  {
1469    if(i1<=size(Sp1[2]))
1470    {
1471      if(i2<=size(Sp2[2]))
1472      {
1473        if(number(Sp1[1][i1])<number(Sp2[1][i2]))
1474        {
1475          s[i]=Sp1[1][i1];
1476          m[i]=Sp1[2][i1];
1477          i++;
1478          i1++;
1479        }
1480        else
1481        {
1482          if(number(Sp1[1][i1])>number(Sp2[1][i2]))
1483          {
1484            s[i]=Sp2[1][i2];
1485            m[i]=Sp2[2][i2];
1486            i++;
1487            i2++;
1488          }
1489          else
1490          {
1491            if(Sp1[2][i1]+Sp2[2][i2]!=0)
1492            {
1493              s[i]=Sp1[1][i1];
1494              m[i]=Sp1[2][i1]+Sp2[2][i2];
1495              i++;
1496            }
1497            i1++;
1498            i2++;
1499          }
1500        }
1501      }
1502      else
1503      {
1504        s[i]=Sp1[1][i1];
1505        m[i]=Sp1[2][i1];
1506        i++;
1507        i1++;
1508      }
1509    }
1510    else
1511    {
1512      s[i]=Sp2[1][i2];
1513      m[i]=Sp2[2][i2];
1514      i++;
1515      i2++;
1516    }
1517  }
1518  return(list(s,m));
1519}
1520example
1521{ "EXAMPLE:"; echo=2;
1522  ring R=0,(x,y),ds;
1523  list Sp1=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
1524  spprint(Sp1);
1525  list Sp2=list(ideal(-1/6,1/6),intvec(1,1));
1526  spprint(Sp2);
1527  spprint(spadd(Sp1,Sp2));
1528}
1529///////////////////////////////////////////////////////////////////////////////
1530
1531proc spsub(list Sp1,list Sp2)
1532"USAGE:   spsub(Sp1,Sp2); list Sp1,Sp2
1533RETURN:  list: difference of spectra Sp1 and Sp2
1534EXAMPLE: example spsub; shows examples
1535"
1536{
1537  return(spadd(Sp1,spmul(Sp2,-1)));
1538}
1539example
1540{ "EXAMPLE:"; echo=2;
1541  ring R=0,(x,y),ds;
1542  list Sp1=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
1543  spprint(Sp1);
1544  list Sp2=list(ideal(-1/6,1/6),intvec(1,1));
1545  spprint(Sp2);
1546  spprint(spsub(Sp1,Sp2));
1547}
1548///////////////////////////////////////////////////////////////////////////////
1549
1550proc spmul(list #)
1551"USAGE:
1552@format
15531) spmul(Sp,k); list Sp, int k
15542) spmul(Sp,k); list Sp, intvec k
1555@end format
1556RETURN:
1557@format
15581) list: product of spectrum Sp and integer k
15592) list: linear combination of spectra Sp with coefficients k
1560@end format
1561EXAMPLE: example spmul; shows examples
1562"
1563{
1564  if(size(#)==2)
1565  {
1566    if(typeof(#[1])=="list")
1567    {
1568      if(typeof(#[2])=="int")
1569      {
1570        return(list(#[1][1],#[1][2]*#[2]));
1571      }
1572      if(typeof(#[2])=="intvec")
1573      {
1574        list Sp0=list(ideal(),intvec(0));
1575        for(int i=size(#[2]);i>=1;i--)
1576        {
1577          Sp0=spadd(Sp0,spmul(#[1][i],#[2][i]));
1578        }
1579        return(Sp0);
1580      }
1581    }
1582  }
1583  return(list(ideal(),intvec(0)));
1584}
1585example
1586{ "EXAMPLE:"; echo=2;
1587  ring R=0,(x,y),ds;
1588  list Sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
1589  spprint(Sp);
1590  spprint(spmul(Sp,2));
1591  list Sp1=list(ideal(-1/6,1/6),intvec(1,1));
1592  spprint(Sp1);
1593  list Sp2=list(ideal(-1/3,0,1/3),intvec(1,2,1));
1594  spprint(Sp2);
1595  spprint(spmul(list(Sp1,Sp2),intvec(1,2)));
1596}
1597///////////////////////////////////////////////////////////////////////////////
1598
1599proc spissemicont(list Sp,list #)
1600"USAGE:   spissemicont(Sp[,opt]); list Sp, int opt
1601RETURN:
1602@format
1603int k=
1604if opt=0:
1605  1, if sum of spectrum Sp over all intervals [a,a+1) is positive
1606  0, if sum of spectrum Sp over some interval [a,a+1) is negative
1607if opt=1:
1608  1, if sum of spectrum Sp over all intervals [a,a+1) and (a,a+1) is positive
1609  0, if sum of spectrum Sp over some interval [a,a+1) or (a,a+1) is negative
1610default: opt=0
1611@end format
1612EXAMPLE: example spissemicont; shows examples
1613"
1614{
1615  int opt=0;
1616  if(size(#)>0)
1617  {
1618    if(typeof(#[1])=="int")
1619    {
1620      opt=1;
1621    }
1622  }
1623  int i,j,k=1,1,0;
1624  while(j<=size(Sp[2]))
1625  {
1626    while(j+1<=size(Sp[2])&&Sp[1][j]<Sp[1][i]+1)
1627    {
1628      k=k+Sp[2][j];
1629      j++;
1630    }
1631    if(j==size(Sp[2])&&Sp[1][j]<Sp[1][i]+1)
1632    {
1633      k=k+Sp[2][j];
1634      j++;
1635    }
1636    if(k<0)
1637    {
1638      return(0);
1639    }
1640    k=k-Sp[2][i];
1641    if(k<0&&opt==1)
1642    {
1643      return(0);
1644    }
1645    i++;
1646  }
1647  return(1);
1648}
1649example
1650{ "EXAMPLE:"; echo=2;
1651  ring R=0,(x,y),ds;
1652  list Sp1=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
1653  spprint(Sp1);
1654  list Sp2=list(ideal(-1/6,1/6),intvec(1,1));
1655  spprint(Sp2);
1656  spissemicont(spsub(Sp1,spmul(Sp2,5)));
1657  spissemicont(spsub(Sp1,spmul(Sp2,5)),1);
1658  spissemicont(spsub(Sp1,spmul(Sp2,6)));
1659}
1660///////////////////////////////////////////////////////////////////////////////
1661
1662proc spsemicont(list Sp0,list Sp,list #)
1663"USAGE:   spsemicont(Sp,k[,opt]); list Sp0, list Sp, int opt
1664RETURN:  list of intvecs l:
1665         spissemicont(sub(Sp0,spmul(Sp,k)),opt)==1 iff k<=l[i] for some i
1666NOTE:    if the spectra Sp occur with multiplicities k in a deformation
1667         of the [quasihomogeneous] spectrum Sp0 then
1668         spissemicont(sub(Sp0,spmul(Sp,k))[,1])==1
1669EXAMPLE: example spsemicont; shows examples
1670"
1671{
1672  list l,l0;
1673  int i,j,k;
1674  while(spissemicont(Sp0,#))
1675  {
1676    if(size(Sp)>1)
1677    {
1678      l0=spsemicont(Sp0,list(Sp[1..size(Sp)-1]));
1679      for(i=1;i<=size(l0);i++)
1680      {
1681        if(size(l)>0)
1682        {
1683          j=1;
1684          while(j<size(l)&&l[j]!=l0[i])
1685          {
1686            j++;
1687          }
1688          if(l[j]==l0[i])
1689          {
1690            l[j][size(Sp)]=k;
1691          }
1692          else
1693          {
1694            l0[i][size(Sp)]=k;
1695            l=l+list(l0[i]);
1696          }
1697        }
1698        else
1699        {
1700          l=l0;
1701        }
1702      }
1703    }
1704    Sp0=spsub(Sp0,Sp[size(Sp)]);
1705    k++;
1706  }
1707  if(size(Sp)>1)
1708  {
1709    return(l);
1710  }
1711  else
1712  {
1713    return(list(intvec(k-1)));
1714  }
1715}
1716example
1717{ "EXAMPLE:"; echo=2;
1718  ring R=0,(x,y),ds;
1719  list Sp0=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
1720  spprint(Sp0);
1721  list Sp1=list(ideal(-1/6,1/6),intvec(1,1));
1722  spprint(Sp1);
1723  list Sp2=list(ideal(-1/3,0,1/3),intvec(1,2,1));
1724  spprint(Sp2);
1725  list Sp=Sp1,Sp2;
1726  list l=spsemicont(Sp0,Sp);
1727  l;
1728  spissemicont(spsub(Sp0,spmul(Sp,l[1])));
1729  spissemicont(spsub(Sp0,spmul(Sp,l[1]-1)));
1730  spissemicont(spsub(Sp0,spmul(Sp,l[1]+1)));
1731}
1732///////////////////////////////////////////////////////////////////////////////
1733
1734proc spmilnor(list Sp)
1735"USAGE:   spmilnor(Sp); list Sp
1736RETURN:  int: Milnor number of spectrum Sp
1737EXAMPLE: example spmilnor; shows examples
1738"
1739{
1740  return(sum(Sp[2]));
1741}
1742example
1743{ "EXAMPLE:"; echo=2;
1744  ring R=0,(x,y),ds;
1745  list Sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
1746  spprint(Sp);
1747  spmilnor(Sp);
1748}
1749///////////////////////////////////////////////////////////////////////////////
1750
1751proc spgeomgenus(list Sp)
1752"USAGE:   spgeomgenus(Sp); list Sp
1753RETURN:  int: geometrical genus of spectrum Sp
1754EXAMPLE: example spgeomgenus; shows examples
1755"
1756{
1757  int g=0;
1758  int i=1;
1759  while(i+1<=size(Sp[2])&&number(Sp[1][i])<=number(0))
1760  {
1761    g=g+Sp[2][i];
1762    i++;
1763  }
1764  if(i==size(Sp[2])&&number(Sp[1][i])<=number(0))
1765  {
1766    g=g+Sp[2][i];
1767  }
1768  return(g);
1769}
1770example
1771{ "EXAMPLE:"; echo=2;
1772  ring R=0,(x,y),ds;
1773  list Sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
1774  spprint(Sp);
1775  spgeomgenus(Sp);
1776}
1777///////////////////////////////////////////////////////////////////////////////
1778
1779proc spgamma(list Sp)
1780"USAGE:   spgamma(Sp); list Sp
1781RETURN:  number: gamma invariant of spectrum Sp
1782EXAMPLE: example spgamma; shows examples
1783"
1784{
1785  int i,j;
1786  number g=0;
1787  for(i=1;i<=ncols(Sp[1]);i++)
1788  {
1789    for(j=1;j<=Sp[2][i];j++)
1790    {
1791      g=g+(number(Sp[1][i])-number(nvars(basering)-2)/2)^2;
1792    }
1793  }
1794  g=-g/4+sum(Sp[2])*number(Sp[1][ncols(Sp[1])]-Sp[1][1])/48;
1795  return(g);
1796}
1797example
1798{ "EXAMPLE:"; echo=2;
1799  ring R=0,(x,y),ds;
1800  list Sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
1801  spprint(Sp);
1802  spgamma(Sp);
1803}
1804///////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.