starting location of vector

i am using the code to find maximum zero span
g = [ 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 ]
pos1 = find(g==1);
zero_span = diff(pos1)-1;
max_zero_span = max(zero_span)
as from vector g we can see that maximum zero span is starting from location 3. how can i find this with the help of MATLAB.

 Accepted Answer

Guillaume
Guillaume on 5 May 2016
Edited: Guillaume on 5 May 2016
This is a variation on run length encoding, for which you'll find plenty of functions on the FileExchange.
In any case, it's trivial to do, if you diff your vector, you'll have -1 for transitions from 1 to 0, +1 for transitions from 0 to 1 and 0 elsewhere. The difference between find on the 1 and -1 will give you the lengths of the runs. To make sure that you find the start of a zero run that starts from the beginning of the vector, prepend it with a 1. Same for the end:
g = [ 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 ];
transitions = diff([1 g 1]);
runstarts = find(transitions == -1);
runends = find(transitions == 1);
%because of the 1 padding you're guaranteed there's always the same number of starts and ends
runlengths = runends - runstarts;
[maxlength, runindex] = max(runlengths);
fprintf('\nThe longest run has length %d, starting at index %d\n\n', maxlength, runstarts(runindex))

4 Comments

Actually, I don't want it by 1's padding.Because later on, I am doing binary addition so padding is not suitable.
I don't understand what you mean by " I don't want it by 1's padding". The padding I mention is only to find the transitions and is necessary for it work regardless of the location of the runs. It does not affect the original vector, so whatever you do afterward is not impacted.
Have you tried the code? Does it not do what you want?
If you don't pad the vector with 1s, you won't find the longest run in
g = [0 0 0 0 0 1 1 1 0 0 1]
%or
g = [1 0 0 1 1 1 0 0 0 0 0]
Note that your original code fails with these examples for this very reason.
actually in some cases i am using the
g = [ 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 ];
in such cases i am using end around zero span as well. like in this case max zero span is of length 11. if i do padding than it will change my result
Well your original code certainly didn't account for that. Padding or no padding. There are many ways to cope with this. Probably the simplest is to temporary rotate the vector so it always starts with 1:
g = [ 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 ];
shift = find(g, 1); %find 1st 1
transitions = diff([circshift(g, 1-shift, 2), 1]); %padding after still required.
runstarts = find(transitions == -1) + shift;
runends = find(transitions == 1) + shift; %note that runends may be greater than numel(g) if the run wraps around
runlengths = runends - runstarts;
[maxlength, runindex] = max(runlengths);
fprintf('\nThe longest run has length %d, starting at index %d\n\n', maxlength, runstarts(runindex))
Left as an exercise to the reader is coping with the special case where g is all zeros (which will make the circshift fail since shift will be empty)

Sign in to comment.

More Answers (4)

g = [ 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 ]
[~,~,ii]=unique(cumsum(g).*not(g))
d=accumarray(ii,(1:numel(ii))',[],@(x) {x});
dd=d(2:end);
[~,mx]=max(cellfun(@numel,dd));
indices=[min(dd{mx}) max(dd{mx})]

1 Comment

I want a simpler solution using for loop's. I can not use such complex statements. please

Sign in to comment.

This is the most simplest solution I came up with. Using the find function and subtract the positions from the next one.
g = [ 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 ];
pos = find(g == 1);
nloop = length(pos)-1;
maxspan = 0;
for i = 1:nloop
span = pos(i+1)-pos(i)-1
if span > maxspan
maxspan = span;
end
end
data = [ 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 ]
[b, n, ind] = RunLength(data);
ind = ind(b == 0);
[len, pos] = max(n(b == 0));
index = ind(pos); % index related to [data]
Image Analyst
Image Analyst on 5 May 2016
Edited: Image Analyst on 5 May 2016
I don't know how you get 3. There is not even a zero at index 3. I get 4 with 3 simple lines of code (not including comments) that you can use if you have the Image Processing Toolbox.
% Define sample data
g = [ 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 ]
% Get run lengths of the zero regions and their locations.
stats = regionprops(logical(~g), 'Area', 'PixelIdxList');
% Get the max length of all the zero regions
[maxRunLength, regionNumber] = max([stats.Area])
% Get the starting index of the longest zero region.
indexOfLongestRun = stats(regionNumber).PixelIdxList(1)
In the command window you will see
g =
1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1
maxRunLength =
9
regionNumber =
1
indexOfLongestRun =
4
If you happen to want to get all the lengths of all the zero regions you can do this:
allZeroRunLengths = [stats.Area]

Categories

Community Treasure Hunt

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

Start Hunting!