Reshape a 2D Matrix to 3D in a block/tile wise manner and back(!)

7 views (last 30 days)
Hi,
I have a 2D Matrix and want to reshape it into blocks of a 3D array by having each block/tile in the third dimension.
Precisely:
2D Matrix = m * n --> 3D Matrix = tilesize x tilesize x nbOfTiles. I do not care a lot about the order, as long as the blocks are created column or row wise, e.g:
tilesize = 2;
m = [ 1 1 2 2 3 3;
1 1 2 2 3 3;
4 4 5 5 6 6;
4 4 5 5 6 6]
% What I want to obtain (here columnwise):
m_result (:,:,1) = [1 1;
1 1]
m_result (:,:,2) = [4 4;
4 4]
m_result (:,:,3) = [2 2;
2 2]
m_result (:,:,4) = [5 5;
5 5]
m_result (:,:,5) = [3 3;
3 3]
m_result (:,:,6) = [6 6;
6 6]
I managed to obtain that using an intermediate step of a cell-array:
m_tiles = mat2cell(m, tilesize * ones(1,size(m,1)/tilesize), tilesize * ones(1,size(m,2)/tilesize));
m_tilesList = reshape(tiles,[numel(tiles) 1]); % Reshape to a list
m_tiles3D = cat(3,m_tilesList{:}); % Convert cell array to 3D Array
QUESTION 1: Can I do that only using reshape?
More importent for me:
What I did not manged, is the transfer/reshape operation back (from 3D to 2D). Nevertheless, what I tried so far are all kinds of variations of something like that:
m_back = reshape (permute(m_tiles3D,[3 2 1]), [size(m,1), size(m,2)]);
QUESTION 2: How can I do the conversion back to m from the 3D Array with the tiles/blocks in the third dimension ?
Thanks and all the best
Tim
PS: I cannot use blockproc function due to extensive calculations and handling activties for each block in the background.

Accepted Answer

Stephen23
Stephen23 on 5 Apr 2022
Edited: Stephen23 on 7 Apr 2022
Q1: "Can I do that only using reshape?"
No, the order of the elements is different, so RESHAPE alone is insufficient (note that RESHAPE does not change the order of elements in memory). You will need to split (e.g. indexing or MAT2CELL) or PERMUTE the elements.
format compact
T = 2;
M = [1,1,2,2,3,3;1,1,2,2,3,3;;4,4,5,5,6,6;4,4,5,5,6,6]
M = 4×6
1 1 2 2 3 3 1 1 2 2 3 3 4 4 5 5 6 6 4 4 5 5 6 6
A = reshape(permute(reshape(M,T,size(M,1)/T,T,[]),[1,3,2,4]),T,T,[])
A =
A(:,:,1) = 1 1 1 1 A(:,:,2) = 4 4 4 4 A(:,:,3) = 2 2 2 2 A(:,:,4) = 5 5 5 5 A(:,:,5) = 3 3 3 3 A(:,:,6) = 6 6 6 6
Q2: "How can I do the conversion back to m from the 3D Array with the tiles/blocks in the third dimension ?"
M = reshape(permute(reshape(A,T,T,size(M,1)/T,[]),[1,3,2,4]),size(M))
M = 4×6
1 1 2 2 3 3 1 1 2 2 3 3 4 4 5 5 6 6 4 4 5 5 6 6
  4 Comments
Stephen23
Stephen23 on 6 Apr 2022
Edited: Stephen23 on 7 Apr 2022
You are right, that seemed to only work for that particular size. Perhaps this (I also updated my answer):
format compact
T = 2;
M = [1,1,2,2,3,3;1,1,2,2,3,3;4,4,5,5,6,6;4,4,5,5,6,6;7,7,8,8,9,9;7,7,8,8,9,9]
M = 6×6
1 1 2 2 3 3 1 1 2 2 3 3 4 4 5 5 6 6 4 4 5 5 6 6 7 7 8 8 9 9 7 7 8 8 9 9
A = reshape(permute(reshape(M,T,size(M,1)/T,T,[]),[1,3,2,4]),T,T,[]) % columnwise
A =
A(:,:,1) = 1 1 1 1 A(:,:,2) = 4 4 4 4 A(:,:,3) = 7 7 7 7 A(:,:,4) = 2 2 2 2 A(:,:,5) = 5 5 5 5 A(:,:,6) = 8 8 8 8 A(:,:,7) = 3 3 3 3 A(:,:,8) = 6 6 6 6 A(:,:,9) = 9 9 9 9
M = reshape(permute(reshape(A,T,T,size(M,1)/T,[]),[1,3,2,4]),size(M))
M = 6×6
1 1 2 2 3 3 1 1 2 2 3 3 4 4 5 5 6 6 4 4 5 5 6 6 7 7 8 8 9 9 7 7 8 8 9 9
And in case you want rowwise (the reverse is left as an exercise for the reader):
A = permute(reshape(M,T,size(M,1)/T,T,[]),[1,3,4,2]) % rowwise
A =
A(:,:,1,1) = 1 1 1 1 A(:,:,2,1) = 2 2 2 2 A(:,:,3,1) = 3 3 3 3 A(:,:,1,2) = 4 4 4 4 A(:,:,2,2) = 5 5 5 5 A(:,:,3,2) = 6 6 6 6 A(:,:,1,3) = 7 7 7 7 A(:,:,2,3) = 8 8 8 8 A(:,:,3,3) = 9 9 9 9
Note that RESHAPE is very fast (it just modifies some meta-data in memory), so calling RESHAPE multiple times has little effect on the efficiency. PERMUTE will be the main time consumer here, it will actually rearrange the data in memory.
Jannes
Jannes on 6 Apr 2022
Thank you very much for your quick reply! I could not try it yet, but I think now I understand the approach and the solution sounds logical.

Sign in to comment.

More Answers (0)

Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!