times Replicate matrix one row at a time




repelem matlab (8)

I have matrix

A = [1;2;3]

How do I replicate A four times, replicating each row four times before moving onto the next, to get

[1;1;1;1;2;2;2;2;3;3;3;3;4;4;4;4]

?


Duplicating a column vector into a longer column vector

How about using kron? It's very suited for this purpose.

kron(A,ones(6,1))

If like me you have no idea what a Kronecker tensor product is you might be interested in this more intuitive (and actually I think faster) solution:

c(ceil((1:length(c)*n)/n));

so here I used vector indexing to replicate the matrix. For example using the two case you have above we could do:

c = 1:3;
c([1 1 1 2 2 2 3 3 3]) %for each
c([1 2 3 1 2 3 1 2 3]) %for times

so the questions is how do we make a vector [1 2 3 1 2 3 1 2 3] without the very functionality you are requesting. So I made a vector with the number of elements we need i.e. 1:9 and then divide by three and round up (i.e. try ceil((1:9)/3) in the command line.

A bit of benchmarking (I know this stuff should be in loops so maybe this isn't so accurate):

c = 1:3; n = 3;
tic; k = kron(c, ones(1, n)); toc; % 0.000208 seconds.
tic; a = c(ceil((1:length(c)*n)/n)); toc;  % 0.000025 seconds.
clear;
c = 1:1000000; n = 3;
tic; k = kron(c, ones(1, n)); toc; % 0.143747 seconds.
tic; a = c(ceil((1:length(c)*n)/n)); toc;  % 0.090956 seconds.
clear;
c = 1:10000; n = 1000;
tic; k = kron(c, ones(1, n)); toc; % 0.583336 seconds.
tic; a = c(ceil((1:length(c)*n)/n)); toc;  % 0.237878 seconds.

Good question +1. A neat one-liner method to accomplish this is via the Kronecker tensor product, eg:

A = [1 2 3];
N = 3;
B = kron(A, ones(1, N));

Then:

B =

     1     1     1     2     2     2     3     3     3

UPDATE: @Dan has provided a very neat solution that looks to be more efficient than my kron method, so check that answer out before leaving the page :-)

UPDATE: @bcumming has also provided a nice solution that should scale very nicely when the input vector is large.


Yet another possibility, which involves no arithmetical operations:

reshape(repmat(A,1,6).',[],1);

However, if you really need speed, and if the A vector size is the same in all iterations of the loop, it's best to precompute (outside the loop) an indexing vector like this

ind = reshape(repmat([1;2;3],1,6).',[],1);

and then within the loop you only need to do

A(ind)

How about using kron? It's perfect for this.

kron(A,ones(4, 1))

well you could try

(A*ones(1,4))' 

A similar function to R's rep in Matlab

You can reproduce the syntax of the rep function in R fairly closely by first defining a function as follows:

function [result]=rep(array, count)
matrix = repmat(array, count,1);
result = matrix(:);

Then you can reproduce the desired behavior by calling with either a row or column vector:

>> rep([1 2 3],3)
ans =
 1     1     1     2     2     2     3     3     3

>> rep([1 2 3]',3)
ans =
 1     2     3     1     2     3     1     2     3

Note I have used the transpose (') operator in the second call to pass the input array as a column vector (a 3x1 matrix).

I benchmarked this on my laptop, and for a base array with 100,000 elements repeated 100 times, it was between 2 to 8 times faster than using the ceil option above, depending on whether you want the first or the second arrangement.


In this particular instance, you could do something along the lines of

A = [1;2;3;4];
B = repmat(A',4,1);
B = B(:);

What this does is replicate A' to create a matrix B:

 1     2     3     4
 1     2     3     4
 1     2     3     4
 1     2     3     4

It then converts it to a single column using B(:).