我想从两个角度(鸟瞰和青蛙的视角)可视化 Polar 方法的算法。
要绘制该方法的第一步,我需要在正方形和圆形中均匀分布的随机数。
我已经能够在正方形中绘制圆,但是如何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)
以及如何改变视角?
我想从两个角度(鸟瞰和青蛙的视角)可视化 Polar 方法的算法。
要绘制该方法的第一步,我需要在正方形和圆形中均匀分布的随机数。
我已经能够在正方形中绘制圆,但是如何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)
以及如何改变视角?
您可以不“拒绝”任何积分。下面的 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)
}
要绘制点,您需要 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