【问题标题】:How to draw random numbers in a circle and a square?如何在圆形和方形中绘制随机数?
【发布时间】:2012-04-12 19:45:36
【问题描述】:

我想从两个角度(鸟瞰和青蛙视角)可视化 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 中实现的目标的现有示例?
  • 我想像现在这样在鸟瞰视角中看到随机数的分布,但在青蛙的视角中也是如此......我怎么能意识到这一点?
  • 请对“青蛙的眼睛”的定义更加准确。很难猜,我们不应该...
  • 我想创建正态分布的随机数,从极坐标法的均匀分布的随机数开始,这是 box muller 算法的一种变体。一步一步你可以从众所周知的正态分布密度函数中看到更多。所以我想从上面看到这些步骤,就像现在一样,从前面看,就像一个正常的密度函数。希望你能理解我的问题:-)

标签: r statistics plot


【解决方案1】:

您可以不“拒绝”任何积分。以下 R 函数需要3*n 随机数,并将在半径为r 的圆中生成n 随机选择的点:

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)
}

【讨论】:

  • 您能否详细说明,或提供参考?我将您的公式重写为单个元素,为 xj = sqrt(unifj)* cos(thetaj) 。我不清楚均匀房车的平方根。乘以一种正态分布角度的余弦,得到一个均匀的 r.v. .
  • 有趣。但我认为扔掉圆外的点更快:A(圆)=πr²=π; A(平方)=a²=4 扔掉=>需要生成 4 / π 对均匀随机数 = 8 / π = ca。每点 2.55 个随机数
  • @Carl 这在 D. Knuth (1981) 的某处有所提及。计算机编程艺术,卷。 2:半数值算法,章节。 3:随机数。我现在手头没有。您可以查看“在 N 球上生成均匀分布随机点的三种不同算法”,了解正态分布出现的原因在。
  • @Hans-Werner:所以当维度增加时它会变得更快。很高兴知道!谢谢。
  • @Hans 感谢您的参考。学习新事物总是很有趣。
【解决方案2】:

要绘制点,您需要 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

【讨论】:

  • 如何限制 q=x^2+y^2 不能为 0 或 >1,如果该条件为假,则应像您发布的那样创建新的随机数?
  • @Tommy:您刚刚(某种程度上)重新发明了一种流行的“拒绝方法”,即从任意分布函数生成随机数。如果您有兴趣,请阅读“C 中的数字食谱”第 7.3 章之类的内容
  • @CarlWitthoft - 好吧,我没有重新发明它 - 我只是重新实现了它;-) 不过还没有读过那个特定的章节。
  • 酷。您也可以设置scale &lt;- 4/pi,因为这是正方形中的点与内切圆中的点的预期比率。
  • @JoshO'Brien 是的,...甚至更大(1.5 左右)以(大部分)避免循环。
猜你喜欢
  • 2022-01-15
  • 2017-08-25
  • 2022-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
  • 1970-01-01
  • 2021-10-21
相关资源
最近更新 更多