Addition of certain consecutive elements along column in a matrix.

5 views (last 30 days)
I have a matrix A, where only one '1' is present in a particular row.
A=[
0 0 0 0 1;
1 0 0 0 0;
1 0 0 0 0;
0 0 1 0 0;
0 0 0 0 1;
0 0 0 0 1;
0 0 0 0 1;
0 0 0 0 1;
0 0 1 0 0;
0 0 1 0 0;
0 0 0 0 1;
0 0 0 0 1]
Now I want to add all the consecutive '1' along columns whose out put will be B.
B[
0 0 0 0 1;
2 0 0 0 0;
0 0 1 0 0;
0 0 0 0 4;
0 0 2 0 0;
0 0 0 0 2]
  3 Comments
Jaladhar Mahato
Jaladhar Mahato on 11 Jan 2018
I have a very big matrix of A. Here each column represents a state of my interest and the rows are time. As You can see for a particular row (time) only one state is on. Now I want to know the length of time where a state is "on" and when it switches its state. Now after the switch how much time, it spent in that state. I think this is enough.
Jos (10584)
Jos (10584) on 11 Jan 2018
But why stores this in a matrix like B? Wouldn't your rather want the output to be like
5 1
1 2
3 1
5 4
3 2
5 2
Where the first column indicates the row where the sequence of 1's start, and the second column the number of 1's in the sequence? From this you can easily build the matrix B

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 11 Jan 2018
Edited: Guillaume on 11 Jan 2018
This should do it:
A=[
0 0 0 0 1;
1 0 0 0 0;
1 0 0 0 0;
0 0 1 0 0;
0 0 0 0 1;
0 0 0 0 1;
0 0 0 0 1;
0 0 0 0 1;
0 0 1 0 0;
0 0 1 0 0;
0 0 0 0 1;
0 0 0 0 1];
assert(all(sum(A, 2)) == 1), 'A must have one and only one 1 per row');
transitions = diff([zeros(1, size(A, 2)); A; zeros(1, size(A, 2))]); %identify starts (1) and ends (-1) of sequences in each column
[transrow, transcol] = find(transitions); %get location.
%Note that since find works columnwise, transx(1:2:end) is the start of sequence, and transy(2:2:end) is the end
seqlengths = transrow(2:2:end) - transrow(1:2:end); %length of sequences
B = zeros(size(A));
B(sub2ind(size(B), transrow(1:2:end), transcol(1:2:end))) = seqlengths; %put sequence length at start locations
B(~any(B, 2), :) = [] %and remove empty rows
edit: I agree with Jos that storing the result as a two column matrix of columnnumber length would make more sense. That is easily obtained with:
C = [transcol(1:2:end, seqlengths];
[~, order] = sort(transrow(1:2:end));
C = C(order, :)
without needing to build B.

More Answers (1)

Jos (10584)
Jos (10584) on 11 Jan 2018
if ~all(sum(A,2)==1)
error('invalid input!')
end
Z = zeros(1,size(A,2))
dA = diff([Z ; A ; Z], 1, 1).'
[C,r1] = find(dA == 1)
[~,r2] = find(dA == -1)
N = r2 - r1
% C and N hold all the information you need to create B
B = zeros(numel(C), size(A,2))
idx = sub2ind(size(B), 1:size(B,1), C(:).')
B(idx) = N

Categories

Find more on Data Type Conversion in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!