我试图通过使用针对Marsaglia极坐标法的Box-Muller变换来测试从正态分布生成数字的速度。据说Marsaglia极坐标法比Box-Muller变换要快,因为它不需要计算sin和cos。但是,当我用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)
为了“有趣”,我在旅途中写下了它。该box_muller
功能在那里也更快。而且,它比python版本快10倍。
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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句