Berk U.
Berk U.

Reputation: 7188

Effiicient ways to count a streak of consecutive integers in MATLAB

Say I have a vector containing only logical values, such as

V = [1 0 1 0 1 1 1 1 0 0]

I would like to write a function in MATLAB which returns a 'streak' vector S for V, where S(i) represents the number of consecutive 1s in V up to but not including V(i). For the example above, the streak vector would be

S = [0 1 0 1 0 1 2 3 4 0] 

Given that I have to do this for a very large matrix, I would very much appreciate any solution that is vectorized / efficient.

Upvotes: 3

Views: 1630

Answers (3)

Gunther Struyf
Gunther Struyf

Reputation: 11168

You could also do it completely vectorized with a couple intermediate steps:

V = [1 0 1 0 1 1 1 1 0 0];

Sall = cumsum(V);
stopidx = find(diff(V)==-1)+1;
V2=V;
V2(stopidx) = -Sall(stopidx)+[0 Sall(stopidx(1:end-1))];
S2 = cumsum(V2);

S = [0 S2(1:end-1)];

Afaik the only thing that can take a while is the find call; you can't use logical indexing everywhere and bypass the find call, because you need the absolute indices.

Upvotes: 1

bdecaf
bdecaf

Reputation: 4732

It's outside the box - but have you considered using text functions? Since strings are just vectors for Matlab it should be easy to use them.

Regexp contains some nice functions for finding repeated values.

Upvotes: 0

Roney Michael
Roney Michael

Reputation: 3994

This should do the trick:

S = zeros(size(V));
for i=2:length(V)
    if(V(i-1)==1)
        S(i) = 1 + S(i-1);
    end
end

The complexity is only O(n), which I guess should be good enough.

For your sample input:

V = [1 0 1 0 1 1 1 1 0 0];
S = zeros(size(V));
for i=2:length(V)
    if(V(i-1)==1)
        S(i) = 1 + S(i-1);
    end
end
display(V);
display(S);

The result would be:

V =

     1     0     1     0     1     1     1     1     0     0


S =

     0     1     0     1     0     1     2     3     4     0

Upvotes: 1

Related Questions