source: git/Singular/LIB/phindex.lib @ 6fe9a5

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