我需要写一个R代码,其中我将使用Box-Muller方法生成随机的卡方分布值。我有一个代码,用于生成从均匀到正态的随机值,然而,似乎无法找到我的方法来进一步为卡方和t分布做这件事。
这是一个通用代码:A <- runif(n, 0, 1)
B <- runif(n, 0, 1)
X1 <- sin(2*pi*A)*sqrt(-2*log(B))
X2 <- cos(2*pi*A)*sqrt(-2*log(B))
输出正态分布的rvs。现在我应该把X1 X2平方然后加起来吗?
在t分布中,如何从X1和X2中推导出一个正态分布变量?
正如stachan提到的,您需要对k个独立的正常RV的平方求和,以便生成具有k个自由度的卡方RV。然而,注意到X1
和X2
的平方之和化简为-2*log(B)
。这意味着如果k
是偶数,你只需要k/2
随机均匀变量,如果k
是奇数,你只需要k %/% 2 + 2
随机均匀变量。
使用Box-Muller变换生成具有df
自由度的n
随机卡方变量的函数看起来像这样:
rchisqBM <- function(n, df) {
k <- df %/% 2
if (k == df/2) {
return(-2*colSums(matrix(log(runif(n*k)), nrow = k)))
} else {
return(-2*(colSums(matrix(log(runif(n*k)), nrow = k)) + log(runif(n))*sin(2*pi*runif(n))^2))
}
}
对于具有k
自由度的t分布RV,将标准正态RV乘以sqrt(k/X2)
,其中X2
为卡方RV:
rnormBM <- function(n) {
k <- ceil(n/2)
theta <- 2*pi*runif(k)
if (k == n/2) {
return(sqrt(-2*log(runif(k)))*c(cos(theta), sin(theta)))
} else {
return(head(sqrt(-2*log(runif(k)))*c(cos(theta), sin(theta)), -1))
}
}
rtBM <- function(n, df) {
return(rnormBM(n)*sqrt(df/rchisqBM(n, df)))
}