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.
Azzi Abdelmalek on 7 Jun 2013
Run this and check the results
Targets=[30 0 20 0 1]'
t = diff(b)
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.