How do I find the indices of the elements of one vector in a matrix in Matlab? - matlab

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

Related

How to raise a matrix to a vector of powers in matlab without for loop?

I have a 2x2 matrix that I want to multiply by itself 10 times while storing the result after each multiplication. This can easily be done with a for loop but I would like to vectorize it an eliminate the for loop. My approach was to have my 2x2 matrix a and raise it to a vector b with elements 1:10. The answer should be a 2x2x10 matrix that replicates typing
a^b(1)
a^b(2)
.
.
.
a^b(10)
To clarify I'm not doing this element wise I need actual matrix multiplication, and prefer not to use a for loop. Thanks for any help you can give me.
here is the code for you. I use the cellfun to do this and I have comments after each line of the code. It can compute and store from fisrt - nth order of the self-multiplication of an arbitrary matrix m. If you have any question, feel free to ask.
function m_powerCell = power_store(m, n) %m is your input matrix, n is the highest power you want to reach
n_mat = [1:n]; %set a vector for indexing each power result in cell
n_cell = mat2cell(n_mat,1,ones(1,n)); %set a cell for each of the power
m_powerCell = cellfun(#(x)power(m, x), n_cell, 'uni', 0); %compute the power of the matrix
end
%this code will return a cell to you, each element is a matrix, you can
%read each of the matrix by m_powerCell{x}, x represents the xth order

Extracting block diagonal from matrix

I have an njxnj matrix made up of nxn matrices. I want to extract the diagonal j blocks of nxn matrices. i.e. I want to extract the diagonal (for n = 2, j = 4):
What would be the most efficient way of doing this?
To index the elements you can use blkdiag to create a corresponding mask.
%your parameters
n=2
j=4
%some example matrix
M=magic(n*j);
%create the input for blkdiag, j matrices of size n
h=repmat({true(n)},j,1)
%use blkdiag to select the elements
M(logical(blkdiag(h{:})))
For large j, this answer of #Daniel becomes slow. I would instead recommend using linear indices of block diagonal.
n=2;
j=4;
%some example matrix
M=magic(n*j);
linIndices = (0:n*((n*j)+1):n*((n*j)+1)*(j-1))+reshape((1:n)'+n*j*(0:n-1),[],1);
newM = reshape(M(linIndices),n,n,[]);

Generate matrix from an index vector

In matlab, I have a matrix and index vector v (in real problem, v vector is very long)
A = [1,2,3;4,5,6;7,8,9]; % 3-by-3 matrix
v = [1,2,3,2,3,3,1]
How can I generate a matrix like
[A(1,:);A(2,:);A(3,:);A(2,:);A(3,:);A(3,:);A(1,:)]
without using loop or write out everything explicitly?
You can use vectors to index, A([1,1,1]) would give you three times the first element.
A(v,:)

How do i find a matrix of 150*25 from two vectors such that each vector elements multiply with each element of another vector of dim 1*150 &1*25?

I have a vector created from linspace between specific numbers and have dimensions of 1*150. Now i want to multiply each element of the above created vector with another vector whose dimension is 1*25. The detail of my code is given below
c_p = linspace(1,.3*pi,150);
c = c_p';
C = zeros([150,25]);
for i= 1:1:size(C,1)
wp= c(i);
for n= 1:25
c_wp(n) = cos(n*wp);
end
C(i,25)= c_wp;
end
The vector is actually a multiple of cosine of length 25 and here wp is the elements of first vector of dimension 1*150. SO by the logic, I must have an output of 150*25 but instead giving me "subscripted assignment dimension mismatch". Any help would be appreciated, as i am new to matlab.
To multiply each element of a row vector a with each element of another row vector b, we can use linear algebra. We transpose a to make it a column vector and then use matrix multiplication:
a.' * b
That way you don't even need a for loop.

How can I assign a value to the diagonals of a 4-D matrix using linear indexing in MATLAB?

I have a 4-D matrix A of size NxNxPxQ. How can I easily change the diagonal values to 1 for each NxN 2-D submatrix in a vectorized way?
Incorporating gnovice's suggestion, an easy way to index the elements is:
[N,~,P,Q]=size(A);%# get dimensions of your matrix
diagIndex=repmat(logical(eye(N)),[1 1 P Q]);%# get logical indices of the diagonals
A(diagIndex)=1;%# now index your matrix and set the diagonals to 1.
You can actually do this very simply by directly computing the linear indices for every diagonal element, then setting them to 1:
[N,N,P,Q] = size(A);
diagIndex = cumsum([1:(N+1):N^2; N^2.*ones(P*Q-1,N)]);
A(diagIndex) = 1;
The above example finds the N diagonal indices for the first N-by-N matrix (1:(N+1):N^2). Each subsequent N-by-N matrix (P*Q-1 of them) is offset by N^2 elements from the last, so a matrix of size PQ-1-by-N containing only the value N^2 is appended to the linear indices for the diagonal of the first matrix. When a cumulative sum is performed over each column using the function CUMSUM, the resulting matrix contains the linear indices for all diagonal elements of the 4-D matrix.
You can use direct indexing, and some faffing about with repmat, to add the indexes for a single 50x50 diagonal to the offsets within the larger matrix of each 50x50 block:
Here's an example for a smaller problem:
A = NaN(10,10,5,3);
inner = repmat(sub2ind([10 10], [1:10],[1:10]), 5*3, 10); % diagonals
outer = repmat([10*10 * [0:5*3-1]]', 1, 10*10); % offsets to blocks
diags = inner + outer;
A(diags(:)) = 1;