## Create a 20x24 matrix with each individual column with random integers without duplicate

### Hyunjae Jeon (view profile)

on 16 Apr 2019
Latest activity Edited by Jan

on 17 Apr 2019

### KSSV (view profile)

Hello,
I am trying to create a 20x24 matrix with each individual column containing random integers without duplicate.
(I just made this number but the size will become bigger)
So far, I could make a 20x1 column named "randomcolumn" containing random numbers by using following codes.
random=randperm(20,20);
randomcolumn=random.';
I am stuck with making this to run with for loop function so that individual columns will add up 24 times.
n=24;
for i=1:n
randomcolumn
end
Any help will be very appreciated. Thank you

### KSSV (view profile)

on 16 Apr 2019

iwant = zeros(20,24) ;
for i = 1:24
iwant(:,i) = randperm(20,20);
end

Hyunjae Jeon

### Hyunjae Jeon (view profile)

on 16 Apr 2019
It worked. Thank you so much!

### Stephen Cobeldick (view profile)

on 16 Apr 2019
Edited by Stephen Cobeldick

### Stephen Cobeldick (view profile)

on 16 Apr 2019

You do not need a loop, here is a much simpler solution in just one line:
>> [~,M] = sort(rand(20,24),1)
M =
16 20 17 10 15 10 13 6 16 13 11 18 12 16 4 17 20 4 1 7 8 12 16 14
10 10 19 14 12 7 1 11 12 16 2 5 8 15 15 14 17 3 19 6 19 2 13 17
20 12 10 8 14 19 14 12 20 9 19 9 1 10 9 9 6 17 10 12 17 20 7 11
17 8 9 5 3 12 18 19 2 17 8 2 11 8 12 2 16 16 15 11 1 18 8 12
4 5 16 7 2 6 2 10 17 14 17 19 10 3 18 16 11 13 7 2 16 6 20 9
3 11 3 20 4 13 12 5 8 11 14 6 3 13 16 3 4 7 12 14 7 5 11 20
15 9 13 2 8 17 16 17 19 7 7 7 9 19 2 4 15 2 13 1 10 9 2 18
11 17 20 9 11 18 6 20 4 8 5 12 18 1 5 8 5 6 14 8 18 15 9 16
5 6 7 4 20 14 5 15 9 3 4 17 15 2 7 18 2 19 8 18 9 14 4 2
6 19 11 15 13 9 7 16 15 12 1 14 6 9 13 11 8 9 3 4 11 8 6 13
12 16 2 17 18 16 15 4 7 4 10 3 17 14 14 7 7 18 6 17 4 16 12 6
14 3 1 13 6 5 4 7 11 15 20 13 19 17 19 1 18 11 11 13 14 7 14 8
19 15 14 11 10 20 3 1 6 10 15 20 14 7 11 12 12 14 17 9 2 11 5 15
1 14 6 3 5 8 19 13 10 18 6 8 16 6 8 20 9 1 16 16 3 17 17 4
8 2 12 19 7 1 8 8 1 1 16 15 7 4 20 5 19 8 5 10 5 3 10 10
18 7 15 12 16 2 20 9 14 20 3 10 2 12 1 15 1 15 18 19 15 10 1 1
2 18 5 6 19 15 9 18 13 19 9 4 20 20 10 13 3 20 20 15 12 19 19 5
9 4 4 18 9 4 17 2 18 2 13 16 4 11 17 19 13 10 9 5 13 13 18 7
13 1 18 1 17 11 10 3 3 5 18 1 5 5 3 6 14 12 2 20 20 1 3 19
7 13 8 16 1 3 11 14 5 6 12 11 13 18 6 10 10 5 4 3 6 4 15 3

Jan

### Jan (view profile)

on 17 Apr 2019
@Stephen: Simpler, but flawed. Modern randperm implementations use the efficient and not flawed Fisher-Yates-Shuffle (also called Knuth-Shuffle), while sorting random numbers has the (tiny) problem, that Matlab's sorting is stable, so if rand replies 2 equal numbers, their order is kept. rand can reply 2^53 different numbers, and the probability to get 2 equal elements is:
m = 2^53;
n = 20;
P = 1 - (m * (m-1) * . . . * (m-n+1)) / m^n
It is tiny, but not vanishing.
Stephen Cobeldick

### Stephen Cobeldick (view profile)

on 17 Apr 2019
"...so if rand replies 2 equal numbers.."
I would be interested to know what is the actual probabilty of that occuring, to know exactly how "tiny" it is. Would a numeric calculation be robust enough?
According to the randperm documentation "randperm uses the same random number generator as rand, randi, and randn": if they use the same random number generator, why are there more different numbers available for randperm ? Given that they use the same random number generator, the only way randperm could be more random than sort(rand(..)) is if it detected identical values and called that random number generator again for them, repeating until no duplicate values exist. Is this documented somewhere?
Jan

### Jan (view profile)

on 17 Apr 2019
@Stephen: I've posted the function to determine the probability in my comment already.
randperm was a simple sort(rand()) call in older Matlab versions. To obtain much more speed and to avoid the mentioned problem, I've implemented the Fisher-Yates shuffle: FEX: Shuffle as C-Mex function. One of the implementations in Matlab:
for i = 2:numel(X) % Shuffle in forward direction:
w = ceil(rand * i); % 1 <= w <= i
t = X(w);
X(w) = X(i);
X(i) = t;
end
See https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle. Although this algorithm uses the same pseudo random number generators as randperm, it does not suffer from the problem of equal numbers and the stable sorting.
Note that this is biased also: ceil(rand * i) is not perfectly equally distributed: rand replies values equally distributed in (0,1) with 53 bit resolution. If this range is multiplied by 2, 3, 4, 5, ... you get different numbers of elements for the different integers. Better (if MathWorks has implemented randi carfully!):
w = randi([1, i]);