For loop to split matrix to equal sized sub-matrices

Given a square matrix of say size 400x400, how would I go about splitting this into constituent sub-matrices of 20x20 using a for-loop? I can't even think where to begin!

I imagine I want something like :

[x,y] = size(matrix)

for i = 1:20:x
    for j = 1:20:y

but I'm unsure how I would proceed. Thoughts?


Solution 1:

Well, I know that the poster explicitly asked for a for loop, and Jeff Mather's answer provided exactly that.

But still I got curious whether it is possible to decompose a matrix into tiles (sub-matrices) of a given size without a loop. In case someone else is curious, too, here's what I have come up with:

T = permute(reshape(permute(reshape(A, size(A, 1), n, []), [2 1 3]), n, m, []), [2 1 3])

transforms a two-dimensional array A into a three-dimensional array T, where each 2d slice T(:, :, i) is one of the tiles of size m x n. The third index enumerates the tiles in standard Matlab linearized order, tile rows first.

The variant

T = permute(reshape(A, size(A, 1), n, []), [2 1 3]);
T = permute(reshape(T, n, m, [], size(T, 3)), [2 1 3 4]);

makes T a four-dimensional array where T(:, :, i, j) gives the 2d slice with tile indices i, j.

Coming up with these expressions feels a bit like solving a sliding puzzle. ;-)

Solution 2:

I'm sorry that my answer does not use a for loop either, but this would also do the trick:

cellOf20x20matrices = mat2cell(matrix, ones(1,20)*20, ones(1,20)*20)

You can then access the individual cells like:

cellOf20x20matrices{i,j}(a,b)

where i,j is the submatrix to fetch (and a,b is the indexing into that matrix if needed)

Regards