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).

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:

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

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();
                    return 0;
                }
        

Download dos Códigos

Código fonte em C: Algoritmo de Gauss-Legendre em C.

Código fonte em Java: Algoritmo de Gauss-Legendre em Java.

Referências

Gauss-Legendre algorithm (Wikipédia)

A versão do código em C foi desenvolvida por Aurélio Araújo, formado em Sistemas de Informação (FAP/CE). Linkedin: Aurélio Araújo.

Observações

Postagem atualizada em 15/07/2017.

Siga o blog por e-mail

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