rank method
The rank of a matrix A
is the dimension of the vector space
generated by its columns. This corresponds to the maximal number of
linearly independent columns of A
.
The rank is generally denoted by rank(A) or rk(A).
Implementation
@override
int rank() {
if (isSquareMatrix && rowCount == 1) {
return this(0, 0) == 0 ? 0 : 1;
}
// If it's a square matrix, we can use the LU decomposition which is faster
if (isSquareMatrix) {
final lower = luDecomposition().first;
// Linearly independent columns
var independentCols = 0;
for (var i = 0; i < lower.rowCount; ++i) {
for (var j = 0; j < lower.columnCount; ++j) {
if ((i == j) && (lower(i, j) != 0)) {
++independentCols;
}
}
}
return independentCols;
}
// If the matrix is rectangular and it's not 1x1, then use the "traditional"
// algorithm
var rank = 0;
final matrix = toListOfList();
const precision = 1.0e-12;
final selectedRow = List<bool>.generate(rowCount, (_) => false);
for (var i = 0; i < columnCount; ++i) {
var j = 0;
for (j = 0; j < rowCount; ++j) {
if (!selectedRow[j] && matrix[j][i].abs() > precision) {
break;
}
}
if (j != rowCount) {
++rank;
selectedRow[j] = true;
for (var p = i + 1; p < columnCount; ++p) {
matrix[j][p] /= matrix[j][i];
}
for (var k = 0; k < rowCount; ++k) {
if (k != j && matrix[k][i].abs() > precision) {
for (var p = i + 1; p < columnCount; ++p) {
matrix[k][p] -= matrix[j][p] * matrix[k][i];
}
}
}
}
}
return rank;
}