2015-10-22 2 views
3

Я пытаюсь проверить скорость генерации чисел из нормального распределения с помощью преобразования Box-Muller против полярного метода Марсалья. Говорят, что полярный метод Марсалии, как предполагается, быстрее, чем преобразование Box-Muller, потому что ему не нужно вычислять sin и cos. Однако, когда я кодирую это в Python, это неверно. Может кто-нибудь проверить это или объяснить мне, почему это происходит?Генерация чисел из нормального распределения в Python

def marsaglia_polar(): 
    while True: 
     x = (random.random() * 2) - 1 
     y = (random.random() * 2) - 1 
     s = x * x + y * y 
     if s < 1: 
      t = math.sqrt((-2) * math.log(s)/s) 
      return x * t, y * t 

def box_muller(): 
    u1 = random.random() 
    u2 = random.random() 

    t = math.sqrt((-2) * math.log(u1)) 
    v = 2 * math.pi * u2 

    return t * math.cos(v), t * math.sin(v) 
+0

Не видя кода !? – tzaman

+0

Мы можем, если вы покажете нам свой код – inspectorG4dget

+0

К сожалению, добавлено !!!! – user2770287

ответ

2

Для «забавы» я написал его в режиме «go». Функция box_muller также работает быстрее. Кроме того, это примерно в 10 раз быстрее, чем версия python.

package main 

import (
    "fmt" 
    "math" 
    "math/rand" 
    "time" 
) 

func main() { 
    rand.Seed(time.Now().UnixNano()) 
    now := time.Now() 
    for i := 0; i < 1000000; i++ { 
     marsaglia_polar() 
    } 
    fmt.Println("marsaglia_polar duration = ", time.Since(now)) 
    now = time.Now() 
    for i := 0; i < 1000000; i++ { 
     box_muller() 
    } 
    fmt.Println("box_muller duration  = ", time.Since(now)) 
} 

func marsaglia_polar() (float64, float64) { 
    for { 
     x := random() * 2 - 1; 
     y := random() * 2 - 1; 
     s := x * x + y * y; 
     if s < 1 { 
      t := math.Sqrt((-2) * math.Log(s)/s); 
      return x * t, y * t 
     } 
    } 
} 

func box_muller() (float64, float64) { 
    u1 := random() 
    u2 := random() 
    t := math.Sqrt((-2) * math.Log(u1)) 
    v := 2 * math.Pi * u2 
    return t * math.Cos(v), t * math.Sin(v) 
} 

func random() float64 { 
    return rand.Float64() 
} 

Выход:

marsaglia_polar duration = 104.308126ms 
box_muller duration  = 88.365933ms 
Смежные вопросы