Ferde
Ferde

Reputation: 25

Count length and frequency of island of consecutive numbers

I have a sequence of ones and zeros and I would like to count how often islands of consecutive ones appear.

Given: S = [1 1 0 0 1 1 1 0 1 0 0 1 0 0 0 1 1 0 0 1 0 0 1 1 0 1]

By counting the islands of consecutive ones I mean this: R = [4 3 1] …because there are four single ones, three double ones and a single triplet of ones.

So that when multiplied by the length of the islands [1 2 3].

[4 3 1] * [1 2 3]’ = 13

Which corresponds to sum(S), because there are thirteen ones.

I hope to vectorize the solution rather than loop something.

I came up with something like: R = histcounts(diff( [0 (find( ~ (S > 0) ) ) numel(S)+1] ))

But the result does not make much sense. It counts too many triplets. All pieces of code I find on the internet revolve around diff([0 something numel(S)]) but the questions are always slightly different and don’t really help me

Thankful for any advice!

Upvotes: 0

Views: 77

Answers (2)

obchardon
obchardon

Reputation: 10792

You could also obtain the same result with:

x = find(S==1)-(1:sum(S)) %give a specific value to each group of 1
h = histc(x,x)            %compute the length of each group, you can also use histc(x,unique(x))
r = histc(h,1:max(h))     %count the occurence of each length   

Result:

r = 
 4,3,1

Upvotes: 1

Euan Smith
Euan Smith

Reputation: 2192

The following should do it. Hopefully the comments are clear.

S = [1 1 0 0 1 1 1 0 1 0 0 1 0 0 0 1 1 0 0 1 0 0 1 1 0 1];
% use diff to find the rising and falling edges, padding the start and end with 0
edges = diff([0,S,0]); 
% get a list of the rising edges
rising = find(edges==1);
% and falling edges
falling = find(edges==-1);
% and thereby get the lengths of all the runs
SRuns = falling - rising;
% The longest run
maxRun = max(SRuns);
% Finally make a histogram, putting the bin centres 
R = hist(SRuns,1:maxRun);

Upvotes: 2

Related Questions