如何使用 box muller 变换生成随机 x 和 y 坐标
How to generate random x and y coordinates using box muller transformation
我正在尝试使用 box muller 变换生成特定范围内(大约 -10 到 +10)的随机 x
和 y
整数值。
我已经记录了一个数据集并计算了每个轴的标准差 sdX = 4.413680773
和 sdY = 4.361846901
。
我试图阅读有关 box muller 变换的内容,但是我一直无法找到很多不涉及希腊字符的清晰信息,因为我已经好几年没有做过那种数学运算了。如果有人能用简单的英语解释我将如何处理这个问题,甚至可以使用 python 代码示例,我们将不胜感激。
您不必自己实施 box-muller 转换。如果想生成正态分布的随机数,可以直接使用numpy。
import numpy as np
mu_x, sigma_x = 0, 4.413680773
s = np.random.normal(mu_x, sigma_x, 1000)
如果您想从二维高斯分布中生成一些随机数,您必须计算协方差并使用 np.random.multivariate_normal
mean = (1, 2)
cov = [[1, 0], [0, 1]]
points = np.random.multivariate_normal(mean, cov, 1000)
通过 Box-Muller 生成普通 RV 所需的代码量并不多。下面的大部分代码都设置了可视化,因此我们可以说服自己该方法是正确的。
不清楚您所说的粗略 (-10, 10) 范围是什么意思。我正在这段代码中生成标准法线变量。您可以根据需要缩放或移动它们。
代码:
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import scipy
# generate two sets of U(0, 1) random variables
u1 = np.random.uniform(size=10000)
u2 = np.random.uniform(size=10000)
# generate *independent* normal random variables using Box-Muller
R_sq = -2 * np.log(u1)
theta = 2 * np.pi * u2
z1 = np.sqrt(R_sq) * np.cos(theta)
z2 = np.sqrt(R_sq) * np.sin(theta)
# compute theoretical normal distribution
x = np.linspace(-4, 4, 1000)
y = scipy.stats.norm.pdf(x, 0, 1)
# plot (kernel density estimated) empirical distribution against theoretical
fig, axes = plt.subplots(2, 1)
axes[0].plot(x, y, label='empirical')
sns.kdeplot(z1, ax=axes[0], label='theoretical')
axes[1].plot(x, y, label='empirical')
sns.kdeplot(z2, ax=axes[1], label='theoretical')
plt.show()
# print correlation matrix of z1 and z2 (as evidence of their independence)
print(np.corrcoef(z1, z2))
控制台输出:
在这里,我们在主对角线上恰好看到 1(表示 z1 和 z1 之间以及 z2 和 z2 之间的完美相关性),而 z1 和 z2 之间的相关性几乎为 0。 (零相关并不意味着独立。但是,如果z1和z2是独立的,则它们将具有零相关。这只是一个试金石。)
[[ 1. -0.00842543]
[-0.00842543 1. ]]
可视化:
为了说服自己,我们实际上生成了正常的 RV。
我正在尝试使用 box muller 变换生成特定范围内(大约 -10 到 +10)的随机 x
和 y
整数值。
我已经记录了一个数据集并计算了每个轴的标准差 sdX = 4.413680773
和 sdY = 4.361846901
。
我试图阅读有关 box muller 变换的内容,但是我一直无法找到很多不涉及希腊字符的清晰信息,因为我已经好几年没有做过那种数学运算了。如果有人能用简单的英语解释我将如何处理这个问题,甚至可以使用 python 代码示例,我们将不胜感激。
您不必自己实施 box-muller 转换。如果想生成正态分布的随机数,可以直接使用numpy。
import numpy as np
mu_x, sigma_x = 0, 4.413680773
s = np.random.normal(mu_x, sigma_x, 1000)
如果您想从二维高斯分布中生成一些随机数,您必须计算协方差并使用 np.random.multivariate_normal
mean = (1, 2)
cov = [[1, 0], [0, 1]]
points = np.random.multivariate_normal(mean, cov, 1000)
通过 Box-Muller 生成普通 RV 所需的代码量并不多。下面的大部分代码都设置了可视化,因此我们可以说服自己该方法是正确的。
不清楚您所说的粗略 (-10, 10) 范围是什么意思。我正在这段代码中生成标准法线变量。您可以根据需要缩放或移动它们。
代码:
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import scipy
# generate two sets of U(0, 1) random variables
u1 = np.random.uniform(size=10000)
u2 = np.random.uniform(size=10000)
# generate *independent* normal random variables using Box-Muller
R_sq = -2 * np.log(u1)
theta = 2 * np.pi * u2
z1 = np.sqrt(R_sq) * np.cos(theta)
z2 = np.sqrt(R_sq) * np.sin(theta)
# compute theoretical normal distribution
x = np.linspace(-4, 4, 1000)
y = scipy.stats.norm.pdf(x, 0, 1)
# plot (kernel density estimated) empirical distribution against theoretical
fig, axes = plt.subplots(2, 1)
axes[0].plot(x, y, label='empirical')
sns.kdeplot(z1, ax=axes[0], label='theoretical')
axes[1].plot(x, y, label='empirical')
sns.kdeplot(z2, ax=axes[1], label='theoretical')
plt.show()
# print correlation matrix of z1 and z2 (as evidence of their independence)
print(np.corrcoef(z1, z2))
控制台输出: 在这里,我们在主对角线上恰好看到 1(表示 z1 和 z1 之间以及 z2 和 z2 之间的完美相关性),而 z1 和 z2 之间的相关性几乎为 0。 (零相关并不意味着独立。但是,如果z1和z2是独立的,则它们将具有零相关。这只是一个试金石。)
[[ 1. -0.00842543]
[-0.00842543 1. ]]
可视化: 为了说服自己,我们实际上生成了正常的 RV。