18

Let's say I have a one-dimensional array:

a = [1, 2, 3];

Is there a built-in Matlab function that takes an array and an integer n and replicates each element of the array n times?

For example calling replicate(a, 3) should return [1,1,1,2,2,2,3,3,3].

Note that this is not at all the same as repmat. I can certainly implement replicate by doing repmat on each element and concatenating the result, but I am wondering if there is a built in function that is more efficient.

Amro
  • 123,847
  • 25
  • 243
  • 454
Dima
  • 38,860
  • 14
  • 75
  • 115

7 Answers7

21

I'm a fan of the KRON function:

>> a = 1:3;
>> N = 3;
>> b = kron(a,ones(1,N))

b =

    1     1     1     2     2     2     3     3     3

You can also look at this related question (which dealt with replicating elements of 2-D matrices) to see some of the other solutions involving matrix indexing. Here's one such solution (inspired by Edric's answer):

>> b = a(ceil((1:N*numel(a))/N))

b =

    1     1     1     2     2     2     3     3     3
Community
  • 1
  • 1
gnovice
  • 125,304
  • 15
  • 256
  • 359
  • what a nice solution, but what about if N be a matrix of frequency of elements of a, means that each element of N is correspond with one element of a? – ghedas Nov 26 '12 at 06:49
  • @ghedas: That's addressed [here](http://stackoverflow.com/q/1975772/52738), if you hadn't yet seen it. – gnovice May 16 '17 at 15:51
20
a = [1 2 3];
N = 3;

b = reshape(repmat(a,N,1), 1, [])
Amro
  • 123,847
  • 25
  • 243
  • 454
14

As of R2015a, there is a built-in and documented function to do this, repelem:

repelem Replicate elements of an array.
    W = repelem(V,N), with vector V and scalar N, creates a vector W where each element of V is repeated N times.

The second argument can also be a vector of the same length as V to specify the number of replications for each element. For 2D replication:

B = repelem(A,N1,N2)

No need for kron or other tricks anymore!

UPDATE: For a performance comparison with other speedy methods, please see the Q&A Repeat copies of array elements: Run-length decoding in MATLAB.

Community
  • 1
  • 1
chappjc
  • 30,359
  • 6
  • 75
  • 132
  • 2
    How did you know this before R2015a was out?! – Luis Mendo Mar 08 '15 at 03:13
  • 6
    @LuisMendo Pre-release. I love reading release notes almost as much as accumarray. :). But I immediately deleted my answer an then undeleted it on release day so as not to break the terms of the pre-release. – chappjc Mar 08 '15 at 03:18
3
>> n=3;
>> a(floor((0:size(a,2)*n-1)/n)+1)

ans =

     1     1     1     2     2     2     3     3     3
Andre
  • 31
  • 1
3

Some exotic alternatives. Admittedly more funny than useful:

  1. Assign the (first) result of meshgrid to a vector:

    b = NaN(1,numel(a)*n); %// pre-shape result
    b(:) = meshgrid(a,1:n);
    
  2. Build a matrix that multiplied by a gives the result:

    b = a * fliplr(sortrows(repmat(eye(numel(a)),n,1))).';
    
  3. Use ind2sub to generate the indices:

    [~, ind] = ind2sub([n 1],1:numel(a)*n);
    b = a(ind);
    
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
2

If you have the image processing toolbox, there is another alternative:

N = 3;
imresize(a, [1 N*numel(a)],'nearest')
Andrey Rubshtein
  • 20,795
  • 11
  • 69
  • 104
  • Actually, your code is wrong. It should be `imresize(a, [1 N*numel(a)],'nearest')`, with an `N`, not a `2`. When you correct this, your solution is actually about 3 times **slower** than the KRON solution (and 5 times slower than the indexing solution `a(ceil((1:N*numel(a))/N))`). – gnovice Jan 25 '12 at 16:27
1
% To get b = [1 1 1 2 2 2 3 3 3]
N = 3;
a = [1 2 3];
temp_a = a(ones(N,1),:);
b = reshape(temp_a,1,numel(temp_a));

% To get b = [1 2 3 1 2 3 1 2 3]
N = 3;
a = [1 2 3];
temp_a = a(ones(N,1),:);
b = reshape(temp_a',1,numel(temp_a));