How to find all minimum elements in a vector - matlab

In Matlab, by the function min(), I can only get one single minimum element of a vector, even if there can be several equal minimum elements. I was wondering how to get the indices of all minimum elements in a vector?
For example,
v=[1,1];
I would like to get the indices 1 and 2, both of which index the smallest elements 1.
Thanks and regards!

You can use find to find the min values:
find(v == min(v))

v = [1 2 3 1 5];
find( v == min(v) )
ans = 1 4
At least in Octave (don't have matlab), this returns the indexes of all minimums in v

Related

How to return the indices of all the even entries in Matlab

given a vector v, I am to find the indices idxeven of all the even entries and return it as a vector.
v = [1 2 6 4 8 3 14 17 pi]
and I want to return:
idxeven = [2 3 4 5 7]
I have tried idxeven=find(v) but it simply returns the indices as a vector. Any help would be appreciated.
k = find(X) returns a vector containing the linear indices of each nonzero element in array X.
first create array X so as for even number in v X is one and zero for the others :
X=(mod(v,2)==0);
then use find to find desired indices :
idxeven=find(X);

Find the position of the minimal value of a three dimensional array in Matlab

Sorry for asking such a simple and silly question, but Matlab is really too hard to use for me. My question is just how to find the position the minimal value of a three dimensional array in Matlab.
For example, suppose I define a three dimensional array
m=zeros(2,2,2);
m(1,2,2)=-2;
The minimal value of m should be -2, located at (1,2,2). I can find the minimal value by
m0=min(min(min(m)));
But when I find its position by using
[x y z]=find(m==m0);
Instead of returning x=1, y=2 and z=2, it returns x=1, y=4 and z=1.
I appreciate if anyone would answer this question!
You can use min to find the minimum index of m and then convert it to x, y and z coordinates. There is no need to use find also.
min can be used with multiple output arguments to return the index of the minimum element. Here, I also use : to return every element of m as a column vector.
>> m=zeros(2,2,2);
>> m(1,2,2)=-2;
>> m(:)
ans =
0
0
0
0
0
0
-2
0
>> [~, ind] = min(m(:))
ind =
7
Now we have our index we need to convert it back into x, y and z coordinates. This can be done using ind2sub or manually by hand.
>> [x y z] = ind2sub(size(m), ind)
x =
1
y =
2
z =
2
You're correct. This is more complicated than it should be. The problem is that MATLAB is hardwired to work with matrices (i.e. arrays of rank 2), rather than arrays of general rank. Here's the solution:
m0 = min(m(:))
[x y z] = ind2sub(size(m), find(m(:) == m0))
Explanation:
If you type help find, you may notice that your original code was using the [rows, cols, vals] version of find, which is not what you expected.
Instead, min(m(:)) is a simplification of your min(min(min(m))). It automatically reshapes m into a rank one array (i.e. a vector).
The expression find(m(:) == m0) returns a single index for the minimum position in this reshaped vector. Finally, ind2sub converts this single index into a set of three indices, given the shape of m.

What does it mean to use logical indexing/masking to extract data from a matrix? (MATLAB)

I am new to matlab and I was wondering what it meant to use logical indexing/masking to extract data from a matrix.
I am trying to write a function that accepts a matrix and a user-inputted value to compute and display the total number of values in column 2 of the matrix that match with the user input.
The function itself should have no return value and will be called on later in another loop.
But besides all that hubbub, someone suggested that I use logical indexing/masking in this situation but never told me exactly what it was or how I could use it in my particular situation.
EDIT: since you updated the question, I am updating this answer a little.
Logical indexing is explained really well in this and this. In general, I doubt, if I can do a better job, given available time. However, I would try to connect your problem and logical indexing.
Lets declare an array A which has 2 columns. First column is index (as 1,2,3,...) and second column is its corresponding value, a random number.
A(:,1)=1:10;
A(:,2)=randi(5,[10 1]); //declares a 10x1 array and puts it into second column of A
userInputtedValue=3; //self-explanatory
You want to check what values in second column of A are equal to 3. Imagine as if you are making a query and MATLAB is giving you binary response, YES (1) or NO (0).
q=A(:,2)==3 //the query, what values in second column of A equal 3?
Now, for the indices where answer is YES, you want to extract the numbers in the first column of A. Then do some processing.
values=A(q,2); //only those elements will be extracted: 1. which lie in the
//second column of A AND where q takes value 1.
Now, if you want to count total number of values, just do:
numValues=length(values);
I hope now logical indexing is clear to you. However, do read the Mathworks posts which I have mentioned earlier.
I over simplified the code, and wrote more code than required in order to explain things. It can be achieved in a single-liner:
sum(mat(:,2)==userInputtedValue)
I'll give you an example that may illustrate what logical indexing is about:
array = [1 2 3 0 4 2];
array > 2
ans: [0 0 1 0 1 0]
using logical indexing you could filter elements that fullfil a certain condition
array(array>2) will give: [3 4]
you could also perform alterations to only those elements:
array(array>2) = 100;
array(array<=2) = 0;
will result in "array" equal to
[0 0 100 0 100 0]
Logical indexing means to have a logical / Boolean matrix that is the same size as the matrix that you are considering. You would use this as input into the matrix you're considering, and any locations that are true would be part of the output. Any locations that are false are not part of the output. To perform logical indexing, you would need to use logical / Boolean operators or conditions to facilitate the selection of elements in your matrix.
Let's concentrate on vectors as it's the easiest to deal with. Let's say we had the following vector:
>> A = 1:9
A =
1 2 3 4 5 6 7 8 9
Let's say I wanted to retrieve all values that are 5 or more. The logical condition for this would be A >= 5. We want to retrieve all values in A that are greater than or equal to 5. Therefore, if we did A >= 5, we get a logical vector which tells us which values in A satisfy the above condition:
>> A >= 5
ans =
0 0 0 0 1 1 1 1 1
This certainly tells us where in A the condition is satisfied. The last step would be to use this as input into A:
>> B = A(A >= 5)
B =
5 6 7 8 9
Cool! As you can see, there isn't a need for a for loop to help us select out elements that satisfy a condition. Let's go a step further. What if I want to find all even values of A? This would mean that if we divide by 2, the remainder would be zero, or mod(A,2) == 0. Let's extract out those elements:
>> C = A(mod(A,2) == 0)
C =
2 4 6 8
Nice! So let's go back to your question. Given your matrix A, let's extract out column 2.
>> col = A(:,2)
Now, we want to check to see if any of column #2 is equal to a certain value. Well we can generate a logical indexing array for that. Let's try with the value of 3:
>> ind = col == 3;
Now you'll have a logical vector that tells you which locations are equal to 3. If you want to determine how many are equal to 3, you just have to sum up the values:
>> s = sum(ind);
That's it! s contains how many values were equal to 3. Now, if you wanted to write a function that only displayed how many values were equal to some user defined input and displayed this event, you can do something like this:
function checkVal(A, val)
disp(sum(A(:,2) == val));
end
Quite simply, we extract the second column of A and see how many values are equal to val. This produces a logical array, and we simply sum up how many 1s there are. This would give you the total number of elements that are equal to val.
Troy Haskin pointed you to a very nice link that talks about logical indexing in more detail: http://www.mathworks.com/help/matlab/math/matrix-indexing.html?refresh=true#bq7eg38. Read that for more details on how to master logical indexing.
Good luck!
%% M is your Matrix
M = randi(10,4)
%% Val is the value that you are seeking to find
Val = 6
%% Col is the value of the matrix column that you wish to find it in
Col = 2
%% r is a vector that has zeros in all positions except when the Matrix value equals the user input it equals 1
r = M(:,Col)==Val
%% We can now sum all the non-zero values in r to get the number of matches
n = sum(r)
M =
4 2 2 5
3 6 7 1
4 4 1 6
5 8 7 8
Val =
6
Col =
2
r =
0
1
0
0
n =
1

Count pixels with certain indices that have a certain value in Matlab

I have two vectors xx and yy holding the x and y indices of certain pixels respectively in matrix A . What I want to do is to check the values of the pixels with those indices and count how many of those pixels have the value 0. For example, if xx=[1 2 3] and y=[2 5 8], I want to check how many of these pixels(x,y) (1,2), (2,5), (3,8) have the value 0. I can do this with for loops but I think it can be done easier in Matlab, so if anyone could please advise.
The following should work:
sum(A(sub2ind(size(A),xx,yy)) == 0)
First, you convert the row and column indices into single indices into the matrix A. Then, you check where A is zero for these indices (which will result in ones). Then you simply sum up the ones.
A dirtier way than sub2ind is
sum( A( [1 size(A,1)]*( [ yy; xx ] - 1 ) + 1 ) == 0 )
You can check here and see that the dirty method is ~x4 times faster than sub2ind. So, if you are in need for speed, use the dirty method ;)

