MATLAB: How to compute blocks of ones in a row

blocksonesrow

Dear All,
I have this matrix.
P=[1 0 1 1 0 0 1 1 1
0 0 1 0 1 1 0 0 0];
I need to accumulate the ones numbers but as blocks of ones with the length of the block, here I have in the first row 3 blocks 1 , 1 1 , 1 1 1 , so the sum is 1+1+1 for the blocks and 2 for the length 1 1 and 3 for 1 1 1 so
sum=1+1+1+2+3
in the second row
sum=1+1+2
I wrote this
ind =strfind([0, P(1,:)],[0 1])
or
ind =find (diff([0 P(1,:)])==1)
it gives me the number of blocks but not the length of every block. I need to write the formula but is rather confuse. could anybody help me please
regards,
Imola

Best Answer

  • A simple way to get the lengths and number of blocks:
    P = [1 0 1 1 0 0 1 1 1];
    transitions = diff([0 P 0]);
    %transitions is 1 when going from 0 to 1 and -1 when going from 1 to 0.
    %because 0 is added before and after, the first transition is always 0 to 1 and last always 1 to 0
    %so there's always the same numbers of 1 and -1 in the diff
    numblocks = sum(transitions == 1) %or sum(transitions == -1)
    blocklengths = find(transitions == -1) - find(transitions == 1)
    To operate on a whole matrix at once is a bit trickier:
    P = [1 0 1 1 0 0 1 1 1
    0 0 1 0 1 1 0 0 0];
    transitions = diff([zeros(size(P, 1), 1) P zeros(size(P, 1), 1)], [], 2);
    [starts, rows] = find(transitions' == 1);
    [ends, ~] = find(transitions' == -1);
    blocklengths = ends - starts;
    sumlengthsbyrow = accumarray(rows, blocklengths, [size(P, 1) 1])
    numblocksbyrow = accumarray(rows, 1, [size(P, 1) 1])
    totalsumbyrow = sumlengthsbyrow + numblocksbyrow
    If you don't want to include the blocks of length 1 in sumlengthsbyrow:
    sumlengthsbyrow = accumarray(rows(blocklengths > 1), blocklengths(blocklengths > 1), [size(P, 1) 1])