Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert cell array of cell arrays to matrix of matrices

Tags:

matlab

I can convert a cell array of matrices to matrix:

>> C={[1,1]; [2,2]; [3,3]};
>> cell2mat(C)
ans =
     1     1
     2     2
     3     3

This is OK. But, I want to convert a cell array including other cell arrays to a matrix:

>> C={{1,1}; {2,2}; {3,3}};    
>> cell2mat(C)
Error using cell2mat (line 53)
Cannot support cell arrays containing cell arrays or objects.

So, desired output is:

>> mycell2mat({{1,1}; {2,2}; {3,3}})
ans =
     1     1
     2     2
     3     3

How to do this?

Edit:

I want to do same thing for multidimensional ones also:

>> mycell2mat({{1,1;1,1}; {2,2;2,2}; {3,3;3,3}})
ans(:,:,1) =

     1     1
     1     1

ans(:,:,2) =

     2     2
     2     2

ans(:,:,3) =

     3     3
     3     3
like image 908
mmdemirbas Avatar asked Nov 24 '12 10:11

mmdemirbas


1 Answers

To be honest, I never liked cell2mat for being slow, so I've come up an alternative solution using comma-separated lists instead!

Transform a cell array of vectors

This is fairly simple, just use the colon operator and concatenate all vectors vertically:

C = {[1,1]; [2,2]; [3,3]};
A = vertcat(C{:})

and so we get:

A =
    1   1
    2   2
    3   3

Transform a cell array of cell arrays

This is a bit trickier. Since it's a cell array of cell arrays, we'll have to obtain a vector of all elements by a double use of the colon and horzcat, and then reshape it into the desired matrix.

C = {{1,1}; {2,2}; {3,3}};
V = [size(C{1}), 1]; V(find(V == 1, 1)) = numel(C);
A = reshape([horzcat(C{:}){:}], V)

and so we get:

A =
    1   1
    2   2
    3   3

The manipulation of V makes sure that A is reshaped correctly without having to specify the output dimensions explicitly (unfortunately, I didn't find a one liner for this). This also works for multi-dimensional cell arrays as well:

C = {{1, 1; 1, 1}; {2, 2; 2, 2}; {3, 3; 3, 3}};
V = [size(C{1}), 1]; V(find(V == 1, 1)) = numel(C);
A = reshape([horzcat(C{:}){:}], V)

A(:,:,1) = 
    1   1
    1   1

A(:,:,2) =   
    2   2
    2   2

A(:,:,3) =    
    3   3
    3   3

P.S

I think the correct result for the last example should be a 6-by-2 matrix instead of a 2-by-2-by-3. However, that is not what you requested, so it's off-topic.

like image 154
Eitan T Avatar answered Sep 19 '22 14:09

Eitan T