source: git/Singular/LIB/linalg.lib @ 3c8425

fieker-DuValspielwiese
Last change on this file since 3c8425 was 2636865, checked in by Gert-Martin Greuel <greuel@…>, 24 years ago
* GMG: al libraries smoothed, syntax of charpoly extended git-svn-id: file:///usr/local/Singular/svn/trunk@4383 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 24.7 KB
Line 
1//
2//      last modified: 04/25/2000 by GMG
3//////////////////////////////////////////////////////////////////////////////
4
5version="$Id: linalg.lib,v 1.5 2000-05-23 23:00:50 greuel Exp $";
6info="
7LIBRARY:  linalg.lib    PROCEDURES FOR ALGORITHMIC LINEAR ALGEBRA
8AUTHOR:   Ivor Saynisch (ivs@math.tu-cottbus.de)
9
10PROCEDURES:
11 inverse(A);        matrix, the inverse of A (for constant matrices)
12 inverse_B(A);      list(matrix Inv,poly p),Inv*A=p*En ( using busadj(A) )
13 inverse_L(A);      list(matrix Inv,poly p),Inv*A=p*En ( using lift )
14 sym_gauss(A);      symmetric gaussian algorithm
15 orthogonalize(A);  Gram-Schmidt orthogonalization
16 diag_test(A);      test whether A can be diagnolized
17 busadj(A);         coefficients of Adj(E*t-A) and coefficients of det(E*t-A)
18 charpoly(A,v);     characteristic polynomial of A ( using busadj(A) )
19 adjoint(A);        adjoint of A ( using busadj(A) )
20 det_B(A);          determinant of A. ( uses busadj(A) )
21 gaussred(A);       gaussian reduction: P*A=U*S, S a row reduced form of A
22 gaussred_pivot(A); gaussian reduction: P*A=U*S, uses row pivoting
23 gauss_nf(A);       gaussian normal form of A
24 mat_rk(A);         rank of constant matrix A
25 U_D_O(A);          P*A=U*D*O, P,D,U,O = permutaion,diag,lower-,upper-triang
26 pos_def(A,i);      test symmetric matrix for positive definiteness
27";
28
29LIB "matrix.lib";
30LIB "ring.lib";
31
32//////////////////////////////////////////////////////////////////////////////
33
34//////////////////////////////////////////////////////////////////////////////
35// help functions
36//////////////////////////////////////////////////////////////////////////////
37static
38proc abs(poly c)
39"RETURN: absolut value of c, c must be constants"
40{
41  if(c>=0){ return(c);}
42  else{ return(-c);}
43}
44
45static
46proc const_mat(matrix A)
47"RETURN:   1 (0) if A is (is not) a constant matrix"
48{
49  int i;
50  int n=ncols(A);
51  def BR=basering;
52  changeord("@R","dp,c",BR);
53  matrix A=fetch(BR,A);
54  for(i=1;i<=n;i=i+1){
55    if(deg(lead(A)[i])>=1){
56      //"input is not a constant matrix";
57      kill @R;
58      setring BR;
59      return(0);
60    }
61  }
62  kill @R;
63  setring BR;
64  return(1); 
65}
66static
67proc red(matrix A,int i,int j)
68"USAGE:    red(A,i,j);  A = constant matrix
69          reduces column j with respect to A[i,i] and column i
70          reduces row j with respect to A[i,i] and row i
71RETURN:   matrix
72"
73{       
74  module m=module(A);
75 
76  if(A[i,i]==0){
77    m[i]=m[i]+m[j];
78    m=module(transpose(matrix(m)));
79    m[i]=m[i]+m[j];
80    m=module(transpose(matrix(m)));
81  }
82 
83  A=matrix(m);
84  m[j]=m[j]-(A[i,j]/A[i,i])*m[i];
85  m=module(transpose(matrix(m)));
86  m[j]=m[j]-(A[i,j]/A[i,i])*m[i];
87  m=module(transpose(matrix(m)));
88 
89  return(matrix(m));
90}
91
92//proc sp(vector v1,vector v2)
93proc inner_product(vector v1,vector v2)
94"RETURN:   inner product <v1,v2> "
95{
96  int k;
97  if (nrows(v2)>nrows(v1)) { k=nrows(v2); } else { k=nrows(v1); }
98  return ((transpose(matrix(v1,k,1))*matrix(v2,k,1))[1,1]);
99}
100
101
102/////////////////////////////////////////////////////////////////////////////
103// user functions
104/////////////////////////////////////////////////////////////////////////////
105
106proc inverse(matrix A)
107"USAGE:    inverse(A);  A = constant, square matrix
108RETURN:   matrix, the inverse matrix of A
109NOTE:     parameters and minpoly are allowed, uses std applied to A enlarged
110          bei unit matrix
111EXAMPLE:  example inverse; shows an example"
112{
113  //erlaubt Parameterringe und minpoly
114
115  int i;
116  int n=nrows(A);
117  string mp=string(minpoly);
118
119  if (ncols(A)!=n){
120    "input is not a square matrix";
121    matrix invmat;
122    return(invmat);
123  }
124  if(!const_mat(A)){
125    "input is not a constant matrix";
126    matrix invmat;
127    return(invmat);
128  }
129         
130  def BR=basering;
131  changeord("@R","c,dp",BR);
132  execute("minpoly="+mp+";");
133  matrix A=fetch(BR,A);
134 
135  matrix B=transpose(concat(A,unitmat(n)));
136  matrix D=transpose(std(B));
137  matrix D1=submat(D,1..n,1..n);
138  matrix D2=submat(D,1..n,(n+1)..2*n);
139  B=transpose(concat(D2,D1));
140
141  changeord("@@R","C,dp",@R);
142  execute("minpoly="+mp+";");
143  matrix B=imap(@R,B);
144 
145  for(i=1;i<=n/2;i=i+1){
146    B=permcol(B,i,n-i+1);
147  }
148  B=std(B);
149  module C=module(B);
150 
151  for (i=1;i<=n;i=i+1){
152    if (deg(B[n+i,i])<0){
153      "matrix is not invertible";
154      setring BR;
155      kill @R;kill @@R;
156      matrix invmat;
157      return(invmat);
158    }
159    else{ C[i] = C[i]/B[n+i,i];}
160  }
161 
162  B=transpose(matrix(C));       
163  matrix invmat[n][n]=B[1..n,1..n];
164  setring BR;
165  matrix invmat=fetch(@@R,invmat);
166  kill @R;kill @@R;     
167  return(invmat);
168}
169example
170{ "EXAMPLE:"; echo = 2;
171  ring r=0,(x),lp;
172  matrix A[4][4]=5,7,3,8,4,6,9,2,3,7,5,7,2,5,6,12;
173  print(A);
174  print(inverse(A));
175  print(inverse(A)*A);         //test for correctness
176}
177
178//////////////////////////////////////////////////////////////////////////////
179proc sym_gauss(matrix A)
180"USAGE:    sym_gauss(A);  A = symmetric matrix
181RETURN:   matrix, diagonalisation with symmetric gauss algorithm
182EXAMPLE:  example sym_gauss; shows an example"
183{
184  int i,j;
185  int n=nrows(A);
186
187  if (ncols(A)!=n){
188    "input is not a square matrix";;
189    return(A);
190  }
191 
192  if(!const_mat(A)){
193    "input is not a constant matrix";
194    return(A);
195  }
196 
197  if(deg(std(A-transpose(A))[1])!=-1){
198    "input is not a symmetric matrix";
199    return(A);
200  }
201
202  for(i=1; i<n; i++){
203    for(j=i+1; j<=n; j++){
204      if(A[i,j]!=0){ A=red(A,i,j); }
205    }
206  }
207 
208  return(A);
209}
210example
211{"EXAMPLE:"; echo = 2;
212  ring r=0,(x),lp;
213  matrix A[2][2]=1,4,4,15;
214  print(A);
215  print(sym_gauss(A));
216}
217
218//////////////////////////////////////////////////////////////////////////////
219proc orthogonalize(matrix A)
220"USAGE:    orthogonalize(A); A = constant matrix
221RETURN:    matrix, orthogonal basis of the colum space of A
222EXAMPLE:   example orthogonalize; shows an example "
223{
224  int i,j;
225  int n=ncols(A);
226  poly k;
227
228  if(!const_mat(A)){
229    "input is not a constant matrix";
230    matrix B;
231    return(B);
232  } 
233
234  module B=module(interred(A));
235 
236  for(i=1;i<=n;i=i+1) {
237    for(j=1;j<i;j=j+1) {
238      k=inner_product(B[j],B[j]);
239      if (k==0) { "Error: vector with zero length"; return(matrix(B)); }
240      B[i]=B[i]-(inner_product(B[i],B[j])/k)*B[j];
241    }
242  }
243 
244  return(matrix(B));
245}
246example
247{ "EXAMPLE:"; echo = 2;
248  ring r=0,(x),lp;
249  matrix A[4][4]=5,6,12,4,7,3,2,6,12,1,1,2,6,4,2,10;
250  print(A);
251  print(orthogonalize(A));
252}
253
254////////////////////////////////////////////////////////////////////////////
255proc diag_test(matrix A)
256"USAGE:   diag_test(A); A = const square matrix
257NOTE:     Der Test ist nur fuer zerfallende Matrizen aussagefaehig.
258          Parameterringe werden nicht unterstuetzt (benutzt factorize,gcd).
259RETURN:   int,  1 falls A diagonalisierbar, 0 nicht diagonalisierbar
260               -1 keine Aussage moeglich, da A nicht zerfallend.
261EXAMPLE:  example diag_test; shows an example"
262{
263  int i,j;
264  int n     = nrows(A);
265  string mp = string(minpoly);
266  string cs = charstr(basering);
267  int np=0;
268
269  if(ncols(A) != n) {
270    "// input is not a square matrix";
271    return(-1);
272  }             
273
274   if(!const_mat(A)){
275    "// input is not a constant matrix";
276    return(-1);
277  } 
278
279  //Parameterring wegen factorize nicht erlaubt
280  for(i=1;i<size(cs);i=i+1){
281    if(cs[i]==","){np=np+1;} //Anzahl der Parameter
282  }
283  if(np>0){
284        "// rings with parameters not allowed";
285        return(-1);
286  }
287
288  //speichern des aktuellen Rings 
289  def BR=basering;
290  //setze R[t]
291  execute("ring rt=("+charstr(basering)+"),(@t,"+varstr(basering)+"),lp;");
292  execute("minpoly="+mp+";");
293  matrix A=imap(BR,A); 
294
295  intvec z;
296  intvec s;
297  poly X;         //characteristisches Polynom
298  poly dXdt;      //Ableitung von X nach t
299  ideal g;            //ggT(X,dXdt)
300  poly b;             //Komponente der Busadjunkten-Matrix
301  matrix E[n][n]; //Einheitsmatrix
302       
303  E=E+1;
304  A=E*@t-A;
305  X=det(A);
306
307  matrix Xfactors=matrix(factorize(X,1));       //zerfaellt die Matrtix ?
308  int nf=ncols(Xfactors);
309
310  for(i=1;i<=nf;i++){
311    if(lead(Xfactors[1,i])>=@t^2){
312      //"Die Matrix ist nicht zerfallend";
313      setring BR;
314      return(-1);
315    }
316  }     
317
318  dXdt=diff(X,@t);
319  g=std(ideal(gcd(X,dXdt)));
320
321  //Busadjunkte
322  z=2..n;       
323  for(i=1;i<=n;i++){
324    s=2..n; 
325    for(j=1;j<=n;j++){
326      b=det(submat(A,z,s));
327   
328      if(0!=reduce(b,g)){
329        //"Die Matrix ist nicht diagonalisierbar!";
330        setring BR;
331        return(0);
332      }
333     
334      s[j]=j;
335    }
336    z[i]=i;
337  }
338 
339  //"Die Matrix ist diagonalisierbar";         
340  setring BR;
341  return(1);
342}
343example
344{ "EXAMPLE:"; echo = 2;
345  ring r=0,(x),dp;
346  matrix A[4][4]=6,0,0,0,0,0,6,0,0,6,0,0,0,0,0,6;
347  print(A);
348  diag_test(A);
349}
350
351//////////////////////////////////////////////////////////////////////////////
352proc busadj(matrix A)
353"USAGE:   busadj(A);  A = square matrix
354RETURN:  list L;
355         L[1] contains the (n+1) coefficients of the characteristic polynomial
356         X of A, i.e.
357              X = L[1][1]+..+L[1][k]*t^(k-1)+..+(L[1][n+1])*t^n
358         L[2] contains the n (nxn)-matrices Hk which are the coefficients of
359              the busadjoint bA=adjoint(E*t-A) of A, i.e.
360              bA = (Hn-1)*t^(n-1)+...+Hk*t^k+...+H0,  ( Hk=L[2][k+1] )
361EXAMPLE: example busadj; shows an example"
362{
363  int k;
364  int n    = nrows(A);
365  matrix E = unitmat(n);
366  matrix H[n][n];
367  matrix B[n][n];
368  list bA, X, L;
369  poly a;
370
371  if(ncols(A) != n) {
372    "input is not a square matrix";
373    return(L);
374  }     
375
376  bA   = E;
377  X[1] = 1;
378  for(k=1; k<n; k++){
379    B  = A*bA[1];              //bA[1] is the last H
380    a  = -trace(B)/k;
381    H  = B+a*E;
382    bA = insert(bA,H);
383    X  = insert(X,a);
384  }
385  B = A*bA[1];
386  a = -trace(B)/n;
387  X = insert(X,a);
388
389  L = insert(L,bA);
390  L = insert(L,X);
391  return(L);
392}
393example
394{ "EXAMPLE"; echo = 2;
395  ring r = 0,(t,x),lp;
396  matrix A[2][2] = 1,x2,x,x2+3x;
397  print(A);
398  list L = busadj(A);
399  poly X = L[1][1]+L[1][2]*t+L[1][3]*t2; X;
400  matrix bA[2][2] = L[2][1]+L[2][2]*t;
401  print(bA);               //the busadjoint of A;
402  print(bA*(t*unitmat(2)-A)); 
403}
404
405//////////////////////////////////////////////////////////////////////////////
406proc charpoly(matrix A, list #)
407"USAGE:   charpoly(A,[v]); A = square matrix, v = name of a ringvariable
408NOTE:    A must be constant in the variable v. The computation uses busadj(A).
409RETURN:  poly, the characteristic polynomial det(E*v-A)
410EXAMPLE: example charpoly; shows an example"
411{
412  int i,j;
413  string s,v;
414  list L;
415  int n     = nrows(A);
416  poly X    = 0;
417  def BR    = basering;
418  string mp = string(minpoly);
419
420  if(ncols(A) != n){   
421    "// input is not a square matrix";
422    return(X);
423  }     
424
425  //test for correct variable
426  if( size(#)==0 ){
427    #[1] = varstr(1);
428  }
429  if( typeof(#[1]) == "string"){
430     v = #[1];
431  }
432  else{
433    "// 2nd argument must be a name of a variable not contained in the matrix";
434    return(X);
435  } 
436       
437  j=-1;
438  for(i=1; i<=nvars(BR); i++){
439    if(varstr(i)==v){j=i;}
440  }
441  if(j==-1){
442    "// "+v+" is not a variable in the basering";
443    return(X);
444  }
445 
446  //var can not be in A
447  s="Wp(";
448  for( i=1; i<=nvars(BR); i++ ){
449    if(i!=j){ s=s+"0";}
450    else{ s=s+"1";}
451    if( i<nvars(BR)) {s=s+",";}
452  }
453  s=s+")";
454
455  changeord("@R",s);
456  execute("minpoly="+mp+";");
457  matrix A = imap(BR,A);
458  for(i=1; i<=n; i++){
459    if(deg(lead(A)[i])>=1){
460      "matrix must not contain the variable "+v;
461      kill @R;
462      setring BR;
463      return(X);
464    }
465  }
466
467  //get coefficients and build the char. poly
468  kill @R;
469  setring BR;
470  L = busadj(A);
471  for(i=1; i<=n+1; i++){
472    execute("X=X+L[1][i]*"+v+"^"+string(i-1)+";");
473  }
474 
475  return(X);
476}
477example
478{ "EXAMPLE"; echo=2;
479  ring r=0,(x,t),dp;
480  matrix A[3][3]=1,x2,x,x2,6,4,x,4,1;
481  print(A);
482  charpoly(A,"t");
483}
484
485//////////////////////////////////////////////////////////////////////////////
486proc adjoint(matrix A)
487"USAGE:    adjoint(A);  A = square matrix
488NOTE:     computation uses busadj(A)
489RETURN:   adjoint
490EXAMPLE:  example adjoint; shows an example"
491{
492  int n=nrows(A);
493  matrix Adj[n][n];
494  list L;
495
496  if(ncols(A) != n) {   
497    "// input is not a square matrix";
498    return(Adj);
499  }     
500 
501  L  = busadj(A);
502  Adj= (-1)^(n-1)*L[2][1];
503  return(Adj);
504 
505}
506example
507{ "EXAMPLE"; echo=2;
508  ring r=0,(t,x),lp;
509  matrix A[2][2]=1,x2,x,x2+3x;
510  print(A);
511  matrix Adj[2][2]=adjoint(A);
512  print(Adj);                    //Adj*A=det(A)*E
513  print(Adj*A);
514}
515
516
517//////////////////////////////////////////////////////////////////////////////
518proc inverse_B(matrix A)
519"USAGE:     inverse_B(A);  A = square matrix
520RETURN:    list Inv with Inv[1]=matrix I and Inv[2]=poly p
521           and I*A = unitmat(n)*p;
522NOTE:      p=1 if 1/det(A) is computable and  p=det(A) if not
523EXAMPLE:   example inverse_B; shows an example"
524{
525  int i;
526  int n=nrows(A);
527  matrix I[n][n];
528  poly factor;
529  list L;
530  list Inv;
531 
532  if(ncols(A) != n) {   
533    "input is not a square matrix";
534    return(I);
535  }     
536 
537  L=busadj(A);
538  I=module(-L[2][1]);        //+-Adj(A)   
539
540  if(reduce(1,std(L[1][1]))==0){
541    I=I*lift(L[1][1],1)[1][1];     
542    factor=1;
543  }
544  else{ factor=L[1][1];}     //=+-det(A) or 1
545  Inv=insert(Inv,factor);
546  Inv=insert(Inv,matrix(I));
547
548  return(Inv);
549}
550example
551{ "EXAMPLE"; echo=2;
552  ring r=0,(x,y),lp;
553  matrix A[3][3]=x,y,1,1,x2,y,x+y,6,7;
554  print(A);
555  list Inv=inverse_B(A);
556  print(Inv[1]);
557  print(Inv[2]);
558  print(Inv[1]*A);
559}
560
561
562//////////////////////////////////////////////////////////////////////////////
563proc det_B(matrix A)
564"USAGE:     det_B(A);  A any matrix 
565RETURN:    returns the determinant of A
566NOTE:      the computation uses the busadj algorithm
567EXAMPLE:   example det_B; shows an example"
568{
569  int n=nrows(A);
570  list L;
571
572  if(ncols(A) != n){ return(0);}
573
574  L=busadj(A);
575  return((-1)^n*L[1][1]);
576 
577 
578}
579example
580{ "EXAMPLE"; echo=2;
581  ring r=0,(x),dp;
582  matrix A[10][10]=random(2,10,10)+unitmat(10)*x;
583  print(A);
584  det_B(A);
585}
586
587
588//////////////////////////////////////////////////////////////////////////////
589proc inverse_L(matrix A)
590"USAGE:     inverse_L(A);  A = square matrix
591RETURN:    list Inv representing a left inverse of A, i.e
592           Inv[1] = matrix I and Inv[2]=poly p such that
593           I*A = unitmat(n)*p;
594NOTE:      p=1 if 1/det(A) is computable and  p=det(A) if not
595EXAMPLE:   example inverse_L; shows an example"
596{
597  int n=nrows(A);
598  matrix I;
599  matrix E[n][n]=unitmat(n);
600  poly factor;
601  poly d=1;
602  list Inv;
603
604  if (ncols(A)!=n){
605    "// input is not a square matrix";
606    return(I);
607  }
608
609  d=det(A);
610  if(d==0){
611    "// matrix is not invertible";
612    return(Inv);
613  }
614
615  // test if 1/det(A) exists
616  if(reduce(1,std(d))!=0){ E=E*d;}
617 
618  I=lift(A,E);
619  if(I==unitmat(n)-unitmat(n)){ //catch error in lift
620    "// matrix is not invertible";
621    return(Inv);
622  }
623
624  factor=d;      //=det(A) or 1
625  Inv=insert(Inv,factor);
626  Inv=insert(Inv,I);
627 
628  return(Inv);
629}
630example
631{ "EXAMPLE"; echo=2;
632  ring r=0,(x,y),lp;
633  matrix A[3][3]=x,y,1,1,x2,y,x+y,6,7;
634  print(A);
635  list Inv=inverse_L(A);
636  print(Inv[1]);
637  print(Inv[2]);
638  print(Inv[1]*A);
639}
640
641//////////////////////////////////////////////////////////////////////////////
642proc gaussred(matrix A)
643"USAGE:     gaussred(A);   A any constant matrix
644RETURN:    list Z:  Z[1]=P , Z[2]=U , Z[3]=S , Z[4]=rank(A)
645           gives a row reduced matrix S, a permutation matrix P and a
646           normalized lower triangular matrix U, with P*A=U*S           
647EXAMPLE:   example gaussred; shows an example"
648{
649  int i,j,l,k,jp,rang;
650  poly c,pivo;
651  list Z;
652  int n = nrows(A);
653  int m = ncols(A);
654  int mr= n; //max. rang
655  matrix P[n][n] = unitmat(n);
656  matrix U[n][n] = P;
657
658  if(!const_mat(A)){
659    "// input is not a constant matrix";
660    return(Z);
661  }
662
663  if(n>m){mr=m;} //max. rang
664
665  for(i=1;i<=mr;i=i+1){
666    if((i+k)>m){break};
667   
668    //Test: Diagonalelement=0
669    if(A[i,i+k]==0){
670      jp=i;pivo=0;
671      for(j=i+1;j<=n;j=j+1){
672        c=abs(A[j,i+k]);
673        if(pivo<c){ pivo=c;jp=j;}
674      }
675      if(jp != i){       //Zeilentausch
676        for(j=1;j<=m;j=j+1){ //Zeilentausch in A (und U) (i-te mit jp-ter)
677          c=A[i,j];         
678          A[i,j]=A[jp,j];
679          A[jp,j]=c;
680        }
681        for(j=1;j<=n;j=j+1){ //Zeilentausch in P
682          c=P[i,j];       
683          P[i,j]=P[jp,j];
684          P[jp,j]=c; 
685        }
686      }
687      if(pivo==0){k++;continue;} //eine von selbst auftauchende Stufe !
688    }                          //i sollte im naechsten Lauf nicht erhoeht sein
689   
690    //Eliminationsschritt   
691    for(j=i+1;j<=n;j=j+1){
692      c=A[j,i+k]/A[i,i+k];
693      for(l=i+k+1;l<=m;l=l+1){
694        A[j,l]=A[j,l]-A[i,l]*c;
695      }
696      A[j,i+k]=0;  // nur wichtig falls k>0 ist
697      A[j,i]=c;    // bildet U
698    }
699  rang=i;   
700  }
701 
702  for(i=1;i<=mr;i=i+1){
703    for(j=i+1;j<=n;j=j+1){
704      U[j,i]=A[j,i];
705      A[j,i]=0;
706    }
707  }
708 
709  Z=insert(Z,rang);
710  Z=insert(Z,A);
711  Z=insert(Z,U);
712  Z=insert(Z,P);
713 
714  return(Z);
715}
716example
717{ "EXAMPLE";echo=2;
718  ring r=0,(x),dp;
719  matrix A[5][4]=1,3,-1,4,2,5,-1,3,1,3,-1,4,0,4,-3,1,-3,1,-5,-2;
720  print(A);
721  list Z=gaussred(A);   //construct P,U,S s.t. P*A=U*S
722  print(Z[1]);          //P
723  print(Z[2]);          //U
724  print(Z[3]);          //S
725  print(Z[4]);          //rank
726  print(Z[1]*A);        //P*A
727  print(Z[2]*Z[3]);     //U*S
728}
729
730//////////////////////////////////////////////////////////////////////////////
731proc gaussred_pivot(matrix A)
732"USAGE:     gaussred_pivot(A);   A any constant matrix
733RETURN:    list Z:  Z[1]=P , Z[2]=U , Z[3]=S , Z[4]=rank(A)
734           gives n row reduced matrix S, a permutation matrix P and a
735           normalized lower triangular matrix U, with P*A=U*S
736NOTE:      with row pivoting           
737EXAMPLE:   example gaussred_pivot; shows an example"
738{
739  int i,j,l,k,jp,rang;
740  poly c,pivo;
741  list Z;
742  int n=nrows(A);
743  int m=ncols(A);
744  int mr=n; //max. rang
745  matrix P[n][n]=unitmat(n);
746  matrix U[n][n]=P;
747
748  if(!const_mat(A)){
749    "// input is not a constant matrix";
750    return(Z);
751  }
752
753  if(n>m){mr=m;} //max. rang
754
755  for(i=1;i<=mr;i=i+1){
756    if((i+k)>m){break};
757   
758    //Pivotisierung
759    pivo=abs(A[i,i+k]);jp=i;
760    for(j=i+1;j<=n;j=j+1){
761      c=abs(A[j,i+k]);
762      if(pivo<c){ pivo=c;jp=j;}
763    }
764    if(jp != i){ //Zeilentausch
765      for(j=1;j<=m;j=j+1){ //Zeilentausch in A (und U) (i-te mit jp-ter)
766        c=A[i,j];         
767        A[i,j]=A[jp,j];
768        A[jp,j]=c;
769      }
770      for(j=1;j<=n;j=j+1){ //Zeilentausch in P
771        c=P[i,j];       
772        P[i,j]=P[jp,j];
773        P[jp,j]=c; 
774      }
775    }
776    if(pivo==0){k++;continue;} //eine von selbst auftauchende Stufe !
777                               //i sollte im naechsten Lauf nicht erhoeht sein
778    //Eliminationsschritt   
779    for(j=i+1;j<=n;j=j+1){
780      c=A[j,i+k]/A[i,i+k];
781      for(l=i+k+1;l<=m;l=l+1){
782        A[j,l]=A[j,l]-A[i,l]*c;
783      }
784      A[j,i+k]=0;  // nur wichtig falls k>0 ist
785      A[j,i]=c;    // bildet U
786    }
787  rang=i;   
788  }
789 
790  for(i=1;i<=mr;i=i+1){
791    for(j=i+1;j<=n;j=j+1){
792      U[j,i]=A[j,i];
793      A[j,i]=0;
794    }
795  }
796 
797  Z=insert(Z,rang);
798  Z=insert(Z,A);
799  Z=insert(Z,U);
800  Z=insert(Z,P);
801 
802  return(Z);
803}
804example
805{ "EXAMPLE";echo=2;
806  ring r=0,(x),dp;
807  matrix A[5][4] = 1, 3,-1,4,
808                   2, 5,-1,3,
809                   1, 3,-1,4,
810                   0, 4,-3,1,
811                  -3,1,-5,-2;
812  list Z=gaussred_pivot(A);  //construct P,U,S s.t. P*A=U*S
813  print(Z[1]);               //P
814  print(Z[2]);               //U
815  print(Z[3]);               //S
816  print(Z[4]);               //rank
817  print(Z[1]*A);             //P*A
818  print(Z[2]*Z[3]);          //U*S
819}
820
821
822//////////////////////////////////////////////////////////////////////////////
823proc gauss_nf(matrix A)
824"USAGE:    gauss_nf(A); A any constant matrix
825RETURN:   matrix; gauss normal form of A
826EXAMPLE:  example gauss_nf; shows an example"
827{
828  list Z;
829  if(!const_mat(A)){
830    "// input is not a constant matrix";
831    return(A);
832  }
833  Z = gaussred(A);
834  return(Z[3]);
835}
836example
837{ "EXAMPLE";echo=2;
838  ring r = 0,(x),dp;
839  matrix A[4][4] = 1,4,4,7,2,5,5,4,4,1,1,3,0,2,2,7;
840  print(gauss_nf(A));
841}
842
843//////////////////////////////////////////////////////////////////////////////
844proc mat_rk(matrix A)
845"USAGE:    mat_rk(A); A any constant matrix
846RETURN:   int, rank of A
847EXAMPLE:  example mat_rk; shows an example"
848{
849  list Z;
850  if(!const_mat(A)){
851    "//input is not a constant matrix";
852    return(-1);
853  }
854  Z = gaussred(A);
855  return(Z[4]);
856}
857example
858{ "EXAMPLE";echo=2;
859  ring r = 0,(x),dp;
860  matrix A[4][4] = 1,4,4,7,2,5,5,4,4,1,1,3,0,2,2,7;
861  mat_rk(A);
862}
863
864//////////////////////////////////////////////////////////////////////////////
865proc U_D_O(matrix A)
866"USAGE:     U_D_O(A);   constant invertible matrix A
867RETURN:    list Z:  Z[1]=P , Z[2]=U , Z[3]=D , Z[4]=O
868           gives a permutation matrix P,
869           a normalized lower triangular matrix U ,
870           a diagonal matrix D, and a normalized upper triangular matrix O
871           with P*A=U*D*O
872NOTE:      Z[1]=-1 means that A is not regular
873EXAMPLE:   example U_D_O; shows an example"
874{
875  int i,j;
876  list Z,L;
877  int n=nrows(A);
878  matrix O[n][n]=unitmat(n);
879  matrix D[n][n];
880
881  if (ncols(A)!=n){
882    "// input is not a square matrix";
883    return(Z);
884  }
885  if(!const_mat(A)){
886    "// input is not a constant matrix";
887    return(Z);
888  }
889 
890  L=gaussred(A);
891
892  if(L[4]!=n){
893    "// input is not an invertible matrix";
894    Z=insert(Z,-1);  //hint for calling procedures
895    return(Z);
896  }
897
898  D=L[3];
899
900  for(i=1; i<=n; i++){
901    for(j=i+1; j<=n; j++){
902      O[i,j] = D[i,j]/D[i,i];
903      D[i,j] = 0;
904    }
905  }
906
907  Z=insert(Z,O);
908  Z=insert(Z,D);
909  Z=insert(Z,L[2]);
910  Z=insert(Z,L[1]);
911  return(Z);
912}
913example
914{ "EXAMPLE";echo=2;
915  ring r = 0,(x),dp;
916  matrix A[5][5] = 10, 4,  0, -9,  8,
917                   -3, 6, -6, -4,  9,
918                    0, 3, -1, -9, -8,
919                   -4,-2, -6, -10,10,
920                   -9, 5, -1, -6,  5;
921  list Z = U_D_O(A);              //construct P,U,D,O s.t. P*A=U*D*O
922  print(Z[1]);                    //P
923  print(Z[2]);                    //U
924  print(Z[3]);                    //D
925  print(Z[4]);                    //O
926  print(Z[1]*A);                  //P*A
927  print(Z[2]*Z[3]*Z[4]);          //U*D*O
928}
929
930
931//////////////////////////////////////////////////////////////////////////////
932proc pos_def(matrix A)
933"USAGE:     pos_def(A); A = constant, symmetric square matrix       
934RETURN:    int; 1 if A is positive definit , 0 if not, -1 if unknown
935EXAMPLE:   example pos_def; shows an example"
936{
937  int j;
938  list Z;
939  int n = nrows(A);
940  matrix H[n][n];
941
942  if (ncols(A)!=n){
943    "// input is not a square matrix";
944    return(0);
945  }
946  if(!const_mat(A)){
947    "// input is not a constant matrix";
948    return(-1);
949  }     
950  if(deg(std(A-transpose(A))[1])!=-1){
951    "// input is not a hermitian (symmetric) matrix";
952    return(-1);
953  }
954 
955  Z=U_D_O(A);
956
957  if(Z[1]==-1){
958    return(0);
959  }  //A not regular, therefore not pos. definit
960
961  H=Z[1];
962  //es fand Zeilentausch statt: also nicht positiv definit
963  if(deg(std(H-unitmat(n))[1])!=-1){
964    return(0);
965  }
966 
967  H=Z[3];
968 
969  for(j=1;j<=n;j=j+1){
970    if(H[j,j]<=0){
971      return(0);
972    } //eigenvalue<=0, not pos.definit
973  }
974
975  return(1); //positiv definit;
976}
977example
978{ "EXAMPLE"; echo=2;
979  ring r = 0,(x),dp;
980  matrix A[5][5] = 20,  4,  0, -9,   8,
981                    4, 12, -6, -4,   9,
982                    0, -6, -2, -9,  -8,
983                   -9, -4, -9, -20, 10,
984                    8,  9, -8,  10, 10;
985  pos_def(A);
986  matrix B[3][3] =  3,  2,  0,
987                    2, 12,  4,
988                    0,  4,  2;
989  pos_def(B);
990}
991
992
993//////////////////////////////////////////////////////////////////////////////
994proc linsolve(matrix A, matrix b)
995"USAGE:     linsolve(A,b); A a constant nxm-matrix, b a constant nx1-matrix
996RETURN:    a solution of inhomogeneous linear system A*X = b
997EXAMPLE:   example linsolve; shows an example"
998{
999  int i,j,k,rc,r;
1000  poly c;
1001  list Z;
1002  int n  = nrows(A);
1003  int m  = ncols(A);
1004  int n_b= nrows(b);
1005  matrix Ab[n][m+1];
1006  matrix X[m][1];
1007       
1008  if(ncols(b)!=1){
1009    "// right hand side b is not a nx1 matrix";
1010    return(X);
1011  }
1012
1013  if(!const_mat(A)){
1014    "// input hand is not a constant matrix";
1015    return(X);
1016  }     
1017 
1018  if(n_b>n){
1019    for(i=n; i<=n_b; i++){
1020      if(b[i,1]!=0){
1021        "// right hand side b not in Image(A)";
1022        return X;
1023      }
1024    }   
1025  }
1026 
1027  if(n_b<n){
1028    matrix copy[n_b][1]=b;
1029    matrix b[n][1]=0;
1030    for(i=1;i<=n_b;i=i+1){
1031      b[i,1]=copy[i,1];
1032    }
1033  }
1034 
1035  r=mat_rk(A);
1036       
1037  //1. b constant vector
1038  if(const_mat(b)){     
1039    //extend A with b
1040    for(i=1; i<=n; i++){
1041      for(j=1; j<=m; j++){
1042        Ab[i,j]=A[i,j];
1043      }
1044      Ab[i,m+1]=b[i,1];
1045    }
1046     
1047    //Gauss reduction
1048    Z  = gaussred(Ab);
1049    Ab = Z[3];  //normal form
1050    rc = Z[4];  //rank(Ab) 
1051    //print(Ab);
1052
1053    if(r<rc){
1054        "// no solution";
1055        return(X);
1056    }
1057    k=m;       
1058    for(i=r;i>=1;i=i-1){
1059     
1060      j=1;     
1061      while(Ab[i,j]==0){j=j+1;}// suche Ecke
1062   
1063      for(;k>j;k=k-1){ X[k]=0;}//springe zur Ecke
1064     
1065
1066      c=Ab[i,m+1]; //i-te Komponene von b
1067      for(j=m;j>k;j=j-1){
1068        c=c-X[j,1]*Ab[i,j];
1069      }
1070      if(Ab[i,k]==0){
1071        X[k,1]=1; //willkuerlich
1072      }
1073      else{
1074        X[k,1]=c/Ab[i,k];
1075      }
1076      k=k-1;
1077      if(k==0){break;}
1078    }
1079   
1080   
1081  }//endif (const b)
1082  else{  //b not constant
1083    "// !not implemented!";
1084 
1085  }
1086
1087  return(X);
1088}
1089example
1090{ "EXAMPLE";echo=2;
1091  ring r=0,(x),dp;
1092  matrix A[3][2] = -4,-6,
1093                    2, 3,
1094                   -5, 7;
1095  matrix b[3][1] = 10,
1096                   -5,
1097                    2;
1098  matrix X = linsolve(A,b);
1099  print(X);
1100  print(A*X);
1101}
1102//////////////////////////////////////////////////////////////////////////////
1103
Note: See TracBrowser for help on using the repository browser.