Extract only diagonal elements from matrix

I have a matrix in one variable and a list of coordinates in another variable. Is there a way to extract only the matching pairs of coordinate from the matrix? I.e. X(1),Y(1); X(2), Y(2)...
I can extract all of the permutations (X1, Y1; X1 Y2 ...X2,Y1 ... etc) and then take the diagonal, but I was wondering if there was a simple solution I'm missing to only extract the matched pairs.
Thanks,
Will
%Data
mat = rand(100);
%Coordinates
x_coord = round(rand(10,1)*100);
y_coord = round(rand(10,1)*100);
%Extract coordinates
extracted_coord = diag(mat(x_coord,y_coord));

 Réponse acceptée

Image Analyst
Image Analyst le 26 Jan 2021
You can do this, where m is your matrix, and v is the vector of extracted values from the x,y locations
v = zeros(1, length(X));
for k = 1 : length(X)
row = Y(k);
col = X(k);
v(k) = m(row, col);
end
Then just repeat with a scrambled x and y - I'm sure there is some function for that. Put the various v into a matrix and use eye() to extract the diagonal.

3 commentaires

Will Bassett
Will Bassett le 29 Jan 2021
I was hoping to find something without a for loop for speed, but this works well and gets the job done. Thanks!
It feels like the kind of thing that has a one line function for it, but perhaps not.
How long was it taking?
I did a million points and it took about 78 milliseconds. If I use 1000 points, it's 0.0003 seconds. Just how many points are you going to use, and what kind of speed do you require?
mat = rand(100);
[rows, columns] = size(mat)
numPoints = 1000000
X = ceil(rand(numPoints,1)*columns);
Y = ceil(rand(numPoints,1)*rows);
tic
v = zeros(1, length(X));
for k = 1 : length(X)
row = Y(k);
col = X(k);
v(k) = mat(row, col);
end
toc
Elapsed time is 0.078826 seconds.
Will Bassett
Will Bassett le 29 Jan 2021
It was taking several seconds for me, but I was using a 2k x 2k matrix and the time consuming thing for that (in my testing) was generating the matrix. Pulling the actual points took about the same as yours. I think the speed is just fine this way.
This is much faster than making the full matrix and diagonalizing as I was doing before.
Thanks

Connectez-vous pour commenter.

Plus de réponses (2)

Florian
Florian le 9 Nov 2023
Modifié(e) : Florian le 9 Nov 2023

0 votes

For a one line solution you can use linear indices via sub2ind:
v = mat(sub2ind(size(mat), 1:length(mat), 1:length(mat));
However i don't know about performance in comparison to the for-loop.
max
max le 24 Août 2024

0 votes

For a square matrix A, if coordinates are taken from vectors say, xc -> row index and yc -> column index, then all the required elements can be accessed by the single command A((yc-1)*size(A,1)+xc)
Example:
n = 4;
A = round(rand(n)*10)
xc = mod(ceil(rand(1,n)*10),n)+1
yc = mod(ceil(rand(1,n)*10),n)+1
A((yc-1)*size(A,1)+xc)

Catégories

En savoir plus sur Mathematics dans Centre d'aide et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by