Finding index of giving conditions and specified index set - matlab

Given a vector x belongs to R^n, an index subset I of S=(1, ..., n), I want to find the index of the largest elements of x in `I, or the index in the full vector.
In other words, how do I find the index of the largest element of a sub vector in the original vector's index space?
What's the best way to do this in MATLAB?
Currently, I use:
xmax = max(x(I));
i = I(x(I) == xmax);
i = i(1);
I'm looking for a more efficient way to achieve this.
Example:
x = [4, 2, 4];
S = [1, 2, 3];
I = [2, 3];
The desired output would be 3.

You can simply use the two output version of max. The second output will give you the location of where the maximum element was found. However, if there are multiple entries where the maximum was found, it will only find the first occurrence. You can then use the second output of max to index into I to get what you want. Therefore:
[~,loc] = max(x(I));
i = I(loc);

Related

Extracting a matrix from a cell vector in MATLAB

A sparse matrix is a large matrix with almost all elements of the same
value (typically zero). The normal representation of a sparse matrix
takes up lots of memory when the useful information can be captured
with much less. A possible way to represent a sparse matrix is with a
cell vector whose first element is a 2-element vector representing the
size of the sparse matrix. The second element is a scalar specifying
the default value of the sparse matrix. Each successive element of the
cell vector is a 3-element vector representing one element of the
sparse matrix that has a value other than the default. The three
elements are the row index, the column index and the actual value.
Write a function called "sparse2matrix" that takes a single input of a
cell vector as defined above and returns the output argument called
"matrix", the matrix in its traditional form. Consider the following
run:
cellvec = {[2 3], 0, [1 2 3], [2 2 -3]};
matrix = sparse2matrix(cellvec)
matrix =
0 3 0
0 -3 0
Good morning/afternoon/night, everyone
I was wondering if you could help me with this.
I am trying to complete this, but I am not sure how to deal with this. I understand that I am interested in the first part of the cell vector, but I am not sure about how to tell Matlab I need that. This is my code:
function matrix = sparse2matrix(x)
A = [2 3];
B = 0;
C = [1, 2, 3];
x = {A, 0, C};
matrix = cell2mat(x);
end
The result of this code is different from the result I showed above.
I am not getting the right answer and honestly I do not know what to do, so I would appreciate if you guide me a little bit.
Not the most elegant way of doing it but it gets the job done. Uses the cell2mat() function and indexing to grab the necessary values for each step. A for-loop is then used to obtain the 3-element vectors that is used to change the array values from the default values in the respective indices.
cellvec = {[2 3], 0, [1 2 3], [2 2 -3]};
[matrix] = sparse2matrix(cellvec)
function [matrix] = sparse2matrix(x)
Matrix_Size = cell2mat(x(1,1));
Matrix_Height = Matrix_Size(1);
Matrix_Width = Matrix_Size(2);
Default_Value = cell2mat(x(1,2));
matrix = Default_Value*ones(Matrix_Height,Matrix_Width);
Triplets = x(3:end);
Number_Of_Triplets = length(Triplets);
for Triplet_Index = 1: Number_Of_Triplets
Current_Triplet = cell2mat(Triplets(1,Triplet_Index));
Row = Current_Triplet(1,1);
Column = Current_Triplet(1,2);
Value = Current_Triplet(1,3);
matrix(Row,Column) = Value;
end
end
Explanation:
The first line in the local function sparse2matrix() indicates to retrieve row 1, column 1 of the cell array x and then convert it to a matrix. The conversion is done using the cell2mat() function.
Matrix_Size = cell2mat(x(1,1));
Results in:
Matrix_Size = [2 3]
The following line indicates to grab index 1 of the previous array Matrix_Size. This will be used to determine the height of the output array matrix. This is done in a similar fashion to evaluate the Matrix_Width using index 2.
Matrix_Height = Matrix_Size(1);
Results in:
Matrix_Height = 2
Ran using MATLAB R2019b

Finding minimum array of matrix with condition

I want to find the minimum of a matrix say A. I could do it in this way:
NM = find(A==min(A));
but I need the minimum array of A which for it, c(NM) is not zero. How can I put this condition on finding minimum value?
Example:
c=[0,18,9,0,100,0];
A=[1,189,125,25,7,1];
I expext it returns 5.
You can use logical indexing to find the desired elements.
find(A==min(A(c~=0)))
Explanation:
Using logical indexing you first find indices of elements of c that are nonzero.
idx1 = c~=0;
then elements of A that correspond to indices of nonzeros elemets of c are extracted.
A1 = A(idx1);
then we find minimum of the extracted elements:
mn = min(A1);
again we use logical indexing to find elements of A that are equal to its minimum.
idx2 = A == mn;
finally using find the logical index idx2 converted to linear index.
result = find (idx2);
First convert your Matrix to a vector (otherwise the minimum of a Matrix is confusing, it might mean the minimum of each column).
Then you can sort the Vector and get the indexes
[val idx] = sort(A(:));
You can then use the indexes to sort your vector c
c = c(idx);
And finally get the first non-zero element of c:
c = c(c~=0);
result = c(1);

Add and remove element of vector at specific position

Let X = [1, 2, 3, 4, 5] and Y = [1, 2, 1, 0, 1] be vectors where X maps into Y.
Now I want to identify the maximum and minimum of Y, which is easy: [value_min, id_min] = min(Y) = [0, 4] and [value_max, id_max] = max(Y) = [2, 2].
Then I want to remove the element from X corresponding to the minimum in Y and expand evenly around the element in X corresponding to the maximum in Y, while keeping the number of points equal. For this example we remove X(4)=[]. Then we expand like X(2)=(X(2) - X(1))/2 and X(3)=(X(3) - X(2))/2 such that X looks like X = [1, 1.5, 2.5, 3, 5]. How can I achieve this? I think there is a general pattwern.
Solution
Now the following snipped should work for any vector of length N. Note that the first and final element are fixed.
[value_max, id_max] = max(Y(2:N-1));
X(id_max) = (X(id_max) - X(id_max-1))/2;
X(id_max+1) = (X(id_max+1) - X(id_max))/2;
[value_min, id_min] = min(Y(2:N-1));
X(id_min)=[];
Here is a solution to your problem but there are a few things you should take care of
% Any Vector should work
X=[1 2 3 4 5];
Y=[1 2 1 0 1];
%We dont need the actual min max
[~,MIN]=min(Y(2:end-1));
[~,MAX]=max(Y(2:end-1));
%you dont look at the first element so the index has to be increased by 1
MIN=MIN+1;
MAX=MAX+1;
X(MIN)=[];%taking out the smallest element
Xnew= [X(1:MAX) X(MAX:end)]; %Extend the vector by taking the MAX value twice
%the mean for 2 elements is A+B/2
Xnew(MAX)=mean(Xnew(MAX-1:MAX)); %the left one and the element next to it
Xnew(MAX+1)=mean(Xnew(MAX+1:MAX+2)); %the right one and the element next ot it
%rewrite X and clear Xnew
X=Xnew;
clear Xnew;
First of all this isnt very efficient, but if its just used to
modify some vectors and not get called a million times a day it will
do the trick.
In your text you say remove the minima then stretch
around the maxima, in your solution metacode it is the other way
around. this will influence the outcome when min and max are next to
each other, so please check which way you prefer.
Y isnt changed in this at all so it cant be performed multiple times on the same vector.
Is N (the length) of any importance later on? if not you can always just refer to "end"

MATLAB: scan the row of a matrix and use values to search another matrix

I have matrix X and A where
X = [x1, y1, 1, 1; x2, y2, 1, 3; x3, y, 2, 4]
A = [1, 1, 0; 1, 3, 1; 1, 4, 2]
I want to:
1. scan the last two columns for every row in X (FYI, these two number combinations are unique)
2. find those values in the first two columns of A
3. get the value of the last column in that row of A.
For example, for the first row of X, I get 1 and 1, so I find 1 and 1 for the first two columns in A (which appears to be the first row), so the number I want to get is 0.
I think I can do it using a loop and a "find" function if it were just one number I'm working with, but I'm new to matlab and have trouble with a combination of two numbers. I would appreciate your help!
The ismember function may be what you're looking for, along with the () and : operators to extract columns from an array.
% Map rows in X to rows in A
[tf,loc] = ismember(X(:,[3 4]), A(:,[1 2]), 'rows');
% Grab the corresponding value from A
rslt = A(loc, 3);
Now you have a logical vector tf that indicates for each row in X whether it was found in A, and loc, which holds the corresponding indexes in to the rows of A for the ones that matched. Then you use those indexes to index in to A to pull out the "value" or dependent variable columns. These are vectorized operations, so it'll be faster than doing it with loops and find().
Read through the documentation for ismember, unique, paren, and the functions they reference to get more background on Matlab's functions for doing recordwise searching like this.

Matlab: finding largest sum of first dimension, grouping by second dimension

I have a 2-D matrix A(value, label). I want to find the label that has the largest and second largest sum of values. For example:
A = (1, 1;
2, 1;
3, 2;
4, 2;
5, 3)
In this case the result should be largest = 2, second largest = 3. How can I do this in MATLAB?
[b,m,n]=unique(a(:,2));
[val, idx]= sort(accumarray(n,a(:,1)),'descend');
b(idx(1:2))
Output is:
ans =
2
3
Something like this should do the trick.
A = [1, 1;
2, 1;
3, 2;
4, 2;
5, 3];
labels = unique(A(:,2)); % Pull out unique labels
for i = 1:numel(labels)
idx = (A(:,2) == labels(i)); % Find elements which match current label
s(i,1) = sum(A(idx,1)); % Sum them
end
r = sortrows([s labels], -1); % Sort by decreasing sum
r(1,2); % Label corresponding to largest sum
r(2,2); % Label corresponding to second largest sum
EDIT accumarray is a built-in function that will do this for you. Although I find the documentation on it somewhat cryptic.
Since your question isn't super clear and i don't get what sum you are referring to I'm just gonna guess that you are aiming for something like this
q=sortrows(A,-1);
q=q(1:2,:);
which will give the two labels (right column) with the largest values (left column) in q.
If this wasn't what you were looking for please comment.
EDIT: Missread which column that contained labels, corrected