I have a 3 dimensional matrix. I want to replicate the matrix of size 8x2x9 to a specified number of times in the third dimension given by a vector say [3, 2, 1, 1, 5, 4, 2, 2, 1]
so that the resultant matrix is of size 8x2x21. Is there any built-in MATLAB function (I'm running version 2014a) to do this similar to the newer repelem
function, for matrices?
A simple example of what I need:
% Input:
A(:,:,1) = [1 2; 1 2];
A(:,:,2) = [2 3; 2 3];
% Function call:
A = callingfunction(A, 1, 1, [1 2]);
% Output:
A(:,:,1) = [1 2; 1 2];
A(:,:,2) = [2 3; 2 3];
A(:,:,3) = [2 3; 2 3];
Multiply Row and Column Vectors The result is a 4-by-3 matrix, where each (i,j) element in the matrix is equal to a(j). *b(i) : a = [ a 1 a 2 a 3 ] , b = [ b 1 b 2 b 3 b 4 ] , a . * b = [ a 1 b 1 a 2 b 1 a 3 b 1 a 1 b 2 a 2 b 2 a 3 b 2 a 1 b 3 a 2 b 3 a 3 b 3 a 1 b 4 a 2 b 4 a 3 b 4 ] .
u = repelem( v , n ) , where v is a scalar or vector, returns a vector of repeated elements of v . If n is a scalar, then each element of v is repeated n times. The length of u is length(v)*n .
B = repmat( A , r ) specifies the repetition scheme with row vector r . For example, repmat(A,[2 3]) returns the same result as repmat(A,2,3) .
According to the documentation for repelem
(first introduced in version R2015a), it can operate on matrices as well. I believe the following code should accomplish what you want (I can't test it because I have an older version):
newMat = repelem(mat, 1, 1, [3 2 1 1 5 4 2 2 1]);
You can use one of the approaches from this question to replicate an index into the third dimension, then simply index your matrix with that. For example (adapting Divakar's solution):
vals = 1:size(mat, 3);
clens = cumsum([3 2 1 1 5 4 2 2 1]);
index = zeros(1, clens(end));
index([1 clens(1:end-1)+1]) = diff([0 vals]);
newMat = mat(:, :, cumsum(index));
You can then generalize this into a function to operate on multiple dimensions like repelem
does:
function A = my_repelem(A, varargin)
index = cell(1, nargin-1);
for iDim = 1:nargin-1
lens = varargin{iDim};
if isscalar(lens)
if (lens == 1)
index{iDim} = ':';
continue
else
lens = repmat(lens, 1, size(A, iDim));
end
end
vals = 1:size(A, iDim);
clens = cumsum(lens);
index{iDim} = zeros(1, clens(end));
index{iDim}([1 clens(1:end-1)+1]) = diff([0 vals]);
index{iDim} = cumsum(index{iDim});
end
A = A(index{:});
end
And for your sample data, you would use it like so:
>> A(:,:,1) = [1 2; 1 2];
>> A(:,:,2) = [2 3; 2 3];
>> A = my_repelem(A, 1, 1, [1 2])
A(:,:,1) =
1 2
1 2
A(:,:,2) =
2 3
2 3
A(:,:,3) =
2 3
2 3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With