Je voudrais générer des échantillons à partir de la région bleue définie ici:
La solution naïve consiste à utiliser l'échantillonnage de rejet dans le carré unitaire, mais cela n'offre qu'une efficacité de (~ 21,4%).
Existe-t-il un moyen de échantillonner plus efficacement?
probability
sampling
monte-carlo
random-generation
Cam.Davidson.Pilon
la source
la source
Réponses:
Est-ce que deux millions de points par seconde suffiront?
La distribution est symétrique: il suffit de calculer la distribution pour un huitième du cercle complet, puis de la copier autour des autres octants. En coordonnées polaires , la distribution cumulée de l'angle Θ pour l'emplacement aléatoire( r , θ ) Θ à la valeur θ est donnée par l'aire entre le triangle ( 0 , 0 ) , ( 1 , 0 ) , ( 1 , tan θ ) et l'arc de cercle s'étendant de (( X, Y) θ ( 0 , 0 ) , ( 1 , 0 ) , ( 1 , bronzageθ) à ( cos θ , sin θ ) . Il est ainsi proportionnel à(1,0) (cosθ,sinθ)
d'où sa densité
Nous pouvons échantillonner à partir de cette densité en utilisant, par exemple, une méthode de rejet (qui a une efficacité de ).8 / π- 2 ≈ 54,6479 %
La densité conditionnelle de la coordonnée radiale est proportionnelle à r d r entre r = 1 et r = sec θ . Cela peut être échantillonné avec une inversion facile du CDF.R r dr r = 1 r = secθ
Si nous générons des échantillons indépendants , la conversion en coordonnées cartésiennes ( x i , y i ) échantillonne cet octant. Du fait que les échantillons sont indépendants, un échange aléatoire des coordonnées produit un échantillon aléatoire indépendant du premier quadrant, comme souhaité. (Les échanges aléatoires nécessitent de générer une seule variable binomiale pour déterminer le nombre de réalisations à échanger.)( rje, θje) ( xje, yje)
Chacune de ces réalisations de nécessite, en moyenne, une variable uniforme (pour R ) plus 1 / ( 8 π( X, Y) R fois deux variables uniformes (pour Θ ) et une petite quantité de calcul (rapide). C'est 4 / ( π - 4 ) ≈ 4,66 varie par point (qui, bien sûr, a deux coordonnées). Tous les détails sont dans l'exemple de code ci-dessous. Ce chiffre représente 10 000 des plus d'un demi-million de points générés.1 / ( 8 π- 2 ) Θ 4/(π−4)≈4.66
Voici le
R
code qui a produit cette simulation et l'a chronométré.la source
Je propose la solution suivante, qui devrait être plus simple, plus efficace et / ou moins coûteuse que les autres soutiens de @cardinal, @whuber et @ stephan-kolassa jusqu'à présent.
Cela implique les étapes simples suivantes:
L'intuition derrière cet algorithme est montrée dans la figure.
Les étapes 2a et 2b peuvent être fusionnées en une seule étape:
Le code suivant implémente l'algorithme ci-dessus (et le teste en utilisant le code de @ whuber).
Quelques tests rapides donnent les résultats suivants.
Algorithme /stats//a/258349 . Meilleur de 3: 0,33 seconde par million de points.
Cet algorithme. Meilleur de 3: 0,18 seconde par million de points.
la source
Eh bien, plus efficacement peut être fait, mais j'espère que vous ne cherchez pas plus rapidement .
Wolfram vous aide à intégrer cela :
Ainsi, la fonction de distribution cumulativeF serait cette expression, mise à l'échelle pour s'intégrer à 1 (c.-à-d. divisée par ∫10F(y)dy ).
Maintenant, pour générer votreX valeur, choisissez un nombre aléatoire t , uniformément répartie entre 0 et 1 . Trouvez ensuiteX tel que F( x ) = t . Autrement dit, nous devons inverser le CDF ( échantillonnage à transformée inverse ). Cela peut être fait, mais ce n'est pas facile. Ni rapide.
Enfin, étant donnéX , choisissez un hasard y qui est uniformément réparti entre 1 - x2-----√ et 1 .
Ci-dessous est le code R. Notez que je pré-évalue le CDF sur une grille deX valeurs, et même alors cela prend quelques minutes.
Vous pouvez probablement accélérer l'inversion du CDF un peu si vous réfléchissez. Là encore, la pensée fait mal. Personnellement, je choisirais l'échantillonnage de rejet, qui est plus rapide et beaucoup moins sujet aux erreurs, sauf si j'avais de très bonnes raisons de ne pas le faire.
la source