Can matlab return the interval of 1's and 0's?
2 views (last 30 days)
Show older comments
Dylan Mecca
on 28 Feb 2018
Commented: Walter Roberson
on 1 Mar 2018
Hi everyone,
I'm looking to see if matlab has the capability to return an interval. I know I can make matlab create a vector or matrix of 1's and 0's interval notation, but can it do this backwards? Can it take a vector or matrix and return the interval where 1's and 0's exist? I've attached a file for reference.
If this is possible, I can't seem to find a command that does this, so if anybody knows of anything please comment; your help is much appreciated!!
4 Comments
Accepted Answer
Jos (10584)
on 28 Feb 2018
Given your replies to the comments, you could store the result in a N-by-2 matrix, where the first row would hold the start indices of the sequences of 1's and the second row holds the last indices of these sequences. Each column of this matrix represents a sequence.
z = [1 1 0 0 0 1 1 1 0 0]
dz = diff([0 z 0])
M = [find(dz==1) ; find(dz==-1)-1]
More Answers (1)
Walter Roberson
on 28 Feb 2018
Note that in the below code, all calculations ignore the 'z' header at the beginning of the file. If you need the 'z' to be counted, then add 1 if you know for sure that there was only a single header line. If you need to deduce the number of header lines and add them to the count then that is possible.
data = dlmread('returninterval.csv','',1,0); %ignore header line!
data = data(:).'; %need row vector
starts = strfind([0 data], [0 1]);
stops = strfind([data 0], [1 0]);
Now starts is a vector of indices at which a group of 1's begins, and stops is a vector of indices at which the group ends (not the index of the 0 that follows.)
You can format this any way you want, but [starts(:), stops(:)] as a numeric array probably makes most sense.
2 Comments
Walter Roberson
on 1 Mar 2018
Here, data is a row vector of values that are all 0 or 1. strfind([data 0], [1 0]) adds a 0 to the end of the row vector, and then asks for the indices of all of the locations that match [1 0].
Anywhere in the inside of the data vector that has a series of 1's, has a 0 after it, so by knowing the position of the [1 0] pairs, you know the location of the ends of the series of 1's. The reason you need to add a 0 to the end first before this matching is that the original data might end in a series of 1's, and if you tried to match that directly looking for [1 0] transitions then you would not find that final series. But if you artificially pad with 0, then data that originally ended with 1 would end [1 0] in the padded version and that [1 0] would be matched by the [1 0] search pattern. If the original data ended with 0, then the padded version would end with [0 0] and would not be matched by the [1 0] search pattern, which is fine because in that case the last element is not the end of a series of 1s. So padding with a final 0 does not hurt and allows you to detect the case where the original data ended with 1.
The logic is quite similar for the line before that where [0 data] is matched for [0 1]: the pre-padding with 0 is there so you can detect the case where the data began with 1 so you know the proper beginning of the series of 1s.
To write this another way: a series of 1's in data either
- has a 0 immediately before the series; or
- starts at the very beginning of the data
- has a 0 immediately after the series; or
- ends at the very end of the data
At first that might look like you need to do four tests, one for series that start and end "inside" somewhere, and one for series that start at the beginning and end "inside" somewhere, and one for series that start "inside" and end "inside" somewhere, and one for the case where the entire range is all 1's, but with this small trick of putting a 0 before and a 0 after, you can handle everything without needing to explicitly take care of special cases.
See Also
Categories
Find more on Logical 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!