Reconstruct matrix from diagonals in matlab - matlab

Given a vector of the counter-diagonals of a matrix in matlab, is there an easy way to reconstruct the matrix?
For example, given
x = [1 2 3 4 5 6 7 8 9]
is there any easy way to reconstruct it to the following?
1 2 4
3 5 7
6 8 9
This is made slightly easier by the fact that the dimensions of the original block are known. Reconstructing a rotation or transposition of the original matrix is fine, since rotating and transposing are easy to undo. Faster is better, this calculation has to be done on many xs.
Thanks!

You can create the corresponding Hankel matrix and use it for sorting (works only if the output is a square matrix!):
x = [1 2 3 4 5 6 7 8 9];
%# find size of output (works only with square arrays)
n=sqrt(length(x));
%# create Hankel matrix
hh = hankel(1:n,n:(2*n-1));
%# sort to get order of elements (conveniently, sort doesn't disturb ties)
[~,sortIdx]=sort(hh(:));
%# reshape and transpose
out = reshape(x(sortIdx),n,n)'; %'# SO formatting
out =
1 2 4
3 5 7
6 8 9

Related

Convert column matrix to multiple rows with duplicated data

In Matlab, given matrix 'a' as:
a = [1 2 3 4 5 6 7 8 9]';
but a few million rows deep, what would be the best way to convert it to the format shown in 'b'?
b = [1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
4 5 6 7 8 9]
where each row in 'b' contains N consecutive values from 'a'?
I can write a function but was wondering if there's a faster, more built-in way?
Another option is the built-in Hankel matrix, for example in your case:
hankel(1:4,4:9)
or in the general case for a vector a and block size N
hankel(a(1:N),a(N:numel(a)))
I have no idea if the implementation of hankel is better or worse than #Luis Mendo solution, so test and see which solution is better for you...
Let
a = [1 2 3 4 5 6 7 8 9].'; % data
N = 4; % block size
If you have the Image Processing Toolbox: use im2col with the 'sliding' option:
b = im2col(a(:), [N 1], 'sliding');
Or, without any toolbox: use implict expansion (or bsxfun) to create the appropriate indexing matrix:
b = a((1:numel(a)-N+1)+(0:N-1).');

How to create more than one matrix in a row using matlab

I am trying to get a series of vectors which come from the same original, to make an easy example, suppose this vector V= (1,2,3,4,5,6,7,8,9,10) (of course mine is bigger)
The first vector has to look like this:
R1=(1,3,5,7,9)= V(1:1:end)
The second vector:
R2=(2,4,6,8,10)=V(2:1:end)
The third vector:
R3=(3,5,7,9)=V(3:1:end)
The fourth vector:
R4=(4,6,8,10)=V(4:1:end)
...
R8=(8,10)=V(8:1:end)
So my questions are:
Is there an easier way to get this result?
How can I know the total number of Ri vectors with distance = 1 that can obtained from V?
Use Matlab's cell object which can hold a vector in every cell.
Use a for loop to fill this cell object gradually.
Code example:
%initialize V
V= [1,2,3,4,5,6,7,8,9,10];
%initialize an empty cell of size [10,1]
R= cell(length(V)-2,1);
%fill the cell
for ii=1:length(R)
R{ii} = V(ii:2:end);
end
%prints results
for ii=1:length(R)
R{ii}
end
Results (each row is a different vector):
1 3 5 7 9
2 4 6 8 10
3 5 7 9
4 6 8 10
5 7 9
6 8 10
7 9
8 10

Incremental matrix without loop

(Just approaching Matlab for personal understanding), suppose I have a Z,Y matrix in this case Z=1 Y=3
A=1:3
output: 1 2 3
Now I need to increase the matrix vertically to obtain:
1 2 3
2 4 6
3 6 9
How can I achieve that without using a loop?
The easiest way is to use vector multiplication.
If your goal is to obtain
1 2 3
2 4 6
3 6 9
given A=1:3
all you have to do is
A.'*A
This will take the vector product of the transpose (.') of A with A itself
Another way is to use bsxfun:
A = [1 2 3];
B = bsxfun(#times, A.', A);
This is essentially the same answer as Federico's where the outer product of the vector is taken.

Removing third dimension of matrix

Lets say I have matrix such that A(:,:,1)=[1,2,3;2,3,4], A(:,:,2)=[3,4,5;4,5,6].
How is the easiest way of accessing and plotting the vectors (1,2,3),(2,3,4),(3,4,5),(4,5,6). I tried creating B=[A(:,:,1);A(:,:,2)], but i need a procedure to arbitrary number of A's.
Hope this isn't trivial and I've formulated myself satisfactory.
You should think 'vertically'. This will allow you to use colon indexing:
>> A(:,:,1) = [1,2,3;2,3,4].'; %'// NOTE: transpose of your original
>> A(:,:,2) = [3,4,5;4,5,6].'; %'// NOTE: transpose of your original
>> A(:,:)
ans =
1 2 3 4
2 3 4 5
3 4 5 6
The colon indexing with two colons works for any dimension A:
>> A(:,:,:,:,1,1) = [1 2 3; 2 3 4].'; %'
>> A(:,:,:,:,2,1) = [3 4 5; 4 5 6].'; %'
>> A(:,:,:,:,1,2) = [5 6 7; 6 7 8].'; %'
>> A(:,:,:,:,2,2) = [7 8 9; 8 9 0].'; %'
>> A(:,:)
ans =
1 2 3 4 5 6 7 8
2 3 4 5 6 7 8 9
3 4 5 6 7 8 9 0
Colon indexing in MATLAB is quite interesting and really powerful once you master it. For example, if you use fewer colons than there are dimensions in the array (like above), MATLAB will automatically concatenate the remainder of the data along the dimension equal to the colon count.
So, if A has 48 dimensions, but you index with just 2 colons: you'll get a 2D array, that is the concatenation of the remaining 46 dimensions along the 2nd dimension.
In general: if A has N dimensions, but you index with just M ≤ N colons: you'll get an M-D array, that is the concatenation of the remaining N-M dimensions along the Mth dimension.
So as long as you are free to define your A to contain vectors on the columns rather than the rows (you should advise everyone to do this, as virtually everything in MATLAB is a bit faster that way), I think this is the fastest and most elegant way to do what you want.
If not, well, then just reshape like Dan :)
Assuming the order does not matter, here is how you can do it for vectors of length 3:
B = reshape(shiftdim(A,2), [], 3)
plot(B')
For vectors of arbitrary dimensions, replace 3 by size(A,2)

How to convert 1D to 2D by Matlab program

I would like to ask a question about Matlab program.
I have vector a
a = [1 2 3 4 5 6 7 8 9 10 11 12];
I would like to convert vector a to 2D array. Normally, I use this code to convert it.
m =1;
for i=1:4
for j=1:3
b(i,j) = a(m);
m=m+1;
end
end
Then b is a 2D matrix.
b =
1 2 3
4 5 6
7 8 9
10 11 12
Anybody, have an idea to convert 1D to 2D without using loop.
Thanks,
Check out the reshape function and help page.
In particular,
B = reshape(A,m,n)
returns the m-by-n matrix B whose elements are taken column-wise from A. An error results if A does not have m*n elements.
Note that it is column-wise, so I suggest you make a matrix with 3 rows and 4 columns and then tip it on its side (A.' will take the transpose of a matrix).