How to get MATLAB to display the index of the minimum value in a 2D array?

I'm trying to write a script in MATLAB that finds the location of the minimum value of a 2D array of numbers. I am certain there is only 1 minimum in this array, so having multiple locations in the array with the same minimum value is not an issue. I can find the minimum value of the array, but in a 30x30 array, I would like to know which row and column that minimum value is in.
As an alternative version, combine min to get the minimum value and find to return the index, if you've already calculated the minimum then just use find.
>> a=magic(30);
>> [r,c]=find(a==min(min(a)))
r =
1
c =
8
Or depending on how you want to use the location information you may want to define it with a logical array instead, in which case logical addressing can be used to give you a truth table.
>> a=magic(30);
>> locn=(a==min(min(a)));
You could reshape the matrix to a vector, find the index of the minimum using MIN and then convert this linear index into a matrix index:
>> x = randi(5, 5)
x =
5 4 4 2 4
4 2 4 5 5
3 1 3 4 3
3 4 2 5 1
2 4 5 3 5
>> [value, index] = min(reshape(x, numel(x), 1));
>> [i,j] = ind2sub(size(x), index)
i =
3
j =
2
Look at the description of the min function. It can return the minimum value as well as the index. For a two dimensional array, just call it twice.
A = rand(30); % some matrix
[minColVal, minColIdx] = min(A);
[minRowVal, minRowIdx] = min(minColVal);
minVal = minRowVal;
minValIdx = [minColIdx(minRowIdx), minRowIdx];
Edit: #b3's solution is probably computationally more elegant (faster and needs less temporary space)
To find min or max in a subset of a vector -
If A is a vector and "lowerBound" and "upperBound" are the bounds of the vector among which you need to find the max (or min) value, then use this command -
[Value,Index]=min(A(lowerBound:upperBound));
This returns "Value" as the min or max value among A(lowerBound) and A(uppedBound) and
"Index" as with "lowerBound" as the offset. So to find the absolute index, you need to add "lowerBound" to the Index.
An alternate solution using an inline function will work.
>> min_index = #(matrix) find(matrix == min(reshape(matrix, [1,numel(matrix)])));
>> a=magic(30);
>> [r,c]=min_index(a)
r =
1
c =
8