domingo, 22 de janeiro de 2012

Média harmónica

Poliedro Já que falávamos de variâncias e médias, um dos cálculos mais belos de média é a média harmónica.

Vou roubar
a explicaçãoo exemplo da Wikipédia por pura preguiça… :-/

[update]
Roubar a explicação não… roubei o exemplo. Para a explicação deixei o apontador para o artigo na Wikipédia – mais preguiçoso ainda!
[/update]


Você se lembra do colégio, quando tinha de calcular a velocidade média percorrida por um carro, certo? Imagine que um carro faz uma viagem de x horas, tendo percorrido metade do tempo a 40Km/h e a outra metade a 60Km/h.

Calcular a velocidade média é bem fácil, não?

(40Km/h + 60Km/h) / 2 = 50Km/h


Então o carro percorreu a distância a uma velocidade média de 50Km/h, tornando fácil calcular, por exemplo, a distância: se o carro andou por 3h, percorreu 150Km.

Porém imagine que a proposição do problema não fosse quanto ao tempo, mas quanto à distância…

O carro percorreu metade do percurso (não do tempo) a 40Km/h e outra metade a 60Km/h. Qual a velocidade média?

Para obter esse resultado, precisamos da média harmónica:

2 / ((1 / 40Km/h) + (1 / 60Km/h)) = 48Km/h


Então é o equivalente a percorrer todo o trajeto a 48Km/h.

Isso também se aplica a diversos outros ramos, como a matemática financeira: se um investidor aplica um mesmo valor em compra de ações todos os meses, no final o preço médio das ações será a média harmónica dos preços das ações em cada mês.

Mãos à massa


Conversamos até agora sobre matemática, agora é hora de ver o código! Usarei novamente Scheme.

Vamos nos concentrar primeiro no cálculo do denominador. Novamente apelaremos para map/reduce.

O map será usado para inverter cada um dos elementos, para tanto usaremos a função lambda (λx.(1/x))xi:
(map (lambda (x) (/ 1 x)) *list*)


Feito isso, precisaremos de um somatório desses elementos, portanto usaremos reduce novamente com #'apply e #'+:
(apply +
       (map (lambda (x) (/ 1 x)) *list*))


O numerador é fácil, é a quantidade de elementos, ou tamanho da lista:
(length *list*)


Basta dividirmos um pelo outro e, quase sem querer, já temos o cálculo da média harmónica!
(define harmonic-mean
  (lambda (*list*)
    (/
      (length *list*)
      (apply +
             (map (lambda (x) (/ 1 x)) *list*)))))


Se quiser testar com os valores do exemplo (40Km/h e 60Km/h):
(let ((params '(40 60)))
  (display (harmonic-mean params))
  (newline))


[update]
Ainda esperando o pessoal do Prettify corrigir o syntax highlighting para LISP.
[/update]


[]’s
Cacilhας, La Batalema
blog comments powered by Disqus