Removing third dimension of matrix - matlab

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)

Related

Convert 3d matrix to String and back to 3d matrix using Matlab

I am currently working on a stenography assignment on how to embed secret image to a cover image using Wang's algorithm. Basically i just want to change for eg:
3d matrix
A(:,:,1) = [5 7 8; 0 1 9; 4 3 6];
A(:,:,2) = [1 0 4; 3 5 6; 9 8 7];
A(:,:,3) = [7 9 3; 4 5 9; 1 9 9];
To
Str = '578019436104356987793459199'
and also vice-versa if anybody can help out.
Another way is to just use sprintf. You first need to transpose each slice independently, so the call to permute as per Ander's answer will get to that point. After you can just supply a single format string of %d (integer) and the actual permuted matrix and it will unroll all elements column-wise and concatenate all of the numbers together. The additional advantage is that you no longer need to assume that only one digit occupies each matrix element:
str = sprintf('%d', permute(A, [2 1 3]));
Example
>> str = sprintf('%d', permute(A, [2 1 3]))
str =
578019436104356987793459199
>> class(str)
ans =
char
However, to reconstruct the matrix, you will have to assume that there's one element per matrix. In this case, you could use the undocumented sprintfc function that can output one cell per character, then convert the characters to numbers with str2double. Finally, reshape your matrix and undo the transpose:
A2 = permute(reshape(str2double(sprintfc('%c', str)), size(A)), [2 1 3]);
Example
>> A2 = permute(reshape(str2double(sprintfc('%c', str)), size(A)), [2 1 3])
A2(:,:,1) =
5 7 8
0 1 9
4 3 6
A2(:,:,2) =
1 0 4
3 5 6
9 8 7
A2(:,:,3) =
7 9 3
4 5 9
1 9 9
Because of the order of the unrolling of MATLAB matrices, your problem is slightly less straightforward than it may seem. You need to use reshape and permute to make it work.
str=arrayfun(#num2str,reshape(permute(A,[2 1 3]),[],1,1)).';
A2=permute(reshape(arrayfun(#str2double,str),[size(A)]),[2 1 3]);
isequal(A2,A)
This of course assumes what #Sardar comments in your question: all numbers have single digits (i.e. are integers range 0-9)

How to create a submatrix of a randomly filled matrix? [duplicate]

I have a 30 x 30 matrix, called A, and I want to assign B as the leftmost 30 x 20 block of A how can I do that?
Is this the correct way to do it?
B = A[30 ; 20]
No the correct way is
B = A(:, 1:20);
where : is shorthand for all of the rows in A.
Matrix indexing in MATLAB uses round brackets, (). Square brackets, [], are used to declare matrices (or vectors) as in
>> v = [1 2 3; 4 5 6; 7 8 9]
v =
1 2 3
4 5 6
7 8 9
excaza provides a very good link on Matrix Indexing in MATLAB which should help you. There is also Matrix Indexing.
A_new = A(:,1:20)
takes all the rows from A with this part A(:,) and the first 20 columns with this part A(,1:20)
A_newis now 30x20
You can also iterate over elements in two loops, but the above answer is easiest

how to assign part of a matrix to other matrix in matlab

I have a 30 x 30 matrix, called A, and I want to assign B as the leftmost 30 x 20 block of A how can I do that?
Is this the correct way to do it?
B = A[30 ; 20]
No the correct way is
B = A(:, 1:20);
where : is shorthand for all of the rows in A.
Matrix indexing in MATLAB uses round brackets, (). Square brackets, [], are used to declare matrices (or vectors) as in
>> v = [1 2 3; 4 5 6; 7 8 9]
v =
1 2 3
4 5 6
7 8 9
excaza provides a very good link on Matrix Indexing in MATLAB which should help you. There is also Matrix Indexing.
A_new = A(:,1:20)
takes all the rows from A with this part A(:,) and the first 20 columns with this part A(,1:20)
A_newis now 30x20
You can also iterate over elements in two loops, but the above answer is easiest

MATLAB Concatenate matrices with unequal dimensions

Is there any easy way to concatenate matrices with unequal dimensions using zero padding?
short = [1 2 3]';
long = [4 5 6 7]';
desiredResult = horzcat(short, long);
I would like something like:
desiredResult =
1 4
2 5
3 6
0 7
Matrices in MATLAB are automatically grown and padded with zeroes when you assign to indices outside the current bounds of the matrix. For example:
>> short = [1 2 3]';
>> long = [4 5 6 7]';
>> desiredResult(1:numel(short),1) = short; %# Add short to column 1
>> desiredResult(1:numel(long),2) = long; %# Add long to column 2
>> desiredResult
desiredResult =
1 4
2 5
3 6
0 7
EDIT:
I have edited my earlier solution so that you won't have to supply a maxLength parameter to the function. The function calculates it before doing the padding.
function out=joinUnevenVectors(varargin)
%#Horizontally catenate multiple column vectors by appending zeros
%#at the ends of the shorter vectors
%#
%#SYNTAX: out = joinUnevenVectors(vec1, vec2, ... , vecN)
maxLength=max(cellfun(#numel,varargin));
out=cell2mat(cellfun(#(x)cat(1,x,zeros(maxLength-length(x),1)),varargin,'UniformOutput',false));
The convenience of having it as a function is that you can easily join multiple uneven vectors in a single line as joinUnevenVectors(vec1,vec2,vec3,vec4) and so on, without having to manually enter it in each line.
EXAMPLE:
short = [1 2 3]';
long = [4 5 6 7]';
joinUnevenVectors(short,long)
ans =
1 4
2 5
3 6
0 7
Matlab automatically does padding when writing to a non-existent element of a matrix.
Therefore, another very simple way of doing this is the following:
short=[1;2;3];
long=[4;5;6;7];
short(1:length(long),2)=long;

Reconstruct matrix from diagonals in 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