# Find multiple values closest to zero

10 views (last 30 days)
Daniel on 12 Aug 2020
Edited: Cris LaPierre on 13 Aug 2020
I have a series of vectors all with multiple zero-crossings, but not always the same number. I've tried this, this, this, and this. The problem I'm having is that while some of these methods do identify the zero-crossings, they don't identify the element that is actually nearest to zero. Here's one example of my values:
values = [-0.0263, -0.0271, -0.0275, -0.0282, -0.0294, -0.0309, -0.0329, -0.0354, -0.0384, -0.0421, -0.0464, -0.0515, -0.0641, 0.2518, 0.4427, 0.4327, 0.4815, 0.4355, 0.3909, 0.4520, 0.4081, 0.3172, 0.3184, -0.0160, -0.0682, -0.0296, 0.1749, 0.3400, 0.3742, 0.4142, 0.3927, 0.4292, 0.4517, 0.4163, 0.4437, 0.3968, -0.0689, -0.0462, -0.0399, -0.0347, -0.0304, -0.0267, -0.0236, -0.0210, -0.0188, -0.0170, -0.0154, -0.0141];
If I've tried these methods correctly, they yield indices 13, 23, 26, and 36. I want it to yield 13, 24, 26, and 37 as 24 is closer to zero than 23 and 37 is closer to zero than 36. Is there a one line way to do this or do I have to try one of these other methods and then check nearby values? Brief update:
I've gotten the result I want with the addition of an if loop. I used find(diff(sign(x)))+1, which identifies the first index after the change in sign. The if loop checks this value against the one before it to see which is closer to zero. Is there a one line version of this?

John D'Errico on 12 Aug 2020
Edited: John D'Errico on 12 Aug 2020
So, you are telling us that you know how to use a fragment like
ind = find(diff(sign(values)))+1
ind =
14 24 27 37
which returns locations of zero crossings. And now, you need to decide which side of that zero crossing is the smaller? Why would you need to use a loop? :)
ind = ind - (abs(values(ind)) > abs(values(ind-1)))
ind =
13 24 26 37
Get used to the idea of using MATLAB to perform vectorized operations. On something like this, there is no need for a loop.

Cris LaPierre on 12 Aug 2020
Edited: Cris LaPierre on 13 Aug 2020
Here's something that works with your sample data.
ind = find(sign(values(1:end-1))~=sign(values(2:end)));
ind = ind + double((values(ind)-values(ind+1))>0)

### Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

R2020a

### Community Treasure Hunt

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

Start Hunting!