8

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];
gnovice
  • 125,304
  • 15
  • 256
  • 359
Santhan Salai
  • 3,888
  • 19
  • 29

1 Answers1

7

For R2015a and newer...

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]);

For pre-R2015a versions...

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
Community
  • 1
  • 1
gnovice
  • 125,304
  • 15
  • 256
  • 359