Почему два случайных отклонения необходимы для обеспечения равномерной выборки больших целых чисел с помощью sample()?

Учитывая, что следующие эквиваленты, мы можем заключить, что R использует ту же функцию C runif для генерации однородных выборок для sample() и runif()...

set.seed(1)
sample(1000,10,replace=TRUE)
#[1] 27 38 58 91 21 90 95 67 63  7

set.seed(1)
ceiling( runif(10) * 1000 )
#[1] 27 38 58 91 21 90 95 67 63  7

Однако они не эквивалентны при работе с большими числами (n > 2^32 - 1):

set.seed(1)
ceiling( runif(1e1) * as.numeric(10^12) )
#[1] 265508663143 372123899637 572853363352 908207789995 201681931038 898389684968
#[7] 944675268606 660797792487 629114043899  61786270468

set.seed(1)
sample( as.numeric(10^12) , 1e1 , replace = TRUE )
#[1] 2655086629 5728533837 2016819388 9446752865 6291140337 2059745544 6870228465
#[8] 7698414177 7176185248 3800351852

Update

Как @Arun указывает 1-й, 3-й, 5-й,... из runif() приблизительный результат 1-го, 2-го, 3-го... от sample().

Оказывается, что обе функции вызывают unif_rand() за кулисами, однако sample, учитывая аргумент, n, который больше, чем наибольшее представляемое целое число типа "integer", но представляемое как целое число как тип "numeric" использует это статическое определение для рисования случайного отклонения (в отличие от просто unif_rand(), как в случае runif())...

static R_INLINE double ru()
   {
       double U = 33554432.0;
       return (floor(U*unif_rand()) + unif_rand())/U;
   }

С загадочной записью в документах, которые...

Два случайных числа используются для обеспечения равномерной выборки больших целых чисел.

  • Почему два случайных числа необходимы для обеспечения равномерной выборки больших целые числа?

  • Что такое константа U для и почему она принимает конкретное значение 33554432.0?

Ответ 1

Причина в том, что 25-разрядный PRNG не будет генерировать достаточное количество бит для генерации всех возможных целочисленных значений в диапазоне, превышающем 2 ^ 25. Чтобы дать ненулевую вероятность для каждого возможного целочисленного значения, необходимо дважды вызвать 25-битный PRNG. С двумя вызовами (например, в коде, который вы цитируете) вы получаете 50 случайных бит.

Обратите внимание, что a double имеет 53 бит мантиссы, поэтому вызов PRNG дважды по-прежнему не имеет 3 бит.