2
votes

I'm trying to generate a randomly scattered but limited number of 1's in a matrix of zeros efficiently.

Say I have a 10x10 matrix of zeros (zeros(10)) and I want to randomly place ten 1's so it looks like:

     0     0     0     0     0     0     0     0     0     1
     0     0     0     0     0     1     0     0     0     0
     0     0     1     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     1     0
     1     0     0     0     0     1     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     1     0     0     0     0     0     0
     0     1     0     0     0     0     0     1     0     0
     0     0     0     0     1     0     0     0     0     0
     0     0     1     0     0     0     0     0     0     0

How can I do this WITHOUT a for-loop and without manually plugging in each position (this example is a much smaller version of my real problem)?

My code so far:

% Generate zeros
M = zeros(10)
% Generate random indices
Rands = [randsample(10, 10) randsample(10, 10)]

Where the first column is intended to be the row indices and the second column the column indices.

Now I obviously can't just drop these indices into the row and column indices of M like this:

M(Rands(:,1), Rands(:,2)) = 1

How can I vecorise the changes to these random indices?

2

2 Answers

5
votes

You can use randperm to randomly generate the linear indices to be filled with 1:

sz = [10 10]; % desired size
n = 10; % desired number of ones
M = zeros(sz);
M(randperm(prod(sz), n)) = 1;

Alternatively, you can use randperm and reshape in one line:

M = reshape(randperm(prod(sz))<=n, sz);
4
votes

You can use sub2ind to convert subscripts to linear index:

M(sub2ind(size(M),Rands(:,1),Rands(:,2)))=1