source: git/Singular/LIB/gaussman.lib @ c71123

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