Vanush Vee
Vanush Vee

Reputation: 454

Finding alternating sequences in MATLAB

I have a vector like:

x = [0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 2 1 2 1 2 1 2 1 2 1 2 1 2 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1]

How can I grab the start and end index of the alternating sequence? (i.e. the 1's and 2's)

Upvotes: 2

Views: 491

Answers (2)

Jonas
Jonas

Reputation: 74940

If you know you have only one sequence, and it's always [1 2...1 2], you can simply use strfind

x = [0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 2 1 2 1 2 1 2 1 2 1 2 1 2 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1];

idx = strfind(x, [1 2]);

start = idx(1);
end = idx(end)+1;

If there may be multiple occurrences, or if it's not always 1-2, or if the sequence isn't complete (e.g. 1 2 1, instead of 1 2 1 2), you can use diff instead:

dx = diff(x);
alt = dx(2:end)==-dx(1:end-1) & dx(1:end-1)~=0;

starts = find(diff(alt)>0) + 1;
ends = find(diff(alt)<0) + 2;

Upvotes: 1

mathematical.coffee
mathematical.coffee

Reputation: 56955

I think this is a cool method, though numerical/array methods would be faster :P You could use regex!

% convert into a space-separated string
% (surely there's a better way than converting to cell array first?)
str = strcat({num2str(x)})
% for some reason all elements are separated by more than one space, convert
%  so they're separated by a single space
str = regexprep(str,' +',' ')

% find start & end indices (into str) alternating sequences
[s e]=regexp(str,'\<([^ ]+) ((?!\1)[^ ]+)(?: \1 \2)+(?: \1)?\>'),'start','end')
% convert these indices into indices into `x`
% (at the moment s & e include spaces)
s = (cell2mat(s)+1)/2
e = (cell2mat(e)+1)/2

% run i is at x( s(i):e(i) )

Upvotes: 1

Related Questions