1

I have 2 data vectors d1 = [1 2 1 3 4] and d2 = [3 1 2 1], and 2 references howMany1= [3 2 2 1 2] and howMany2 = [2 1 2 2]. The elements of d1 and d2 are to be repeated according to the elements of howMany1 and howMany2: so d1(1) i.e. the first element of d1 should repeat 3 times,d1(2) should repeat 2 times and so on.. and the final result should be d1_repeated = [1 1 1 2 2 1 1 3 4 4] and d2_repeated = [3 3 1 2 2 1 1]

How could I do that in MATLAB? I reviewed the a similar post in which one vector is being repeated, so I tried to do the same and made a for loop. Here is my code:

clear all
close all
clc
% data

d1 = [1 2 1 3 4];
d2 = [3 1 2 1];
howMany1 = [3 2 2 1 2]; % Determines how many times each index in IDX1 should be repeated.
howMany2 = [2 1 2 2];
d = {d1 d2}
howMany = {howMany1 howMany2}
Anew = cell(1,2)
for k = 1:2 % 2 data vectors     
Anew{1,k} = arrayfun(@(x) repmat(d{k}(x), howMany{k}(x), 1), 1:numel(d{k}), 'uni', 0);
Anew = vertcat(Anew{:});

end

but I receive the following error:

Error using vertcat

Dimensions of matrices being concatenated are not consistent.

Then I tried to change the vert cat to horzcat, but I receive the repetitions as group of doubles:

Anew = 

  Columns 1 through 7

    [3x1 double]    [2x1 double]    [1]    [2x1 double]    [2x1 double]    [2x1 double]    [3]

  Column 8

    [2x1 double]

Im wondering what is the problem here? Thank you for taking the time.

KianStar
  • 177
  • 1
  • 9

1 Answers1

4

This can be done by combining ismember and cumsum:

d1(cumsum(ismember(1:sum(howMany1),cumsum([1 howMany1]))))

Breakdown:

Compare 1:sum(howMany1) with the cumulative sum of howMany1. This is a vector with 1 and 0 that shows the position of where the next value from d1 should start.

ismember(1:sum(howMany1),cumsum([1 howMany1]))
ans =
     1     0     0     1     0     1     0     1     1     0

The cumulative sum of this gives a vector that looks like:

cumsum(ismember(1:sum(howMany1),cumsum([1 howMany1])))
ans =
     1     1     1     2     2     3     3     4     5     5

Now, this can be used as indices to d1 when creating the d1_repeated.

d1(cumsum(ismember(1:sum(howMany1),cumsum([1 howMany1]))))
ans =
     1     1     1     2     2     1     1     3     4     4
Stewie Griffin
  • 14,889
  • 11
  • 39
  • 70