Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 in 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

like image 255
user415141 Avatar asked Aug 09 '10 13:08

user415141


People also ask

How do you make a diagonal matrix of a vector?

D = diag( v ) returns a square diagonal matrix with the elements of vector v on the main diagonal. D = diag( v , k ) places the elements of vector v on the k th diagonal. k=0 represents the main diagonal, k>0 is above the main diagonal, and k<0 is below the main diagonal.

How do you convert a diagonal to a matrix?

To convert a vector into a diagonal matrix in R, we can use diag function along with matrix function and use ncol argument where we can put the number of columns equal to the number of values in the vector.

What do you mean by diagonal matrix?

A square matrix in which every element except the principal diagonal elements is zero is called a Diagonal Matrix. A square matrix D = [dij]n x n will be called a diagonal matrix if dij = 0, whenever i is not equal to j. There are many types of matrices like the Identity matrix.


3 Answers

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
like image 51
Amro Avatar answered Oct 20 '22 16:10

Amro


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
like image 25
Jonas Avatar answered Oct 20 '22 16:10

Jonas


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);
like image 27
gnovice Avatar answered Oct 20 '22 18:10

gnovice