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

Thread Subject:
Shrinking Cell Arrays

Subject: Shrinking Cell Arrays

From: Mike

Date: 18 Feb, 2010 15:20:10

Message: 1 of 7

I am preallocating a cell array because MATLAB suggested it for greater efficiency. In the suggestion box there was this sentence:

"If you do not know the size of an array before the loop begins, preallocate it, and then if necessary, shrink it after the loop completes."

I have been searching for hours and I have not been able to find anything about shrinking the cell array. I tried checking the first element of each row starting at the end, but I can't make comparisons on cells to determine which row is the last with data. Can anyone help this MATLAB rookie?

Thank you.

Subject: Shrinking Cell Arrays

From: Jan Simon

Date: 18 Feb, 2010 15:31:02

Message: 2 of 7

Dear Mike!

> I am preallocating a cell array because MATLAB suggested it for greater efficiency. In the suggestion box there was this sentence:
>
> "If you do not know the size of an array before the loop begins, preallocate it, and then if necessary, shrink it after the loop completes."
>
> I have been searching for hours and I have not been able to find anything about shrinking the cell array. I tried checking the first element of each row starting at the end, but I can't make comparisons on cells to determine which row is the last with data. Can anyone help this MATLAB rookie?

It would be helpful if you post the number of dimensions of the used cell.

You can use the logical array:
  CELLFUN('isempty', C)

Or, assumed to be the easiest method, store the largest indices during the creation of the cell elements.

For more detailed answers, post your code.

Kind regards, Jan

Subject: Shrinking Cell Arrays

From: Sadik

Date: 18 Feb, 2010 15:32:02

Message: 3 of 7

Did you try converting your cell array into a matrix first, using cell2mat? Maybe that would help.

Best.

"Mike " <mimoran@wfubmc.edu> wrote in message <hljlr9$a96$1@fred.mathworks.com>...
> I am preallocating a cell array because MATLAB suggested it for greater efficiency. In the suggestion box there was this sentence:
>
> "If you do not know the size of an array before the loop begins, preallocate it, and then if necessary, shrink it after the loop completes."
>
> I have been searching for hours and I have not been able to find anything about shrinking the cell array. I tried checking the first element of each row starting at the end, but I can't make comparisons on cells to determine which row is the last with data. Can anyone help this MATLAB rookie?
>
> Thank you.

Subject: Shrinking Cell Arrays

From: Sadik

Date: 18 Feb, 2010 15:39:21

Message: 4 of 7

But you're saying there are gaps in the cell array, so cell2mat wouldn't work. I like Jan's solution.

Best.

"Sadik " <sadik.hava@gmail.com> wrote in message <hljmhi$pv8$1@fred.mathworks.com>...
> Did you try converting your cell array into a matrix first, using cell2mat? Maybe that would help.
>
> Best.
>
> "Mike " <mimoran@wfubmc.edu> wrote in message <hljlr9$a96$1@fred.mathworks.com>...
> > I am preallocating a cell array because MATLAB suggested it for greater efficiency. In the suggestion box there was this sentence:
> >
> > "If you do not know the size of an array before the loop begins, preallocate it, and then if necessary, shrink it after the loop completes."
> >
> > I have been searching for hours and I have not been able to find anything about shrinking the cell array. I tried checking the first element of each row starting at the end, but I can't make comparisons on cells to determine which row is the last with data. Can anyone help this MATLAB rookie?
> >
> > Thank you.

Subject: Shrinking Cell Arrays

From: Mike

Date: 18 Feb, 2010 16:33:21

Message: 5 of 7

HERE IS THE CODE:

%=================================================
values = cell(50, 4);

    % Loop through the events based on the number of colons in our input data
    for i = 1:numberOfColons
    
        individualEvent = substr(compressedEvents, startOfEvent, (endi(i) - startOfEvent - 1));
    
        % Assign the current : index to be the index of the beginning of the
        % next event in compressedEvents
        startOfEvent = endi(i);
    
        boxAndNeuron = substr(individualEvent, 0, 1);
    
        % Determine which box and neuron we are dealing with based on the
        % received character value
        switch boxAndNeuron
            case '*' % v-- Box 1 --v
                box = 1;
                neuron = 1;
            case '+'
                box = 1;
                neuron = 2;
            case '\'
                box = 1;
                neuron = 3;
            case '-'
                box = 1;
                neuron = 4;
            case '.' % v-- Box 2 --v
                box = 2;
                neuron = 1;
            case '/'
                box = 2;
                neuron = 2;
            case '0'
                box = 2;
                neuron = 3;
            case '1'
                box = 2;
                neuron = 4;
            case '2' % v-- Box 3 --v
                box = 3;
                neuron = 1;
            case '3'
                box = 3;
                neuron = 2;
            case '4'
                box = 3;
                neuron = 3;
            case '5'
                box = 3;
                neuron = 4;
            case '6' % v-- Box 4 --v
                box = 4;
                neuron = 1;
            case '7'
                box = 4;
                neuron = 2;
            case '8'
                box = 4;
                neuron = 3;
            case '9'
                box = 4;
                neuron = 4;
        end
    
        % Convert the character from substr into the ASCII equivalent decimal
        % and subtract 64 to get the proper channel number
        channel = ((substr(individualEvent, 1, 1))-0) - 64;
    
        % Break apart the retrieved timestamp into the integer and fraction
        % portion, convert them independently back to decimal from hexadecimal,
        % and then compute them back into a decimal timestamp
        eventLength = length(individualEvent);
    
        timeStampSubstring = substr(individualEvent, 2);
        [endInteger] = regexp(timeStampSubstring,'[.]'); % endInteger will contain the index of the decimal point skipping the first two characters
    
        integer = hex2dec(substr(timeStampSubstring, 0, (endInteger(1) - 1)));
        fraction = hex2dec(substr(timeStampSubstring, endInteger(1), (eventLength - endInteger(1))));
    
        timestamp = integer + (fraction / 1000000);
        
        
        % Add the values from this decompressed data to the cell array that
        % will be returned from this function.
        values(i,:) = { box channel neuron timestamp };
    end
