source: git/Singular/LIB/gaussman.lib @ 86c1f0

spielwiese
Last change on this file since 86c1f0 was 86c1f0, checked in by Mathias Schulze <mschulze@…>, 23 years ago
*mschulze: added sppairs git-svn-id: file:///usr/local/Singular/svn/trunk@5576 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 39.0 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="$Id: gaussman.lib,v 1.49 2001-08-09 08:39:54 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
379static proc maxorddif(matrix H)
380{
381  int i,j,d;
382  int d0,d1=-1,-1;
383  for(i=nrows(H);i>=1;i--)
384  {
385    for(j=ncols(H);j>=1;j--)
386    {
387      d=ord(H[i,j]);
388      if(d>=0)
389      {
390        if(d0<0||d<d0)
391        {
392          d0=d;
393        }
394        if(d1<0||d>d1)
395        {
396          d1=d;
397        }
398      }
399    }
400  }
401  return(d1-d0);
402}
403///////////////////////////////////////////////////////////////////////////////
404
405proc monodromy(poly t,list #)
406"USAGE:    monodromy(t[,opt]); poly t[, int opt]
407ASSUME:   basering with characteristic 0 and local degree ordering,
408          t with isolated singularity at 0
409RETURN:
410@format
411if opt=0:
412list l:
413  ideal l[1]: exp(-2*pi*i*l[1]) are the eigenvalues of the monodromy
414if opt=1:
415list l: Jordan data jordan(M) of a monodromy matrix exp(-2*pi*i*M)
416default: opt=1
417@end format
418SEE ALSO: mondromy_lib
419KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice; monodromy
420EXAMPLE:  example monodromy; shows examples
421"
422{
423  int opt=1;
424  if(size(#)>0)
425  {
426    if(typeof(#[1])=="int")
427    {
428      opt=#[1];
429    }
430  }
431
432  def R=basering;
433  int n=nvars(R)-1;
434  def G=gmsring(t,"s");
435  setring G;
436
437  int mu=ncols(gmsbasis);
438  ideal r=gmspoly*gmsbasis;
439  list l;
440  matrix U=freemodule(mu);
441  matrix A0[mu][mu],C;
442  module H,H1=freemodule(mu),freemodule(mu);
443  module H0;
444  int k=-1;
445  while(size(reduce(H,std(H0*s)))>0)
446  {
447    k++;
448    dbprint(printlevel-voice+2,"// k="+string(k));
449    dbprint(printlevel-voice+2,"// compute matrix A of t");
450    if(opt==0)
451    {
452      l=gmscoeffs(r,k,mu);
453    }
454    else
455    {
456      l=gmscoeffs(r,k,mu+n);
457    }
458    C,r=l[1..2];
459    A0=A0+C;
460
461    dbprint(printlevel-voice+2,"// compute saturation of H''");
462    H0=H;
463    H1=jet(module(A0*H1+s^2*diff(matrix(H1),s)),k);
464    H=H*s+H1;
465  }
466  A0=A0-k*s;
467
468  dbprint(printlevel-voice+2,"// compute basis of saturation of H''");
469  H=std(H0);
470  int d0=maxorddif(H)/deg(s);
471  dbprint(printlevel-voice+2,"// k="+string(d0+1));
472  dbprint(printlevel-voice+2,"// compute matrix A of t");
473  if(opt==0)
474  {
475    l=gmscoeffs(r,d0+1,d0+1);
476  }
477  else
478  {
479    l=gmscoeffs(r,d0+1,d0+1+n);
480  }
481  C,r=l[1..2];
482  A0=A0+C;
483  dbprint(printlevel-voice+2,"// transform A to saturation of H''");
484  l=division(H*s,A0*H+s^2*diff(matrix(H),s));
485  matrix A=jet(l[1],l[2],0);
486
487  dbprint(printlevel-voice+2,
488    "// compute eigenvalues e with multiplicities m of A");
489  l=eigenval(jet(A,0));
490  def e,m=l[1..2];
491  dbprint(printlevel-voice+2,"// e="+string(e));
492  dbprint(printlevel-voice+2,"// m="+string(m));
493
494  if(opt==0)
495  {
496    setring(R);
497    ideal e=imap(G,e);
498    return(list(e));
499  }
500
501  dbprint(printlevel-voice+2,"// compute maximal integer difference d1 of e");
502  int d1=maxintdif(e);
503  dbprint(printlevel-voice+2,"// d1="+string(d1));
504
505  if(d1>0)
506  {
507    dbprint(printlevel-voice+2,"// k="+string(d0+d1+1));
508    dbprint(printlevel-voice+2,"// compute matrix A of t");
509    l=gmscoeffs(r,d0+d1+1,d0+d1+1);
510    C,r=l[1..2];
511    A0=A0+C;
512    dbprint(printlevel-voice+2,"// transform A to saturation of H''");
513    l=division(H*s,A0*H+s^2*diff(matrix(H),s));
514    A=jet(l[1],l[2],d1);
515
516    intvec d;
517    d[mu]=0;
518    int i,j;
519    for(i=ncols(e);i>=1;i--)
520    {
521      for(j=i-1;j>=1;j--)
522      {
523        k=int(e[j]-e[i]);
524        if(k>d[j])
525        {
526          d[j]=k;
527        }
528        if(-k>d[i])
529        {
530          d[i]=-k;
531        }
532      }
533    }
534    for(j,k=ncols(e),mu;j>=1;j--)
535    {
536      for(i=m[j];i>=1;i--)
537      {
538        d[k]=d[j];
539        k--;
540      }
541    }
542
543    while(d1>0)
544    {
545      dbprint(printlevel-voice+2,"// transform basis to reduce d1 by 1");
546
547      A0=jet(A,0);
548      U=0;
549      for(i=ncols(e);i>=1;i--)
550      {
551        U=syz(power(A0-e[i],n+1))+U;
552      }
553      A=lift(U,A*U);
554
555      for(i=mu;i>=1;i--)
556      {
557        for(j=mu;j>=1;j--)
558        {
559          if(d[i]==0&&d[j]>0)
560          {
561            A[i,j]=A[i,j]/s;
562          }
563          else
564          {
565            if(d[i]>0&&d[j]==0)
566            {
567              A[i,j]=A[i,j]*s;
568            }
569          }
570        }
571      }
572      for(i=mu;i>=1;i--)
573      {
574        if(d[i]>0)
575        {
576          A[i,i]=A[i,i]-1;
577          d[i]=d[i]-1;
578        }
579      }
580
581      d1--;
582      dbprint(printlevel-voice+2,"// d1="+string(d1));
583    }
584
585    A=jet(A,0);
586  }
587
588  setring(R);
589  matrix A=imap(G,A);
590  return(jordan(A));
591}
592example
593{ "EXAMPLE:"; echo=2;
594  ring R=0,(x,y),ds;
595  poly f=x5+x2y2+y5;
596  print(monodromy(f));
597}
598///////////////////////////////////////////////////////////////////////////////
599
600proc spectrum(poly t)
601"USAGE:    spectrum(t); poly t
602ASSUME:   basering with characteristic 0 and local degree ordering,
603          t with isolated singularity at 0
604RETURN:
605@format
606list Sp: spectrum of t
607  ideal Sp[1]: spectral numbers in increasing order
608  intvec Sp[2]:
609    int Sp[2][i]: multiplicity of spectral number Sp[1][i]
610@end format
611SEE ALSO: spectrum_lib
612KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice; spectrum
613EXAMPLE:  example spnumbers; shows examples
614"
615{
616  return(sppairs(t,0));
617}
618example
619{ "EXAMPLE:"; echo=2;
620  ring R=0,(x,y),ds;
621  poly t=x5+x2y2+y5;
622  spprint(spectrum(t));
623}
624///////////////////////////////////////////////////////////////////////////////
625
626proc sppairs(poly t,list #)
627"USAGE:    sppairs(t[,opt]); poly t[, int opt]
628ASSUME:   basering with characteristic 0 and local degree ordering,
629          t with isolated singularity at 0
630RETURN: list l:
631@format
632  ideal l[1]: spectral numbers in increasing order
633if opt<=0:
634  intvec l[2]:
635    int l[2][i]: multiplicity of spectral number l[1][i]
636if opt>=1:
637  intvec l[2]: weight filtration indices in decreasing order
638  intvec l[3]:
639    int l[3][i]: multiplicity of spectral pair (l[1][i],l[2][i])
640default: opt=1
641@end format
642SEE ALSO: spectrum_lib
643KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice;
644          spectrum; spectral pairs
645EXAMPLE:  example sppairs; shows examples
646"
647{
648  int opt=1;
649  if(size(#)>0)
650  {
651    if(typeof(#[1])=="int")
652    {
653      opt=#[1];
654    }
655  }
656
657  def R=basering;
658  int n=nvars(R)-1;
659  def G=gmsring(t,"s");
660  setring(G);
661
662  int mu=ncols(gmsbasis);
663  ideal r=gmspoly*gmsbasis;
664  list l;
665  matrix U=freemodule(mu);
666  matrix A0[mu][mu],C;
667  module H0;
668  module H,H1=freemodule(mu),freemodule(mu);
669  int k=-1;
670  while(size(reduce(H,std(H0*s)))>0)
671  {
672    k++;
673    dbprint(printlevel-voice+2,"// k="+string(k));
674    dbprint(printlevel-voice+2,"// compute matrix A of t");
675    l=gmscoeffs(r,k,mu+n);
676    C,r=l[1..2];
677    A0=A0+C;
678
679    dbprint(printlevel-voice+2,"// compute saturation of H''");
680    H0=H;
681    H1=jet(module(A0*H1+s^2*diff(matrix(H1),s)),k);
682    H=H*s+H1;
683  }
684  A0=A0-k*s;
685
686  dbprint(printlevel-voice+2,"// compute basis of saturation of H''");
687  H=std(H0);
688  int d0=maxorddif(H)/deg(s);
689  dbprint(printlevel-voice+2,"// transform H'' to saturation of H''");
690  l=division(H,freemodule(mu)*s^k);
691  H0=l[1];
692
693  dbprint(printlevel-voice+2,"// k="+string(d0+1));
694  dbprint(printlevel-voice+2,"// compute matrix A of t");
695  l=gmscoeffs(r,d0+1,d0+1+n);
696  C,r=l[1..2];
697  A0=A0+C;
698  dbprint(printlevel-voice+2,"// transform A to saturation of H''");
699  l=division(H*s,A0*H+s^2*diff(matrix(H),s));
700  matrix A=jet(l[1],l[2],0);
701
702  int i,j;
703  matrix V;
704  if(opt<=0)
705  {
706    dbprint(printlevel-voice+2,"// transform to Jordan basis");
707    U=jordanbasis(A)[1];
708    V=lift(U,freemodule(mu));
709    A=V*A*U;
710    dbprint(printlevel-voice+2,"// compute normal form of H''");
711    H0=std(V*H0);
712
713    dbprint(printlevel-voice+2,"// compute spectral numbers");
714    ideal a;
715    for(i=1;i<=mu;i++)
716    {
717      j=leadexp(H0[i])[nvars(basering)+1];
718      a[i]=A[j,j]+deg(lead(H0[i]))/deg(s)-1;
719    }
720
721    setring(R);
722    return(spgen(imap(G,a)));
723  }
724
725  dbprint(printlevel-voice+2,
726    "// compute eigenvalues e with multiplicities m of A");
727  l=eigenval(A);
728  def e,m=l[1..2];
729  dbprint(printlevel-voice+2,"// e="+string(e));
730  dbprint(printlevel-voice+2,"// m="+string(m));
731  dbprint(printlevel-voice+2,"// compute maximal integer difference d1 of e");
732  int d1=maxintdif(e);
733  dbprint(printlevel-voice+2,"// d1="+string(d1));
734
735  if(d1>0)
736  {
737    dbprint(printlevel-voice+2,"// k="+string(d0+d1+1));
738    dbprint(printlevel-voice+2,"// compute matrix A of t");
739    l=gmscoeffs(r,d0+d1+1,d0+d1+1);
740    C,r=l[1..2];
741    A0=A0+C;
742    dbprint(printlevel-voice+2,"// transform A to saturation of H''");
743    l=division(H*s,A0*H+s^2*diff(matrix(H),s));
744    A=jet(l[1],l[2],d1);
745
746    intvec d;
747    d[mu]=0;
748    for(i=ncols(e);i>=1;i--)
749    {
750      for(j=i-1;j>=1;j--)
751      {
752        k=int(e[j]-e[i]);
753        if(k>d[j])
754        {
755          d[j]=k;
756        }
757        if(-k>d[i])
758        {
759          d[i]=-k;
760        }
761      }
762    }
763    for(j,k=ncols(e),mu;j>=1;j--)
764    {
765      for(i=m[j];i>=1;i--)
766      {
767        d[k]=d[j];
768        k--;
769      }
770    }
771
772    while(d1>0)
773    {
774      dbprint(printlevel-voice+2,"// transform to separate eigenvalues");
775      A0=jet(A,0);
776      U=0;
777      for(i=ncols(e);i>=1;i--)
778      {
779        U=syz(power(A0-e[i],n+1))+U;
780      }
781      V=lift(U,freemodule(mu));
782      A=V*A*U;
783      H0=V*H0;
784
785      dbprint(printlevel-voice+2,"// transform to reduce d1 by 1");
786      for(i=mu;i>=1;i--)
787      {
788        for(j=mu;j>=1;j--)
789        {
790          if(d[i]==0&&d[j]>0)
791          {
792            A[i,j]=A[i,j]/s;
793          }
794          else
795          {
796            if(d[i]>0&&d[j]==0)
797            {
798              A[i,j]=A[i,j]*s;
799            }
800          }
801        }
802      }
803      H0=transpose(H0);
804      for(i=mu;i>=1;i--)
805      {
806        if(d[i]>0)
807        {
808          A[i,i]=A[i,i]-1;
809          d[i]=d[i]-1;
810          H0[i]=H0[i]*s;
811        }
812      }
813      H0=transpose(H0);
814
815      d1--;
816      dbprint(printlevel-voice+2,"// d1="+string(d1));
817    }
818
819    A=jet(A,0);
820  }
821
822  dbprint(printlevel-voice+2,"// transform to Jordan basis");
823  intvec w0;
824  l=jordanbasis(A);
825  U,w0=l[1..2];
826  V=lift(U,freemodule(mu));
827  A0=V*A*U;
828
829  dbprint(printlevel-voice+2,"// compute weight filtration basis");
830  vector u;
831  i=1;
832  while(i<ncols(A))
833  {
834    j=i+1;
835    while(j<ncols(A)&&A[i,i]==A[j,j])
836    {
837      if(w0[i]<w0[j])
838      {
839        k=w0[i];
840        w0[i]=w0[j];
841        w0[i]=k;
842        u=U[i];
843        U[i]=U[j];
844        U[j]=u;
845      }
846      j++;
847    }
848    if(j==ncols(A)&&A[i,i]==A[j,j]&&w0[i]<w0[j])
849    {
850      k=w0[i];
851      w0[i]=w0[j];
852      w0[i]=k;
853      u=U[i];
854      U[i]=U[j];
855      U[j]=u;
856    }
857    i=j;
858  }
859
860  dbprint(printlevel-voice+2,"// transform to weight filtration basis");
861  V=lift(U,freemodule(mu));
862  A=V*A*U;
863  dbprint(printlevel-voice+2,"// compute normal form of H''");
864  H0=std(V*H0);
865
866  dbprint(printlevel-voice+2,"// compute spectral pairs");
867  ideal a;
868  intvec w;
869  for(i=1;i<=mu;i++)
870  {
871    j=leadexp(H0[i])[nvars(basering)+1];
872    a[i]=A[j,j]+deg(lead(H0[i]))/deg(s)-1;
873    w[i]=w0[j]+n;
874  }
875  setring(R);
876  return(sppgen(imap(G,a),w));
877}
878example
879{ "EXAMPLE:"; echo=2;
880  ring R=0,(x,y),ds;
881  poly t=x5+x2y2+y5;
882  spprint(sppairs(t));
883}
884///////////////////////////////////////////////////////////////////////////////
885
886proc vfilt(poly t,list #)
887"USAGE:    vfilt(t[,opt]); poly t, int opt
888ASSUME:   basering with characteristic 0 and local degree ordering,
889          t with isolated singularity at 0
890RETURN:
891@format
892list V: V-filtration of t on H''/H'
893  intvec V[1]: spectral numbers in increasing order
894  intvec V[2]:
895    int V[2][i]: multiplicity of spectral number V[1][i]/V[2][i]
896if opt>=1:
897  list V[4]:
898    module V[3][i]: vector space basis of V[1][i]/V[2][i]-th graded part
899                    in terms of V[5]
900  ideal V[4]: monomial vector space basis of H''/H'
901  ideal V[5]: standard basis of Jacobian ideal
902default: opt=1
903@end format
904NOTE:     H' and H'' denote the Brieskorn lattices
905SEE ALSO: spectrum_lib
906KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice;
907          Hodge filtration; V-filtration; spectrum
908EXAMPLE:  example vfilt; shows examples
909"
910{
911  int opt=1;
912  if(size(#)>0)
913  {
914    if(typeof(#[1])=="int")
915    {
916      opt=#[1];
917    }
918  }
919
920  def R=basering;
921  int n=nvars(R)-1;
922  def G=gmsring(t,"s");
923  setring G;
924
925  int mu=ncols(gmsbasis);
926  ideal r=gmspoly*gmsbasis;
927  list l;
928  matrix U=freemodule(mu);
929  matrix A[mu][mu],C;
930  module H,H1=freemodule(mu),freemodule(mu);
931  module H0;
932  int k=-1;
933  int N=n+1;
934
935  while(size(reduce(H,std(H0*s)))>0)
936  {
937    k++;
938    dbprint(printlevel-voice+2,"// k="+string(k));
939    dbprint(printlevel-voice+2,"// compute matrix A of t");
940    l=gmscoeffs(r,k);
941    C,r=l[1..2];
942    A=A+C;
943
944    dbprint(printlevel-voice+2,"// compute saturation of H''");
945    H0=H;
946    H1=jet(module(A*H1+s^2*diff(matrix(H1),s)),k);
947    H=H*s+H1;
948  }
949  A=A-k*s;
950
951  dbprint(printlevel-voice+2,"// compute basis of saturation of H''");
952  H=std(H0);
953  int d0=maxorddif(H)/deg(s);
954  dbprint(printlevel-voice+2,"// k="+string(d0+N));
955  dbprint(printlevel-voice+2,"// compute matrix A of t");
956  l=gmscoeffs(r,d0+N,d0+N);
957  C,r=l[1..2];
958  A=A+C;
959
960  dbprint(printlevel-voice+2,"// transform H'' to saturation of H''");
961  l=division(H,freemodule(mu)*s^k);
962  H0=jet(l[1],l[2],N-1);
963
964  dbprint(printlevel-voice+2,"// compute vector spaces");
965  poly p;
966  int i0,j0,i1,j1;
967  matrix V0[mu*N][mu*N];
968  matrix V1[mu*N][mu*(N-1)];
969  for(i0=mu;i0>=1;i0--)
970  {
971    for(i1=mu;i1>=1;i1--)
972    {
973      p=H0[i1,i0];
974      while(p!=0)
975      {
976        j1=leadexp(p)[1];
977        for(j0=N-j1-1;j0>=0;j0--)
978        {
979          V0[i1+(j1+j0)*mu,i0+j0*mu]=V0[i1+(j1+j0)*mu,i0+j0*mu]+leadcoef(p);
980          if(j1+j0+1<N)
981          {
982            V1[i1+(j1+j0+1)*mu,i0+j0*mu]=
983            V1[i1+(j1+j0+1)*mu,i0+j0*mu]+leadcoef(p);
984          }
985        }
986        p=p-lead(p);
987      }
988    }
989  }
990
991  dbprint(printlevel-voice+2,"// transform A to saturation of H''");
992  l=division(H*s,A*H+s^2*diff(matrix(H),s));
993  A=jet(l[1],l[2],N-1);
994
995  dbprint(printlevel-voice+2,"// compute matrix M of A");
996  matrix M[mu*N][mu*N];
997  for(i0=mu;i0>=1;i0--)
998  {
999    for(i1=mu;i1>=1;i1--)
1000    {
1001      p=A[i1,i0];
1002      while(p!=0)
1003      {
1004        j1=leadexp(p)[1];
1005        for(j0=N-j1-1;j0>=0;j0--)
1006        {
1007          M[i1+(j0+j1)*mu,i0+j0*mu]=leadcoef(p);
1008        }
1009        p=p-lead(p);
1010      }
1011    }
1012  }
1013  for(i0=mu;i0>=1;i0--)
1014  {
1015    for(j0=N-1;j0>=0;j0--)
1016    {
1017      M[i0+j0*mu,i0+j0*mu]=M[i0+j0*mu,i0+j0*mu]+j0;
1018    }
1019  }
1020
1021  dbprint(printlevel-voice+2,"// compute eigenvalues eA of A");
1022  ideal eA=eigenval(jet(A,0))[1];
1023  dbprint(printlevel-voice+2,"// eA="+string(eA));
1024
1025  dbprint(printlevel-voice+2,"// compute eigenvalues eM of M");
1026  ideal eM;
1027  k=0;
1028  intvec u;
1029  for(int i=N;i>=1;i--)
1030  {
1031    u[i]=1;
1032  }
1033  i0=1;
1034  while(u[N]<=ncols(eA))
1035  {
1036    for(i,i1=i0+1,i0;i<=N;i++)
1037    {
1038      if(eA[u[i]]+i<eA[u[i1]]+i1)
1039      {
1040        i1=i;
1041      }
1042    }
1043    k++;
1044    eM[k]=eA[u[i1]]+i1-1;
1045    u[i1]=u[i1]+1;
1046    if(u[i1]>ncols(eA))
1047    {
1048      i0=i1+1;
1049    }
1050  }
1051  dbprint(printlevel-voice+2,"// eM="+string(eM));
1052
1053  dbprint(printlevel-voice+2,"// compute V-filtration on H''/sH''");
1054  ideal a;
1055  k=0;
1056  list V;
1057  V[ncols(eM)+1]=interred(V1);
1058  intvec d;
1059  if(opt<=0)
1060  {
1061    for(i=ncols(eM);number(eM[i])-1>number(n-1)/2;i--)
1062    {
1063      dbprint(printlevel-voice+2,"// compute V["+string(i)+"]");
1064      V1=module(V1)+syz(power(M-eM[i],n+1));
1065      V[i]=interred(intersect(V1,V0));
1066
1067      if(size(V[i])>size(V[i+1]))
1068      {
1069        k++;
1070        a[k]=eM[i]-1;
1071        d[k]=size(V[i])-size(V[i+1]);
1072      }
1073    }
1074
1075    dbprint(printlevel-voice+2,"// symmetry index found");
1076    int j=k;
1077
1078    if(number(eM[i])-1==number(n-1)/2)
1079    {
1080      dbprint(printlevel-voice+2,"// compute V["+string(i)+"]");
1081      V1=module(V1)+syz(power(M-eM[i],n+1));
1082      V[i]=interred(intersect(V1,V0));
1083
1084      if(size(V[i])>size(V[i+1]))
1085      {
1086        k++;
1087        a[k]=eM[i]-1;
1088        d[k]=size(V[i])-size(V[i+1]);
1089      }
1090    }
1091
1092    dbprint(printlevel-voice+2,"// apply symmetry");
1093    while(j>=1)
1094    {
1095      k++;
1096      a[k]=a[j];
1097      a[j]=n-1-a[k];
1098      d[k]=d[j];
1099      j--;
1100    }
1101
1102    setring(R);
1103    ideal a=imap(G,a);
1104    return(list(a,d));
1105  }
1106  else
1107  {
1108    list v;
1109    int j=-1;
1110    for(i=ncols(eM);i>=1;i--)
1111    {
1112      dbprint(printlevel-voice+2,"// compute V["+string(i)+"]");
1113      V1=module(V1)+syz(power(M-eM[i],n+1));
1114      V[i]=interred(intersect(V1,V0));
1115
1116      if(size(V[i])>size(V[i+1]))
1117      {
1118        if(number(eM[i]-1)>=number(n-1)/2)
1119        {
1120          k++;
1121          a[k]=eM[i]-1;
1122          v[k]=matrix(freemodule(ncols(V[i])),mu,mu*N)*division(V0,V[i])[1];
1123        }
1124        else
1125        {
1126          if(j<0)
1127          {
1128            if(a[k]==number(n-1)/2)
1129            {
1130              j=k-1;
1131            }
1132            else
1133            {
1134              j=k;
1135            }
1136          }
1137          k++;
1138          a[k]=a[j];
1139          a[j]=eM[i]-1;
1140          v[k]=v[j];
1141          v[j]=matrix(freemodule(ncols(V[i])),mu,mu*N)*division(V0,V[i])[1];
1142          j--;
1143        }
1144      }
1145    }
1146
1147    dbprint(printlevel-voice+2,"// compute graded parts");
1148    for(k=1;k<size(v);k++)
1149    {
1150      v[k]=interred(reduce(v[k],std(v[k+1])));
1151      d[k]=size(v[k]);
1152    }
1153    v[k]=interred(v[k]);
1154    d[k]=size(v[k]);
1155
1156    setring(R);
1157    ideal a=imap(G,a);
1158    list v=imap(G,v);
1159    ideal m=imap(G,gmsbasis);
1160    ideal g=imap(G,gmsstd);
1161    attrib(g,"isSB",1);
1162    return(list(a,d,v,m,g));
1163  }
1164}
1165example
1166{ "EXAMPLE:"; echo=2;
1167  ring R=0,(x,y),ds;
1168  poly t=x5+x2y2+y5;
1169  vfilt(t);
1170}
1171///////////////////////////////////////////////////////////////////////////////
1172
1173proc endfilt(list V)
1174"USAGE:   endfilt(V); list V
1175ASSUME:  V computed by vfilt
1176RETURN:
1177@format
1178list V1: endomorphim filtration of V on the Jacobian algebra
1179  ideal V1[1]: spectral numbers in increasing order
1180  intvec V1[2]:
1181    int V1[2][i]: multiplicity of spectral number V1[1][i]
1182  list V1[3]:
1183    module V1[3][i]: vector space basis of the V1[1][i]-th graded part
1184                     in terms of V1[4]
1185  ideal V1[4]: monomial vector space basis
1186@end format
1187SEE ALSO: spectrum_lib
1188KEYWORDS: singularities; Gauss-Manin connection; Brieskorn lattice; spectrum;
1189          Hodge filtration; V-filtration
1190EXAMPLE: example endfilt; shows examples
1191"
1192{
1193  def a,d,v,m,g=V[1..5];
1194  int mu=ncols(m);
1195
1196  module V0=v[1];
1197  for(int i=2;i<=size(v);i++)
1198  {
1199    V0=V0,v[i];
1200  }
1201
1202  dbprint(printlevel-voice+2,"// compute multiplication in Jacobian algebra");
1203  list M;
1204  matrix U=freemodule(ncols(m));
1205  for(i=ncols(m);i>=1;i--)
1206  {
1207    M[i]=lift(V0,coeffs(reduce(m[i]*m,U,g),m)*V0);
1208  }
1209
1210  int j,k,i0,j0,i1,j1;
1211  number b0=number(a[1]-a[ncols(a)]);
1212  number b1,b2;
1213  matrix M0;
1214  module L;
1215  list v0=freemodule(ncols(m));
1216  ideal a0=b0;
1217
1218  while(b0<number(a[ncols(a)]-a[1]))
1219  {
1220    dbprint(printlevel-voice+2,"// find next possible index");
1221    b1=number(a[ncols(a)]-a[1]);
1222    for(j=ncols(a);j>=1;j--)
1223    {
1224      for(i=ncols(a);i>=1;i--)
1225      {
1226        b2=number(a[i]-a[j]);
1227        if(b2>b0&&b2<b1)
1228        {
1229          b1=b2;
1230        }
1231        else
1232        {
1233          if(b2<=b0)
1234          {
1235            i=0;
1236          }
1237        }
1238      }
1239    }
1240    b0=b1;
1241
1242    list l=ideal();
1243    for(k=ncols(m);k>=2;k--)
1244    {
1245      l=l+list(ideal());
1246    }
1247
1248    dbprint(printlevel-voice+2,"// collect conditions for V1["+string(b0)+"]");
1249    j=ncols(a);
1250    j0=mu;
1251    while(j>=1)
1252    {
1253      i0=1;
1254      i=1;
1255      while(i<ncols(a)&&a[i]<a[j]+b0)
1256      {
1257        i0=i0+d[i];
1258        i++;
1259      }
1260      if(a[i]<a[j]+b0)
1261      {
1262        i0=i0+d[i];
1263        i++;
1264      }
1265      for(k=1;k<=ncols(m);k++)
1266      {
1267        M0=M[k];
1268        if(i0>1)
1269        {
1270          l[k]=l[k],M0[1..i0-1,j0-d[j]+1..j0];
1271        }
1272      }
1273      j0=j0-d[j];
1274      j--;
1275    }
1276
1277    dbprint(printlevel-voice+2,"// compose condition matrix");
1278    L=transpose(module(l[1]));
1279    for(k=2;k<=ncols(m);k++)
1280    {
1281      L=L,transpose(module(l[k]));
1282    }
1283
1284    dbprint(printlevel-voice+2,"// compute kernel of condition matrix");
1285    v0=v0+list(syz(L));
1286    a0=a0,b0;
1287  }
1288
1289  dbprint(printlevel-voice+2,"// compute graded parts");
1290  option(redSB);
1291  for(i=1;i<size(v0);i++)
1292  {
1293    v0[i+1]=std(v0[i+1]);
1294    v0[i]=std(reduce(v0[i],v0[i+1]));
1295  }
1296
1297  dbprint(printlevel-voice+2,"// remove trivial graded parts");
1298  i=1;
1299  while(size(v0[i])==0)
1300  {
1301    i++;
1302  }
1303  list v1=v0[i];
1304  intvec d1=size(v0[i]);
1305  ideal a1=a0[i];
1306  i++;
1307  while(i<=size(v0))
1308  {
1309    if(size(v0[i])>0)
1310    {
1311      v1=v1+list(v0[i]);
1312      d1=d1,size(v0[i]);
1313      a1=a1,a0[i];
1314    }
1315    i++;
1316  }
1317  return(list(a1,d1,v1,m));
1318}
1319example
1320{ "EXAMPLE:"; echo=2;
1321  ring R=0,(x,y),ds;
1322  poly t=x5+x2y2+y5;
1323  endfilt(vfilt(t));
1324}
1325///////////////////////////////////////////////////////////////////////////////
1326
1327proc spgen(ideal a)
1328"USAGE:   spgen(a); ideal a
1329RETURN:
1330@format
1331list Sp: numbers in a with multiplicities
1332  ideal Sp[1]: numbers in a in increasing order
1333  intvec Sp[2]:
1334    int Sp[2][i]: multiplicity of number Sp[1][i] in a
1335@end format
1336EXAMPLE: example spgen; shows examples
1337"
1338{
1339  ideal a0=jet(a,0);
1340  int i,j;
1341  poly p;
1342  for(i=1;i<=ncols(a0);i++)
1343  {
1344    for(j=i+1;j<=ncols(a0);j++)
1345    {
1346      if(number(a0[i])>number(a0[j]))
1347      {
1348        p=a0[i];
1349        a0[i]=a0[j];
1350        a0[j]=p;
1351      }
1352    }
1353  }
1354  j=1;
1355  a=a0[1];
1356  intvec m=1;
1357  for(i=2;i<=ncols(a0);i++)
1358  {
1359    if(a0[i]==a[j])
1360    {
1361      m[j]=m[j]+1;
1362    }
1363    else
1364    {
1365      j++;
1366      a[j]=a0[i];
1367      m[j]=1;
1368    }
1369  }
1370  return(list(a,m));
1371}
1372example
1373{ "EXAMPLE:"; echo=2;
1374  ring R=0,(x,y),ds;
1375  ideal a=-1/2,-3/10,-3/10,-1/10,-1/10,0,1/10,1/10,3/10,3/10,1/2;
1376  spprint(spgen(a));
1377}
1378///////////////////////////////////////////////////////////////////////////////
1379
1380proc sppgen(ideal a,intvec w)
1381"USAGE:   sppgen(a,w); ideal a, intvec w
1382RETURN:
1383@format
1384list Spp: pairs in a and w with multiplicities
1385  ideal Spp[1]: numbers in a in increasing order
1386  intvec Spp[2]: integers in w in decreasing order
1387  intvec Spp[3]:
1388    int Spp[3][i]: multiplicity of pair (Spp[1][i],Spp[2][i]) in a,w
1389@end format
1390EXAMPLE: example sppgen; shows examples
1391"
1392{
1393  ideal a0=jet(a,0);
1394  intvec w0=w;
1395  int i,j,k;
1396  poly p;
1397  for(i=1;i<=ncols(a0);i++)
1398  {
1399    for(j=i+1;j<=ncols(a0);j++)
1400    {
1401      if(number(a0[i])>number(a0[j])||a0[i]==a0[j]&&w0[i]>w0[j])
1402      {
1403        p=a0[i];
1404        a0[i]=a0[j];
1405        a0[j]=p;
1406        k=w0[i];
1407        w0[i]=w0[j];
1408        w0[j]=k;
1409      }
1410    }
1411  }
1412  j=1;
1413  a=a0[1];
1414  w=w0[1];
1415  intvec m=1;
1416  for(i=2;i<=ncols(a0);i++)
1417  {
1418    if(a0[i]==a[j]&&w0[i]==w[j])
1419    {
1420      m[j]=m[j]+1;
1421    }
1422    else
1423    {
1424      j++;
1425      a[j]=a0[i];
1426      w[j]=w0[i];
1427      m[j]=1;
1428    }
1429  }
1430  return(list(a,w,m));
1431}
1432example
1433{ "EXAMPLE:"; echo=2;
1434  ring R=0,(x,y),ds;
1435  ideal a=-1/2,-3/10,-3/10,-1/10,-1/10,0,1/10,1/10,3/10,3/10,1/2;
1436  intvec w=2,1,1,1,1,1,1,1,1,1,0;
1437  spprint(sppgen(a,w));
1438}
1439///////////////////////////////////////////////////////////////////////////////
1440
1441proc spprint(list Sp)
1442"USAGE:   spprint(Sp); list Sp
1443RETURN:  string: spectrum or spectral pairs Sp
1444EXAMPLE: example spprint; shows examples
1445"
1446{
1447  string s;
1448  if(size(Sp)==2)
1449  {
1450    for(int i=1;i<size(Sp[2]);i++)
1451    {
1452      s=s+"("+string(Sp[1][i])+","+string(Sp[2][i])+"),";
1453    }
1454    s=s+"("+string(Sp[1][i])+","+string(Sp[2][i])+")";
1455  }
1456  else
1457  {
1458    for(int i=1;i<size(Sp[3]);i++)
1459    {
1460      s=s+"(("+string(Sp[1][i])+","+string(Sp[2][i])+"),"+string(Sp[3][i])+"),";
1461    }
1462    s=s+"(("+string(Sp[1][i])+","+string(Sp[2][i])+"),"+string(Sp[3][i])+")";
1463  }
1464  return(s);
1465}
1466example
1467{ "EXAMPLE:"; echo=2;
1468  ring R=0,(x,y),ds;
1469  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));
1470  spprint(Sp);
1471}
1472///////////////////////////////////////////////////////////////////////////////
1473
1474proc spadd(list Sp1,list Sp2)
1475"USAGE:   spadd(Sp1,Sp2); list Sp1,Sp2
1476RETURN:  list: sum of spectra Sp1 and Sp2
1477EXAMPLE: example spadd; shows examples
1478"
1479{
1480  ideal s;
1481  intvec m;
1482  int i,i1,i2=1,1,1;
1483  while(i1<=size(Sp1[2])||i2<=size(Sp2[2]))
1484  {
1485    if(i1<=size(Sp1[2]))
1486    {
1487      if(i2<=size(Sp2[2]))
1488      {
1489        if(number(Sp1[1][i1])<number(Sp2[1][i2]))
1490        {
1491          s[i]=Sp1[1][i1];
1492          m[i]=Sp1[2][i1];
1493          i++;
1494          i1++;
1495        }
1496        else
1497        {
1498          if(number(Sp1[1][i1])>number(Sp2[1][i2]))
1499          {
1500            s[i]=Sp2[1][i2];
1501            m[i]=Sp2[2][i2];
1502            i++;
1503            i2++;
1504          }
1505          else
1506          {
1507            if(Sp1[2][i1]+Sp2[2][i2]!=0)
1508            {
1509              s[i]=Sp1[1][i1];
1510              m[i]=Sp1[2][i1]+Sp2[2][i2];
1511              i++;
1512            }
1513            i1++;
1514            i2++;
1515          }
1516        }
1517      }
1518      else
1519      {
1520        s[i]=Sp1[1][i1];
1521        m[i]=Sp1[2][i1];
1522        i++;
1523        i1++;
1524      }
1525    }
1526    else
1527    {
1528      s[i]=Sp2[1][i2];
1529      m[i]=Sp2[2][i2];
1530      i++;
1531      i2++;
1532    }
1533  }
1534  return(list(s,m));
1535}
1536example
1537{ "EXAMPLE:"; echo=2;
1538  ring R=0,(x,y),ds;
1539  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));
1540  spprint(Sp1);
1541  list Sp2=list(ideal(-1/6,1/6),intvec(1,1));
1542  spprint(Sp2);
1543  spprint(spadd(Sp1,Sp2));
1544}
1545///////////////////////////////////////////////////////////////////////////////
1546
1547proc spsub(list Sp1,list Sp2)
1548"USAGE:   spsub(Sp1,Sp2); list Sp1,Sp2
1549RETURN:  list: difference of spectra Sp1 and Sp2
1550EXAMPLE: example spsub; shows examples
1551"
1552{
1553  return(spadd(Sp1,spmul(Sp2,-1)));
1554}
1555example
1556{ "EXAMPLE:"; echo=2;
1557  ring R=0,(x,y),ds;
1558  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));
1559  spprint(Sp1);
1560  list Sp2=list(ideal(-1/6,1/6),intvec(1,1));
1561  spprint(Sp2);
1562  spprint(spsub(Sp1,Sp2));
1563}
1564///////////////////////////////////////////////////////////////////////////////
1565
1566proc spmul(list #)
1567"USAGE:
1568@format
15691) spmul(Sp,k); list Sp, int k
15702) spmul(Sp,k); list Sp, intvec k
1571@end format
1572RETURN:
1573@format
15741) list: product of spectrum Sp and integer k
15752) list: linear combination of spectra Sp with coefficients k
1576@end format
1577EXAMPLE: example spmul; shows examples
1578"
1579{
1580  if(size(#)==2)
1581  {
1582    if(typeof(#[1])=="list")
1583    {
1584      if(typeof(#[2])=="int")
1585      {
1586        return(list(#[1][1],#[1][2]*#[2]));
1587      }
1588      if(typeof(#[2])=="intvec")
1589      {
1590        list Sp0=list(ideal(),intvec(0));
1591        for(int i=size(#[2]);i>=1;i--)
1592        {
1593          Sp0=spadd(Sp0,spmul(#[1][i],#[2][i]));
1594        }
1595        return(Sp0);
1596      }
1597    }
1598  }
1599  return(list(ideal(),intvec(0)));
1600}
1601example
1602{ "EXAMPLE:"; echo=2;
1603  ring R=0,(x,y),ds;
1604  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));
1605  spprint(Sp);
1606  spprint(spmul(Sp,2));
1607  list Sp1=list(ideal(-1/6,1/6),intvec(1,1));
1608  spprint(Sp1);
1609  list Sp2=list(ideal(-1/3,0,1/3),intvec(1,2,1));
1610  spprint(Sp2);
1611  spprint(spmul(list(Sp1,Sp2),intvec(1,2)));
1612}
1613///////////////////////////////////////////////////////////////////////////////
1614
1615proc spissemicont(list Sp,list #)
1616"USAGE:   spissemicont(Sp[,opt]); list Sp, int opt
1617RETURN:
1618@format
1619int k=
1620if opt=0:
1621  1, if sum of spectrum Sp over all intervals [a,a+1) is positive
1622  0, if sum of spectrum Sp over some interval [a,a+1) is negative
1623if opt=1:
1624  1, if sum of spectrum Sp over all intervals [a,a+1) and (a,a+1) is positive
1625  0, if sum of spectrum Sp over some interval [a,a+1) or (a,a+1) is negative
1626default: opt=0
1627@end format
1628EXAMPLE: example spissemicont; shows examples
1629"
1630{
1631  int opt=0;
1632  if(size(#)>0)
1633  {
1634    if(typeof(#[1])=="int")
1635    {
1636      opt=1;
1637    }
1638  }
1639  int i,j,k=1,1,0;
1640  while(j<=size(Sp[2]))
1641  {
1642    while(j+1<=size(Sp[2])&&Sp[1][j]<Sp[1][i]+1)
1643    {
1644      k=k+Sp[2][j];
1645      j++;
1646    }
1647    if(j==size(Sp[2])&&Sp[1][j]<Sp[1][i]+1)
1648    {
1649      k=k+Sp[2][j];
1650      j++;
1651    }
1652    if(k<0)
1653    {
1654      return(0);
1655    }
1656    k=k-Sp[2][i];
1657    if(k<0&&opt==1)
1658    {
1659      return(0);
1660    }
1661    i++;
1662  }
1663  return(1);
1664}
1665example
1666{ "EXAMPLE:"; echo=2;
1667  ring R=0,(x,y),ds;
1668  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));
1669  spprint(Sp1);
1670  list Sp2=list(ideal(-1/6,1/6),intvec(1,1));
1671  spprint(Sp2);
1672  spissemicont(spsub(Sp1,spmul(Sp2,5)));
1673  spissemicont(spsub(Sp1,spmul(Sp2,5)),1);
1674  spissemicont(spsub(Sp1,spmul(Sp2,6)));
1675}
1676///////////////////////////////////////////////////////////////////////////////
1677
1678proc spsemicont(list Sp0,list Sp,list #)
1679"USAGE:   spsemicont(Sp,k[,opt]); list Sp0, list Sp, int opt
1680RETURN:  list of intvecs l:
1681         spissemicont(sub(Sp0,spmul(Sp,k)),opt)==1 iff k<=l[i] for some i
1682NOTE:    if the spectra Sp occur with multiplicities k in a deformation
1683         of the [quasihomogeneous] spectrum Sp0 then
1684         spissemicont(sub(Sp0,spmul(Sp,k))[,1])==1
1685EXAMPLE: example spsemicont; shows examples
1686"
1687{
1688  list l,l0;
1689  int i,j,k;
1690  while(spissemicont(Sp0,#))
1691  {
1692    if(size(Sp)>1)
1693    {
1694      l0=spsemicont(Sp0,list(Sp[1..size(Sp)-1]));
1695      for(i=1;i<=size(l0);i++)
1696      {
1697        if(size(l)>0)
1698        {
1699          j=1;
1700          while(j<size(l)&&l[j]!=l0[i])
1701          {
1702            j++;
1703          }
1704          if(l[j]==l0[i])
1705          {
1706            l[j][size(Sp)]=k;
1707          }
1708          else
1709          {
1710            l0[i][size(Sp)]=k;
1711            l=l+list(l0[i]);
1712          }
1713        }
1714        else
1715        {
1716          l=l0;
1717        }
1718      }
1719    }
1720    Sp0=spsub(Sp0,Sp[size(Sp)]);
1721    k++;
1722  }
1723  if(size(Sp)>1)
1724  {
1725    return(l);
1726  }
1727  else
1728  {
1729    return(list(intvec(k-1)));
1730  }
1731}
1732example
1733{ "EXAMPLE:"; echo=2;
1734  ring R=0,(x,y),ds;
1735  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));
1736  spprint(Sp0);
1737  list Sp1=list(ideal(-1/6,1/6),intvec(1,1));
1738  spprint(Sp1);
1739  list Sp2=list(ideal(-1/3,0,1/3),intvec(1,2,1));
1740  spprint(Sp2);
1741  list Sp=Sp1,Sp2;
1742  list l=spsemicont(Sp0,Sp);
1743  l;
1744  spissemicont(spsub(Sp0,spmul(Sp,l[1])));
1745  spissemicont(spsub(Sp0,spmul(Sp,l[1]-1)));
1746  spissemicont(spsub(Sp0,spmul(Sp,l[1]+1)));
1747}
1748///////////////////////////////////////////////////////////////////////////////
1749
1750proc spmilnor(list Sp)
1751"USAGE:   spmilnor(Sp); list Sp
1752RETURN:  int: Milnor number of spectrum Sp
1753EXAMPLE: example spmilnor; shows examples
1754"
1755{
1756  return(sum(Sp[2]));
1757}
1758example
1759{ "EXAMPLE:"; echo=2;
1760  ring R=0,(x,y),ds;
1761  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));
1762  spprint(Sp);
1763  spmilnor(Sp);
1764}
1765///////////////////////////////////////////////////////////////////////////////
1766
1767proc spgeomgenus(list Sp)
1768"USAGE:   spgeomgenus(Sp); list Sp
1769RETURN:  int: geometrical genus of spectrum Sp
1770EXAMPLE: example spgeomgenus; shows examples
1771"
1772{
1773  int g=0;
1774  int i=1;
1775  while(i+1<=size(Sp[2])&&number(Sp[1][i])<=number(0))
1776  {
1777    g=g+Sp[2][i];
1778    i++;
1779  }
1780  if(i==size(Sp[2])&&number(Sp[1][i])<=number(0))
1781  {
1782    g=g+Sp[2][i];
1783  }
1784  return(g);
1785}
1786example
1787{ "EXAMPLE:"; echo=2;
1788  ring R=0,(x,y),ds;
1789  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));
1790  spprint(Sp);
1791  spgeomgenus(Sp);
1792}
1793///////////////////////////////////////////////////////////////////////////////
1794
1795proc spgamma(list Sp)
1796"USAGE:   spgamma(Sp); list Sp
1797RETURN:  number: gamma invariant of spectrum Sp
1798EXAMPLE: example spgamma; shows examples
1799"
1800{
1801  int i,j;
1802  number g=0;
1803  for(i=1;i<=ncols(Sp[1]);i++)
1804  {
1805    for(j=1;j<=Sp[2][i];j++)
1806    {
1807      g=g+(number(Sp[1][i])-number(nvars(basering)-2)/2)^2;
1808    }
1809  }
1810  g=-g/4+sum(Sp[2])*number(Sp[1][ncols(Sp[1])]-Sp[1][1])/48;
1811  return(g);
1812}
1813example
1814{ "EXAMPLE:"; echo=2;
1815  ring R=0,(x,y),ds;
1816  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));
1817  spprint(Sp);
1818  spgamma(Sp);
1819}
1820///////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.