How to find X value of given Y close to zero ?

Hello!
My question is How to find the value of Y more close to zero first (note Y consists of both positive and negative numbers) and then find the corresponding X value from a matrix ? Many thanks in advance.
For example: 6x6 matrix
338.00 339.00 340.00 341.00 342.00 343.00
1.00 -100.00 -100.00 -100.00 -100.00 -100.00 -100.00
2.00 100.00 100.00 100.00 100.00 100.00 100.00
3.00 0.28 0.12 -0.05 -0.21 -0.38 -0.55
4.00 0.28 0.12 -0.05 -0.21 -0.38 -0.55
5.00 8.21 8.24 8.26 8.28 8.30 8.32
6.00 8.21 8.24 8.26 8.28 8.30 8.32
To find the value closest to 0, which is -0.05 corresonding to the value 340. 340 is the output value.

 Accepted Answer

[~,ix]=min(abs(m),[],'all','linear');
[~,j]=ind2sub(size(m),ix);
>> o(j)
ans =
340
>>

More Answers (1)

Jon
Jon on 9 Dec 2020
Edited: Jon on 9 Dec 2020
Here's another approach that is maybe more obvious to understand
x = [338.00 339.00 340.00 341.00 342.00 343.00]
data = [ ...
-100.00 -100.00 -100.00 -100.00 -100.00 -100.00
100.00 100.00 100.00 100.00 100.00 100.00
0.28 0.12 -0.05 -0.21 -0.38 -0.55
0.28 0.12 -0.05 -0.21 -0.38 -0.55
8.21 8.24 8.26 8.28 8.30 8.32
8.21 8.24 8.26 8.28 8.30 8.32]
% find column locations of minimum
[~,icol] = min(abs(data)) % columns correspond to x values
% select the x value corresponding to the column where the minimum was found
% just need the first instance if there are more than one
xmin = x(icol(1))

10 Comments

Sorry the returned value was not the one I needed.
Yeah, the above will return the first column regardless as min(abs(data)) will return a row vector of column minima; the indices will be an array of save size and so the first of those will always be column 1.
When I run my code above I get column 3 which is what I think you wanted.
x =
338 339 340 341 342 343
data =
-100.0000 -100.0000 -100.0000 -100.0000 -100.0000 -100.0000
100.0000 100.0000 100.0000 100.0000 100.0000 100.0000
0.2800 0.1200 -0.0500 -0.2100 -0.3800 -0.5500
0.2800 0.1200 -0.0500 -0.2100 -0.3800 -0.5500
8.2100 8.2400 8.2600 8.2800 8.3000 8.3200
8.2100 8.2400 8.2600 8.2800 8.3000 8.3200
icol =
3 3 3 3 3 3
xmin =
340
But that may just be lucky. I actually misunderstood what was returned by min with two left hand arguments. I had assumed it was the row and column indices of where the minimum values were found. Sorry
"I get column 3 ..."
No, you get ROW three for each of the six columns. As you say, it's purely fortuitous that that is the same row with the first set of minima that matches the column with the minimum overall.
Observe
>> m=randn(6)
m =
0.7908 0.6973 0.9180 -0.0658 -0.8766 0.3735
-1.6529 -0.4536 -0.6555 -0.4475 -0.6388 -0.9694
1.3133 1.3221 0.0839 1.0784 -0.0981 0.4772
-0.1528 -0.1622 0.3515 0.3904 1.6527 -0.3038
-0.0072 -1.1710 -0.9282 0.5705 1.2322 -1.5383
-0.9102 1.2852 0.1685 -0.1661 2.1676 1.4931
>> [mn,imn]=min(abs(m))
mn =
0.0072 0.1622 0.0839 0.0658 0.0981 0.3038
imn =
5 4 3 1 3 4
>>
Here is a straight forward approach that I think does work (not that there is anything wrong with the functioning of your approach it is just somewhat difficult to understand how it works):
x = [338.00 339.00 340.00 341.00 342.00 343.00]
data = randn(5,6)
% find the minimum value in each column
[colMin] = min(abs(data)); % columns correspond to x values
% find the column that has smallest minimum
[minval,idx] = min(colMin)
xmin = x(idx)
dpb
dpb on 10 Dec 2020
Edited: dpb on 10 Dec 2020
Yes, before TMW introduced the 'all' qualifier one of the common MATLAB idioms was min(min(x)) to find the global minimum of 2D array -- which is your code above in one line instead of two. Alternatively, one wrote min(x(:)) where the (:) operation expands x to a long column vector. That is the same as the combination of the 'all','linear' options.
Using and becoming familiar/proficient with various forms of array addressing is important to the effective use of MATLAB; the ind2sub call above simply turns the linear address returned from min to the row,col subscripts based on the size() of the array.
There could have been an option for multiple outputs from functions like min that would return the subscripts, but that gets into the quagmire of higher-dimensioned arrays so TMW has chosen to only return the one linear location.
The real hassle is there's no syntax by which to return anything except the first return value in nested function calls so one is forced into the temporary index value. I've thought an 'indexonly' flag would be the other optional input variable that could have been introduced for precisely such use cases as this.
Thank you for the extended, patient, discussion. Now that you have explained it, I can understand how your code works. I guess I just glazed over when I saw the ind2sub, and all of the additional arguments to the min function. I guess a fluency issue. I've certainly used ind2sub before, and it's not hard to understand. I just don't use it often enough that I could just look at it and have immediate recognition. I tend to use min(x(:)) to get the global minimum. Anyhow I learned something which is always good.
Glad to help...teaching as well as "just" answers is the goal of many of us here...
Glad to see my question raised discussion! Thanks for helping! Merry Xmas!

Sign in to comment.

Asked:

on 9 Dec 2020

Commented:

on 10 Dec 2020

Community Treasure Hunt

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

Start Hunting!