Doragan
Doragan

Reputation: 94

Efficient allocation of cell array in matlab

I have some which converts a cell array of strings into a cell array of characters.

Note. For a number of reasons, both the input (C) and the output (C_itemised) must be cell arrays.

The cell array of strings (C) is as follows:

>> C(1:10)

ans = 

't1416933446'
''
't1416933446'
''
't1416933446'
''
't1416933446'
''
't1416933446'
''

I have only shown a portion of the array here. In reality it is ~28,000 rows in length.

I have some code which does this, although it is very inefficient. The cellstr function takes up 72% of the code's time, as it is currently called thousands of times. The code is as follows:

C_itemised=cell(length(C),500);
for i=3:length(C)
    temp=char(C{i});

    for j=1:length(temp)
        C(i-2,j)=cellstr(temp(j));
    end
end

I have a feeling that some minor modifications could take out the inner loop, thus cutting down the overall running time substantially. I have tried a number of ways to do this, but I think I keep getting confused about whether to use {} or (), and haven't been able to find anything online that can help me. Can anyone see a way to make the code more efficient?

Please also note that this function is used in conjunction with other functions, and does work, although it is running slower than would be ideal. Therefore, I do not wish to change the format of C_itemised.

EDIT: (A sample of) the output of my current function is:

C_itemised(1,1:12)

ans = 

Columns 1 through 12

't'    '1'    '4'    '1'    '6'    '9'    '3'    '3'    '4'    '4'    '6'    []

Upvotes: 3

Views: 123

Answers (1)

rayryeng
rayryeng

Reputation: 104503

One thing I can suggest is to use the undocumented function sprintfc. This function is hidden from normal use in MATLAB, but it is used internally with a variety of other functions. Mainly, if you tried doing help sprintfc, it'll say that there's no function found! It's cool to sniff around the source sometimes!

How sprintfc works is that you provide it a formatting string, much like printf, and the data you want printed. It will take each individual element in the data and place them into individual cell arrays. As an example, supposing I had a string D = 'abcdefg';, if we did:

out = sprintfc('%c', D);

We get:

>> celldisp(out)

out{1} =

a


out{2} =

b


out{3} =

c


out{4} =

d


out{5} =

e


out{6} =

f


out{7} =

g

As such, it takes each element in your string and places them as individual characters serving as individual elements in a new cell array. The %c formatting string means that we want to print a single character per element. Check out the link to Undocumented MATLAB that I posted above if you want to learn more!


Therefore, try simplifying your loop to this:

C_itemised=cell(length(C));
for i=1:length(C)
    C_itemised{i} = sprintfc('%c', C{i});
end

C_itemised will be a cell array, where each element C_itemised{i} is another cell array, with each element in this cell array being a single character that is composed of the string C{i}.


Minor Note

You said you were confused about {} and () in MATLAB for cells. {} is used to access individual elements inside the cell. So doing C{1} for example will grab whatever is stored in the first element of the cell array. () is used to slice and index into the cells. For example, if you wanted to make another cell array that is a subset of the current one, you would do something like C(1:3). This will create a three element cell array which is composed of the first three cells in C.

Upvotes: 3

Related Questions