También puede hacer esto en coordenadas esféricas, en cuyo caso no hay rechazo. Primero genera el radio y los dos ángulos al azar, luego usa la fórmula de transición para recuperar , y ( , , ).xyzx=rsinθcosϕy=rsinθsinϕz=rcosθ
Generas unifomly entre y . Sin embargo, el radio y la inclinación no son uniformes. La probabilidad de que un punto esté dentro de la bola de radio es por lo que la función de densidad de probabilidad de es . Puede verificar fácilmente que la raíz cúbica de una variable uniforme tiene exactamente la misma distribución, por lo que así es como puede generar . La probabilidad de que un punto se encuentre dentro de un cono esférico definido por la inclinación es o siϕ02πrθrr3r3r2rθ(1−cosθ)/21−(1−cos(−θ))/2θ>π/2 . Entonces la densidad es . Puede verificar que menos el arcocoseno de una variable uniforme tenga la densidad adecuada.θsin(θ)/2
O más simplemente, podemos simular el coseno de uniformemente entre y .θ−11
En R esto se vería como se muestra a continuación.
n <- 10000 # For example n = 10,000.
phi <- runif(n, max=2*pi)
r <- runif(n)^(1/3)
cos_theta <- runif(n, min=-1, max=1)
x <- r * sqrt(1-cos_theta^2) * cos(phi)
y <- r * sqrt(1-cos_theta^2) * sin(phi)
z <- r * cos_theta
Al escribir y editar esta respuesta, me di cuenta de que la solución es menos trivial de lo que pensaba.
Creo que el método más fácil y computacionalmente más eficiente es seguir el método de @ whuber para generar en la esfera de la unidad como se muestra en esta publicación y escalarlos con .(x,y,z)r
xyz <- matrix(rnorm(3*n), ncol=3)
lambda <- runif(n)^(1/3) / sqrt(rowSums(xyz^2))
xyz <- xyz*lambda