Independent random selection with replacement of elements per column in a matrix

I have a matrix A which is of size r1 x c. I'm trying to create a matrix B which is of size r2 x c where for each individual column, I would like to randomly sample with replacement.

I wrote this code that does what I am looking for:

%// Define a random index : 
RO = randi(r1,r2,c);

%// Define an output matrix
B = zeros(r2,c);

%// Perform selection        
for i1 = 1:c
    for i2 = 1:r2
        B(i2,i1) = A(RO(i2,i1),i1);
    end
end

Is there an easier and/or faster way to do this in MATLAB without loops?

Upvotes: 1

Views: 62

Answers (1)

rayryeng
rayryeng

Reputation: 104545

If I am interpreting this code correctly, you have a matrix and for each column, you consider this to be an individual signal and you want to randomly sample r2 elements from each signal to create another r2 signal that possibly has duplicates. You wish to stack these columns horizontally to generate an output matrix. A property with this matrix is that for each column, this random sampling is applied only for the corresponding column in the input matrix.

You can certainly do this vectorized. The matrix RO would be used as row coordinates and the column coordinates, which we will call RC, would simply be matrix of enumerations where each row is the linear range 1:c and there are r2 of these stacked on top of each other. This can be achieved with repmat.

First obtain the linear indices of the row and column coordinates via sub2ind then use this to index into your input matrix A.

RO = randi(r1,r2,c);
RC = repmat(1:c,r2,1);
ind = sub2ind(size(A), RO, RC);
B = A(ind);

To show that this works, I've created the following data:

rng(123);
r1 = 5;
r2 = 10;
c = 3;
A = randi(10, r1, c);

Running your code above gives me:

>> B

B =

     6    10     8
     7    10     5
     7    10     4
     3    10     4
     3     5     5
     6     5     1
     8     7     4
     6     7     8
     6     7     5
     6     7     4

Using the same matrix RO that was generated, the more optimized code that I wrote also gives:

>> B

B =

     6    10     8
     7    10     5
     7    10     4
     3    10     4
     3     5     5
     6     5     1
     8     7     4
     6     7     8
     6     7     5
     6     7     4

Upvotes: 0

Related Questions