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

7 visualizzazioni (ultimi 30 giorni)
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.

Risposta accettata

Stephen23
Stephen23 il 5 Apr 2022
Modificato: Stephen23 il 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 Commenti
Stephen23
Stephen23 il 6 Apr 2022
Modificato: Stephen23 il 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 il 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.

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Creating and Concatenating Matrices in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by