Is it possible to concatenate 3D matrices in Matlab? - arrays

Lets say I have two matrices A and B that are 3D. A is 420x420x3 and B is 420x420x3. After concatenation I want to obtain C that is 420x420x6 as the concatenation of A and B in the third dimension.
How would I do that at matlab ?

Simply use cat:
C = cat(3, A, B);
Best,

Related

Matlab: How to do `repelem` where each element is a matrix?

Suppose I have m-by-n matrices A, B, C arranged in an m-by-n-by-3 tensor P:
P = cat(3, A, B, C);
I now want to make a new tensor where each matrix is repeated K times, making the third dimension size 3K. That is, if K=2 then I want to build the tensor
Q = cat(3, A, A, B, B, C, C);
Is there a nice builtin way to achieve this, or do I need to write a loop for it? Preferably as fast or faster than the manual way.
If A, B, C were scalars I could have used repelem, but it does not work the way I want for matrices. repmat can be used to build
cat(3, A, B, C, A, B, C)
but that is not what I am after either.
As noted by #Cris Luengo, repelem(P, 1, 1, k) will actually do what you want (in spite of what the MATLAB documentation says), but I can think of two other ways to achieve this.
First, you could use repmat to duplicate the tensor k times in the second dimension and then reshape:
Q = reshape(repmat(P, 1, k, 1), m, n, []);
Second, you could use repelem to give you the indices of the third dimension to construct Q from:
Q = P(:, :, repelem(1:size(P,3), k));

Multidimensional array : Split and put back together

I am trying to turn a 3 dimensional array "upside-down" as:
I have tried the inverse function, but if we look at the inverse operation in mathematical terms, it gives us another result. I need to turn without changing the data in the array. How to do that?
To split the 3-dimensional array (A x B x C) into A-sub-array (2d, B x C) I have used squeeze: k=squeeze(array(n,:,:)). Now I have a 2-dimensional array of size B x C. How to put it back together (in 3 dimensional array)?
You can use permute() to change the order of dimensions, which can be used as a multidimensional transpose.
Putting 2D matrices into a 3D one then is a simple indexing operation. Read more in indexing here.
A = rand(10,10,10);
B = permute(A, [ 3 2 1 ]); % Permute he order of dimensions
mat1 = rand(10,10);
mat2 = rand(10,10);
mat_both(:,:,2) = mat2; % Stack 2D matrices along the third dimension
mat_both(:,:,1) = mat1;
mat_both = cat(3,mat1, mat2); % Stacks along the third dimension in a faster way

Extract row or column from a 2D array to a 2D array [duplicate]

This question already has an answer here:
Vector multiplication using MATMUL in Fortran
(1 answer)
Closed 6 years ago.
in matlab I am used to write something like this
A = [1,2;3,4]
B = A(:,1)
So I extract the first column of matrix A and store it in matrix B, which is just a vector or a 2x1 Matrix. However I can't do this in Fortran, since it regards A(:,1) as an one dimensional array and thus gives me an error if I want to assign this to a "matrix" B of size 2x1.
This is an minimal example in Fortran:
program test
implicit none
double complex, dimension(:,:), allocatable :: A, B
allocate(A(2,2), B(2,1))
A = transpose(reshape((/ 1, 2, 3, 4/), shape(A)))
B = A(:,1) !gives error that shape mismatch
end program test
Since I don't want to treat vectors separately in my algorithm, how can I achieve Matlab like behaviour?
Try
B = A(:, 1:1)
Or you should also be able to do this:
B(:,1) = A(:,1)
Either should work.

How to inverse a whole cell array

I have one cell array A= {<2x6 double>,<4x6 double>,<43x6 doubl>}. and now I want to calculate the inverse value of each matrix elements inside the cell array. I have written below code but It doesn't work.
C = cellfun(#inv, A, 'Un', false);
can you please guide me how can I write the proper code? e.g the element inside of the cell array is 2 and I want to show the inverse of this value like 1/2
inv is the matrix inverse, which will give you the error Matrix must be square, as it tries to invert the three matrices inside of A. You probably want element-wise division: 1./X
C = cellfun(#(X) 1./X, A, 'Un', false);

Extracting a block out of a multidimensional matrix

Consider the multi-dimensional matrix A where size(A) has the identical even elements N. How should one find the matrix B with size(B)=size(A)/2 such that:
B(1,1,...,1)=A(1,1,...,1),
B(1,1,...,2)=A(1,1,...,2),
...
B(N/2,N/2,...,N/2)=A(N/2,N/2,...,N/2).
I generally don't like arrayfun (or loopy functions), but if the number of dimensions is not in the thousands, then this should be just fine:
Nv = size(A)/2;
S = arrayfun(#(x){1:x},Nv);
B = A(S{:});
Should work with different sized dimensions too. Just decide how you want to deal with dimensions where mod(size(A),2)~=0.

Resources