source: git/Singular/LIB/linalg.lib @ 0b59f5

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