19 de janeiro de 2010

Shell x Listas x Monte Carlo

Muitas vezes é interessante guardas listas de sítios e sortear somente dentro desta lista para evitar gerar números aleatórios que não serão usados. É fácil usar listas em uma dimensão: quando um sítio sai da lista ele pode ser substituído pelo ultimo da fila e esta perde um elemento.

Tudo muito bom, tudo muito legal, mas há um preço a pagar se estamos interessados no comportamento dinâmico... um não, dois !



Primeiro, o tempo de Monte Carlo tem que ser normalizado em termos do número de elementos da lista. Por exemplo: se a lista tem o tamanho j e a rede tem N sítios, o incremento no tempo é dado pela razão N/j que é maior que um. Conclusão o tempo passa mais rápido ( o que não é ruim), o problema é que essa razão deve ser tratada como um ponto flutuante.
 A cada iteração vamos ter que somar pontos flutuante, não há como fugir, então devemos ter cuidado com o número de somas efetuadas. Nessas horas é bom aproveitar as operações 64 bits e usar variáveis Long Double, tipicamente ela tem 18 casas decimais de precisão. O erro após X iterações é da ordem de X*10^{-18}. 

Segundo, cada realização terá um sequência de tempo diferente já que o tempo depende do histórico do tamanho da lista j.
Uma maneira de contornar o problema é dividir o tempo em intervalos, tomar a média das grandezas em estudo naquele intervalo e atribuir o resultado ao tempo médio dos pontos dentro do intervalo.
Note que isso introduz dos erros: o erro estatístico da média estudada ( esse existe de qualquer forma ) e o erro do tempo que está ligado de alguma forma a dinâmica ( esse é novo ).

Como resolver isso de forma rápida é fácil ?

Bom, para todo problema sempre existe um script.

É só pegar todos os dados, organizar por ordem de tempo, dividir em arquivos ( escolhi 50 pontos por arquivo). Depois tirar as media do tempo e da grandeza de interesse para cada um dos arquivos.   

cat dados | sort -n | split  -l 50 -a 3 -d
for i in x[0-9][0-9][0-9]
do
cat $i | mawk  '{ print (r+=$1)/NR, (s+=$2)/NR }' | tail -n 1 >> a.agr
done
rm -f x[0-9][0-9][0-9]


Curto e Grosso: Viva o POSIX !

Notem que o intervalo de tempo não é fixo, depende da distribuição dos meus 50 pontos. Chame de janelas adaptativas para se vangloriar !

Imagine a quantidade de rotinas para fazer isso em C ?
Além disso, você teria que tratar I/O em C ! Está aí uma coisa que eu não pretendo fazer nessa vida !   
   
 

0 Comments: