0
votes

I have a 4D matrix (dims - x,y,z,t). I want to reshape it to a 1D cell array of length x*y*z where each element is a long vector of size t which captures all elements at each volume location (x,y,z). After that I need to reshape it back.

I thought of looping over the array to do it since I can't really find a built in function to do it.

Any insights will be super helpful! Thanks!

3

3 Answers

4
votes

See if this is that you want:

x = randn(2,3,4,5); % example data
x = reshape(x, [], size(x,4)); % collapse first three dimensions
x = mat2cell(x, ones(1,size(x,1)), size(x,2)); % split first dimension into cells
3
votes

Luis's answer is great for being semi-vectorized (mat2cell uses a loop). If what you desire is a cell array of size x*y*z where each element is t long, it's possible to use a loop over each volume location and extract the t elements that "temporally" occupy this spot in 4D. Make sure you squeeze out any singleton dimensions to get the resulting vector. This is something to consider if you wanted to go with the loop approach. Assuming your matrix is called A, try the following:

B = cell(size(A,1)*size(A,2)*size(A,3), 1);
count = 1;
for ii = 1 : size(A,1) 
    for jj = 1 : size(A,2)
        for kk = 1 : size(A,3)
            B{count} = squeeze(A(ii,jj,kk,:));
            count = count + 1;
        end
    end
end

To get this back into a 4D matrix form, you'd just apply the same logic but in reverse:

Ar = zeros(size(A));
count = 1;
for ii = 1 : size(A,1) 
    for jj = 1 : size(A,2)
        for kk = 1 : size(A,3)
            Ar(ii,jj,kk,:) = B{count};
            count = count + 1;
        end
    end
end
3
votes

Like Luis' solution, but simpler and more complete:

% Transform to cell
x = randn(2,3,4,5); % example data
y = reshape(x, [], size(x,4));
z = num2cell(y,2);

% transform back 
x = reshape(cat(1,z{:}), size(x));