how to find indices that fulfil a certain criteria

2 views (last 30 days)
Lets say I want to write a script and the input is the following vector:
vector = [1 1 1 1 3 3 3 9 9 9 9 2 2 1 1 1 2 7 9 7 2 1 1 1]
I want the result to be a new vector that contain the indices [12 21] (the two 2's in bold and italic). The script should chose these indices because they are the first to follow index 7 and 17 (in bold) and at the same time have a value of that particular index +/- one... I hope it make sense and that it is doable. Thanks Michael

Accepted Answer

Iain
Iain on 17 Sep 2014
after_7 = 1:numel(vector) > 7;
after_17= 1:numel(vector) > 17;
twos_after_7 = vector == 2 & after_7;
twos_after_17 = vector == 2 & after_17;
output = find(twos_after_7,1,'first');
output(2) = find(twos_after_17,1,'first');
  2 Comments
Michael Clausen
Michael Clausen on 17 Sep 2014
Thank you Lain, I should probably specify that the vector I included in my question is an example. In reality I have very large data sets and is interested in a script that use the data and the vector with indexes I already have (here exemplified by 7 and 17) to generate a new vector with the indexes exemplified as 12 and 21.
In other words it should be more general (nor necessarily 7 and 17) and it should select indexes for data points that fulfil the +/- one criteria. If the vector instead was:
vector = [1 1 1 1 3 3 3 9 9 9 9 3.5 2 1 1 1 2 7 9 7 3.5 1 1 1]
it should come up with 12 and 22.. Do you think this is possible? Thank you very much
Iain
Iain on 17 Sep 2014
Edited: Iain on 17 Sep 2014
Ok... rereading it...
indexes = [7 17 64 504 3020]; %or whatever....
for i = 1:numel(indexes)
idx = indexes(i);
first_value = vector(idx);
after_value = 1:numel(vector) > idx;
hits = after_value & first_value > (vector-1) & (first_value < vector + 1);
result(i) = find(hits,1);
end

Sign in to comment.

More Answers (1)

Guillaume
Guillaume on 17 Sep 2014
Edited: Guillaume on 17 Sep 2014
vector = [1 1 1 1 3 3 3 9 9 9 9 2 2 1 1 1 2 7 9 7 2 1 1 1];
refindices = [7 17];
outindices = zeros(size(refindices));
for refi = 1:numel(refindices)
refindex = refindices(refi);
outindex = find(abs(vector(refindex+1:end) - vector(refindex)) <= 1, 1);
if ~isempty(outindex)
outindices(refi) = refindex + outindex;
else
%whatever you want to do or nothing if you want 0 when criteria is not found
end
end
would be one way to do it.
Another option, sort of avoiding the loop (the loop is implemented by cellfun):
vector = [1 1 1 1 3 3 3 9 9 9 9 2 2 1 1 1 2 7 9 7 2 1 1 1];
refindices = [7 17];
splitvector = mat2cell(vector, 1, diff([1 refindices numel(vector)+1]));
outindices = refindices + cellfun(@(subv) find(abs(subv(2:end) - subv(1)) <= 1, 1), splitvector(2:end));

Community Treasure Hunt

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

Start Hunting!