File Exchange

## Random Integer Generator

version 1.1.0.0 (6.74 KB) by
This program quickly outputs n random integers in the specified range from a to b.

Updated 23 Dec 2013

View Version History

The program quickly outputs n random integers in the range from a to b. The integers are drawn from a uniform distribution to make selection of integers equally probable.

This program is intended to be especially quick with very large ranges of integers and selecting only a very small number of those integers.

User specifies whether output is sorted or random order.

User specifies whether to remove duplicate integers or to allow duplicate integers.

### Cite As

Edward Zechmann (2021). Random Integer Generator (https://www.mathworks.com/matlabcentral/fileexchange/18443-random-integer-generator), MATLAB Central File Exchange. Retrieved .

Tyler

The help for this file says that a 0 as the third input removes duplicates and 1 keeps them (lines 23-25). This is backward. It is listed correctly in the example however. Otherwise, its a useful function.

Karim Mansour

Very Nice ! Thanks

John D'Errico

Perhaps one of the changes made fixed the bug I found. This now works properly:

rand_int(1,3,2)
ans =
1
3

John D'Errico

Better now. But further testing found a new bug. Sampling 2 integers from a range that is 4 integers long or longer works fine.

rand_int(1,4,2)
ans =
4
2

But, if I want exactly 2 random integers from the set [1 2 3], I only get 1 integer.

rand_int(1,3,2)
ans =
3

The other improvements bring this much closer to a 5. I'd have rated it a 5 until I found this problem. Since this bug (it should be a trivial fix) would push me down to a 4 rating, I won't propose a new rating until I check back for the repaired version.

John D'Errico

I'd have to disagree with Jos here. There is value in a code which performs more quickly than a simple solution.

a=0;b=1000000;n=10;

tic,r = randperm(b-a+1) - 1 ;r = a + r(1:n) ;toc
Elapsed time is 0.883846 seconds.

tic,x = rand_int(a,b,n);toc
Elapsed time is 0.003325 seconds.

If you often need to sample only a few integers without replacement from a large set, this seems like a worthwhile utility. Admittedly, its a lot of code for something that might have been done more simply. For example, a simple, brute force, pure rejection code should work fairly well too:

function x = johnsrandint(a,b,n)
flag = true;
while flag
x = unique(round((a - 1/2) + (b-a+1)*rand(n,1)));
flag = (length(x)~=n);
end

tic,x = johnsrandint(0,1000000,10);toc
Elapsed time is 0.000656 seconds.

tic,x = rand_int(a,b,n);toc
Elapsed time is 0.002503 seconds.

On the other hand, there are regimes where my simple alternative is also not efficient. For example, when n is any significant fraction of (b-a), my version may be slow, since then the probability of too many rejection steps occurring will be high. So the author might choose to add a third regime to his code, for extremely small samples relative to (b-a).

On to the real purpose of a review...

This code is generally well written. It has good internal comments that explain what is done at each step. This is helpful for debugging purposes.

The code checks for inconsistent inputs, and attempts to return something logical anyway. I'd be tempted to return an error there, or at least a warning message, but the author is not unreasonable in this approach.

The help is expansive and descriptive, with examples of use. My only comment on the help is that I'd like to see a better description of what is to be expected. For example, the only description of the ndraw output is:

% % ndraw is the array of selected integers. The output is sorted.

We can infer that ndraw is an array. But is it a vector? What shape should we expect it to be? Row or column vector? We know that the array is sorted, but in which order? Tell your user these things, rather than forcing them to test run the code to find out that information.

I'd also suggest a bit more explicitness in the description of the inputs. Must it be true that a<=b ? What happens if this fails to be true? What if n>(b-a) ? Must {a,b,n} all be integers? What happens if n is not an integer?

Next, there is a bug in this code. The author has attempted to ensure that all integers are equally likely to be drawn, without replacement. He has done so by expanding the region of sampling by +/- 0.5. He also uses floor and ceil to ensure that the input interval ends are integer. So a few quick test runs by me found the following bug:

rand_int(0.25, 10, 5)
ans =
0
1
4
7
8

Note that the lower endpoint was 0.25, yet the sample had a 0 in it. The bug can be repaired of course, with a quick test in the very beginning.

I was originally expecting to apply a 4 rating to this code, but when I recognized the existence of a bug, it pushed me down to a 3. I will always consider revising a rating upwards if/when I learn of repairs to the code & help.

Jos x@y.z

If any, this submission has only educational value, and the author should stress that quite explicitly.

r = randperm(b-a+1) - 1 ;
r = a + r(1:n) ;

will do the job much smoother.

##### MATLAB Release Compatibility
Created with R2007b
Compatible with any release
##### Platform Compatibility
Windows macOS Linux