collegesista
collegesista

Reputation: 87

Creating a random int generator with an even probability

In the code below, I want to ensure that there is an even chance of theImageRand being equal to theImage or theImage2, but I realized that between 1 and 100 more numbers are equal to 2 mod 1 than 2 mod 0. So theImage is being chosen a disproportionate amount of the time.

This was the simplest idea that came to me, but maybe there is a function that can do this easier? I was also thinking that I could find a number that fits what I'm looking for and put that into randi(n).

xRand = randi(100);
    if mod(xRand,2) == 1 
       theImageRand = theImage;
    elseif mod(xRand,2) == 0
       theImageRand = theImage2;
    end

Please let me know if I can explain more clearly. Thanks in advance.

Upvotes: 2

Views: 64

Answers (2)

Matt
Matt

Reputation: 13953

tl;dr

Your code does exactly what you want, but it can be simplified by using randi(2) and removing the calculation of mod. However, it is worth to address some more points...


mod(xRand,2) to reduce 1-100 to 0/1

For xRand between 1 and 100, the result of mod(xRand,2) will be distributed equally on 0 and 1 as you can see by executing the following code:

xRand = 1:100;
xMod = mod(xRand,2);
cnt1 = sum(xMod == 1)    % results in 50
cnt0 = sum(xMod == 0)    % results in 50 as well

Basically, your code works as expected because randi chooses uniformly distributed numbers from 1 to 100. Subsequently, mod reduces them into a binary representation which is still uniformly distributed since the mapping is done for equal bins.


Simplification using randi(2)

The whole process of generating these uniformly distributed binary numbers can be simplified by just generating a binary set from the beginning. To achieve this, you can use randi(2) which directly gives you 1 or 2 as rayryeng pointed out in his comment to the question.
That would give you the following code:

xRand = randi(2);
if xRand == 1 
   theImageRand = theImage;
elseif xRand == 2
   theImageRand = theImage2;
end

Is it correct?

Now we have a look at the interesting part of this question: Is the result really uniformly distributed? To check that, we can run the code N times and then analyze how many times each image has been chosen. Therefore, we assign 1 to the first image and 2 to the second image and store the result in res. After the for-loop, we take the sum of the elements where they are 1 or 2.

N = 1000000;

theImage = 1;
theImage2 = 2;

res = zeros(N,1);

for n = 1:N
    xRand = randi(2);
    if xRand == 1
       theImageRand = theImage;
    elseif xRand == 2
       theImageRand = theImage2;
    end
%     xRand = randi(100);
%     if mod(xRand,2) == 1
%        theImageRand = theImage;
%     elseif mod(xRand,2) == 0
%        theImageRand = theImage2;
%     end
    res(n) = theImageRand;
end

cnt1 = sum(res==1);
cnt2 = sum(res==2);

percentage1 = cnt1/N*100    % approximately 50
percentage2 = cnt2/N*100    % approximately 50 as well

As we can see, percentage1 and percentage2 are approximately 50 which means the two images get both chosen around 50% of the time. It can be misleading to count the difference between cnt1 and cnt2 because this number can be high if N is large. However, if we observe this difference for many realization, the overall mean will be approximately zero. Furthermore, we can observe that your code using mod(randi(100),2) gives a distribution of 50% as well. It is just not as efficient and straight-forward as the solution with randi(2), which performs approximately 15% faster on my machine using R2016a.

Bottomline: I would recommend to use randi(2) as proposed above since it is more intuitive and more efficient as well. The observed difference is attributed to the random process and equalizes itself with more realizations. It is important to consider the percentage and not the absolute difference of the two images.

Upvotes: 5

user6549996
user6549996

Reputation:

You can generate a number between zero and two and then check if xRand equals zero or one, which has an even chance of happening; however larger numbers make the chance of getting one over the other vary more.

(I've said two because when declaring random values, always have one extra.)

Upvotes: 0

Related Questions