How to get diagonal elements of non-square matrix?

7 visualizaciones (últimos 30 días)
turningpoint
turningpoint el 26 de Mzo. de 2017
Comentada: Christopher Gordon el 20 de Feb. de 2021
Hi, guys!
I am working with rectangular matrixes and I want to extract the values that go from the upper left corner to lower right (diagonal). I have tried to write some codes, but they don't give me good results (it actually gets worst as the matrix gets "more rectangular"). Does anyone have an ideia?
Thank you,
Carolina Magalhães
  2 comentarios
Jan
Jan el 26 de Mzo. de 2017
What is the wanted output for a rectangular matrix? Do you mean the diagnonal from the [1,1] element to the [n,n] element, when the n is: min(size(X))? Or do you mean the "diagonal" from the element [1,1] to [m,n], when m and n are the dimensions of the matrix? In the latter case, what is the wanted result? The nearest element or a bilinear interpolation?
turningpoint
turningpoint el 26 de Mzo. de 2017
Thanks for the fast response! I want the "diagonal" from (1,1) to (m,n). Bilinear interpolation would give me the most correct result.

Iniciar sesión para comentar.

Respuesta aceptada

Guillaume
Guillaume el 26 de Mzo. de 2017
What you want effectively is the values on the line going from one corner to the other.
If you have the image processing toolbox, you could use improfile for that:
m = rand(20, 10); %demo matrix;
[colfrom, rowfrom, values] = improfile(m, [1, size(m, 2)], [1, size(m, 1)]);
If you do not have the toolbox, you can implement your own line drawing algorithm. Bresenham's and Wu's are both very easy to implement.
  2 comentarios
turningpoint
turningpoint el 26 de Mzo. de 2017
Thanks a lot! I did not know that function, but it worked!
Jan
Jan el 26 de Mzo. de 2017
improfile replies a [19 x 1] vector. This might be useful:
[s1, s2] = size(m);
values = improfile(m, [1, s2], [1, s1], max(s1, s2), 'bilinear')

Iniciar sesión para comentar.

Más respuestas (2)

Image Analyst
Image Analyst el 26 de Mzo. de 2017
Try this:
m = randi(9, 5, 12) % Sample data
[rows, columns] = size(m)
for k = 1 : min([rows, columns])
output(k) = m(k,k);
end
output % Echo to command window
  2 comentarios
turningpoint
turningpoint el 26 de Mzo. de 2017
I wanna go from (1,1) to (m,n) and this only goes from (1,1) to (min(m,n),min(m,n)), which leaves most of the numbers out as my matrix gets more rectangular.
Image Analyst
Image Analyst el 27 de Mzo. de 2017
I thought you wanted to go down the exact diagonal at 45 degrees. If you go from corner to corner without going down a 45 degree diagonal, then you'll have to interpolate values. I didn't know you wanted to interpolate - I thought you wanted to extract existing values. If you want to interpolate then improfile() is the way to go.

Iniciar sesión para comentar.


Jan
Jan el 26 de Mzo. de 2017
Editada: Jan el 26 de Mzo. de 2017
You can create your own interpolation method:
function D = Diagonal(M, n)
% Inputs: M: Matrix
% n: Number of points, default: length(M)
% Outputs: D: Interpolated values of diagonal with n elements
% Author: Jan Simon, License: CC BY-SA 3.0
[s1, s2] = size(M);
if nargin == 1
n = max(s1, s2); % Number of wanted points, can be defined freely
end
x = linspace(1, s2, n); % n steps along rows
xN = floor(x);
xN(n) = s2 - 1; % care about last step
xS = x - xN;
y = linspace(1, s1, n); % n steps along columns
yN = floor(y);
yN(n) = s1 - 1; % care about last step
yS = y - yN;
Index = sub2ind([s1, s2], yN, xN); % Get linear index
D = (M(Index) .* (1 - xS) + M(Index + s1) .* xS) .* (1 - yS) + ...
(M(Index + 1) .* (1 - xS) + M(Index + s1 + 1) .* xS) .* yS;
end
  2 comentarios
turningpoint
turningpoint el 26 de Mzo. de 2017
I have found a simpler way with the improfile tool. Thank you for your answer!
Christopher Gordon
Christopher Gordon el 20 de Feb. de 2021
Jan,
I'd like to try your method, but I keep ending up with a vector instead of the expanded array. My starting matrix is 30 columns (spectra) where each column is 1024 rows (pixels) long (1024 x 30 overall). Those spectra were taken at various points along my detectors 1024 pixel chip at randome points. The first is at pixel 13 and the last one is at pixel 1010, with 28 other pixels in between. What I would like to do is diagonally interpolate/extrapolate to see what the spectrum would be at each of the 1024 pixels. Is this possible with your function?

Iniciar sesión para comentar.

Categorías

Más información sobre Linear Algebra en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by