Calcular uma integral

10 Julho, 2008

Não sei se eu (finalmente) passei em cálculo, mas enfim…

Estava eu vendo uns programinhas em D passados quando achei um que calculava uma integral definida, então resolvi portá-lo para Haskell.

Primeiro algum embasamento teórico:

Basicamente, uma integral é utilizada para se calcular a área sob uma função (não importando sua forma). Basicamente, a idéia é dividir a função f(x) em vários retângulos de comprimendo dx e altura f(n), onde n é o ponto atual. Vale frisar que é a área até o eixo x.

Observe que quanto menor o valor de dx, maior a precisão.

Neste exemplo, utilizaremos retângulos com base de 0,00001 unidades.

A rotina principal para este cálculo é:

area ini fim fn =
    let
        alturas = map fn [ini,ini+dx .. fim]
        areas = map (dx *) alturas
    in
        foldl (+) 0 areas
    where
        dx = 0.00001

Onde ini e fim delimitam o intervalo que se está calculando. fn é a função.

As funções utilizadas para isso foram:

  • map = recebe uma função e uma lista. Retorna uma nova lista, com os valores da função aplicada a cada elemento da lista original. Por exemplo: map (0-) [1,2,3] aplica a função “0-n”, onde n será cada elemento da lista, retornando uma lista [-1,-2,-3].
  • foldl = recebe uma função, um valor e uma lista. Aplica a função ao valor e ao primeiro elemento da lista, então  ao valor resultante e ao segundo elemento,  e por aí vai. Por exemplo: foldl (+) 0 [1,2,3] retorna a soma  aplicaria (((0+1)+2)+3), retornando 6. Vale lembrar que essa função avalia a lista da esquerda para a direita (sim, existe uma foldr)

Basicamente o que é feito é:

  • Crio a lista com todos os valores no intervalo: [ini,ini+dx .. fim];
  • Acho as alturas de cada retângulo, aplicando a função passada à essa lista: alturas = map fn [ini,ini+dx .. fim];
  • Acho a área de cada retângulo, multiplicando cada altura pela base (dx): areas = map (dx *) alturas;
  • Somo todas as áreas, começando com 0: foldl (+) 0 areas.

Um uso disse seria:

main = do
    (putStrLn.show) (area 0 1 (\x -> x + 3))

Aqui eu calculo a área aproximada da reta x + 3, de x=0 até x=1.

A sintaxe \x -> x + 3 é chamada expressão lambda, e é utilizada para definir uma função anônima inline, que recebe um argumento x e retorna esse argumento + 3.

Deixe um comentário