Почему генерация случайных чисел из распределения ядра в 1000 раз медленнее, если усечь? - PullRequest
0 голосов
/ 23 сентября 2018

Я бы предпочел усечь мой дистрибутив, но на данный момент это просто невозможно, учитывая штраф времени.

Стандартное распределение ядра:

expectation=fitdist(BTS,'kernel');

Результат:

tic;expectation.random(10000,1);toc;
Elapsed time is 0.000745 seconds.

Сокращенный код:

Exp{i,j}=truncate(expectation,min(BTS)-1,max(BTS)+1);

Результат:

tic;random(Exp{i,j},1,10000);toc
Elapsed time is 0.772295 seconds.

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Примечание: Это скорее комментарий, но он был слишком длинным, чтобы поместиться в разделе комментариев.

Matlab не обязательно обеспечивает самый быстрый способ генерации случайных чисел.Одним из крайних случаев является биномиальная случайная величина, которую matlab генерирует путем рисования n чисел Бернулли и их суммирования.Ваш пример - просто другой случай.

Я предлагаю вам либо

  • реализовать выборку самостоятельно, поэтому вы можете настроить ее для своих нужд,

  • или использоватьШопена, см. статью здесь , которую вы можете получить здесь , которая (насколько мне известно) является самым новым из таких алгоритмов

Пожалуйста, обратите внимание, что хотя "усечение" звучит так, как будто это делает вещи проще / быстрее, это не всегда так.Особенно в наши дни, когда существуют очень быстрые генераторы для нормального распределения.С другой стороны, x1000 слишком большой штраф по сравнению с лучшими методами.

0 голосов
/ 24 сентября 2018

В качестве альтернативы вы можете попытаться извлечь случайные числа из неусеченного дистрибутива и выполнить усечение самостоятельно.

У меня нет набора инструментов статистики, поэтому я буду использовать randn здесь, чтобырисует случайные числа:

function M = truncated_normal(n)
M = randn(n,1);
I = M < -2 | M > 2;
n = nnz(I);
if n>0
   M(I) = truncated_normal(n);
end

Эта функция извлекает n случайные числа из заданного распределения, затем находит любые значения, которые находятся за пределами выбранного интервала (M < -2 | M > 2), и выводит новые значения для них с помощьюрекурсивный вызов самого себя.

Функция также может быть записана с циклом while, если вы предпочитаете.Но пока вероятность случайного значения в хвостах мала, требуется очень мало итераций.

...