1

I have a 300x178 matrix and I want to find the minimum of each column of that matrix, i.e. resulting in a 1x178 array. Then I want to store the sum of all elements but the minimum in each column in the 300x178 matrix on the location/pixel of the minimum value, leaving all other elements zero. How can I do this using MATLAB?

Example:

1 4 6 3
2 6 7 4
5 1 5 7

becomes:

1 0 0 1
0 0 0 0
0 1 1 0

and eventually:

8  0  0 14
0  0  0 0
0 11 18 0
Adriaan
  • 17,741
  • 7
  • 42
  • 75
user5618251
  • 317
  • 1
  • 9
  • Your example and the text of your question do not correspond, see my answer. Both have a similar solution though. – Adriaan Nov 25 '22 at 07:42

1 Answers1

3

Your example and title do not correspond to the question text. Your example sums all values in a column and stores them at the location of the minimum, which the title also asks. You can do this by making smart use of sub2ind:

A = [1 4 6 3
2 6 7 4
5 1 5 7];
C = zeros(size(A));
[tmp, idx] = min(A);  % find the locations of minima
% one liner to store the sum of columns
C(sub2ind(size(A), idx, 1:size(A,2))) = sum(A,1);
C =

     8     0     0    14
     0     0     0     0
     0    11    18     0

If, on the other hand, you're after what your question text asks about, subsequently subtract A on the minimum locations using the same sub2ind trick:

C(sub2ind(size(A), idx, 1:size(A,2))) = C(sub2ind(size(A), idx, 1:size(A,2))) - A(sub2ind(size(A), idx, 1:size(A,2)))

C =

     7     0     0    11
     0     0     0     0
     0    10    13     0

This way you get the sum of all elements but the minimum.


For an in-depth explanation what sub2ind does, read this fantastic Q/A by Luis Mendo keeping in mind that in A(2,3) the 2 and 3 are called subscripts, which, in case of a 3-by-4 matrix, translates to linear index 8.

I cannot test this on my R2007b, but according to the documentation on min you could use [M, I] = min(A, [], 1, 'linear') to get the linear indices into I directly, without going through sub2ind:

C = zeros(size(A));
[tmp, idx] = min(A, [], 1, 'linear');
C(idx) = sum(A, 1);
% Optional, to sum all but the minimum
C(idx) = C(idx) - A(idx); 

Small note from the documentation on the occurrence of multiple same-valued minima in your original matrix:

If the smallest element occurs more than once, then I contains the index to the first occurrence of the value.

Adriaan
  • 17,741
  • 7
  • 42
  • 75