Gerador Aleatório para Distribuição Normal

De Augusto Baffa Wiki
Revisão de 19h52min de 28 de dezembro de 2020 por Abaffa (discussão | contribs)
Ir para navegação Ir para pesquisar
Outros idiomas:
English • ‎português do Brasil

A distribuição normal ou gaussiana é, sem dúvida, a distribuição estatística mais famosa (principalmente por causa de sua ligação com o Teorema do Limite Central).

Acontece que usando um método especial chamado Transformação de Box-Muller, podemos gerar variáveis aleatórias normalmente distribuídas a partir de geradores aleatórios uniformes.


[math]Z0 = \sqrt{-2ln(U_1)}.cos(2\pi U_2)[/math]


[math]Z1 = \sqrt{-2ln(U_1)}.sin(2\pi U_2)[/math]


Uma amostra Box-Muller para uma distribuição normal é definida por [math]\mathcal {N}(\mu, \sigma) = z \times \sigma + \mu[/math], onde [math]z = Z_0 \text{ ou } Z_1[/math].

Exemplo em Python

Exemplo com 1 milhão de sorteios
def pseudo_normal(mu=0.0, sigma=1.0, size=1):
    """
    Generates normal distribution from uniform generator
       using Box-Muller transform
    """
    # Sets seed based on the decimal portion of the current system clock
    t = time.perf_counter()
    seed1 = int(10**9*float(str(t-int(t))[0:]))
    U1 = pseudo_uniform(seed=seed1, size=size)
    
    t = time.perf_counter()
    seed2 = int(10**9*float(str(t-int(t))[0:]))
    U2 = pseudo_uniform(seed=seed2, size=size)
    
    # Standard Normal pair
    Z0 = np.sqrt(-2*np.log(U1)) * np.cos(2*np.pi*U2)
    Z1 = np.sqrt(-2*np.log(U1)) * np.sin(2*np.pi*U2)    
    
    # Scaling
    Z0 = Z0 * sigma + mu
    
    return Z0