从 Python 中的正态分布生成数字
Generating numbers from normal distribution in Python
我正在尝试使用针对 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)
对于"fun",我是用go写的。 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
我正在尝试使用针对 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)
对于"fun",我是用go写的。 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