1
votes

I am using Matlab function round(rand(256)) to create a square matrix of size 256x256 with random distribution of 0s and 1s.

What I specifically want to do is that I want to somehow specify number of 1s that rand() (or any other relevant function for that matter) to generate and distribute throughout the matrix randomly

3

3 Answers

3
votes

Magdrop’s answer is the most straight-forward method, it computes the percentile of the random values to determine the threshold.

Another two options involve randperm:

  1. Randomly permute all indices into the matrix, then threshold:

    sz = [256,256]; % matrix size
    n = 256; % number of zeros
    M = randperm(prod(sz)) <= n;
    M = reshape(M,sz);
    
  2. Randomly permute indices and select n as the locations of the ones:

    indx = randperm(prod(sz),n);
    M = zeros(sz);
    M(indx) = 1;
    
1
votes

You could also generate the random value the usual way, but before you round them, sort them as a vector. The number of 1s will the index in the sorted vector you want to cut for 1s or 0s. For example, let say we want 50 1s:

matrix = rand(256,256);
vec = sort(reshape(matrix,[],1));
thresh = vec(50);
matrix(matrix <= thresh) = 1;
matrix(matrix > thresh) = 0; 
0
votes

You could use the randi function to determine the locations of where to insert the ones, and then place those ones into your matrix. For example for n ones:

matrix = zeros(256,256);
onesIndices = randi([0 256*256],1,n);
matrix(onesIndices) = 1;

One problem with this approach is that randi can generate repeat values, though for this example, where the size of the matrix is large and the number of ones is low, this is pretty unlikely. You could test if this is the case and "reroll:" so if sum(sum(matrix)) is less than n you know you had a repeat value.

Edit: a better approach is to use randperm instead of randi and only take the first n elements. This should prevent there from being repeats and having to re-roll.