Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

To resolve issues starting MATLAB on Mac OS X 10.10 (Yosemite) visit: http://www.mathworks.com/matlabcentral/answers/159016

Elegant way to replicate a vector, placing it into each cell in a cell array

Asked by Andrew on 7 Jun 2011

Hi,

I would like to be able to create a cell array, with each cell containing the same 1 by 3 vector that I specify. For example, suppose that I have the following:

A=[1 2 3];

and suppose that I want to obtain the following:

mycell={[1 2 3],[1 2 3],[1 2 3];[1 2 3],[1 2 3],[1 2 3]};

Is there an elegant way to do this? It is as if I would like a sort of "repcell" function, similar to the repmat function. I am not sure if one exists, though.

I could do this:

tic
mycell=cell(2,3);
for i=1:1:size(mycell,1)
    for j=1:1:size(mycell,2)
        mycell{i,j}=A;
    end
end
toc

and I get "Elapsed time is 0.000956 seconds." Or I could do:

tic
myarray=repmat(A,2,3);
mycell=mat2cell(myarray,[1 1],[3 3 3]);
toc

and I get "Elapsed time is 0.029993 seconds."

Either one of these seems like it will work fine for me, even when I want my cell array to be very large. Still, I am wondering, is there a more elegant way to do this (even in terms of code readability)?

Thank you very much for your time.

Andrew DeYoung

Carnegie Mellon University

0 Comments

Andrew

Products

3 Answers

Answer by Matt Fig on 7 Jun 2011
Accepted answer
mycell = repmat({A},2,3)

Your MAT2CELL method properly pre-allocates a cell array, in the sense James Tursa is talking about. It can be written as a one-liner:

mycell = mat2cell(repmat(A,M,N),ones(1,M),ones(1,N)*length(A));

So does this, and it is much faster than the MAT2CELL method:

mycell = cellfun(@double,repmat({A},M,N),'Un',0);

1 Comment

Andrew on 7 Jun 2011

Thank you for your time!

Matt Fig
Answer by Fangjun Jiang on 7 Jun 2011
A=[1 2 3];
mycell=cell(2,3);
mycell(:)={A};

4 Comments

Fangjun Jiang on 7 Jun 2011

My guess would be that Andrew wants to initialize the cell array, like pre-allocate memory. In that case, what will be the best approach? Or is it even necessary or possible to pre-allocate a cell array.

Andrew on 7 Jun 2011

Thanks! Yes, I would like to initialize the cell array. Downstream, I will need to be able to alter the contents of the cells, so perhaps the shared reference copy to A is not the best. Thank you for your time!

James Tursa on 7 Jun 2011

@Andrew: I am still not clear what you are doing downstream with mycell. Are you *replacing* cells with a completely different variables, or are you replacing only certain *elements* of the cell contents with different value? i.e., are you doing something like:

mycell{k} = something_else

Or are you doing something like:

mycell{k}(m) = some_value

If it is the former, then pre-allocating mycell with variable contents ala repmat and the like makes no sense whatsoever, and you would be better off pre-allocating an empty cell array and then filling the contents downstream as you go.

Fangjun Jiang
Answer by Fangjun Jiang on 7 Jun 2011

I am not trying to win a competition but here is the example. It looks like it will be faster to pre-allocate using hidden reference than using the repmat().

>> clear all;
A=1:3;
tic;
mycell=cell(10000,1);
mycell(:)={A};
for k=length(mycell)
    mycell{k}=rand(1,3);
end
toc;
clear all;
A=1:3;
tic;
mycell=repmat({A},10000,1);
for k=length(mycell)
    mycell{k}=rand(1,3);
end
toc;
Elapsed time is 0.003057 seconds.
Elapsed time is 0.012636 seconds.

And it is still the case if the loop is mycell{k}(2)=rand;

10 Comments

Sean de Wolski on 8 Jun 2011

http://www.mathworks.com/matlabcentral/newsreader/view_thread/292183

cell array preallocation thread on CSSM.

James Tursa on 8 Jun 2011

The data storage layout for a cell array is *exactly* the same as the data storage layout for all other variables ... the data is contiguous in memory. But the "data" for a cell array in this context is variable pointers. So, yes, the actual content of the cells themselves are not in general contiguous in memory (the variables being pointed to are not contiguous), but the *pointers* to these variables, which is what is physically stored in the cell array data area, *are* contiguous in memory. It is *that* memory that gets constantly copied and re-copied in a loop that increases the size of the cell array if you don't pre-allocate the cell array. The L in your above code has nothing to do with this since it only affects the cell variables and not the physical cell array data area. e.g., to see the effect isolated:

n = 100000;
A = 1:3;

clear mycell1
tic
mycell1 = cell(1,n); % pre-allocated
for k=1:n
mycell1{k} = A; % not growing in a loop
end
toc

clear mycell2
tic
for k=1:n
mycell2{k} = A; % growing in a loop
end
toc

isequal(mycell1,mycell2)

Elapsed time is 0.049412 seconds.
Elapsed time is 27.087694 seconds.
ans =
1

Fangjun Jiang on 8 Jun 2011

Thank you, James! Your comments have enlightened me. And Thank you Sean for the link. I enjoyed reading it.

Fangjun Jiang

Contact us