[Math] Generating random numbers from a non-uniform distribution over a unit circle

algorithmsprobabilityprobability distributionsrandomrandom variables

I have a non-uniform distribution over a unit circle, peaking at $\frac{3}{\pi}$ at $(0,0)$ and tailing away to zero at the edge,

$f(x,y) = \frac{3}{\pi} \cdot (1 – \sqrt{x^2+y^2})$

I wish to generate a few random points within the unit circle according to this distribution.

Is there a straightforward method?

Best Answer

Probably the easiest to implement would be rejection sampling. A simple implementation would be as follows.

Let $\mu = \max_{(x,y) \in [0,1]^2} f(x,y) = \frac3{\pi}$.

  1. Sample $x,\,y, \, u \sim \text{Unif}[0,1]$ independent uniform random variables.
  2. If $u > f(x,y)/\mu$ then return to step 1. Else accept $(x,y)$.

To see why this works you will want to read the wikipedia page cited above (or another source).


Example Implementation in R

library(dplyr)
library(ggplot2)

samples <- sapply(1:100000, function(i){
  success <- FALSE

  while(success == FALSE){
    x <- runif(1,-1,1)
    y <- runif(1,-1,1)
    u <- runif(1,0,1)

    if( u < 1- sqrt(x^2 + y^2) ){
      success <- TRUE
    }
  }

  return( c(x,y) )
}) %>% t %>% as.data.frame %>% select(x = V1, y = V2)

ggplot(samples, aes(x,y)) +  stat_density2d(aes(fill=..level..), geom="polygon")

enter image description here