Clear Filters
Clear Filters

Can matlab return the interval of 1's and 0's?

4 views (last 30 days)
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
Dylan Mecca
Dylan Mecca on 28 Feb 2018
Jos: In your small example provided, I'd like matlabe to return the interval where 1's exist, like so: (1,2)U(6,8). I understand that the union notation wouldn't really make sense. I'm open to hear points for things that matlab is capable of? Eventually, I want to use this tool to do other matlab operations, so I'm not picky about format as long as matlab can read it.
Dylan Mecca
Dylan Mecca on 28 Feb 2018
Walter Roberson: I'm not sure which would be better out of a numeric form or a string like what you'be mentioned. I put this post up to see what possiblitites are out there, so whatever you may have in mind is helpful!

Sign in to comment.

Accepted Answer

Jos (10584)
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
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
Dylan Mecca
Dylan Mecca on 1 Mar 2018
Can you explain what the format is when you use strfind([ data 0],[ 1 0])? I'm not sure what that is representing exactly.
Walter Roberson
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
  1. has a 0 immediately before the series; or
  2. starts at the very beginning of the data
  3. has a 0 immediately after the series; or
  4. 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.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!