I'm facing a problem. I have a zeros matrix 600x600
. I need to fill this matrix with 1080 1
s randomly. Any suggestions?
Asked
Active
Viewed 286 times
3 Answers
6
Or, use the intrinsic routine randperm
thusly:
A = zeros(600);
A(randperm(600^2,1080)) = 1;

High Performance Mark
- 77,191
- 7
- 105
- 161
-
-
@Adriaan: thanks. I'm working on a machine w'out Matlab at the moment. – High Performance Mark Jan 04 '16 at 11:35
-
1Performance wise currently my answer is fastest, yours second and Patrik's third; if you initialise a sparse matrix instead yours is fastest by far. – Adriaan Jan 04 '16 at 11:52
-
2A [`sparse` array](https://en.wikipedia.org/wiki/Sparse_matrix) (instead of a full, `zeros` array) is probably a better idea in this scenario, due to the low sparsity (0.3%; as mentioned by Adriaan), which could increase performance in any subsequent computations. Yet if a full matrix must be used, depending on whether this array needs to be re-initialized many times or not, one might resort to ["preallocation using the corner element"](http://undocumentedmatlab.com/blog/preallocation-performance#non-default) or [`nullcopy`](http://www.mathworks.com/help/simulink/slref/coder.nullcopy.html). – Dev-iL Jan 04 '16 at 12:13
-
Hmmm.. in `R`, where one can specify randoms with or without replacement, `A = matrix(0,600,600); A[ sample(1:600^2,1080,replace=FALSE)] = 1;` runs pretty fast. Dunno where the hangup is in your answer. – Carl Witthoft Jan 04 '16 at 14:36
-
@CarlWitthoft the array's small enough that it is fast anyway, but when you increase the size (say 1e4 square) the sparsity helps MATLAB in calculating only things for the desired elements, and not everything else as well. Same with allocating memory for a sparse array or full array, see the docs Dev-iL linked. – Adriaan Jan 04 '16 at 22:44
3
A = sparse(600,600); %// set up your matrix
N=1080; %// number of desired ones
randindex = randi(600^2,N,1); %// get random locations for the ones
while numel(unique(randindex)) ~= numel(randindex)
randindex = randi(600^2,N,1); %// get new random locations for the ones
end
A(randindex) = 1; %// set the random locations to 1
This utilises randi
to generate 1080
numbers randomly between 1
and 600^2
, i.e. all possible locations in your vectors. The while
loop is there in case it happens that one of the locations occurs twice, thus ending up with less than 1080 1
.
The reason you can use a single index in this case for a matrix is because of linear indexing.
The big performance difference with respect to the other answers is that this initialises a sparse matrix, since 1080/600^2 = 0.3%
is very sparse and will thus be faster. (Thanks to @Dev-iL)
2
This is one way to do it,
N = 1080; % Number of ones
M = zeros(600); % Create your matrix
a = rand(600^2,1); % generate a vector of randoms with the same length as the matrix
[~,asort] = sort(a); % Sorting will do uniform scrambling since uniform distribution is used
M(asort(1:N)) = 1; % Replace first N numbers with ones.

patrik
- 4,506
- 6
- 24
- 48