source: git/Singular/LIB/jordan.lib @ 7303d9

spielwiese
Last change on this file since 7303d9 was 7303d9, checked in by Mathias Schulze <mschulze@…>, 25 years ago
*mschulze git-svn-id: file:///usr/local/Singular/svn/trunk@2839 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 8.5 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2
3version="$Id: jordan.lib,v 1.8 1999-02-11 11:47:45 mschulze Exp $";
4info="
5LIBRARY: jordan.lib  PROCEDURES TO COMPUTE THE JORDAN NORMAL FORM
6AUTHOR:  Mathias Schulze, email: mschulze@mathematik.uni-kl.de
7
8 jordan(M[,opt]);  eigenvalues, Jordan block sizes, transformation matrix of M
9 jordanmatrix(l);  Jordan matrix with eigenvalues l[1], Jordan block sizes l[2]
10 jordanform(M);    Jordan normal form of constant square matrix M
11 inversemat(M);    inverse matrix of invertible constant matrix M
12";
13
14LIB "ring.lib";
15///////////////////////////////////////////////////////////////////////////////
16
17///////////////////////////////////////////////////////////////////////////////
18// PROCEDURE: jordan  PROCEDURES TO COMPUTE THE JORDAN NORMAL FORM           //
19// AUTHOR:    Mathias Schulze, email: mschulze@mathematik.uni-kl.de          //
20///////////////////////////////////////////////////////////////////////////////
21
22proc jordan(matrix M,list #)
23"USAGE:   jordan(M[,opt]); M constant square matrix, opt integer
24ASSUME:  the eigenvalues of M are in the coefficient field
25RETURN:  a list l with 3 entries of type ideal, list of intvecs, matrix with
26           l[1]       : eigenvalues of M
27           l[2][i][j] : size of j-th Jordan block with eigenvalue l[1][i]
28           l[3] : transformation matrix U with U^(-1)*M*U in Jordan normal form
29         which entries of l are computed depends on opt:
30           opt=-1 : compute l[1]
31           opt= 0 : compute l[1] and l[2] (default)
32           opt= 1 : compute l[1],l[2] and l[3]
33           opt= 2 : compute l[1] and l[3]
34NOTE:    a non constant polynomial matrix M is replaced by its constant part
35EXAMPLE: example jordan; shows an example
36"
37{
38  // test if square matrix
39  int n=nrows(M);
40  if(n!=ncols(M))
41  {
42    "//no square matrix";
43    return();
44  }
45
46  // get constant part
47  def br=basering;
48  map zero=br,0;
49  M=zero(M);
50  kill zero;
51
52  // change to polynomial ring for factorization
53  changeord("pr","dp");
54  matrix M=imap(br,M);
55
56  // factorize characteristic polynomial
57  list l=factorize(det(M-var(1)*freemodule(n)),2);
58
59  // get multiplicities mM
60  def eM,mM=l[1..2];
61  kill l;
62
63  // test if eigenvalues in the coefficient field
64  int i;
65  for(i=size(eM);i>=1;i--)
66  {
67    if(deg(eM[i])>1)
68    {
69      kill pr;
70      "//eigenvalues not in the coefficient field";
71      return();
72    }
73  }
74
75  // get eigenvalues eM
76  map inv=pr,-var(1);
77  eM=simplify(inv(eM),1);
78  setring br;
79  map zero=pr,0;
80  ideal eM=zero(eM);
81  kill pr;
82
83  // sort eigenvalues
84  int j;
85  poly e;
86  int m;
87  for(i=size(eM);i>=2;i--)
88  {
89    for(j=i-1;j>=1;j--)
90    {
91      if(eM[i]<eM[j])
92      {
93        e=eM[i];
94        eM[i]=eM[j];
95        eM[j]=e;
96        m=mM[i];
97        mM[i]=mM[j];
98        mM[j]=m;
99      }
100    }
101  }
102  kill e,m;
103
104  // get option parameter
105  int opt=0;
106  if(size(#)>0)
107  {
108    if(typeof(#[1])=="int")
109    {
110      opt=#[1];
111    }
112  }
113  if(opt<0)
114  {
115    return(list(eM));
116  }
117
118  // define needed variables
119  int k,l;
120  matrix E=freemodule(n);
121  matrix Mi,Ni;
122  module sNi;
123  list K;
124  if(opt>=1)
125  {
126    module V,K1,K2;
127    matrix v[n][1];
128  }
129  if(opt<=1)
130  {
131    list bM;
132    intvec bMi;
133  }
134
135  // do the following for all eigenvalues eM[i]
136  for(i=ncols(eM);i>=1;i--)
137  {
138    Mi=M-eM[i]*E;
139
140    // compute kernels K of powers of Mi
141    K=list(module());
142    for(Ni,sNi=Mi,0;size(sNi)<mM[i];Ni=Ni*Mi)
143    {
144      sNi=syz(Ni);
145      K=K+list(sNi);
146    }
147
148    if(opt<=1)
149    {
150      // compute Jordan block size vector corresponding to eigenvalue eM[i]
151      bMi=0;
152      bMi[size(K[2])]=0;
153      for(j=size(K);j>=2;j--)
154      {
155        for(k=size(bMi);k>size(bMi)+size(K[j-1])-size(K[j]);k--)
156        {
157          bMi[k]=bMi[k]+1;
158        }
159      }
160      bM=list(bMi)+bM;
161    }
162
163    if(opt>=1)
164    {
165      // compute generating vectors for Jordan basis vectors corresponding to
166      // eigenvalue eM[i]
167      if(size(K)>1)
168      {
169        for(j,K1=2,0;j<=size(K)-1;j++)
170        {
171          K2=K[j];
172          K[j]=interred(reduce(K[j],std(K1+module(Mi*K[j+1]))));
173          K1=K2;
174        }
175        K[j]=interred(reduce(K[j],std(K1)));
176      }
177
178      // compute Jordan basis vectors corresponding to eigenvalue eM[i] from
179      // generating vectors
180      for(j=size(K);j>=2;j--)
181      {
182        for(k=size(K[j]);k>=1;k--)
183        {
184          v=K[j][k];
185          for(l=j;l>=1;l--)
186          {
187            V=module(v)+V;
188            v=Mi*v;
189          }
190        }
191      }
192    }
193  }
194  kill l;
195
196  // create return list
197  list l=eM;
198  if(opt<=1)
199  {
200    l[2]=bM;
201  }
202  if(opt>=1)
203  {
204    l[3]=V;
205  }
206
207  return(l);
208}
209example
210{
211  "EXAMPLE:";
212  echo=2;
213  ring R=0,x,dp;
214  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
215  print(M);
216  jordan(M);
217}
218///////////////////////////////////////////////////////////////////////////////
219
220///////////////////////////////////////////////////////////////////////////////
221// PROCEDURE: jordanmatrix  PROCEDURES TO COMPUTE THE JORDAN NORMAL FORM     //
222// AUTHOR:    Mathias Schulze, email: mschulze@mathematik.uni-kl.de          //
223///////////////////////////////////////////////////////////////////////////////
224
225proc jordanmatrix(list l)
226"USAGE:   jordanmatrix(l); l list of ideal and list of intvecs
227RETURN:  the Jordan matrix J with
228           l[1]       : eigenvalues of J
229           l[2][i][j] : size of j-th Jordan block with eigenvalue l[1][i]
230EXAMPLE: example jordanmatrix; shows an example
231"
232{
233  // check parameters
234  if(size(l)<2)
235  {
236    "//not enough entries in argument list";
237    return();
238  }
239  def eJ,bJ=l[1..2];
240  kill l;
241  if(typeof(eJ)!="ideal")
242  {
243    "//first entry in argument list not an ideal";
244    return();
245  }
246  if(typeof(bJ)!="list")
247  {
248    "//second entry in argument list not a list";
249    return();
250  }
251  if(size(eJ)<size(bJ))
252  {
253    int s=size(eJ);
254  }
255  else
256  {
257    int s=size(bJ);
258  }
259
260  // get size of Jordan matrix
261  int i,j,k,n;
262  for(i=s;i>=1;i--)
263  {
264    if(typeof(bJ[i])!="intvec")
265    {
266      "//second entry in argument list not a list of integer vectors";
267      return();
268    }
269    else
270    {
271      for(j=size(bJ[i]);j>=1;j--)
272      {
273        k=bJ[i][j];
274        if(k>0)
275        {
276          n=n+k;
277        }
278      }
279    }
280  }
281  matrix J[n][n];
282
283  // create Jordan matrix
284  int l;
285  for(i,l=1,1;i<=s;i++)
286  {
287    for(j=1;j<=size(bJ[i]);j++)
288    {
289      k=bJ[i][j];
290      if(k>0)
291      {
292        while(k>=2)
293        {
294          J[l,l]=eJ[i];
295          J[l,l+1]=1;
296          k,l=k-1,l+1;
297        }
298        J[l,l]=eJ[i];
299        l++;
300      }
301    }
302  }
303
304  return(J);
305}
306example
307{
308  "EXAMPLE:";
309  echo=2;
310  ring R=0,x,dp;
311  print(jordanmatrix(list(ideal(2,3),list(intvec(1),intvec(2)))));
312}
313///////////////////////////////////////////////////////////////////////////////
314
315///////////////////////////////////////////////////////////////////////////////
316// PROCEDURE: jordanform  PROCEDURES TO COMPUTE THE JORDAN NORMAL FORM       //
317// AUTHOR:    Mathias Schulze, email: mschulze@mathematik.uni-kl.de          //
318///////////////////////////////////////////////////////////////////////////////
319
320proc jordanform(matrix M)
321"USAGE:   jordanform(M); M constant square matrix
322ASSUME:  the eigenvalues of M are in the coefficient field
323RETURN:  the Jordan normal form of M
324NOTE:    a non constant polynomial matrix M is replaced by its constant part
325EXAMPLE: example jordanform; shows an example
326"
327{
328  return(jordanmatrix(jordan(M)));
329}
330example
331{
332  "EXAMPLE:";
333  echo=2;
334  ring R=0,x,dp;
335  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
336  print(M);
337  print(jordanform(M));
338}
339///////////////////////////////////////////////////////////////////////////////
340
341///////////////////////////////////////////////////////////////////////////////
342// PROCEDURE: inversemat  PROCEDURES TO COMPUTE THE JORDAN NORMAL FORM       //
343// AUTHOR:    Mathias Schulze, email: mschulze@mathematik.uni-kl.de          //
344///////////////////////////////////////////////////////////////////////////////
345
346proc inversemat(matrix M)
347"USAGE:   inversemat(M); M constant square matrix
348ASSUME:  M is invertible
349RETURN:  the inverse matrix of M
350NOTE:    a non constant polynomial matrix M is replaced by its constant part
351EXAMPLE: example inversemat; shows an example
352"
353{
354  // test if square matrix
355  int n=nrows(M);
356  if(n!=ncols(M))
357  {
358    "//no square matrix";
359    return();
360  }
361
362  // get constant part
363  def br=basering;
364  map zero=br,0;
365  M=zero(M);
366
367  // compute inverse
368  return(lift(M,freemodule(n)));
369}
370example
371{
372  "EXAMPLE:";
373  echo=2;
374  ring R=0,x,dp;
375  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
376  print(M);
377  print(inversemat(M));
378}
379///////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.