Dynamically update cell without clearing previous content?

Hi all,
I'd like to dynamically update cell content and size, without clearing the previous cell content. Check the following code:
clear; clc;
nr = 1;
for i = 1:5
a = cell(1, nr);
a{:, i} = {nr};
nr = nr + 1;
end
,
>> a
a =
[] [] [] [] {1x1 cell}
>> a{5}
ans =
[5]
Imagine I do not know how many iterations I will do, meaning cell size of 'a' needs to be dynamically updated with the number of iterations (which is why I use a = cell(1, nr) in the loop). However, after each iteration, content of 'a' is cleared, so I get only the last cell element of 'a'. But what I want is:
>> a
a =
{1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell}
>> [a{:}]
ans =
[1] [2] [3] [4] [5]
I cannot move a = cell(1, nr) out of the for loop because in my real work I do not know how many iterations I will do. Any ideas? Thanks!

5 Comments

a = cell(1, nr)
is what is causing you to only have the last result - you keep recreating your cell array and throwing away the previous one.
You can concatenate e.g.
a = [a, someNewCell];
or better, if you can estimate an upper bound on your number of iterations create a cell array of that size first and then just assign to it and delete any empty cells at the end. Dynamically growing an array is slow and especially a cell array. Everything involving cell arrays tends to be slow.
Hi Adam,
Thanks, I think concatenation is the solution, although 'a' now changes size on every iteration.
Problem is I cannot estimate an upper bound of iteration number. In my real work it is a while loop, depending on the threshold I set the number of iterations can be very large or small.
Well, it can be a dynamically calculated size, it doesn't have to be a hard-coded upper bound.
If the size is dynamically calculated, why would I need to delete any empty cells at the end then?
I mean the upper bound estimate. Based on knowledge of your algorithm you should be able to come up with some calculation that at least estimates the maximum size. If your algorithm can potentially run to infinity then that is a problem in itself.
Obviously the upper bound will leave lots of empty cells in a realistic run though.

Sign in to comment.

 Accepted Answer

solution: 'a' can be dynamically updated without special treatment:
clear; clc;
nr = 1;
a = cell(1);
for i = 1:5
a{i} = {nr};
nr = nr + 1;
end

3 Comments

But a is no longer a cell - it's a cell array. You're not updating a particular cell. You're changing a by adding cells. You're growing a cell array rather than updating a cell. http://matlab.wikia.com/wiki/FAQ#What_is_a_cell_array.3F I guess it's just semantics but sometime slight differences in wording mean different things.
Yes, it is growing a cell array, not a cell, I should be more careful. Indeed what I wanted was to throw matrices with different size into a cell array.
This cell array growing process, is it slow? MATLAB does not ask me to pre-allocate memory for it but I guess as it dynamically grows, it's inefficient because of no pre-allocation?
I'm not sure how much preallocation would help, because it doesn't know the size, unless you made a guess. Allocating a bunch of empty cells with the cell() function would not help, I don't think. But maybe if you could preallocate cells with some array in them. Anyway, cells are very slow and inefficient and memory hogs but by their nature. Just run "whos" on a cell array and a table or double containing the very same numbers and you'll find the cell array can be many times larger.
rows = 2000;
m = rand(rows);
whos m
s = 2;
d = s * ones(rows/s, 1);
ca = mat2cell(m, d, d);
whos ca
In the above example, the double array is 32 MB while the cell array with the same numbers is 144 MB.

Sign in to comment.

More Answers (0)

Categories

Tags

Asked:

on 15 Jun 2017

Commented:

on 15 Jun 2017

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!