source: git/Singular/LIB/phindex.lib @ 906458

spielwiese
Last change on this file since 906458 was 906458, checked in by Frank Seelisch <seelisch@…>, 15 years ago
removed some docu errors prior to release 3-1-0 git-svn-id: file:///usr/local/Singular/svn/trunk@11638 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 19.5 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2version="$Id: phindex.lib,v 1.4 2009-04-07 16:18:05 seelisch Exp $";
3category=" ";
4info="
5LIBRARY : phindex.lib Procedures to compute the index of real analytic vector fields
6
7NOTE: To compute the Poincare-Hopf index of a real analytic vector field
8      with an algebraically isolated singularity at 0 (w. an a. i. s),
9      we use the algebraic formula for the degree of the real analytic map
10      germ  found by Eisenbud-Levine in 1997. This result was also proved by
11      Khimshiashvili. If the isolated singularity is non algebraically
12      isolated  and the vector field has similar reduced complex zeroes of
13      codimension 1, we use a formula as the Eisenbud-Levine found by Victor
14      Castellanos, in both cases is necessary to use a local order (ds,...).
15      To compute the signature of a quadratic form (or symmetric matrix)
16      we use the method of Lagrange.
17
18PROCEDURES:
19 signatureL(M[,n]);   signature of symmetric matrix M, method of Lagrange.
20 signatureLqf(h[,n]); signature of quadratic form h, method of Lagrange.
21 PH_ais(I)            P-H index of real analytic vector field I w. an a. i. s.
22 PH_nais(I)           P-H index of real analytic vector field I w. a non a. i. s
23";
24
25LIB "primdec.lib";
26LIB "zeroset.lib";
27
28/////////////////////////////////////////////////////////////////////////////
29proc signatureL(M,int #)
30"USAGE:    signatureL(M[,r]); M symmetric matrix, r int (optional).
31RETURN:   the signature of M of type int or if r is given and !=0 then
32          intvec with (signature, nr. of +, nr. of -) is returned.
33THEORY:   Given the matrix M, we construct the quadratic form associated. Afterwards
34          we use the method of Lagrange to compute the signature. The law of
35          inertia for a real quadratic form A(x,x) says that in a
36          representation of A(x,x) as a sum of independent squares
37                            A(x,x)=sum_{i=1}^r a_iX_i^2.
38          The number of positive and the number of negative squares are
39          independent of the choice of representation. The signature -s- of
40          A(x,x) is the difference between the number -pi- of positive squares
41          and the number -nu- of negative squares in the representation of
42          A(x,x). The rank -r- of M (or A(x,x)) and the signature -s-
43          determine the numbers -pi- and -nu- uniquely, since
44                            r=pi+nu,   s=pi-nu.
45          The method of Lagrange is a procedure to reduce any real quadratic
46          form to a sum of squares.
47          Ref. Gantmacher, The theory of matrices, Vol. I, Chelsea Publishing
48               Company, NY 1960, page 299.
49EXAMPLE:  example signatureL; shows an example
50"
51{
52  if(typeof(M)!="matrix")
53  {
54    ERROR("** The argument is not a matrix type");
55  }
56  option(noprot);
57  option(noredefine);
58  int nv1=ncols(M);
59  matrix zero[nv1][nv1]=0;
60  if (transpose(M)!=M)
61    {
62      ERROR("** The matrix is non symmetric");
63    }
64  if (M==0)
65    {
66      ERROR("** The matrix is zero");
67    }
68  option(noprot);
69  option(noredefine);
70  def h=basering;
71  int chr=char(h);
72  ring signLagrange=chr,(x(1..nv1)), lp; //ring to compute the quadratic form associated to M
73  matrix Ma=fetch(h,M);
74  int nv=ncols(Ma);
75  matrix X[1][nv]=maxideal(1);
76  matrix Ax=X*Ma*transpose(X);
77  poly Axx=Ax[1,1]; //quadratic form associated to matrix M
78  if (size(#)==0)
79    {
80      def sal=SigntL(Axx);
81      return(sal[1]);
82    }
83  else
84    {
85      return(SigntL(Axx));
86    }
87}
88example
89{ "EXAMPLE:"; echo = 2;
90  ring r=0,(x),ds;
91  matrix M[5][5]=0,0,0,1,0,0,1,0,0,-1,0,0,1,0,0,1,0,0,3,0,0,-1,0,0,1;
92  signatureL(M,1); //The rank of M is 3+1=4
93  matrix H[5][5]=0,-7,0,1,0,-7,1,0,0,-1,0,0,1,0,0,1,0,0,-3,5,0,-1,0,5,1;
94  signatureL(H);
95}
96////////////////////////////////////////////////////////////////////////
97proc signatureLqf(h,int #)
98"USAGE:    signatureLqf(h); h quadratic form (poly type).
99RETURN:   the signature of h of type int or if r is given and !=0 then
100          intvec with (signature, nr. of +, nr. of -) is returned.
101THEORY:   To compute the signature we use the method of Lagrange. The law of
102          inertia for a real quadratic form h(x,x) says that in a
103          representation  of h(x,x) as a sum of independent squares
104          h(x,x)=sum_{i=1}^r a_i*X_i^2 the number of positive and the number of negative squares are
105          independent of the choice of representation. The signature -s- of
106          h(x,x) is the difference between the number -pi- of positive squares
107          and the number -nu- of negative squares in the representation of
108          h(x,x). The rank -r- of h(x,x) and the signature -s- determine the
109          numbers -pi- and -nu- uniquely, since
110                             r=pi+nu,   s=pi-nu.
111          The method of Lagrange is a procedure to reduce any real quadratic
112          form to a sum of squares.
113          Ref. Gantmacher, The theory of matrices, Vol. I, Chelsea Publishing
114               Company, NY 1960, page 299.
115EXAMPLE:  example signatureLqf; shows an example
116"
117{
118  if(typeof(h)!="poly")
119  {
120    ERROR("** The argument is not a poly type");
121  }
122  option(noprot);
123  option(noredefine);
124  poly M=h;
125  int nv1=nvars(basering);
126  if (M==0)
127   {
128     ERROR("** The quadratic form is zero");
129   }
130  poly Axx=M;
131  poly Bxx;
132  poly bxx1;
133  poly bxx2;
134  def coe1;
135  int i;
136  int jb;
137  int k;
138  int haycuadrados;
139  int haycruzados;
140  int positivo=0;
141  int negativo=0;
142  int lAxx;
143  while (Axx<>0) //Lagrange method to compute the signature
144    {
145      haycruzados=1;
146      haycuadrados=1;
147      lAxx=size(Axx);
148      i=1;
149      while (i<=lAxx and haycuadrados)
150    {
151      jb=1;
152      while (jb<=nv1 and haycuadrados)
153        {
154          if (leadmonom(Axx[i])/(x(jb)^2)==1) //there is squares
155        {
156          Bxx=Axx;
157          if (leadcoef(Axx[i])>0)
158            {
159              positivo=positivo+1;
160            }
161          else
162            {
163              negativo=negativo+1;
164            }
165          coe1=1/(4*leadcoef(Bxx[i]));
166          Axx=Bxx-coe1*(diff(Bxx,x(jb)))^2;
167          haycuadrados=0;
168        }
169          jb=jb+1;
170        }
171      i=i+1;
172    }
173      if (haycruzados) //there is no squares
174    {
175      int ia=1;
176      int ja=1;
177      int ka=1;
178      while (ia<=nv1 and haycruzados)
179        {
180          while (ja<=nv1 and haycruzados)
181        {
182          ka=ja+1;
183          while (ka<=nv1 and haycruzados)
184            {
185              if (leadmonom(Axx[ia])/leadmonom(x(ja)*x(ka))==1)
186            {
187              Bxx=Axx;
188              bxx1=diff(Bxx,x(ja))+diff(Bxx,x(ka));
189              bxx2=diff(Bxx,x(ja))-diff(Bxx,x(ka));
190              coe1=1/(4*leadcoef(Bxx[ia]));
191              Axx=Bxx-coe1*(bxx1^2-bxx2^2);
192              positivo=positivo+1;
193              negativo=negativo+1;
194              haycruzados=0;
195            }
196              ka=ka+1;
197            }
198          ja=ja+1;
199        }
200          ia=ia+1;
201        }
202    }
203    }
204 if (size(#)==0)
205    {
206      def sal=positivo-negativo;
207      return(sal);
208    }
209  else
210    {
211      int sig=positivo-negativo;
212      intvec dat=sig,positivo,negativo;
213      return(dat);
214    }
215}
216example
217{ "EXAMPLE:"; echo = 2;
218  ring r=0,(x(1..4)),ds;
219  poly Ax=4*x(1)^2+x(2)^2+x(3)^2+x(4)^2-4*x(1)*x(2)-4*x(1)*x(3)+4*x(1)*x(4)+4*x(2)*x(3)-4*x(2)*x(4);
220  signatureLqf(Ax,1); //The rank of Ax is 3+1=4
221  poly Bx=2*x(1)*x(4)+x(2)^2+x(3)^2;
222  signatureLqf(Bx);
223}
224/////////////////////////////////////////////////////////////////////////////
225proc PH_ais(I)
226"USAGE:    PH_ais(I); I ideal of coordinates of the vector field.
227RETURN:   the Poincare-Hopf index of type int.
228NOTE:     the isolated singularity must be algebraically isolated.
229THEORY:   The Poincare-Hopf index of a real vector field X at the isolated
230          singularity 0 is the degree of the map (X/|X|) : S_epsilon ---> S,
231          where S is the unit sphere, and the spheres are oriented as
232          (n-1)-spheres in R^n. The degree depends only on the germ, X, of X
233          at 0. If the vector field X is real analytic, then an invariant of
234          the germ is its local ring
235                            Qx=R[[x1..xn]]/Ix
236          where R[[x1,..,xn]] is the ring of germs at 0 of real-valued analytic
237          functions on R^n, and Ix is the ideal generated by the components
238          of X. The isolated singularity of X is algebraically isolated if the
239          algebra Qx is finite dimensional as real vector space, geometrically
240          this mean that 0 is also an isolated singularity for the
241          complexified vector field. In this case the Poincare-Hopf index is
242          the signature of the non degenerate bilinear form <,> obtained by
243          composition of the product in the algebra Qx with a linear
244          functional map
245                       <,> : (Qx)x(Qx) ---(.)--> Qx ---(L)--> R
246          with L(Jo)>0, where Jo is the residue class of the Jacobian
247          determinant in Qx. Here, we use a natural linear functional defined
248          as follows. Suppose that E={E_1,..E_r} is a basis of Qx, then Jo can
249          be written as
250                      Jo=a_1E_{j1}+...+a_kE_{jk},  js\in {1...r}, s=1..k, k<=r,
251          where a_s are constant. The linear functional L:Qx--->R is defined as
252                                  L(E_{j1})=(a_1)/|a_1|=sign of a_1,
253          the other elements of the base are sent to 0.
254          Refs. -Eisenbud & Levine, An algebraic formula for the degree of
255                 a C^\infty map germ, Ann. Math., 106, (1977), 19-38.
256                -Khimshiashvili, On a local degree of a smooth map, trudi
257                 Tbilisi Math. Inst., (1980), 105-124.
258EXAMPLE:  example  PH_ais; shows an example.
259"
260{
261  if(typeof(I)!="ideal")
262  {
263    ERROR("** The argument is not of ideal type");
264  }
265  ideal A=I;
266  ideal qI=std(A);
267  int siono=vdim(qI);
268  int l;
269  if (siono==-1)
270    {
271      ERROR("** The vector field does not have an algebraically isolated singularity");
272    }
273  if (siono!=0)
274    {
275      option(noredefine);
276      option(noprot);
277      def oldr=basering;
278      def chr1=char(oldr);
279      int n=nvars(oldr);
280      ideal E=kbase(qI);
281      int m=size(E);
282      poly Jx=det(jacob(A));
283      poly Jo=reduce(Jx,qI);
284      ring newr=chr1,(x(1..m)),ds; //ring to compute the quadratic form
285      int nv=nvars(basering);
286      ideal E=fetch(oldr,E);
287      ideal qI=fetch(oldr,qI);
288      poly Jo=fetch(oldr,Jo);
289      attrib(qI,"isSB",1);
290      int scoef=1;
291      int multby;
292      poly Eik;
293      poly Axx=0;
294      int tEik;
295      int stEik;
296      def lcEik;
297      if (leadcoef(Jo[1])<0)
298    {
299      scoef=-1;
300    }
301      for (int si=1; si<=nv; si++)
302        {
303          for (int sk=si; sk<=nv; sk++)
304        {
305          Eik=reduce(E[si]*E[sk],qI);
306          tEik=size(Eik);
307          for(int stEik=1; stEik<=tEik; stEik++)
308        {
309          if (leadmonom(Eik[stEik])==leadmonom(Jo[1]))
310            {
311              if (si==sk)
312            {
313              multby=1;
314            }
315              else
316            {
317              multby=2;
318            }
319              lcEik=leadcoef(Eik[stEik]);
320              if (lcEik<0)
321            {
322              Axx=Axx-multby*scoef*lcEik*x(si)*x(sk);
323            }
324              else
325            {
326              Axx=Axx+multby*scoef*lcEik*x(si)*x(sk);
327            }
328            }
329        }
330        }
331        }
332      l=SignatLalt(Axx); //signature of billinear form
333      kill newr;
334    }
335  else
336    {
337      l=0;
338    }
339  return(l);
340}
341example
342{ "EXAMPLE"; echo = 2;
343  ring r=0,(x,y,z),ds;
344  ideal I=x3-3xy2,-y3+3yx2,z3;
345  PH_ais(I);
346}
347///////////////////////////////////////////////////////////////////////////
348proc PH_nais(I)
349"USAGE:    PH_nais(I); I ideal of coordinates of the vector field.
350RETURN:   the Poincare-Hopf index of type int.
351NOTE:     the vector field must be a non algebraically isolated singularity
352          at 0, with reduced complex zeros of codimension 1.
353THEORY:   Suppose that 0 is an algebraically isolated singularity of the real
354          analytic vector field X, geometrically this corresponds to the fact that the
355          complexified vector field has positive dimension singular locus,
356          algebraically this mean that the local ring Qx=R[[x1..xn]]/Ix
357          where R[[x1,..,xn]] is the ring of germs at 0 of real-valued analytic
358          functions on R^n, and Ix is the ideal generated by the components
359          of X is infinite dimensional as real vector space. In the case that
360          X has a reduced hypersurface as complex zeros we have the next.
361          There exist a real analytic function f:R^n-->R, and a real analytic
362          vector field Y s. t. X=fY. The function f does not change of sign
363          out of 0 and
364                      Mx=R[[x1..xn]]/(Ix : radical(Ix))
365          is a finite dimensional sub-algebra of Qx. The Poincare-Hopf index
366          of X at 0 is the sign of f times the signature of the non degenerate
367          bilinear form <,> obtained by composition of the product in the
368          algebra Mx with a linear functional map
369                       <,> : (Mx)x(Mx) ---(.)--> Mx ---(L)--> R
370          with L(Jp)>0, where Jp is the residue class of the Jacobian
371          determinant of X, JX, over f^n, JX/(f^n) in Mx. Here, we use a
372          natural linear functional defined as follows. Suppose that
373          E={E_1,..E_r} is a basis of Mx, then Jp is writing as
374                      Jp=a_1E_{j1}+...+a_kE_{jk},  js\in {1...r}, s=1..k, k<=r,
375          where a_s are constant. The linear functional L:M--->R is defined as
376                                  L(E_{j1})=(a_1)/|a_1|=sign of a_1,
377          the other elements of the base are sent to 0.
378          Refs. -Castellanos-Vargas, V., Una formula algebraica del indice de
379                 Poincare-Hopf para campos vectoriales reales con una variedad
380                 de ceros complejos, Ph. D. thesis CIMAT (2000), chapther 1,
381                 Guanajuato Mexico.
382                -Castellanos -Vargas, V. The index of non algebraically
383                 isolated singularity, Bol. Soc. Mat. Mexicana, (3)
384                 Vol. 8, 2002, 141-147.
385
386EXAMPLE:  example  PH_nais; shows an example.
387"
388{
389  if(typeof(I)!="ideal")
390  {
391    ERROR("** The argument is not of ideal type");
392  }
393  ideal A=I;
394  int siono=vdim(std(A));
395  int l;
396  if (siono!=0)
397    {
398      if (siono!=-1)
399    {
400      ERROR("** The vector field has an algebraically isolated singularity, USE: PH_ais ");
401    }
402      option(noprot);
403      option(noredefine);
404      int n=nvars(basering);
405      def oldr=basering;
406      int chr1=char(oldr);
407      ring newring=chr1,(x(1..n)), dp; //ring to compute the radical
408      ideal A= fetch(oldr,A);
409      ideal rI=radical(A);
410      setring oldr;
411      ideal rI=fetch(newring,rI);
412      if (size(rI)!=1)
413    {
414      ERROR("** The vector field does not have a non algebraically isolated singularity of codimension 1");
415    }
416      ideal qI=std(quotient(A,rI));
417      ideal E=kbase(qI);
418      int m=size(E);
419      poly Jx=det(jacob(A));
420      poly Jy=Quotient(Jx,rI[1]^n)[1];
421      poly Jo=reduce(Jy,qI);
422      ring newr=chr1,(x(1..m)),ds; //ring to compute the quadratic form
423      int nv=nvars(basering);
424      ideal E=fetch(oldr,E);
425      ideal qI=fetch(oldr,qI);
426      poly Jo=fetch(oldr,Jo);
427      attrib(qI,"isSB",1);
428      int scoef=1;
429      if (leadcoef(Jo[1])<0)
430    {
431      scoef=-1;
432    }
433      int multby;
434      def lcEik;
435      poly Eik;
436      poly Axx=0;
437      int si=1;
438      int sk;
439      int tEik;
440      int stEik;
441      while (si<=nv)
442    {
443      sk=si;
444      while (sk<=nv)
445        {
446          Eik=reduce(E[si]*E[sk],qI);
447          tEik=size(Eik);
448          for(int stEik=1; stEik<=tEik; stEik++)
449        {
450          if (leadmonom(Eik[stEik])==leadmonom(Jo[1]))
451            {
452              if (si==sk)
453            {
454              multby=1;
455            }
456              else
457            {
458              multby=2;
459            }
460              lcEik=leadcoef(Eik[stEik]);
461              if (lcEik<0)
462            {
463              Axx=Axx-multby*lcEik*scoef*x(si)*x(sk);
464            }
465              else
466            {
467              Axx=Axx+multby*lcEik*scoef*x(si)*x(sk);
468            }
469            }
470        }
471          sk=sk+1;
472        }
473      si=si+1;
474    }
475      l=SignatLalt(Axx); //signature of bilinear form
476      return(l);
477    }
478  else
479    {
480      return(0);
481    }
482}
483example
484{"EXAMPLE:"; echo = 2;
485  ring r=0,(x,y,z),ds;
486  ideal I=x5-2x3y2-3xy4+x3z2-3xy2z2,-3x4y-2x2y3+y5-3x2yz2+y3z2,x2z3+y2z3+z5;
487  PH_nais(I);
488}
489//////////////////////////////////////////////////////////////////////
490static proc SigntL(poly M)  //static procedure to compute the signature of any quadratic form.
491"USAGE:    SigntL(M); M is a quadratic form.
492RETURN:   The signature of M of type int.
493ASSUME:   M is a quadratic form (ply type).
494"
495{
496  int nv1=nvars(basering);
497  poly Axx=M;
498  poly Bxx;
499  poly bxx1;
500  poly bxx2;
501  def coe1;
502  int i;
503  int jb;
504  int k;
505  int haycuadrados;
506  int haycruzados;
507  int positivo=0;
508  int negativo=0;
509  int lAxx;
510  while (Axx<>0)
511    {
512      haycruzados=1;
513      haycuadrados=1;
514      lAxx=size(Axx);
515      i=1;
516      while (i<=lAxx and haycuadrados)
517    {
518      jb=1;
519      while (jb<=nv1 and haycuadrados)
520        {
521          if (leadmonom(Axx[i])/(x(jb)^2)==1)
522        {
523          Bxx=Axx;
524          if (leadcoef(Axx[i])>0)
525            {
526              positivo=positivo+1;
527            }
528          else
529            {
530              negativo=negativo+1;
531            }
532          coe1=1/(4*leadcoef(Bxx[i]));
533          Axx=Bxx-coe1*(diff(Bxx,x(jb)))^2;
534          haycuadrados=0;
535          haycruzados=0;
536        }
537          jb=jb+1;
538        }
539      i=i+1;
540    }
541      if (haycruzados)
542    {
543      int ia=1;
544      int ja=1;
545      int ka=1;
546      while (ia<=nv1 and haycruzados)
547        {
548          while (ja<=nv1 and haycruzados)
549        {
550          ka=ja+1;
551          while (ka<=nv1 and haycruzados)
552            {
553              if (leadmonom(Axx[ia])/leadmonom(x(ja)*x(ka))==1)
554            {
555              Bxx=Axx;
556              bxx1=diff(Bxx,x(ja))+diff(Bxx,x(ka));
557              bxx2=diff(Bxx,x(ja))-diff(Bxx,x(ka));
558              coe1=1/(4*leadcoef(Bxx[ia]));
559              Axx=Bxx-coe1*(bxx1^2-bxx2^2);
560              positivo=positivo+1;
561              negativo=negativo+1;
562              haycruzados=0;
563            }
564              ka=ka+1;
565            }
566          ja=ja+1;
567        }
568          ia=ia+1;
569        }
570    }
571    }
572  int dat1=positivo-negativo;
573  intvec dat=dat1,positivo,negativo;
574  return(dat);
575}
576////////////////////////////////////////////////////////////////////////////
577//NOTE: SignatLalt is a procedure to compute the signature of a special
578//      bilinear form that is necessary to compute the Poincare-Hopf index.
579static proc SignatLalt(poly M)
580"USAGE:    SignatLalt(M); M is a quadratic form (a polynomial).
581RETURN:   The signature of type int.
582"
583{
584 int nv1=nvars(basering);
585 if (M==0)
586   {
587     ERROR("** The quadratic form is zero");
588   }
589 poly Axx=M;
590 poly Bxx;
591 poly bxx1;
592 poly bxx2;
593 def coe1;
594 int i;
595 int jb;
596 int k;
597 int haycuadrados;
598 int sihay=1;
599 int positivo=0;
600 int negativo=0;
601 int variableactual=0;
602 int posicion=1;
603 int lAxx;
604 while (Axx<>0 and sihay)
605   {
606     haycuadrados=1;
607     lAxx=size(Axx);
608     i=posicion;
609     while (i<=lAxx and haycuadrados)
610       {
611     jb=variableactual+1;
612     while (jb<=nv1 and haycuadrados)
613       {
614         if (leadmonom(Axx[i])/(x(jb)^2)==1)
615           {
616         Bxx=Axx;
617         if (leadcoef(Axx[i])>0)
618           {
619             positivo=positivo+1;
620           }
621         else
622           {
623             negativo=negativo+1;
624           }
625         coe1=1/(4*leadcoef(Bxx[i]));
626         Axx=Bxx-coe1*(diff(Bxx,x(jb)))^2;
627         haycuadrados=0;
628         variableactual=jb;
629         posicion=i;
630           }
631         jb=jb+1;
632       }
633     if (i==lAxx and haycuadrados)
634       {
635         sihay=0;
636       }
637     i=i+1;
638       }
639   }
640 return(positivo-negativo);
641}
Note: See TracBrowser for help on using the repository browser.