I have two vectors which are of same length M and N. The values of the vectors represent the indices of another matrix A so that the corresponding indices in vector M and N make index pairs of A.
For example I have matrices
M=[1 2 3 4] and N=[5 6 7 8]
I would like to find the values of specific indices in matrix A and store them to another vector I, like this:
I = [A(1,5) A(2,6) A(3,7) A(4,8)]
How could this be done?
You can convert them to linear indices using sub2ind and then use those linear indices to index A:
ind = sub2ind(size(A), M(:), N(:));
I = A(ind);
Note I've gone M(:) as this guarantees that M will be a column vector
Related
Generating evenly space can use linspace, but I wonder if I can vectorize it. What I mean is as follow:
Given an input vector, say [1 2], I want to generate a 2X6 matrix such that:
in the first row, the entries are [0:0.2:1]
the entries for the second row are [0:0.4:2]
In general, the input vector may not be known, it can change from [1 2] to [1:3:10] or other vectors. However, the first column much be a zero vector and the number of columns can be treated to be the known in advanced.
I do not want to write it using a for loop if possible.
Assuming A = [x, y], you can generate the desired 2 x 6 matrix M as follows:
B = A/A(1);
M = B.'*linspace(0, A(1), 6);
In order to calculate local maximums of 2D matrix Y, I use this
[~, indices]= localmax(Y);
But the indices is 1D. How to convert it back to 2D so to access its corresponding element in Y?
From the documentation for localmax:
Linear indices of the nonzero values of lmaxima. Use ind2sub to
convert the linear indices to matrix row and column indices.
For example:
inputmatrix = ...
[3 2 5 3
4 6 3 2
4 4 7 4
4 6 2 2];
[~,indices] = localmax(inputmatrix,4,false);
[I, J] = ind2sub(size(indices), indices);
Edit: I should have clarified as well. As #LuisMendo mentions in the comments above, you can access the elements of Y directly with these linear indices by using Y(indices).
I have two sparse matrices in Matlab, A and B,
and I want to compute a three-dimensional matrix C such that
C(i,j,k) = A(i,j) * B(j,k)
can I do this without a loop?
(Side question: Is there a name for this operation?)
Edit:
Seems my question has already been asked (just for full matrices):
Create a 3-dim matrix from two 2-dim matrices
For full matrices:
You can do it using bsxfun and shiftdim:
C = bsxfun(#times, A, shiftdim(B,-1))
Explanation: Let A be of size M x N and B of size N x P. Applying shiftdim(B,-1) gives a 1 x N x P array. bsxfun implicitly replicates A along the third dimension and shiftdim(B,-1) along the first to compute the desired element-wise product.
Another possibility, usually less efficient than bsxfun, is to repeat the arrays explicity along the desired dimensions, using repmat:
C = repmat(A, [1 1 size(B,2)]) .* repmat(shiftdim(B,-1), [size(A,1) 1 1])
For sparse matrices:
The result cannot be sparse, as sparse ND-arrays are not supported.. But you can do the computations with sparse A and B using linear indexing:
ind1 = repmat(1:numel(A),1,size(B,2));
ind2 = repmat(1:numel(B),size(A,1),1);
ind2 = ind2(:).';
C = NaN([size(A,1),size(A,2),size(B,2)]); %// preallocate with appropriate shape
C(:) = full(A(ind1).*B(ind2)); %// need to use full if C is to be 3D
Answer to your side question: the name for this operation is a hash join.
My situation is:
I get a 1000*2 matrix and a 1000*1 vector.
And the row i in the matrix is mapped to the element i in the vector.
And the elements in the vector are all integer.
Now I want to sort the elements in the vector from low to high.
And I want to get a new matrix with the sequence of the new vector. And the mapping relationships are equal to the original situation.
How to do this in Matlab?
Thanks!
Use sortrows:
First concat your vector to your matrix:
M2 = [V, M];
Then sort rows:
M2 = sortrows(M2); %// You should just do sortrows([V, M]) here, I just split it for the explanation
Then split the vector and the matrix:
V_sorted = M2(:,1);
M_sorted = M2(:, 2:end);
Or alternatively you can use the second output from sort:
[V_sorted, newRowOrder] = sort(V);
M_sorted = M(newRowOrder, :);
Suppose I have a 9x9 matrix A that that consists of integers. I have another matrix IDX that's 2500x4 and consists of the same integers in A. I want to find the indices of all the values in IDX in the matrix A.
Here's what I have:
for ii=1:length(IDX)
Mat_idx=ismember(A,IDX(ii,:));
[StatIdxX StatIdxY] = find(Mat_idx);
end
Now for each ii the StatIdxX and StatIdxY are the row and col indices of IDX in the matrix A. This is slow, and the culprit is ismember
Any thoughts on speeding this up?
Thanks.
first flatten A with A=A(:), that will make a single linear index instead of row,col.
Then just use logical indexing. For example:
B=zeros(size(IDX));
for n=1:numel(A)
B(IDX==A(n))=n;
end