source: git/Singular/LIB/linalg.lib @ 49998f

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