Cálculo de Pi via Algoritmo de Gauss-Legendre (Java e C)

Por
|  

Introdução

Desde o ensino fundamental, os estudantes utilizam a constante matemática Pi para o cálculo da área da circunferência. Mais adiante, essa constante passa a ser usada na trigonometria, no cálculo de volumes e outras aplicações.

Pi (π) é a razão entre o comprimento/perímetro de uma circunferência e o seu diâmetro. Entretanto, ao longo da história da matemática, surgiram outras formas de se calcular essa constante. Nessa postagem será abordada uma das formas de se calcular Pi: o algoritmo de Gauss-Legendre.

O foco principal é demonstrar esse algoritmo na prática nas linguagens Java e C, entretanto é importante compreender antes de tudo como esse algoritmo funciona.

Observação: não confunda este algoritmo com a o método numérico de integração de mesmo nome (Legendre-Gauss Quadrature).

Leia também: Algoritmo de Gauss-Legendre iterativo para o cálculo de pi

O Algoritmo de Gauss-Legendre

O algoritmo de Gauss-Legendre é um algoritmo que utiliza cinco funções matemáticas, sendo que quatro delas fazem o uso de recursão. Para quem não sabe, em programação e matemática, recursão é basicamente quando uma função chama a si própria. É quando utilizamos vários ou alguns casos básicos de uma determinada função para desenvolvermos ou calcularmos algo mais complexo. A recursão faz uso da repetição, ou seja, uma função pode se chamar várias vezes consecutivas até atingir um caso básico e, a partir desse caso básico, obter o resultado.

Podemos utilizar a sequência de Fibonacci como exemplo, onde um número é igual a soma de seus dois anteriores:

0, 1, 1, 2, 3, 5, 8, 13...

Nessa sequência temos dois casos básicos: o 0 (zero) e o 1 (um). Sem eles essa sequência seria impossível, pois nunca teríamos um caso básico a partir do qual poderíamos calcular qualquer valor da sequência. A função iria invocar a si mesma infinitas vezes sem nunca chegar a um resultado.

Voltando ao algoritmo, segue as quatro funções:

Seguem os casos básicos dessas quatro funções:

Segue a fórmula que calcula aproximadamente o valor de Pi:

Observe nas funções que, sem o valor de índice 'n', não conseguimos calcular o valor de índice posterior "n+1". Outro ponto importante é que quanto maior for o índice, mais próximo de Pi o resultado será. Consequentemente, mais trabalhoso será o cálculo, pois teremos que calcular o valor dos índices anteriores. Exemplo:

Abaixo segue o algoritmo de Gauss-Legendre em Java:

public class GaussLegendre {

 public static double a(int n){
  if(n == 0){
   return 1;
  }else{
   return (a(n - 1) + b(n - 1))/2.0;
  }
 }
 
 public static double b(int n){
  if(n == 0){
   return 1.0/Math.sqrt(2.0);
  }else{
   return Math.sqrt(a(n - 1) * b(n - 1));
  }
 }
 
 public static double t(int n){
  if(n == 0){
   return 1.0/4.0;
  }else{
   return t(n - 1) - p(n - 1) * Math.pow(a(n - 1) - a(n), 2);
  }
 }
 
 public static double p(int n){
  if(n == 0){
   return 1;
  }else{
   return 2 * p(n - 1);
  }
 }
 
 public static double pi(int n){
  return Math.pow(a(n) + b(n), 2)/ (4 * t(n));
 }
 
 public static void main(String [] args){
  /*
   * Basta alterar o valor de 10 por outro
   * valor maior, para obter valores mais precisos.
   * CUIDADO!!! Se você colocar um valor muito alto,
   * pode gerar extrema lentidão no seu pc. 
   */
  System.out.println(pi(10));
 }
 
}

Abaixo segue o algoritmo de Gauss-Legendre em C:

#include <math.h>
#include <stdio.h>

double a(int n);
double b(int n);
double t(int n);
double p(int n);

double a(int n){
       if(n == 0){
            return 1;
       }else{
             return (a(n - 1) + b(n - 1))/2;
       }
}

double b(int n){
       if(n == 0){
            return 1/sqrt(2);
       }else{
             return sqrt(a(n - 1) * b(n - 1));
       }
}

double t(int n){
       if(n == 0){
            return 0.25;
       }else{
             return t(n - 1) - p(n - 1) * pow(a(n - 1) - a(n), 2);
       }
}

double p(int n){
       if(n == 0){
            return 1;
       }else{
             return 2 * p(n - 1);
       }
}

double pi(int n){
       return pow(a(n) + b(n), 2)/(4 * t(n));
}

int main(){
    /*
     * Basta alterar o valor de 10 por outro
  * valor maior, para obter valores mais precisos.
  * CUIDADO!!! Se você colocar um valor muito alto,
  * pode gerar extrema lentidão no seu pc. 
  */
    printf("%f", pi(10));
    getch();
}

Download dos Códigos

Você também pode baixar o algoritmo de Gauss-Legendre em Java e em C nos links abaixo.

Referências


Siga o blog

Redes sociais: Facebook, Twitter, YouTube, Pinterest, Instagram, Telegram

Receba notificações de novas postagens e novidades do blog por e-mail.

Importante: utilize o bom senso na hora de comentar. Acesse a política de privacidade para maiores informações sobre comentários.

Nenhum comentário:

Postar um comentário