使用R中的均匀(0,1)生成N(0,1)
我尝试使用统一(0,1)生成N(0,1)进行模拟,但无法运行代码 首先,通过将x作为正常CDF的对象,然后取出直方图,找到my x。然后施加一条法线曲线以查看其是否适合。下面是我的代码使用R中的均匀(0,1)生成N(0,1),r,statistics,simulation,probability,normal-distribution,R,Statistics,Simulation,Probability,Normal Distribution,我尝试使用统一(0,1)生成N(0,1)进行模拟,但无法运行代码 首先,通过将x作为正常CDF的对象,然后取出直方图,找到my x。然后施加一条法线曲线以查看其是否适合。下面是我的代码 sigma=1; mu=0 u<-runif(n) x<-mu + sqrt(2*sigma(log(u*sigma*sqrt(2*pi)))) hist(x, Freq=F) xpt<-seq(-5,5,0.1) ypt<-dnorm(xpt,0,1) lines(xpt,ypt,col
sigma=1; mu=0
u<-runif(n)
x<-mu + sqrt(2*sigma(log(u*sigma*sqrt(2*pi))))
hist(x, Freq=F)
xpt<-seq(-5,5,0.1)
ypt<-dnorm(xpt,0,1)
lines(xpt,ypt,col=2)
sigma=1;μ=0
u你似乎颠倒了概率密度函数(PDF)而不是累积密度函数(CDF)
实际上,正态随机变量不是用逆CDF生成的,因为它的CDF不是封闭形式
检查Box-Muller变换。模拟两组独立的均匀随机变量:
u <- runif(1000)
v <- runif(1000)
x <- sqrt(-2 * log(u)) * cos(2 * pi * v)
# y <- sqrt(-2 * log(u)) * sin(2 * pi * v)
u我所有评论的来源:
Averill M.Law,W.David Kelton,《仿真建模与分析》,第三版,McGraw-Hill,2000年。ISBN:0-07-058290-4
通过生成两个U(0,1)随机变量,可以使用Box-Muller变换
`x1 = sqrt(-2 * log(u1)) * cos(2 * pi * u2)`
`x2 = sqrt(-2 * log(u1)) * sin(2 * pi * u2)`
概括而言:
box_muller <- function(n = 1, mean = 0, sd = 1)
{
x <- vector("numeric", n)
i <- 1
while(i <= n)
{
u1 <- runif(1, 0, 1)
u2 <- runif(1, 0, 1)
x[i] <- sqrt(-2 * log(u1)) * cos(2 * pi * u2)
if ((i + 1) <= n)
{
x[i + 1] <- sqrt(-2 * log(u1)) * sin(2 * pi * u2)
i <- i + 1
}
i <- i + 1
}
x * sd + mean
}
hist(box_muller(1000))
你也可以考虑<强> Ziggurat Alogrithm < /强>
< P>如果你想从倒CDF中得到真正的样本,那么CDF=1/2(1 +ERF(XMU/Sigma *SqRT(2)))
要反转它,需要erf-1(x),它可以用qnorm
表示。
沿途
erfinv <- function (x) {
qnorm((1.0 + x)/2.0)/sqrt(2.0)
}
sample <- function(U01, mu, sigma) {
N01 = sqrt(2.0) * erfinv( 2.0 * U01 - 1.0 )
mu + sigma*N01
}
n = 10
u <- runif(n)
q <- sample(u, 0.0, 1.0)
print(u)
print(q)
erfinv仅用于上下文:是否有理由不使用更高效、更紧凑的rnorm()
?
erfinv <- function (x) {
qnorm((1.0 + x)/2.0)/sqrt(2.0)
}
sample <- function(U01, mu, sigma) {
N01 = sqrt(2.0) * erfinv( 2.0 * U01 - 1.0 )
mu + sigma*N01
}
n = 10
u <- runif(n)
q <- sample(u, 0.0, 1.0)
print(u)
print(q)