MATLAB: Construct matrix from selected matrix elements - matlab

I have a 3x3x3 matrix which contains a particular set of elements that I would like to extract. However, I would like for the elements to be ordered in a matrix after selecting them. An example is:
a(1,:,:)=1*[1 2 3; 4 5 6; 7 8 9];
a(2,:,:)=2*[1 2 3; 4 5 6; 7 8 9];
a(3,:,:)=3*[1 2 3; 4 5 6; 7 8 9];
a(a>1.0)
The condition a(a>1.0) gives me a vector of elements, but is there a way to order them in a matrix following their original ordering?

What would you like to do to the elements that don't satisfy your criteria?
You could do something like a(a<=1) = nan;

Suppose 2-D matrix for simplicity:
a = [1 2 3; ...
4 5 6];
Let's take only even values and keep them in their original shape:
a(mod(a, 2) == 0)
You might want:
2
4 6
However, in the world of matrix, is there such a matrix which has empty space? Yes, a sparse matrix. But, you must note that a sparse matrix is filled with 0 not just missing.
So, my suggestion is to replace other values with NaN
b = a; % just make a duplicate
b(mod(b, 2) == 1) = nan
b =
nan 2 nan
4 nan 6

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)

I have a questions regarding matlab matrix

Suppose I have this matrix:
m=[1 2 3;4 5 6; 7 8 9]
I want this matrix in MATLAB:
a=[1,1,1,2,2,2,2,3,3,3;1,1,1,2,2,2,3,3,3;4,4,4,5,5,5,6,6,6;4,4,4,5,5,5,6,6,6;7,7,7,8,8,8,9,9,9;7,7,7,8,8,8,9,9,9]
Please help to make this matrix,
Thanks in advance,
I like the kronecker tensor product
m=[1 2 3;4 5 6; 7 8 9];
a = kron(m,ones(2,3))
each element in a is a product between the current element in m and the matrix in the second argument (which would be clear if the second argument contains other values than 1). But this would do for your example
This may be faster than using a Kronecker product:
m = [1 2 3;4 5 6; 7 8 9]; %// data
rep = [2 3]; %// number of repetitions of rows and columns respectively
a = m(ceil((1:size(m,1)*rep(1))/rep(1)), ceil((1:size(m,2)*rep(2))/rep(2)));

Compare two unequal matrix some specific column without using for loop

I want to compare two matrices without using a for loop. Given
A=[2 1 8;
2 4 7;
2 3 7;
3 5 2;
5 1 4;
5 6 2;
5 3 7];
B=[3 6 5;
1 4 2];
Now I want to compare col(2) two of matrix B with col(2) two of matrix A and at the same time col(3) three of matrix B and col(1) one of matrix A. Now I want to get the result from matrix A like this:
c=[2 4 7;
5 6 2];
I think #mizanbuet wants to extract rows from A where the 3rd element of the row is in the first column of B and the 2nd element in the row is in the 2nd column of B.
Easy with some ismember and logical indexing:
A2inB2 = ismember(A(:,2),B(:,2));
A1inB3 = ismember(A(:,1),B(:,3));
c = A( A2inB2 & A1inB3, :);

Removing NaN elements from a matrix

There is one NaN element per row, I want to remove it.
A=[NaN 1 2;
3 NaN 4;
NaN 5 6];
The desired output is:
[1 2;
3 4;
5 6]
A = [NaN 1 2 ; 3 NaN 4; NaN 5 6]
sz = size(A);
B = reshape(A', size(A,1)*size(A,2), 1);
B(isnan(B)) = [];
B = reshape(B, sz(2)-1, sz(1))'
I thought it could be done in one line, but I was wrong. See solution below:
Given (added row helps me debug my indexing below):
>> A = [NaN 1 2 ; 3 NaN 4; NaN 5 6; 7 8 NaN]
A =
NaN 1 2
3 NaN 4
NaN 5 6
7 8 NaN
Then:
>> Atrans = A';
>> B = reshape( Atrans(~isnan(Atrans)) ,[],size(Atrans,2))'
B =
1 2
3 4
5 6
7 8
Incidentally, the Matlab idiom of performing a simple logical check on an array within an logical indexing operation is very common and incredibly useful. The archetypical example is:
>> x(x>0) %This returns a 1D column vector of all values of x
%which are greater than 0, regardless of the initial
%size of x. Multidimensional inputs are unwrapped
%column-first
Everything else above is size and dimension handling.
Here it is - please note that the code is not robust. It assumes that indeed in every row there is a NaN element.
While it is not a vectorized solution, it has other advantages - like a clear code.
for i=1:size(A,1)
x = A(i,:);
x(isnan(x)) = [];
B(i,:) = x;
end
B
B =
1 2
3 4
5 6

How do you concatenate the rows of a matrix into a vector?

For an m-by-m (square) array, how do you concatenate all the rows into a column vector with size m^2 ?
There are a couple of different ways you can collapse your matrix into a vector, depending upon how you want the contents of your matrix to fill that vector. Here are two examples, one using the function reshape (after first transposing the matrix) and one using the colon syntax (:):
>> M = [1 2 3; 4 5 6; 7 8 9]; % Sample matrix
>> vector = reshape(M.', [], 1) % Collect the row contents into a column vector
vector =
1
2
3
4
5
6
7
8
9
>> vector = M(:) % Collect the column contents into a column vector
vector =
1
4
7
2
5
8
3
6
9
A very important note in changing a matrix to a vector is that , MATLAB produce the output vector form the columns of the matrix, if you use A(:)
for example :
A = [1 2 3 ; 4 5 6]
B = A (:)
B = [1 4 2 5 3 6]
You can see the direction of changing in the following image.