%=================================================

Which goes back to

%==================================================
decompressedArray = decompress(dataReceived); % Unpack and decompress the data we received
                
        % Concatenate the new data on to the previous data
        dataArray = cat(1, dataArray, decompressedArray);
%==================================================

I need any empty rows at the end of the returned cell array to be removed before concatenating. I will look at teh current suggestions and see if they are what I need.

Thanks.

Subject: Shrinking Cell Arrays

From: Jan Simon

Date: 18 Feb, 2010 21:21:19

Message: 6 of 7

Dear Mike!

> values = cell(50, 4);
> for i = 1:numberOfColons
> individualEvent = substr(compressedEvents, startOfEvent, (endi(i) - startOfEvent - 1));
> startOfEvent = endi(i);
> boxAndNeuron = substr(individualEvent, 0, 1);
> switch boxAndNeuron
> case '*' % v-- Box 1 --v
> box = 1;
> neuron = 1;
> case '+'
> box = 1;
> neuron = 2;
> case '\'
> box = 1;
> neuron = 3;
> case '-'
> box = 1;
> neuron = 4;
> case '.' % v-- Box 2 --v
> box = 2;
> neuron = 1;
> case '/'
> box = 2;
> neuron = 2;
> case '0'
> box = 2;
> neuron = 3;
> case '1'
> box = 2;
> neuron = 4;
> case '2' % v-- Box 3 --v
> box = 3;
> neuron = 1;
> case '3'
> box = 3;
> neuron = 2;
> case '4'
> box = 3;
> neuron = 3;
> case '5'
> box = 3;
> neuron = 4;
> case '6' % v-- Box 4 --v
> box = 4;
> neuron = 1;
> case '7'
> box = 4;
> neuron = 2;
> case '8'
> box = 4;
> neuron = 3;
> case '9'
> box = 4;
> neuron = 4;
> end
>
> channel = ((substr(individualEvent, 1, 1))-0) - 64;
> eventLength = length(individualEvent);
> timeStampSubstring = substr(individualEvent, 2);
> [endInteger] = regexp(timeStampSubstring,'[.]');
> integer = hex2dec(substr(timeStampSubstring, 0, (endInteger(1) - 1)));
> fraction = hex2dec(substr(timeStampSubstring, endInteger(1), (eventLength - endInteger(1))));
> timestamp = integer + (fraction / 1000000);
> values(i,:) = { box channel neuron timestamp };
> end
>
> decompressedArray = decompress(dataReceived);
> dataArray = cat(1, dataArray, decompressedArray);

> I need any empty rows at the end of the returned cell array to be removed before concatenating. I will look at teh current suggestions and see if they are what I need.

-------------------------------
Hmm - the code is not easy to read.

??? If you assign exactly [numberOfColons] rows, why not just create this number of cells?! Then you do not have to crop them finally.
  values = cell(numberOfColons, 4);
  for i = 1:numberOfColons
  ...

> values(i,:) = { box channel neuron timestamp };
I assume this to be faster - but please test this by your own:
  values{i,1} = box;
  values{i,2} = channel;
  values{i,3} = neuron;
  values{i,4} = timestamp;

> channel = ((substr(individualEvent, 1, 1))-0) - 64;
What is SUBSTR?! It would be nice to explain what you are posting.
If "substr(individualEvent, 0, 1)" means "individualEvent(1)" I'd definitely recommend the later. However, it can be simplified to:
  channel = substr(individualEvent, 1, 1) - 64;

The switch expression is large. I'd expect something like this to be more efficient:
  index = findstr(substr(individualEvent, 0, 1), '*+\-./0123456789');
  box = ceil(index / 4);
  neuron = mod(index - 1, 4) + 1;

> fraction = hex2dec(substr(timeStampSubstring, endInteger(1), (eventLength - endInteger(1))));

I expect sscanf(substr(timeStampSubstring, endInteger(1), (eventLength - endInteger(1))), '%x') to be faster.

Kind regards, Jan

Subject: Shrinking Cell Arrays

From: Mike

Date: 19 Feb, 2010 17:01:06

Message: 7 of 7

It's often the simplest solution that gets overlooked. It never occurred to me that I know how many events I would have in my data based on the number of colons I found! I guess sometimes it takes a fresh pair of eyes.

Thank you for looking through my code and noticing that.

Regards,

Mike

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us