saastn
saastn

Reputation: 6015

How to reshape multi-dimensional matrix to 2-d and vice versa?

I have this function f that takes an n x dx matrix and returns an n x dy matrix. Now I have an n1 x dx x n2, so I need to reshape it to an n1*n2 x dx and then reshape the results back again to n1 x dy x n2. This is my code:

function main
n1 = 4;
n2 = 5;
dx = 2;
dy = 3;
x = ones(n1, dx);
x = bsxfun(@times, permute(1:n2, [1, 3, 2]), x)
x2d = reshape(permute(x, [1 3 2]), n1*n2, dx)
y2d = f(x2d)
y = permute(reshape(y2d', dy, n1, n2), [2 1 3])

%%
% x = cat(4, x, x+3)

end

function y = f(x)
y = [x, sum(x, 2)];
end

Well, problem begins where I need higher dimensions of samples. I'm really stuck with 4-dimensional matrices, like cat(4, x, x+n2). So is there a general solution that reshapes these:

n1 x dx x n2 x ... x nm -> (n1*n2*...*nm) x dx
(n1*n2*...*nm) x dy     -> n1 x dy x n2 x ... x nm

Upvotes: 2

Views: 910

Answers (2)

You just have to permute the second dimension and then do a reshape, and vice versa:

% assume size(arr) is [n1, dx, n2, n3, ..., nm]
permuted = permute(arr, [1, 3:ndims(arr), 2]);  % [n1, n2, n3, ..., nm, dx]
final = reshape(permuted, [], size(permuted, ndims(permuted)));

And for the reverse transform:

% assume size(arr) is [n1*n2*n3*...*nm, dy]
% and you have to know new_size = [n1, n2, n3, ..., nm]
% and watch out for dy == 1 case: trailing singleton is removed
reshaped = reshape(arr, [new_size, size(arr, numel(new_size)+1)]);  % [n1, n2, n3, ..., nm, dy]
final = permute(reshaped, [1, numel(new_size)+1, 2:numel(new_size)]);

You might have to watch out with edge cases with few dimensions.

Upvotes: 3

rahnema1
rahnema1

Reputation: 15837

Instead of performing multiple reshapes and permutes you can redefine f so it can take a n-dimensional array.

function y = f(x)
    y = cat(2,x,sum(x,2));
end

Upvotes: 1

Related Questions