Comment générer des points uniformément répartis dans la boule d'unité 3D?


11

J'ai posté une question précédente , c'est lié mais je pense qu'il vaut mieux commencer un autre fil. Cette fois, je me demande comment générer des points uniformément répartis à l'intérieur de la sphère d'unité 3D et comment vérifier la distribution visuellement et statistiquement aussi? Je ne vois pas les stratégies qui y sont affichées directement transférables à cette situation.


4
Les techniques de la question précédente s'appliquent directement une fois que vous constatez que le nombre de points dans la distance de l'origine doit être proportionnel à . Ainsi, si vous générez une variable uniforme indépendante dans avec un point à la surface de la sphère, la mise à l'échelle de fait l'affaire. r 3 u [ 0 , 1 ] w w u 1 / 3rr3u[0,1]wwu1/3
whuber

@whuber: peut-être que je n'ai tout simplement pas compris l'essence des techniques précédentes. Permettez-moi d'essayer ce que vous avez décrit. De plus, quelles sont les façons de vérifier à nouveau l'uniformité?
Qiang Li

2
Fonction K de @Qiang Ripley et tests du chi carré. Vous pouvez également vérifier l'uniformité de la projection radiale des points sur la surface de la sphère, l'uniformité du cube des longueurs des points et l'indépendance de ces deux.
whuber

Pour moi, ce n'est pas si évident ce que signifie "uniformément distribué" ... Et probablement un essai pour le définir créera automatiquement un algorithme de génération (=

@mbq, je pense que pour définir le terme, nous devons avoir un pdf de . fR,Θ,Φ(r,θ,ϕ)=r2
Qiang Li

Réponses:


14

Le moyen le plus simple consiste à échantillonner uniformément les points dans l'hypercube correspondant et à éliminer ceux qui ne se trouvent pas dans la sphère. En 3D, cela ne devrait pas se produire si souvent, environ 50% du temps. (Le volume de l'hypercube est 1, le volume de la sphère est )43πr3=0.523...


+1. C'est l'une des techniques recommandées par la FAQ comp.graphics.algorithms "Points aléatoires uniformes sur la sphère".
David Cary

1
Et si on veut faire ça pour ? n>100
ares

2
C'est ce qu'on appelle la «méthode de rejet». Tout en fonctionnant bien en trois dimensions, par vingt-sept dimensions, un seul sur mille milliards de points réside dans la balle de 27 et non dans le reste du cube de 27, de sorte que la méthode de rejet ne se généralise pas bien. Je le mentionne car j'ai actuellement besoin d'échantillons uniformément dans une boule de 2440 dimensions.
Reb.Cabin

13

Vous pouvez également le faire en coordonnées sphériques, auquel cas il n'y a pas de rejet. Vous générez d'abord le rayon et les deux angles au hasard, puis vous utilisez la formule de transition pour récupérer , et ( , , ).xyzx=rsinθcosϕy=rsinθsinϕz=rcosθ

Vous générez uniformément entre et . Le rayon et l'inclinaison ne sont cependant pas uniformes. La probabilité qu'un point se trouve à l'intérieur de la boule de rayon est donc la fonction de densité de probabilité de est . Vous pouvez facilement vérifier que la racine cubique d'une variable uniforme a exactement la même distribution, c'est ainsi que vous pouvez générer . La probabilité qu'un point se trouve à l'intérieur d'un cône sphérique défini par l'inclinaison est ou siϕ02πrθrr3r3r2rθ(1cosθ)/21(1cos(θ))/2θ>π/2 . La densité est donc . Vous pouvez vérifier que moins l'arc cosinus d'une variable uniforme a la bonne densité.θsin(θ)/2

Ou plus simplement, nous pouvons simuler le cosinus de uniformément entre et .θ11

Dans R, cela ressemblerait à ce qui suit.

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

Au cours de l'écriture et de l'édition de cette réponse, j'ai réalisé que la solution est moins triviale que je ne le pensais.

Je pense que la méthode la plus simple et la plus efficace sur le plan informatique est de suivre la méthode de @ whuber pour générer sur la sphère unitaire comme indiqué dans ce post et les mettre à l'échelle avec .(x,y,z)r

xyz <- matrix(rnorm(3*n), ncol=3)
lambda <- runif(n)^(1/3) / sqrt(rowSums(xyz^2))
xyz <- xyz*lambda

3
C'est une bien meilleure réponse en raison de l'absence de rejet. Dans les espaces de grande dimension, l'échantillonnage de rejet peut être très coûteux en raison de la faible probabilité d'acceptation.
kingledion

2
Le dernier morceau de code peut être adapté à une dimension supérieure, par exemple d. Pour cela, remplacez toutes les instances de 3par d.
gui11aume

0

À mon avis, l'option la plus simple qui se généralise également aux boules de dimensions supérieures (ce qui n'est pas le cas des coordonnées sphériques et encore moins le cas de l'échantillonnage de rejet) est de générer des points aléatoires qui sont le produit de deux variables aléatoires où est une variable aléatoire gaussienne (c'est-à-dire isotrope, c'est-à-dire pointant dans n'importe quelle direction uniformément) normalisée de sorte qu'elle se trouve sur la sphère et qui est une variable aléatoire uniforme dans à la puissance , étant la dimensionnalité des données, en prenant soin du rayon.P = N / | | N | | U 1 / n N U [ 0 , 1 ] 1 / n nPP=N/||N||U1/nNU[0,1]1/nn

Et voilà!


2
Un rayon uniformément réparti ne donnera pas un point uniforme dans la balle ...
kjetil b halvorsen

1
Vrai. Vous auriez besoin d'adapter un peu la distribution de la variable pour prendre en compte les régions de densité plus faible / plus élevée. U
Jean-Luc Bouchot
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.