Excel VBA: реализация алгоритма Box Muller, Zigurrat и Ratio of Uniforms - PullRequest
0 голосов
/ 09 января 2019

Это очень специфический вопрос, объединяющий стохастические знания и навыки VBA. Очень волнительно!

Я пытаюсь сравнить несколько методов генерации стандартных, нормально распределенных чисел с учетом источника равномерно распределенных случайных чисел. Поэтому я реализую алгоритм Box Muller , Ziggurat Algorithm и Ratio of Uniforms Algorithm . Каждая реализация прекрасно работает с точки зрения генерации чистого стандарта, обычно распространения. (проверено Шапиро-Вилк-Тест ).

Что я хочу выяснить: Какой самый быстрый метод ?

Тестирование каждой отдельной программы с общим числом сгенерированных 10 ^ 7 чисел это время выполнения:

Box-Muller: 3,7 секунды
Зиккурат: 1,28 секунды
Соотношение Униформа: 10,77 секунд

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

Моя проблема : после некоторых исследований я обнаружил, что алгоритм отношения форм должен быть самым быстрым (примерно в 3–4 раза быстрее, чем Бокс Мюллер). Эта информация только опирается на этот стек :

enter image description here

Мне любопытно , если это просто неправильное утверждение этого пользователя или (что я действительно ожидаю большего) , если мой код реализован не полностью . Поэтому я опубликую свой код и надеюсь, что кто-то может помочь мне с моим вопросом, если мой код просто не достаточно хорош или Ratio of Uniforms просто не работает так быстро, как упоминалось.

Sub RatioUniforms()

Dim x(10000000) As Double
Dim passing As Long
Dim amount As Long: amount = 10000000
Dim u1 As Double
Dim u2 As Double
Dim v2 As Double

    Do While passing <= amount
        Do
            u1 = Rnd    'rnd= random number(0,1)
        Loop Until u1 <> 0  'u1 musn't become 0
        v2 = Rnd
        u2 = (2 * v2 - 1) * (2 * exp(-1)) ^ (1 / 2)
        If u1 ^ 2 <= exp(-1 / 2 * u2 ^ 2 / u1 ^ 2) Then
            x(passing) = u2 / u1
            passing = passing + 1
        End If
    Loop

 End Sub

Большое спасибо, что помогаете мне в этом разговоре. Может быть, некоторые из вас пробовали эти алгоритмы на VBA или других языках и могут помочь мне с опытом работы во время выполнения? Если вам нужно что-то еще узнать о моих других реализациях, просто дайте мне знать. Хорошего дня!

...