Reshape a 2D Matrix to 3D in a block/tile wise manner and back(!)
조회 수: 6 (최근 30일)
이전 댓글 표시
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.
댓글 수: 0
채택된 답변
Stephen23
2022년 4월 5일
편집: Stephen23
2022년 4월 7일
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]
A = reshape(permute(reshape(M,T,size(M,1)/T,T,[]),[1,3,2,4]),T,T,[])
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))
댓글 수: 4
Stephen23
2022년 4월 6일
편집: Stephen23
2022년 4월 7일
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]
A = reshape(permute(reshape(M,T,size(M,1)/T,T,[]),[1,3,2,4]),T,T,[]) % columnwise
M = reshape(permute(reshape(A,T,T,size(M,1)/T,[]),[1,3,2,4]),size(M))
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
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
2022년 4월 6일
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.
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Creating and Concatenating Matrices에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!