Reputation: 367
I have a matrix:
X =
0 81 13 15 100 2
11 0 6 10 200 8
19 22 0 20 300 23
I want to get the first four minimal values in the whole array X
with the indices of each value in the array. For example I should get vector v = [2 6 8 10]
and the index of each value in X
.
Also, I want to ignore the zero values when the row number equals the column number.
I have tried to use the min
and sort
functions, but I am not sure how to do it.
Upvotes: 0
Views: 98
Reputation: 5822
Use:
vals = sort(X(~eye(size(X)))); %takes non diagonal values and sort the result
res = vals(1:4) %finds the first 4 elements (which are the smallest)
[row, col] = find(ismember(X,res)); %gets the indices
result:
res = [2; 6; 8; 10]
By The way, if you don't want to ignore all the diagonal values, only the zero ones, use:
vals = sort(X(~eye(size(X)) | (eye(size(X)) & X~=0)));
Upvotes: 2
Reputation: 45752
I would suggest the following
X2 = X;
X2(~~eye(size(X2))) = inf; %// or X2(logical(eye(size(X2)))) = inf
[val, idx] = sort(X2(:));
result = val(1:4);
[idxRow, idxCol] = ind2sub(size(X), idx(1:4));
Upvotes: 2
Reputation: 11218
Just want to add to drorco's perfect answer how to find indexes of this first elements:
indexes = arrayfun( @(a) find(X==a), res);
or if you want to get numbers of rows and columns:
[r,c] = arrayfun( @(a) find(X==a), res);
P.S. it works perfectly if all elements except zeros in X
are unique.
Upvotes: 1
Reputation: 9864
Sort all but the ones on the diagonal and then find the indices of the ones which are smaller than or equal to the 4th element of sorted array and not on the diagonal:
T=sort(X(~eye(size(X))));
v = T(1:4);
[I,J] = find(X <= v(end) & ~eye(size(X)));
Upvotes: 1