我想从两个角度(鸟瞰和青蛙的眼睛视角)可视化极地方法的算法。
要绘制方法的第一步,我需要在方形和圆形中均匀分布的随机数。
我已经能够在一个正方形中绘制圆圈了,但是如何在这个结构中绘制随机数(z1
)?
require (plotrix)
require (grid)
z1 = runif (100)
plot (c(-1,1), c(-1,1), type="n", asp=1)
rect(-1,-1,1,1)
draw.circle (0,0,1)
如何改变观点?
答案 0 :(得分:4)
你可以不“拒绝”任何一点。以下R函数需要3*n
个随机数,并会在半径为n
的圆中生成r
个随机选择的点:
randp <- function(n = 1, r = 1) {
if (n < 1 || r < 0) return(c())
x <- rnorm(n)
y <- rnorm(n)
r <- r * sqrt(runif(n)/(x^2 + y^2))
if (n == 1) U <- c(x, y)
else U <- cbind(r*x, r*y)
return(U)
}
答案 1 :(得分:3)
要绘制点,您需要x和y坐标。 ...但是由于你的方格从-1到1,你还需要缩放点(或改变方形):
x = runif(100, min=-1, max=1)
y = runif(100, min=-1, max=1)
points(x,y)
更新
这是一个在圆上生成随机数的函数。它使用拒绝来丢弃圆圈外的点。它使用(在我看来)有趣的方式:它生成一批数字,拒绝一些,然后生成更多,直到有足够的值可用。这通常比一次生成一个数字更有效......
再次更新我通过不追加新批次直到结束来提高速度。还增加了速度比较。
rndCircle <- function(n = 100, r=1) {
scale <- 1.15 # Generate 15% more values than requested
m <- matrix(0, 0, 2, dimnames=list(NULL, c('x','y')))
lst <- list(m)
nMore <- n
while (nMore > 0) {
#cat("nMore=", nMore, "\n") # uncomment to see how many iterations are needed
m <- matrix(runif(floor(nMore*scale)*2, min=-1, max=1), ncol=2)
m <- m[rowSums(m*m) <= 1, , drop=FALSE]
nMore <- nMore - nrow(m)
lst[[length(lst)+1L]] <- m
}
# Combine and truncate to desired length
do.call(rbind, lst)[seq_len(n),]*r
}
# Measure performance
set.seed(42); system.time( rndCircle(1e6) ) # 0.19
# Compare to @Hans Werner's solution
set.seed(42); system.time( randp(1e6) ) # 0.26