3

I have one array, for example B = [2,5,7], and also have a number C = 10, where C is always larger than or equal to the largest number in B. and I want to generate an array A according to B and C. In this specific example, I have

A = [1, 2, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9, 10]

that is, I generate an array [1:C], but with each element in B are duplicated 3 times. Is there any good way that does not use for loop to generate array A?

Thank you!

Divakar
  • 218,885
  • 19
  • 262
  • 358
ezheng
  • 103
  • 5

4 Answers4

3

You can use repelem (introduced in Matlab R2015a):

B = [2 5 7]
C = 10;
n = 3;

r = ones(1,C);
r(B) = n;
A = repelem(1:C, r)
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
2

How about...

B = [2,5,7];
C = 10;
A = sort([1:C,B,B])
RPM
  • 1,704
  • 12
  • 15
  • 1
    Overall, I like it. The main drawback is calling a sort function, which may be time-consuming. I wait if there are better answers. Thanks. – ezheng Oct 21 '15 at 06:16
  • Luis Mendo's answer is also good, but I do not have Matlab 2015. I accept this answer because it is easy and not error-prone. – ezheng Oct 25 '15 at 22:40
0

I think the answer of @RPM could be faster. But because you specifically asked for a solution without sort:

B = [2,5,7];
C = 10;
D = setdiff(1:C,B)-1;

A = reshape(repmat(1:C,3,1),1,3*C);
A([3*D+1,3*D+2]) = [];

which will also return the correct result. I'm not to sure about the order setdiff() has. It might be worse than sort() in all cases. Especially with A = sort([1:C,B,B]) as the input is already almost in order.

Dennis Klopfer
  • 759
  • 4
  • 17
  • 2
    @RPM's solution is 2 orders of magnitude faster than this. – IKavanagh Oct 21 '15 at 08:11
  • Good to know, thanks. Thats also why I upvoted his answer. Though, if the task is reversed and the numbers not in ``B`` should be trippled, this should be a reasonable solution avoiding ``sort()`` as one could get rid of ``setdiff()`` as well. – Dennis Klopfer Oct 21 '15 at 08:21
0

Following the same philosophy as this solution to Repeat copies of array elements: Run-length decoding in MATLAB, you can do something similar here, like this -

%// Get increment array (increments used after each index being repeated in B) 
inc = zeros(1,C);
inc(B+1) = N-1

%// Calculate ID array (places in output array where shifts occur)
id = zeros(1,C+(N-1)*numel(B));
id(cumsum(inc) + (1:C)) = 1

%// Finally get cumulative summation for final output 
A = cumsum(id)

Sample run -

B =
     2     5     7
C =
    10
N =
     3
inc =
     0     0     2     0     0     2     0     2     0     0
id =
     1     1     0     0     1     1     1     0     0     1     1     0     0     1     1     1
A =
     1     2     2     2     3     4     5     5     5     6     7     7     7     8     9    10
Community
  • 1
  • 1
Divakar
  • 218,885
  • 19
  • 262
  • 358