domingo, 15 de janeiro de 2012

Variância

Glider Uma das operações mais importantes e necessárias da matemática é a variância de amostra. É usada, por exemplo, para o cálculo do desvio padrão e da regressão linear.

Usando linguagens funcionais, a implementação fica muito mais elegante.

Erlang


Em Erlang, a função para o cálculo da variância toma o seguinte formato:
variance(List) ->
Xm = mean(List),
Num = lists:sum([math:pow(Xi - Xm, 2) || Xi <- List]),
Denom = length(List) - 1,
Num / Denom.


É preciso ainda definir a função de média, mean/1:
mean(List) ->
lists:sum(List) / length(List).


LISP


Em Scheme a implementação é um pouco mais verbosa, mas ainda assim elegante.

Segue o código em R⁵RS:
(define variance
(lambda (*list*)
(let ((xm (mean *list*)))
(/
(apply +
(map (lambda (x) (expt (- x xm) 2)) *list*))
(- (length *list*) 1)))))


Também precisamos implementar a média:
(define mean
(lambda (*list*)
(/
(apply + *list*)
(length *list*))))


Paradigma imperativo


Para comparação, segue a implementação de variância em uma linguagem imperativa, C:
double variance(int length, double *list) {
double x_mean = mean(length, list);
double sum = 0;
int i;

for (i=0; i<length; ++i)
sum += pow(list[i] - x_mean, 2.);

return sum / (length - 1);
}


É preciso incluir o cabeçalho math.h. Segue a implementação da função mean():
double mean(int length, double *list) {
double sum = 0;
int i;

for (i=0; i<length; ++i)
sum += list[i];

return sum / length;
}


Perceba a mudança de estado, o que não ocorre nos códigos funcionais.

Escolhi C em vez de Python, porque Python também suporta bem o paradigma funcional, enquanto C é quase necessariamente imperativa.

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