开发者

transforming a matrix into a vector along its diagonals

im not not a programmer, i just need to solve something numerically in matlab. i need a function to make the following transformation for any square matrix:

from

row 1: 1 2 3 
row 2: 4 5 6
row 3: 7 8 9

to

1 4 2 7 5 3 8 6 9

ie write the matrix i开发者_StackOverflow中文版n a vector along its diagonals from left to top right. any ideas please?


i really need a little more help though:

say the matrix that we have transformed into the vector, has entries denoted by M(i,j), where i are rows and j columns. now i need to be able to find out from a position in the vector, the original position in the matrix, i.e say if its 3rd entry in the vector, i need a function that would give me i=1 j=2. any ideas please? im really stuck on this:( thanks


This is quite similar to a previous question on traversing the matrix in a zigzag order. With slight modification we get:

A = rand(3);                        %# input matrix

ind = reshape(1:numel(A), size(A)); %# indices of elements
ind = spdiags(fliplr(ind));         %# get the anti-diagonals
ind = ind(end:-1:1);                %# reverse order
ind = ind(ind~=0);                  %# keep non-zero indices
B = A(ind);                         %# get elements in desired order

using the SPDIAGS function. The advantage of this is that it works for any arbitrary matrix size (not just square matrices). Example:

A =
      0.75127      0.69908      0.54722      0.25751
       0.2551       0.8909      0.13862      0.84072
      0.50596      0.95929      0.14929      0.25428
B =
  Columns 1 through 6
      0.75127       0.2551      0.69908      0.50596       0.8909      0.54722
  Columns 7 through 12
      0.95929      0.13862      0.25751      0.14929      0.84072      0.25428


Here's one way to do this.

%# n is the number of rows (or cols) of the square array
n = 3;
array = [1 2 3;4 5 6;7 8 9]; %# this is the array we'll reorder

%# create list of indices that allow us
%# to read the array in the proper order
hh = hankel(1:n,n:(2*n-1)); %# creates a matrix with numbered antidiagonals
[dummy,sortIdx] = sort(hh(:)); %# sortIdx contains the new order

%# reorder the array
array(sortIdx)

ans =
     1     4     2     7     5     3     8     6     9


You can convert your matrix to a vector using the function HANKEL to generate indices into the matrix. Here's a shortened version of Jonas' answer, using M as your sample matrix given above:

N = size(M,1);
A = hankel(1:N,N:(2*N-1));
[junk,sortIndex] = sort(A(:));

Now, you can use sortIndex to change your matrix M to a vector vec like so:

vec = M(sortIndex);

And if you want to get the row and column indices (rIndex and cIndex) into your original matrix that correspond to the values in vec, you can use the function IND2SUB:

[rIndex,cIndex] = ind2sub(N,sortIndex);


A=[1,2,3;4,5,6;7,8,9];
d = size(A,1);
X=[];
for n = 1:2*size(A,1) - 1
    j = min(n,d); i = (n+1)-(j);
    X = cat(2,X,diag(flipud(A(i:j,i:j)))');
end

X
X =
     1     4     2     7     5     3     8     6     9


You can generate the diagonals in this way:

for i = -2:2
    diag(flipud(a), i)
end

I don't know whether this is the optimal way to concatenate the diagonals:

d = []
for i = -2:2
    d = vertcat(d, diag(flipud(a), i))
end

(I tested it in octave, not in matlab)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