! Computing the rank of a matrix. (RankFind.lng);
! Keywords: Matrix rank, Rank of Matrix;
SETS:
dimr: listr; ! The row dimension;
dimc: listc; ! The col dimension;
rxc( dimr, dimc): A, WORK;
ENDSETS DATA:
tolpiv = 1e-14; ! Pivot tolerance;
! Case 1;
!Case01 dimr = 1..4;
!Case01 dimc = 1..4;
!Case01 A=
5 7 3 -1
1 -2 0 4
1 2 4 5
2 -4 0 8;
! Case 2;
!Case02 dimr = 1..4;
!Case02 dimc = 1..4;
!Case02 A=
4 8 4 -2
4 -8 0 16
-2 -4 -2 1
2 -4 0 8;
! Case 3;
!Case03 dimr = 1..2;
!Case03 dimc = 1..4;
!Case03 A=
4 8 4 -2
4 -8 0 16;
! Case 4;
!Case04; dimr = 1..4!Case04; dimc = 1..3!Case04; A=
1 3 4
2 2 4
3 4 7
4 5 9;
ENDDATA
procedure comprank:
! Compute the rank of a dense matrix.
! Inputs:
A = a matrix,
tolpiv = a pivot tolerance, e.g., 10^(-13),
Output:
rank = rank of the matrix;
nremr = @size( dimr); ! row dimension;
nremc = @size( dimc); ! col dimension;
! Copy A into the WORK matrix;
@FOR( rxc( i, j): WORK( i, j) = A( i, j));
! Load all the rows and cols onto the unpivoted lists;
@FOR( dimr( i): listr( i) = i;);
@FOR( dimc( j): listc( j) = j;);
rank = 0; ! Count number of successful pivots;
! Keep pivoting while we have acceptable pivot;
more = 1;
@FOR( dimr( k) | more:
! Find the largest unpivoted element;
pivMAX = 0;
@FOR( dimr( kr) | kr #le# nremr:
icand = listr( kr);
@FOR( dimc( kc) | kc #le# nremc:
jcand = listc( kc);
@IFC( @ABS( work( icand, jcand)) #gt# pivmax:
pivmax = @abs( work( icand, jcand)); !Found new big;
ipos = kr; ! Remember list posn of row;
jpos = kc; ! Remember list posn of col;
);
);
);
! Did we find another acceptable pivot element? ;
@IFC( pivmax #ge# tolpiv:
! Yes, get ready to do the pivot;
rank = rank + 1;
ipiv = listr( ipos); ! Get pivot row;
jpiv = listc( jpos); ! Get pivot col;
! Remove pivot row and column from unpivoted lists;
listr( ipos) = listr( nremr);
nremr = nremr - 1;
listc( jpos) = listc( nremc);
nremc = nremc - 1;
! Now actually do the pivot, updating the unpivoted rows and cols;
divisor = WORK( ipiv, jpiv);
@FOR( dimr( kr) | kr #le# nremr:
ii = listr( kr);
mult = WORK( ii, jpiv)/ divisor;
@FOR( dimc( kc) | kc #le# nremc:
jj = listc( kc);
WORK( ii, jj) = WORK( ii, jj) - mult*WORK( ipiv, jj);
);
);
@else
more = 0; ! Could not find a pivot. Get out;
)
);
endprocedure
CALC:
@SET( 'TERSEO',2); ! Output level (0:verb, 1:terse, 2:only errors, 3:none);
@SET( 'OROUTE',1); ! 1: Route output immediately to the window line by line;
! Compute rank of matrix A;
comprank;
ENDCALC
DATA:
@TEXT() = 'Given matrix:';
@TEXT() = @table( A);
@TEXT() = ' The rank= ', rank;
ENDDATA
|