Comment générer des nombres selon une distribution de Soliton?


10

La distribution de Soliton est une distribution de probabilité discrète sur un ensemble {1,,N} avec la fonction de masse de probabilité

p(1)=1N,p(k)=1k(k1)for k{2,,N}

Je voudrais l'utiliser dans le cadre d'une implémentation d'un code LT , idéalement en Python où un générateur de nombres aléatoires uniforme est disponible.

Réponses:


9

Si nous commençons à , le télescope de sommes, donnant 1 - 1 / k pour le CDF (modifié). Inverser cela et prendre soin du cas spécial k = 1 , donne l'algorithme suivant (codé , je le crains, mais vous pouvez le prendre comme pseudocode pour une implémentation Python):k=21-1/kk=1R

rsoliton <- function(n.values, n=2) {
  x <- runif(n.values)         # Uniform values in [0,1)
  i <- ceiling(1/x)            # Modified soliton distribution
  i[i > n] <- 1                # Convert extreme values to 1
  i
}

À titre d'exemple de son utilisation (et d'un test), dessinons valeurs pour N = 10 :dix5N=dix

n.trials <- 10^5
i <- rsoliton(n.trials, n=10)
freq <- table(i) / n.trials  # Tabulate frequencies
plot(freq, type="h", lwd=6)

Distribution de fréquence


1
Pour la distribution de solitons "robuste" associée, vous devrez probablement vous contenter d'une solution légèrement moins efficace (basée sur une recherche binaire ou l'équivalent).
whuber

Comment avez-vous trouvé ça si rapidement?
Alex Chamberlain

2
@Alex Chamberlain parce qu'il est bon: D
gui11aume

7

Python (adapté de la solution @ whuber's R )

from __future__ import print_function, division                                           
import random                                                                   
from math import ceil                                                           

def soliton(N, seed):                                                           
  prng = random.Random()                                                        
  prng.seed(seed)                                                                  
  while 1:                                                                         
    x = random.random() # Uniform values in [0, 1)                                 
    i = int(ceil(1/x))       # Modified soliton distribution                            
    yield i if i <= N else 1 # Correct extreme values to 1                         

if __name__ == '__main__':                                                         
  N = 10                                                                           
  T = 10 ** 5 # Number of trials                                                   
  s = soliton(N, s = soliton(N, random.randint(0, 2 ** 32 - 1)) # soliton generator                   
  f = [0]*N                       # frequency counter                              
  for j in range(T):                                                               
    i = next(s)                                                                    
    f[i-1] += 1                                                                    

  print("k\tFreq.\tExpected Prob\tObserved Prob\n");                               

  print("{:d}\t{:d}\t{:f}\t{:f}".format(1, f[0], 1/N, f[0]/T))                     
  for k in range(2, N+1):                                                          
    print("{:d}\t{:d}\t{:f}\t{:f}".format(k, f[k-1], 1/(k*(k-1)), f[k-1]/T))

Exemple de sortie

k   Freq.   Expected Prob   Observed Prob

1   9965    0.100000    0.099650
2   49901   0.500000    0.499010
3   16709   0.166667    0.167090
4   8382    0.083333    0.083820
5   4971    0.050000    0.049710
6   3354    0.033333    0.033540
7   2462    0.023810    0.024620
8   1755    0.017857    0.017550
9   1363    0.013889    0.013630
10  1138    0.011111    0.011380

Exigences

Le code devrait fonctionner en Python 2 ou 3.


+1 Merci d'avoir partagé la traduction Python. Bienvenue sur notre site!
whuber

Pas de soucis. Si je fais fonctionner les codes LT, ils seront sur GitHub.
Alex Chamberlain

1
Implémentation de @whuber LT maintenant sur GitHub . Pas parfait, mais c'est un début.
Alex Chamberlain
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.