Matrix.fromBlocks constructor
Constructs a new Matrix from smaller square matrices (blocks).
The blocks of the matrix are specified in a two-dimensional list, with each inner list representing a row of blocks. This allows you to construct a large matrix from smaller matrices, each representing a block of the larger one.
It's essential that all block matrices are square and of the same size. This constructor
will throw an ArgumentError if the blocks are not all the same size, or if they're not
all square matrices.
Example:
var block1 = Matrix([
[1, 2],
[3, 4]
]);
var block2 = Matrix([
[5, 6],
[7, 8]
]);
var block3 = Matrix([
[9, 10],
[11, 12]
]);
var block4 = Matrix([
[13, 14],
[15, 16]
]);
var matrix = Matrix.fromBlocks([
[block1, block2],
[block3, block4]
]);
print(matrix);
Output:
Matrix: 4x4
┌ 1 2 5 6 ┐
| 3 4 7 8 |
| 9 10 13 14 |
└ 11 12 15 16 ┘
blocks: A 2D list of square Matrix objects that will be used to create
the new Matrix. All matrices must be of the same size.
Implementation
factory Matrix.fromBlocks(List<List<Matrix>> blocks) {
int rows = blocks.length;
int cols = blocks[0].length;
int blockSize = blocks[0][0]._data.length;
// Check for block validity and uniformity.
for (var blockRow in blocks) {
if (blockRow.length != cols) {
throw ArgumentError('All rows of blocks must have the same length.');
}
for (var block in blockRow) {
if (block._data.length != blockSize ||
block._data[0].length != blockSize) {
throw ArgumentError(
'All blocks must be square matrices and have the same dimensions.');
}
}
}
// Pre-compute the final size of the matrix and allocate memory at once.
List<List<dynamic>> matrix = List.generate(rows * blockSize,
(_) => List<dynamic>.filled(cols * blockSize, Complex.zero()));
// Re-order loops for more linear data access.
for (int row = 0; row < blockSize; ++row) {
for (int col = 0; col < blockSize; ++col) {
for (int blockRow = 0; blockRow < rows; ++blockRow) {
for (int blockCol = 0; blockCol < cols; ++blockCol) {
matrix[blockSize * blockRow + row][blockSize * blockCol + col] =
blocks[blockRow][blockCol]._data[row][col];
}
}
}
}
return Matrix(matrix);
}