Search code examples
matlabmatrixoctavevectorizationcell-array

Extracting portions of matrix into cell array


I have a pretty large matrix M and I am only interested in a few of the columns. I have a boolean vector V where a value of 1 represents a column that is of interest. Example:

      -1 -1 -1  7  7 -1 -1 -1  7  7  7
M  =  -1 -1  7  7  7 -1 -1  7  7  7  7
      -1 -1  7  7  7 -1 -1 -1  7  7 -1

V  =   0  0  1  1  1  0  0  1  1  1  1

If multiple adjacent values of V are all 1, then I want the corresponding columns of M to be extracted into another matrix. Here's an example, using the matrices from before.

      -1  7  7             -1  7  7  7
M1  =  7  7  7       M2  =  7  7  7  7
       7  7  7             -1  7  7 -1

How might I do this efficiently? I would like all these portions of the matrix M to be stored in a cell array, or at least have an efficient way to generate them one after the other. Currently I'm doing this in a while loop and it is not as efficient as I'd like it to be.

(Note that my examples only include the values -1 and 7 just for clarity; this isn't the actual data I use.)


Solution

  • You can utilize the diff function for this, to break your V vector into blocks

    % find where block differences exist
    diffs = diff(V);
    % move start index one value forward, as first value in
    % diff represents diff between first and second in original vector
    startPoints = find(diffs == 1) + 1;
    endPoints = find(diffs == -1);
    
    % if the first block begins with the first element diff won't have
    % found start
    if V(1) == 1
        startPoints = [1 startPoints];
    end
    
    % if last block lasts until the end of the array, diff won't have found end
    if length(startPoints) > length(endPoints)
        endPoints(end+1) = length(V);
    end
    
    % subset original matrix into cell array with indices
    results = cell(size(startPoints));
    for c = 1:length(results)
        results{c} = M(:,startPoints(c):endPoints(c));
    end