How to calculate both length and indices of a series of a certain value in a vector

2 views (last 30 days)
As the question heading says I have a problem where I have a vector, and I need to know the length and the indices of the longest series of zeros in that vector. I googled the problem before and found this:
t = diff([false;Targets==0;false]);
p = find(t==1);
q = find(t==-1);
[maxlen,ix] = max(q-p);
first = p(ix);
last = q(ix)-1;
where t is the dataset. This works really well as far as I can tell. However, I do not quite understand the code. And I was hoping that someone could explain a bit what it actually does. In particular it's the first line that I don't quite understand what it does. t = diff([false;t==0;false]); that is. There's nothing in the documentation about having a vector (especially using logic) as input for the diff function. So what exactly does that line do? I suppose the following two lines (and the rest too) will be obvious when I know what the first line does.

Answers (3)

Azzi Abdelmalek
Azzi Abdelmalek on 7 Jun 2013
Run this and check the results
Targets=[30 0 20 0 1]'
a=Targets==0
b=[false;a;false]
t = diff(b)

Angus
Angus on 7 Jun 2013
From the docs:
***********
Y = diff(X) calculates differences between adjacent elements of X.
If X is a vector, then diff(X) returns a vector, one element shorter than X, of differences between adjacent elements:
[X(2)-X(1) X(3)-X(2) ... X(n)-X(n-1)] If X is a matrix, then diff(X) returns a matrix of row differences:
[X(2:m,:)-X(1:m-1,:)] In general, diff(X) returns the differences calculated along the first non-singleton (size(X,dim) > 1) dimension of X.
Y = diff(X,n) applies diff recursively n times, resulting in the nth difference. Thus, diff(X,2) is the same as diff(diff(X)).
Y = diff(X,n,dim) is the nth difference function calculated along the dimension specified by scalar dim. If order n equals or exceeds the length of dimension dim, diff returns an empty array.
************
So in your case:
t==0 converts your vector to logical 0/1 (logical 1 identifies a zero in your vector)
[false;t==0;false] vertically concatenates the, now, logical vector with an extra logical 0 on each end to pad it.
diff([false;t==0;false]) will return a new vector that effectively uses '1' to identify the start of a series of zeros and '-1' as the end of the series.
I think the remainder of the code makes sense after that.

Christian
Christian on 7 Jun 2013
Thanks so much for the help. The explanation was really helpful and the example made it very easy to grasp. You're both awesome!

Community Treasure Hunt

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

Start Hunting!