Search code examples
matlabfor-loopvectorizationcell-array

How can I use vertorisation to have a function normalize columns of a cell array iterating through different max values for each column?


I am trying to use vectorisation to have a function normalize values of a cell array throughout different max values for each column.

Suppose I have a cell array called holdArray,

holdArray =  {1   2   3   4   5   6
              7   8   9   10  11  12
              13  14  15  16  17  18
              19  20  21  22  23  24}

and suppose I have another cell array containing the max values of each column of holdArray called maxVal,

maxVal = {19   20   21   22   23   24}

I am trying to normalize the columns in holdArray using the values in maxVal, i.e every value in the first column in holdArray will be normalized using the first value in maxVal and so on.

I know I can easily do this using a for loop but because the arrays I will be working with will be very large I would much rather use vectorisation. currently I have done it this way where D is just an array to hold the normalized values D = cellfun(@(x)(x./maxVal(1,:)), holdArray, 'UniformOutput', false)

Which returns this output:

D = 

    [1x6 double]    [1x6 double]    [1x6 double]    [1x6 double]    [1x6 double]    [1x6 double]
    [1x6 double]    [1x6 double]    [1x6 double]    [1x6 double]    [1x6 double]    [1x6 double]
    [1x6 double]    [1x6 double]    [1x6 double]    [1x6 double]    [1x6 double]    [1x6 double]
    [1x6 double]    [1x6 double]    [1x6 double]    [1x6 double]    [1x6 double]    [1x6 double]

Meaning it normalises each value in the column across all the values in maxVal

Any explanation onto how to use vectorisation to get this would be appreciated.

Thanks


Solution

  • Not sure why you are using a cell for doubles? Use cell2mat to convert it to a matrix, then vectorisation is easy...

    holdArray =  {1   2   3   4   5   6
                  7   8   9   10  11  12
                  13  14  15  16  17  18
                  19  20  21  22  23  24};
    
    holdArray = cell2mat(holdArray); % Converts cell to matrix
    
    maxVal = {19   20   21   22   23   24};
    maxVal = cell2mat(maxVal);
    
    % Make matrix same size as holdArray but entire column is maxVal
    maxVal = repmat(maxVal, size(holdArray,1),1); 
    
    % Element-wise division to normalise
    holdArray = holdArray./maxVal;
    
    % ans =
    %
    %  [0.0526    0.1000    0.1429    0.1818    0.2174    0.2500
    %   0.3684    0.4000    0.4286    0.4545    0.4783    0.5000
    %   0.6842    0.7000    0.7143    0.7273    0.7391    0.7500
    %   1.0000    1.0000    1.0000    1.0000    1.0000    1.0000]
    
    % If you really want it back in a cell, you can use mat2cell
    holdArray = mat2Cell(holdArray, size(holdArray,1));
    

    Since max operates on columns anyway, you don't need cell/vector maxVal at all, and the entire code could be condensed to this:

    holdArray = {1   2  ... };  % abbreviated, use above definition
    holdArray = cell2mat(holdArray);
    holdArray = holdArray ./ repmat(max(holdArray), size(holdArray,1), 1); 
    holdArray = mat2Cell(holdArray, size(holdArray,1));