Get the positions of the first logicals (multiple sets) in an array

Hi. I am trying to find where the value of an array increases to a particular threshold (thresh=5). For example, I started off with:
x = [0.5,1.6,1.5,5.2,8.5,9.3,6.3,2.2,1.9,1.8,7.4,6.4,6.5,2.3,2.4,8.5,7.6,5.3,2.0,2.4]
I converted this to a logical :
thresh = 5;
x_log = x>thresh;
which gives me:
x_log = [0 0 0 1 1 1 1 0 0 0 1 1 1 0 0 1 1 1 0 0]
What I actually need is a logical that just has the first 1 of each group. So the output should be [0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0] ... is there a function I don't know of that can do this? I can't find it. Or do you suggest another way to do this using the original array?
Thanks a lot in advance!

4 Comments

Long way I did this is:
x_idx = x>5;
x_idx = find(ischange(double(x_idx),'Threshold',0));
x_idx(2:2:end,:) = [];
x_new = zeros(length(x),1);
x_new(x_idx) = 1;
Why do you say it works?
x = [0 0 0 1 1 1 1 0 0 0 1 1 1 0 0 1 1 1 0 0];
x_idx = x>5;
x_idx = find(ischange(double(x_idx),'Threshold',0));
x_idx(2:2:end,:) = [];
x_new = zeros(length(x),1);
x_new(x_idx) = 1
x_new = 20×1
0 0 0 0 0 0 0 0 0 0
No element of x_new is 1.
See my solution below in the official "Answers" section of this page.
x = [0.5,1.6,1.5,5.2,8.5,9.3,6.3,2.2,1.9,1.8,7.4,6.4,6.5,2.3,2.4,8.5,7.6,5.3,2.0,2.4]
if you use the original x array, sorry. Not the logical. I'm converting it to logical here using x_idx = x>5.

Sign in to comment.

 Accepted Answer

x = [0.5,1.6,1.5,5.2,8.5,9.3,6.3,2.2,1.9,1.8,7.4,6.4,6.5,2.3,2.4,8.5,7.6,5.3,2.0,2.4];
thresh = 5;
x_log = x>thresh
x_log = 1×20 logical array
0 0 0 1 1 1 1 0 0 0 1 1 1 0 0 1 1 1 0 0
One way to get the indices of the first 1s:
idx = find(diff([false x_log]) == 1)
idx = 1×3
4 11 16
Another way:
idx = strfind([false x_log],[false true])
idx = 1×3
4 11 16
(In either case, a false/0 element is prepended to x_log to correctly handle the case that x_log starts with a true/1.)
Then, regardless of how you get idx, build x_new from idx:
x_new = false(1,numel(x));
x_new(idx) = true
x_new = 1×20 logical array
0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0

2 Comments

nice! thank you. very similar to what i did, but more logical (pun maybe intended).

Sign in to comment.

More Answers (1)

Try this:
x = [0.5,1.6,1.5,5.2,8.5,9.3,6.3,2.2,1.9,1.8,7.4,6.4,6.5,2.3,2.4,8.5,7.6,5.3,2.0,2.4];
mask = x > 5
mask = 1×20 logical array
0 0 0 1 1 1 1 0 0 0 1 1 1 0 0 1 1 1 0 0
props = regionprops(mask, 'PixelIdxList');
for k = 1 : length(props)
startingIndexes(k) = props(k).PixelIdxList(1);
end
% Show in command window:
startingIndexes
startingIndexes = 1×3
4 11 16

Categories

Products

Release

R2022a

Asked:

on 16 Jun 2022

Commented:

on 16 Jun 2022

Community Treasure Hunt

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

Start Hunting!