Um gerador de números aleatórios é um rotina que gera números pseudo-aleatórios a partir de uma parâmetro de entrada chamado de semente. Em geral o número gerado é um número real no intervalo $[0,1)$. O papél da semente é fazer com que o gerador retorne sempre os mesmos números se for iniciado com a mesma semente. Por exemplo, se você executa o gerador duas vezes sendo que na primeira você usou a semente igual a $-1$ e em cada vez obteve, respectivamente, os números $a_1$ e $a_2$ então se você reiniciar a gerador com a mesma semente e executar-lo duas vezes então irá obter novamente os mesmos valores $a_1$ e $a_2$.

Dizemos que os números são pseudo-aleatórios pois na prática é impossível gerar números verdadeiramente aleatórios sem uso de alguma “moeda quântica”, entretanto a correlação entre os números gerados por uma bom gerador não é forte o suficiente para interferir em cálculos físicos, o que já nos basta. Apresentarei aqui a rotina ran1 retirada do livro numerical recipes com pequenas alterações.

A rotina ran1:

Usaremos uma variável inteira chamada semente para, adivinhem, guardar a semente. Ao chamar a ran1 pela primeira vez em um programa, semente deverá ser um valor negativo. ran1 irá alterar o valor de semente para um número positivo assim da próxima vez que você chamar ran1 ela entenderá que não está sendo inicializada e irá gerar um número aleatório sem correlação com o anterior. Por causa disso acho interessante usar uma variável semente0 para a semente propriamente dita e semente1 para usar como argumento para ran1 onde, no começo, semente1=semente0 dessa forma não perdemos a informação da semente que utilizamos para inicializar o gerador.

O número aleatório p gerado tem precisão dupla então não tente guardalo em uma variável inteira sem converter.

Suponha que queremos guardar na variável de precisão dupla p um número aleatório no intervalo $[x_0, x_1)$, para isso faça:

  • p = ran1(semente1)
    
  • Como $p\in[0, 1)$ multiplicamos ele pelo comprimento do intervalo:
    p = p*(x1-x0)
    
  • Dessa forma temos $p\in[0, x_1-x_0)$. Agora some $x_0$ a $p$:
    p = p+x0
    
  • Temos, finalmente, $p\in[x_0, x_1)$ como queríamos. De forma mais reduzida, pode-se fazer tudo em um cálculo só quando se chama o gerador, da forma:
    p = ran1(semente1) * (x1-x0) + x0
    

ran1 em C

Usar a ran1 em c é fácil. Simplesmente faça:

  • No diretório do seu programa em c baixe o arquivo ran1.c digitando no terminal
    wget -O ran1.c https://github.com/ismaeldamiao/avulsos/raw/master/c/rotinas/ran1.c
    
  • Utilize a seguinte macro, ela irá incluir a funcão double ran1(long int *) no seu programa:
    #include "ran1.c"
    
  • Declare uma variável long int para guardar a semente, que inicialmente deve ser negativa, por exemplo:
    long int semente = -1L;
    
  • Chame a função ran1 quantas vezes quiser, lembrando de indicar a região da memória da semente, por exemplo:
    double aleatorio = ran1(&semente);
    
  • Compile seu programa normalmente.

ran1 em FORTRAN 90

Usar a ran1 em FORTRAN 90 é fácil. Simplesmente faça:

  • No diretório do seu programa em FORTRAN 90 baixe o arquivo ran1.90 digitando no terminal
    wget -O https://github.com/ismaeldamiao/avulsos/raw/master/fortran/rotinas/ran1.f90
    
  • Utilize a linha INCLUDE "ran1.f90" dentro do CONTAINS, ela irá incluir a funcão REAL(8) ran1(INTEGER(8)) no seu programa. Deve ficar mais ou menos assim:
PROGRAM SeuPrograma
! Seu codigo
CONTAINS
   INCLUDE "ran1.f90"
END PROGRAM SeuPrograma
  • Declare uma variável INTEGER(8) para guardar a semente, que inicialmente deve ser negativa, por exemplo:
    INTEGER(8) :: semente = -1
    
  • Chame a função ran1 quantas vezes quiser, por exemplo:
REAL(8) :: aleatorio

aleatorio = ran1(semente)
  • Compile seu programa normalmente.