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

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