I need to find the minimum value and the locations of all occurrences.

5 views (last 30 days)
I have an array that is (n,m), with random integers. I am finding the minimum/maximum value of this array, but the value may occur more than once. I need to be able to list the locations in (row,column) for all occurrences of the minimum/maximum.
a=randi([1,10],n,m);
min_val=min(a(:));
[row,column]=find(a==min_val);
fprintf('The minimum value in the array is %5.0f \n', min_val);
fprintf('The location of the minimum value is row %3.0f column %3.0f \n', row, column);
a =
1 2 5 6 3
4 10 7 1 6
10 2 6 9 10
4 4 7 4 1
4 9 1 9 1
The minimum value in the array is 1
The location of the minimum value is row 1 column 5
The location of the minimum value is row 2 column 4
The location of the minimum value is row 5 column 1
The location of the minimum value is row 3 column 4
The location of the minimum value is row 5 column 5
When I print the results the locations get mixed up.

Accepted Answer

Walter Roberson
Walter Roberson on 8 Feb 2025
fprintf('The location of the minimum value is row %3.0f column %3.0f \n', row, column);
When you do this in fprintf(), all of the contents of "row" is used up before any of the content of "column" gets used up.
You need to do something like
fprintf('The location of the minimum value is row %3.0f column %3.0f \n', [row, column].');
row and column are each column vectors on output from find() of a 2D array (provided that the array had more than one row!)
Using [] between two column vectors gets an N x 2 array in which the first column is row information and the second column is column information.
Using .' on the N x 2 array gives an 2 x N array in which the first row is row information and the second row is column information.
fprintf() will "use up" the contents of the array "down the columns". So first it will pick out one row information item, and then it will pick out one column information item. After that it will pick out the next row information item and the next column information item. And so on.
The alternative is to use
fprintf("%s\n", compose("The location of the minimum value is row %3.0f column %3.0f", row, column));
When compose() is passed a string() format item, compose() emits string() results. compose() knows to take corresponding data from corresponding parameters -- it will take row(1) together column(1), then row(2) together with column(2) and so on. With the results of compose() being a string() array, the outer fprintf() call prints the string() entries.

More Answers (1)

dpb
dpb on 8 Feb 2025
Moved: dpb on 8 Feb 2025
a =[ 1 2 5 6 3
4 10 7 1 6
10 2 6 9 10
4 4 7 4 1
4 9 1 9 1];
[r,c]=find(a==min(a,[],'all')); % find overall minimum indices in array
[r c]
ans = 5×2
1 1 5 3 2 4 4 5 5 5
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
[r,ix]=sort(r); % arrange by row
c=c(ix);
[r c]
ans = 5×2
1 1 2 4 4 5 5 3 5 5
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
arrayfun(@(r,c)fprintf('R=%3d C=%3d\n',r,c),r,c) % print
R= 1 C= 1 R= 2 C= 4 R= 4 C= 5 R= 5 C= 3 R= 5 C= 5
fprintf processes multiple inputs in order, each element in the list is output sequentially, then on to the next. Thus your output is all the rows in order, then the columns regardless of which is actually which in the format string. The above is the equivalent of writing an explicit for...end loop over the number of elements found by passing r and c to the anonymous function via arrayfun by which the two arrays are then passed an element at a time from each...

Categories

Find more on System Composer in Help Center and File Exchange

Products


Release

R2024b

Community Treasure Hunt

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

Start Hunting!