UNIVERSIDADE FEDERAL DO RIO GRANDE DO NORTE CENTRO DE CIÊNCIAS EXATAS E DA TERRA PROGRAMA DE PÓS-GRADUAÇÃO EM MATEMÁTICA APLICADA E ESTATÍSTICA Daniel de Souza Grilo Sobre a Integração Indefinida de Funções Racionais Complexas: teoria e implementação de algoritmos racionais Natal 2015 Daniel de Souza Grilo Sobre a Integração Indefinida de Funções Racionais Complexas: teoria e implementação de algoritmos racionais Dissertação apresentada ao Programa de Pós-graduação em Matemática Aplicada e Estatística da Universidade Federal do Rio Grande do Norte, para a obtenção de Título de Mestre em Matemática Aplicada, na Área de Computação Algébrica. Orientador: Nir Cohen Natal 2015 ii Grilo, Daniel de S. Sobre a Integração Indefinida de Funções Racionais Complexas: teoria e implementação de algoritmos racionais 162 páginas Dissertação (Mestrado) - Programa de Pósgraduação em Matemática Aplicada e Estatística da Universidade Federal do Rio Grande do Norte. Centro de Ciências Exatas e da Terra. Departamento de Matemática. 1. Integração indefinida 2. Funções racionais 3. Algoritmos I. Universidade Federal do Rio Grande do Norte. Centro de Ciências Exatas e da Terra. Departamento de Matemática. Programa de Pós-graduação em Matemática Aplicada e Estatística. Comissão Julgadora: Prof. Dr. Examinador Interno Prof. Dr. Examinador Externo Prof. Dr. Nir Cohen Presidente iii Dedicado a minha família e, in memoriam, a Manuel Eric Bronstein e Petrus Thomas Ratajczyk. iv Agradecimentos À Alma Mater e ao PPgMAE/UFRN que me abençoaram e nutriram tanto com saber quanto com trabalho. Em seguida, agradeço a todos os mestres que contribuíram para o meu conhecimento acadêmico, em especial aqueles que me influenciaram diretamente na elaboração deste trabalho. Nominalmente, os Professores Doutores Nir Cohen, Edgar Silva Pereira, Roberto Hugo Bielschowsky, Marcelo Ferreira Siqueira e Vilmar Trevisan. Agradeço ainda aos coordenadores e vice-coordenadores do PPgMAE/UFRN de todos os tempos, pela disposição nobre em cuidar de um programa de pósgraduação. Uma missão nada trivial. Em especial, agradeço às Professoras Doutoras Carla Almeida Vivacqua e Elaine Gouvea Pimentel, por todo o suporte dado. Finalmente, agradeço a todos com quem convivo: meus colegas de curso, meus amigos, minha família e, acima de tudo, àqueles a quem dedico este trabalho, especialmente minha mãe Márcia Barros de Souza, meu pai José Arimatéia Pitaguares Grilo, minha irmã Lara de Souza Barreto e minha amada noiva Ana Helena Almeida Libanio de Araújo. v Resumo Apresentamos algoritmos de integração indefinida de funções racionais sobre subcorpos dos complexos, a partir de uma abordagem algébrica. Estudamos o algoritmo local de Bernoulli e algoritmos racionais de integração para a classe de funções em questão, a saber, os algoritmos de Hermite; Horowitz-Ostrogradsky; Rothstein-Trager e Lazard-Rioboo-Trager. Estudamos também o algoritmo de Rioboo para conversão de logaritmos envolvendo extensões complexas para funções arco tangente reais, quando estes logaritmos surgem da integração de funções racionais com coeficientes reais. Concluímos fornecendo pseudocódigos e códigos para implementação no software Maxima relativos aos algoritmos estudados neste trabalho, e, além disso, a algoritmos para cálculo de mdc de polinômios; decomposição em frações parciais; fatoração livres de quadrados; cálculo de subresultantes, entre outros algoritmos acessórios ao trabalho. Será também apresentado no apêndice o algoritmo de Zeilberger-Almkvist para integração de funções hiperexponenciais, bem como seu pseudocódigo e código para Maxima. Como alternativa aos algoritmos de Rothstein-Trager e Lazard-Rioboo-Trager, apresentamos ainda um código para o algoritmo de Bernoulli para denominadores livres de quadrados; e outro para o algoritmo de Czichowski, ainda que este não seja estudado em detalhes no trabalho, devido às bases teóricas necessárias para o seu entendimento, as quais se encontram fora do escopo deste trabalho. Diversos exemplos são fornecidos de modo a demonstrar o o funcionamento dos algoritmos de integração deste trabalho. Palavras-chave: Integração Indefinida; Funções Racionais; Algoritmos. vi Abstract We present indefinite integration algorithms for rational functions over subfields of the complex numbers, through an algebraic approach. We study the local algorithm of Bernoulli and rational algorithms for the class of functions in concern, namely, the algorithms of Hermite; Horowitz-Ostrogradsky; Rothstein-Trager and Lazard-Rioboo-Trager. We also study the algorithm of Rioboo for conversion of logarithms involving complex extensions into real arctangent functions, when these logarithms arise from the integration of rational functions with real coefficients. We conclude presenting pseudocodes and codes for implementation in the software Maxima concerning the algorithms studied in this work, as well as to algorithms for polynomial gcd computation; partial fraction decomposition; squarefree factorization; subresultant computation, among other side algorithms for the work. We also present the algorithm of Zeilberger-Almkvist for integration of hyperexpontential functions, as well as its pseudocode and code for Maxima. As an alternative for the algorithms of Rothstein-Trager and Lazard-Rioboo-Trager, we yet present a code for Benoulli’s algorithm for square-free denominators; and another for Czichowski’s algorithm, although this one is not studied in detail in the present work, due to the theoretical basis necessary to understand it, which is beyond this work’s scope. Several examples are provided in order to illustrate the working of the integration algorithms in this text Keywords: Indefinite Integration; Rational Functions; Algorithms. Lista de Figuras 4.1 4.2 4.3 4.4 4.5 Gráfico de 𝑓 próximo do intervalo [−5/4, − 3/4]. . Gráfico da forma descontínua de ∫ 𝑓 = 𝐹1 (𝑥). . . Gráfico de ∫ 𝑓 = 𝐹2 (𝑥). . . . . . . . . . . . . . . . Comparação das formas contínua e descontínua de Comparação das formas contínua e descontínua de . . . . . . . . . ∫ 𝑓. ∫ 𝑓. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 70 72 73 78 Lista de Figuras viii Sumário 1 Introdução 1.1 Motivação e Objetivos do Trabalho 1.2 Histórico do Problema Abordado . 1.3 Visão Geral dos Capítulos e Seções 1.4 Esclarecimentos Acerca do Presente . . . . . . . . . . . . Texto . . . . . . . . . . . . 2 Noções Preliminares 2.1 Resultantes e Sequências de Restos Polinomiais 2.1.1 Resultantes e Subresultantes . . . . . . . 2.1.2 Sequências de Restos Polinomiais . . . . 2.2 Fatoração Livre de Quadrados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Integração Indefinida de Funções Racionais Complexas 3.1 O Algoritmo de Bernoulli . . . . . . . . . . . . . . . . . . 3.1.1 Exemplos . . . . . . . . . . . . . . . . . . . . . . . 3.2 O Algoritmo de Hermite . . . . . . . . . . . . . . . . . . . 3.2.1 Versão Original do Algoritmo de Hermite . . . . . . 3.2.2 Versão Quadrática do Algoritmo de Hermite . . . . 3.2.3 Versão Linear do Algoritmo de Hermite . . . . . . . 3.2.4 Exemplos . . . . . . . . . . . . . . . . . . . . . . . 3.3 O Algoritmo de Horowitz-Ostrogradsky . . . . . . . . . . . 3.3.1 Exemplos . . . . . . . . . . . . . . . . . . . . . . . 3.4 O Algoritmo de Rothstein-Trager . . . . . . . . . . . . . . 3.4.1 Exemplos . . . . . . . . . . . . . . . . . . . . . . . 3.5 O Algoritmo de Lazard-Rioboo-Trager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 2 6 8 . . . . 11 11 11 15 18 . . . . . . . . . . . . 25 25 28 29 29 30 31 33 36 38 39 47 50 Sumário x 3.5.1 Exemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4 Integração Indefinida de Funções Racionais Reais 59 4.1 O Algoritmo de Rioboo para Funções Racionais Reais . . . . . . . 60 4.1.1 Exemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 5 Pseudocódigos e Códigos em Maxima 5.1 Funções para Manipulação de Polinômios 5.1.1 Group . . . . . . . . . . . . . . . 5.1.2 LC . . . . . . . . . . . . . . . . . 5.1.3 Mon . . . . . . . . . . . . . . . . 5.1.4 Parts . . . . . . . . . . . . . . . . 5.1.5 RPoly . . . . . . . . . . . . . . . 5.2 MDC de Polinômios e Resultantes . . . . 5.2.1 PDiv . . . . . . . . . . . . . . . . 5.2.2 PPsDiv . . . . . . . . . . . . . . 5.2.3 GCD . . . . . . . . . . . . . . . . 5.2.4 ExGCD . . . . . . . . . . . . . . 5.2.5 HExGCD . . . . . . . . . . . . . 5.2.6 HFExGCD . . . . . . . . . . . . 5.2.7 DioExGCD . . . . . . . . . . . . 5.2.8 DioHExGCD . . . . . . . . . . . 5.2.9 DioHFExGCD . . . . . . . . . . 5.2.10 SubRes . . . . . . . . . . . . . . . 5.2.11 Normalize . . . . . . . . . . . . . 5.3 Fatorações e Frações Parciais . . . . . . 5.3.1 LFactor . . . . . . . . . . . . . . 5.3.2 SQFR . . . . . . . . . . . . . . . 5.3.3 PFrac . . . . . . . . . . . . . . . 5.4 Hermite e Horowitz . . . . . . . . . . . . 5.4.1 HermO . . . . . . . . . . . . . . . 5.4.2 HermQ . . . . . . . . . . . . . . . 5.4.3 HermL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 80 80 81 81 82 82 83 83 84 85 86 87 88 88 89 90 91 93 94 94 94 96 97 97 98 99 xi Sumário 5.5 5.6 5.7 5.8 5.4.4 HorOstro . . . . . . . . . . . . . . . Logaritmos . . . . . . . . . . . . . . . . . . 5.5.1 Bern . . . . . . . . . . . . . . . . . . 5.5.2 RothTra . . . . . . . . . . . . . . . . 5.5.3 LaRiTra . . . . . . . . . . . . . . . . 5.5.4 Czi . . . . . . . . . . . . . . . . . . . Conversão Real . . . . . . . . . . . . . . . . 5.6.1 Classic . . . . . . . . . . . . . . . . . 5.6.2 Rioboo . . . . . . . . . . . . . . . . . 5.6.3 Rioboo2 . . . . . . . . . . . . . . . . Manipuladores de Extensões Algébricas . . . 5.7.1 NoSolve . . . . . . . . . . . . . . . . 5.7.2 DomSolve . . . . . . . . . . . . . . . 5.7.3 LinSolve . . . . . . . . . . . . . . . . 5.7.4 QuadSolve . . . . . . . . . . . . . . . 5.7.5 CubeSolve . . . . . . . . . . . . . . . 5.7.6 Solve . . . . . . . . . . . . . . . . . . 5.7.7 RHS . . . . . . . . . . . . . . . . . . 5.7.8 SolveSys . . . . . . . . . . . . . . . . 5.7.9 Extensions . . . . . . . . . . . . . . . 5.7.10 VerifyRatSols . . . . . . . . . . . . . Montagem de Integrais de Funções Racionais 5.8.1 RealLog . . . . . . . . . . . . . . . . 5.8.2 ComplLog . . . . . . . . . . . . . . . 5.8.3 InertLog . . . . . . . . . . . . . . . . 5.8.4 GenList . . . . . . . . . . . . . . . . 5.8.5 IRF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Considerações Finais 6.1 A Integração de Funções Elementares . . . . . . . . . 6.2 O Cenário da Computação Algébrica . . . . . . . . . 6.3 Referências em Computação Algébrica . . . . . . . . 6.4 Acerca dos Códigos para Implementação em Maxima . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 102 102 105 106 108 110 110 110 111 112 112 113 113 114 114 115 117 117 118 118 119 119 121 123 124 125 . . . . 131 131 132 133 134 Sumário A Integração de Funções Hiperexponenciais A.1 O Algoritmo de Almkvist-Zeilberger . . . . A.1.1 Exemplos . . . . . . . . . . . . . . A.2 Pseudocódigos e Códigos para o Algoritmo A.2.1 DenMult . . . . . . . . . . . . . . . A.2.2 IHF . . . . . . . . . . . . . . . . . xii . . . . . . . . . . . . . . . . . . . . . . . . . . de Almkvist-Zeilberger . . . . . . . . . . . . . . . . . . . . . . . . . . 143 143 150 158 158 160 Capítulo 1 Introdução 1.1 Motivação e Objetivos do Trabalho O problema da integração indefinida de funções é, como conhecemos, aquele de encontrar uma função cuja derivada seja precisamente aquela função que se integra. Por isto, este também é chamado de problema da antiderivação. O primeiro contato que se tem com este problema geralmente se dá durante os cursos de Cálculo. Nesta ocasião, o estudante, via de regra, é apresentado a diversas técnicas de integração que, na maior parte das vezes, necessitam de uma medida de intuição e heurística para que possam ser utilizadas de maneira apropriada. Não raro, o processo de integração acaba por depender fortemente de uma mudança de variável adequada, ou se resume à detecção de algum padrão do integrando que indique qual expressão dentro de uma tabela de integrais é a solução do problema. Porém, quando queremos automatizar processos com eficiência através de implementações em máquinas, apesar de podermos desenvolver códigos heurísticos, o mais desejável é que se busque por algoritmos de terminação finita que não contem com recursos que seriam próprios do uso da razão, e que possam ser bem delimitados por um conjunto finito de tarefas sequenciadas. Felizmente, o problema da integração de funções pode, de fato, ser automatizado de maneira não heurística para certas classes de integrandos. Neste trabalho, mostraremos como isto pode ser feito para o caso simples em que o integrando é uma função racional complexa, isto é, a razão entre dois polinômios complexos. Capítulo 1. Introdução 2 A intenção é expor uma teoria introdutória sobre o problema (e resolução) da integração indefinida de funções à luz da Computação Algébrica, utilizando algoritmos que são usados ainda hoje em diversos Sistemas de Computação Algébrica (doravante CAS — do inglês, Computer Algebra System). A resolução algorítmica do problema da integração de funções racionais é o ponto de partida para se entender como buscar uma solução, nas mesmas condições, para o problema mais geral da integração de funções elementares — uma classe de funções que engloba o conjunto das funções racionais. Os algoritmos abordados neste trabalho, com exceção do algoritmo de Bernoulli, são classificados como algoritmos racionais, no sentido de que, no curso de sua execução, não requerem fatorações completas do denominador do integrando e evitam introduções de constantes algébricas desnecessárias à resolução do problema, tanto na representação final da integral, quanto durante os cálculos. Além disso, a base de seu funcionamento são as operações de corpo, isto é, as quatro operações aritméticas básicas aplicadas, neste contexto, a polinômios. Isto é percebido de maneira muito forte nos constantes cálculos de mdc entre polinômios que serão realizados. O desenvolvimento teórico do presente trabalho baseia-se em conceitos da teoria de Álgebra Abstrata. No que concerne a esta teoria, o que for omitido aqui poderá ser encontrado entre os capítulos de I a IV, VII e IX de [16]. 1.2 Histórico do Problema Abordado Segundo M. Ostrogradsky [26], tanto Newton quanto Leibniz tentaram desenvolver métodos de integração indefinida para funções racionais reais, sem obterem êxito completo. A abordagem utilizada por Leibniz consistia em fatorar o denominador do integrando sobre os reais, realizar a decomposição completa em frações parciais e integrar parcela a parcela. Ele obteve sucesso em calcular a integral de quaisquer termos com denominadores lineares (a menos de uma potência) na decomposição em frações parciais, mas não conseguiu o mesmo para os denominadores quadráticos de maneira completa. Continuando os esforços de Leibniz, J. Bernoulli consegue resolver o subproblema da integração de termos com denominadores quadráticos, publicando, no 3 1.2. Histórico do Problema Abordado Acta Eruditorum de 1703, o que se acredita ser o algoritmo de terminação finita mais antigo para a integração de funções racionais de que se tem registro [21, Cap. IX, p. 353], o qual é lecionado ainda hoje em grande parte dos cursos de Cálculo. Infelizmente, este método, apesar de bastante simples, apresenta uma dificuldade computacional proibitiva, que acaba por fazer com que, na prática, ele não seja utilizado com frequência. A dificuldade em questão é a necessidade de se saber a fatoração completa do denominador do integrando sobre os reais (o que, não raro, pode recorrer a expressões envolvendo muitas extensões algébricas) e decompor o integrando em frações parciais completas com esta dada fatoração (o que requer muitas operações aritméticas envolvendo diversos termos algébricos distintos). Por outro lado, além de uma importância histórica, este método possui uma importância teórica que motiva o seu estudo. Ele é capaz de explicitar a integral de uma função racional com coeficientes reais como sendo a soma entre uma parte racional real — uma função racional real que dispensa quaisquer extensões algébricas com unidade imaginária —, e outra parte transcendental real — formada por somas de logaritmos e arcos tangentes de polinômios com coeficientes reais. Desse modo, a integral de uma função racional real obtida pelo método de Bernoulli é ainda contínua no intervalo de definição do integrando, de modo que o Teorema Fundamental do Cálculo pode ser aplicado corretamente para o cálculo da integral definida da função original, qualquer que seja o intervalo de integração. O método possui ainda uma variante para funções racionais com coeficientes complexos em geral, em qual caso, a parte racional vem a ser ainda uma função racional complexa e a parte transcendental pode ser expressa apenas como uma combinação linear com coeficientes complexos de logaritmos de polinômios com coeficientes complexos. Diante destas considerações, a pesquisa por métodos alternativos de integração de funções racionais prosseguiu, de modo que, no século XIX, este problema já consistia numa área de pesquisa ativa. Em 1845, M. Ostrogradsky [26] propôs um método de integração que dispensa qualquer tipo de fatoração (mais ainda, dispensa qualquer decomposição em frações parciais e introdução de números algébricos durante os cálculos) e que é capaz de calcular completamente a parte racional da integral de uma função racional utilizando o corpo de constantes original do integrando, deixando a parte transcendental inerte. Mais precisamente, Capítulo 1. Introdução 4 o método expressa a parte transcendental como sendo a integral não calculada de um novo integrando racional completamente determinado e cujo denominador é livre de quadrados (dito de outro modo, todas as suas raízes possuem multiplicidade 1). Este era o método ensinado nas escolas russas naquela época e está presente em textos de Análise russos mais antigos [10, Cap. VIII, §2]. Foi redescoberto por E. Horowitz no século XX, que também apresentou detalhadamente um estudo sobre a sua complexidade [13], razão pela qual o método recebe, hoje, o nome de algoritmo de Horowitz-Ostrogradsky. Porém, no restante do mundo, outros métodos foram descobertos e ensinados. Um método notável também descoberto no século XIX é o algoritmo de Hermite. Foi publicado em 1872 [12]. Essencialmente, tanto o método de Ostrogradsky quanto o método de Hermite produzem os mesmos resultados. A diferença é que o primeiro condiciona o problema da integração à resolução de um sistema linear para explicitar tanto a parte racional quanto o integrando da parte transcendental, enquanto o segundo, originalmente, utiliza fatorações livres de quadrados do denominador, decomposição em frações parciais do integrando e a resolução de uma equação diofantina de polinômios para “retirar partes” do integrando a cada passo e construir a parte a parte racional sucessivamente, deixando aquilo que não pode ser “retirado” para formar o integrando da parte transcendental (este processo ocasiona sucessivas reduções de potência do denominador de cada parcela das frações parciais, razão pela qual o método de Hermite é chamado de redução). O modo como cada algoritmo trabalha reflete apenas na forma final da expressão, mas não na validade. Duas melhorias podem ser feitas ao método de Hermite. A primeira dispensa a necessidade de se decompor o integrando em frações parciais e é conhecida como versão quadrática do método de Hermite. A segunda dispensa ainda a necessidade prévia de se conhecer a fatoração livre de quadrados do denominador — esta é calculada a cada passo do processo —, sendo conhecida como versão linear do mesmo método e foi proposta por D. Mack [22]. Tais nomenclaturas derivam da própria complexidade destas versões [2, Cap. 2, §2]. Mantêm, contudo, o caráter de redução. Embora os métodos de Ostrogradsky e Hermite não contem com fatorações 5 1.2. Histórico do Problema Abordado completas do denominador e calculem de maneira satisfatória a parte racional da integral utilizando somente operações de corpo (isto é, sem introduzir novas extensões algébricas no corpo de constantes, nem introduzindo funções transcendentais como logaritmos ou arcos tangentes), eles não são capazes de resolver definitivamente o problema da integração indefinida de funções racionais, uma vez que só são capazes de fornecer a parte transcendental da integral em termos de um novo integrando racional. O problema da integração indefinida da parte transcendental sem fatoração completa permaneceria em aberto por mais de um século e só viria a ser resolvido recentemente. Em registro, o primeiro método para a integração da parte transcendental sem fazer uso de fatorações completas do denominador do integrando foi descoberto de maneira independente por M. Rothstein [31] e B. Trager [34]. A proposta deste método é descobrir o menor número de extensões que deve ser feita ao corpo de constantes original do integrando, de modo que a integral possa ser expressa como uma combinação linear de logaritmos de polinômios cujos coeficientes (tanto da combinação quanto dos polinômios) pertencem à nova extensão. Uma vez descobertas as extensões necessárias (as quais são as raízes de um polinômio obtido por cálculo de resultantes), os polinômios que aparecem como argumentos dos logaritmos são determinados por cálculos de mdc a partir das extensões. Uma melhoria ao método de Rothstein-Trager foi descoberta e publicada por D. Lazard e R. Rioboo [17] e, de maneira independente, também por Trager, apesar de ele não tê-la publicado formalmente [11, Cap. 11, §5]. A ideia por trás desta melhoria — conhecida como algoritmo de Lazard-Rioboo-Trager — é utilizar subresultantes para calcular de modo quase direto os argumentos que aparecem nos logaritmos da parte transcendental, dispensando cálculos de mdc envolvendo novas constantes algébricas. Em 1995, uma alternativa aos métodos de Rothstein-Trager e Lazard-RiobooTrager utilizando bases de Gröbner seria proposta por Czichowski [9]. Apesar de os algoritmos de Hermite e Ostrogradsky, combinados com os algoritmos de Rothstein-Trager, Lazard-Rioboo-Trager e Czichowski fornecerem soluções satisfatórias ao problema da integração indefinida de funções racionais, as fórmulas encontradas para as integrais nem sempre podem ser utilizadas para calcular corretamente a integral definida de funções racionais reais. É o caso, Capítulo 1. Introdução 6 por exemplo, quando a integral possui extensões complexas. Felizmente, em conformidade com o próprio algoritmo e Bernoulli, Rioboo mostrou em [28] um método para expressar a integral de uma função racional com coeficientes reais como sendo também uma função com coeficientes reais, utilizando, tanto quanto possível, somente operações de corpo e, se necessário, anexando minimamente extensões reais ao corpo de constantes. Tanto quanto o método de Bernoulli, o processo não gera novas singularidades (denominadores polinomiais não constantes), o que significa que integral encontrada é, ainda, contínua no intervalo de definição do integrando original. A ideia é agrupar pares conjugados de logaritmos complexos que apareçam na expressão complexa da integral e convertê-los em uma combinação linear envolvendo um logaritmo e funções arcos tangentes, onde os argumentos de cada parcela são polinômios e todos os coeficientes na expressão são reais. Obtemos, novamente, uma função contínua no intervalo de definição do integrando e, dessa forma, também é possível calcular a integral definida de uma função racional de maneira correta, sem recorrer a métodos aproximativos, e sim utilizando de maneira direta o Teorema Fundamental do Cálculo, do mesmo modo que no algoritmo de Bernoulli. O ponto importante de se combinar os algoritmos racionais mencionados é que, do mesmo modo como comparamos os algoritmos de Hermite e Horowitz, o resultado final é essencialmente o mesmo do algoritmo de Bernoulli, tanto no caso de integração de funções com coeficientes complexos, quanto no caso de funções com coeficientes estritamente reais, porém a forma deste resultado costuma ser consideravelmente mais simples, se comparada àquela fornecida pelo método de Bernoulli. 1.3 Visão Geral dos Capítulos e Seções Como dissemos na seção 1.1, buscaremos desenvolver algoritmos de integração indefinida para funções racionais à luz da Computação Algébrica. Com exceção do algoritmo de Bernoulli, todos os algoritmos que estudaremos procurarão se ater ao máximo a operações racionais. Como já vimos na seção 1.2, isto quer dizer que evitaremos, tanto quanto pudermos, introduzir extensões algébricas desnecessárias durante a resolução dos problemas, e que, via de regra, nos limitaremos a trabalhar 7 1.3. Visão Geral dos Capítulos e Seções com operações de corpo para obter os resultados desejados. Além de estarmos interessados em resultados mais simples, a razão para isto reside no fato de querermos diminuir a complexidade dos algoritmos, mas isto não será tratado com detalhes neste texto — nosso foco será demonstrar como os métodos funcionam, e não analisar seu desempenho. No capítulo 2, estudaremos brevemente conceitos envolvendo resultantes, sequências de restos de polinômios e fatorações livres de quadrados. Apesar destes conteúdos estarem presentes em certos textos de Álgebra, não são comumente estudados, de modo que sua exposição é razoável no presente texto. São fundamentais para embasar teoricamente os capítulos posteriores. No capítulo 3 apresentaremos os algoritmos racionais e não heurísticos para a integração de funções racionais. Como introdução, apresentaremos o algoritmo de Bernoulli. Em seguida, estudaremos os algoritmos de Hermite; de HorowitzOstrogradsky; de Rothstein-Trager; e Lazard-Rioboo-Trager. Optamos por omitir uma apresentação detalhada do algoritmo de Czichowski devido à demanda teórica para o seu entendimento. Complementando o terceiro capítulo, o capítulo 4 será dedicado ao problema da integração definida de funções racionais com coeficientes reais, onde explicitaremos o algoritmo clássico e o algoritmo de Rioboo para conversão de logaritmos complexos em uma combinação de funções arco tangente envolvendo apenas extensões reais, conforme mencionado na seção 1.2. Apresentaremos, no capítulo 5, códigos para implementação no software Maxima (software livre copyleft do CAS pioneiro Macsyma) que possibilitam a construção de um programa para integração de funções racionais sobre subcorpos dos complexos. Os principais são baseados em pseudocódigos presentes em [2, Caps. 1, 2], os quais também são apresentados juntamente com seus respectivos códigos no presente trabalho. Aqui, também apresentaremos um código para o algoritmo de Czichowksi. O capítulo 6 trará as considerações finais. Falaremos brevemente sobre o campo da Computação Algébrica como um todo e do problema mais geral da integração indefinida de funções elementares. Apresentaremos também referências de literatura acerca do problema da integração de funções em geral. Também serão feitos alguns comentários acerca do funcionamento dos códigos apresentados Capítulo 1. Introdução 8 no capítulo 5. Ao longo do trabalho serão apresentados exemplos que ilustram o funcionamento dos algoritmos de integração e dos códigos fornecidos no capítulo 5. No apêndice A, apresentaremos o algoritmo de Zeilberger-Almkvist para a integração de funções hiperexponenciais. Trata-se de um algoritmo aplicado a funções cuja derivada logarítmica seja uma função racional e que é sempre capaz de encontrar a integral de uma função dessa forma quando a mesma pode ser expressa como um múltiplo racional seu. Dentre outras classes de funções, pode ser aplicado a funções racionais, mas diferente dos demais algoritmos estudados, este nem sempre é capaz de obter uma solução para esta classe de funções. Além de apresentar este algoritmo, também forneceremos os pseudocódigos e os códigos para implementação em Maxima relativos ao mesmo. 1.4 Esclarecimentos Acerca do Presente Texto Antes de prosseguirmos, alguns esclarecimentos são válidos. 1. A sigla “DFU” indica “domínio de fatoração única”. A função cont(𝑎) indica o conteúdo do polinômio 𝑎, isto é, o mdc de seus coeficientes, enquanto que pp(𝑎) indica a parte primitiva, definida como sendo 𝑎/ cont(𝑎). cl(𝑝) indica o coeficiente líder do polinômio 𝑝, isto é, o coeficiente (não nulo) do termo 𝑥grau(𝑝) em 𝑝. A função pquo(𝑎,𝑏) indica o pseudoquociente da pseudodivisão de 𝑎 por 𝑏, enquanto prem(𝑎,𝑏) indica o pseudo-resto da mesma pseudodivisão, isto é, equivalem respectivamente ao quociente e resto da divisão de cl(𝑏)𝛿+1 𝑎 por 𝑏, onde 𝛿 = max(−1, grau(𝑎) − grau(𝑏)). Note que pquo(𝑎,𝑏) e prem(𝑎,𝑏) são polinômios cujo domínio de coeficientes é o mesmo que o de 𝑎 e 𝑏 não sendo necessário recorrer a um corpo de frações, caso o domínio original não seja um. Subscritos 𝑥 como em pp𝑥 , cl𝑥 , cont𝑥 e prem𝑥 irão indicar que os argumentos destas funções serão tratados como polinômios na variável 𝑥. 2. 𝐼 é a unidade imaginária, isto é, 𝐼 2 = −1. 3. Dois mdc para um par de polinômios serão tratados como iguais a menos 9 1.4. Esclarecimentos Acerca do Presente Texto de uma multiplicação por elemento do corpo de coeficientes, ou seja, apenas o grau e a relação entre os coeficientes é importante. Isto quer dizer que a expressão 𝑔 = mdc(𝑎,𝑏), por exemplo, indica que 𝑔 é um dos possíveis mdc para 𝑎 e 𝑏. 4. Dados dois polinômios 𝑝 e 𝑞, estes são ditos primos entre si, relativamente primos, ou coprimos, se grau(mdc(𝑝,𝑞)) = 0. Uma fração reduzida é aquela em que o numerador e o denominador são primos entre si. Uma fração própria é aquela em que o grau do numerador é menor que o grau do denominador. 5. Não estamos interessados nos valores dos logaritmos que aparecem durante este trabalho, mas nas suas propriedades algébricas. Isto quer dizer que, sempre que o leitor se deparar com um logaritmo complexo, poderá fixar qualquer valor para o mesmo, dentro do conceito de ramos de um logaritmo complexo. Além disso, como a variável de integração será sempre complexa, não utilizaremos o valor absoluto sobre o argumento dos logaritmos na integral, ficando implícita a existência de uma parte real e outra imaginária na fórmula da integral. Por outro lado, caso se deseje uma resposta para uma variável de integração real, supondo que o integrando seja uma função racional com coeficientes reais, poderemos, da mesma forma, empregar os algoritmos aqui estudados e simplesmente substituir os argumentos dos logaritmos pelos seus valores absolutos no final. 6. Quando quer que haja denominadores mônicos, estaremos supondo que o numerador e o denominador da fração tenha sido multiplicado pelo inverso do coeficiente líder do denominador para efeitos de simplificação dos cálculos. 7. Os exemplos apresentados seguirão a notação dos códigos e pseudocódigos apresentados no capítulo 5. 8. Está implícito que 𝑥 é a variável de integração de todas as integrais presentes neste trabalho, donde omitiremos o diferencial 𝑑𝑥. Sempre que não houver ambiguidades, a variável 𝑥 também será omitida de expressões funcionais, isto é, a expressão 𝑓 (𝑥) passará a ser representada por 𝑓 . Capítulo 1. Introdução 10 9. As imagens deste trabalho foram geradas com o apoio do CAS Maple. Já os códigos foram elaborados no ambiente do CAS Maxima. Capítulo 2 Noções Preliminares 2.1 Resultantes e Sequências de Restos Polinomiais 2.1.1 Resultantes e Subresultantes Estudamos agora as resultantes e subresultantes. A resultante ente dois polinômios é uma ferramenta que auxilia na detecção de seus fatores comuns, ou mesmo na detecção de raízes comuns entre os mesmos que estejam no fecho algébrico do corpo de constantes dos polinômios. As subresultantes de um par de polinômios, por sua vez, possuem uma relação especial com qualquer sequência de restos polinomiais gerada por este par e possuem uma importante propriedade algébrica envolvendo homomorfismos sobre anéis de polinômios induzidos a partir do anel de coeficientes em questão. Utilizaremos os conceitos de resultante e subresultante ao estudarmos os algoritmos de Rothstein-Trager e Lazard-Rioboo-Trager. Definição 2.1.1. Seja 𝑅 um anel comutativo e 𝑝,𝑞 ∈ 𝑅[𝑥] ∖ {0}. Escrevamos 𝑝 = 𝑎𝑚 𝑥𝑚 + · · · 𝑎1 𝑥 + 𝑎0 e 𝑞 = 𝑏𝑛 𝑥𝑛 + · · · 𝑏1 𝑥 + 𝑏0 , onde 𝑎𝑚 ̸= 0, 𝑏𝑛 ̸= 0 e pelo menos um entre 𝑚 e 𝑛 é não nulo. A matriz de Sylvester de 𝑝 e 𝑞 é a matriz (𝑚 + 𝑛) × (𝑚 + 𝑛) definida por Capítulo 2. Noções Preliminares ⎛ 𝑆(𝑝,𝑞) = ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ 12 𝑎𝑚 · · · · · · · · · 𝑎1 𝑎0 ⎟ .. ⎟ . ⎟ ⎟ 𝑎𝑚 · · · · · · · · · 𝑎1 𝑎0 ⎟ ⎟ ⎟ 𝑏𝑛 · · · 𝑏1 𝑏 0 ⎟ ⎟ ... ⎟ ⎟ ⎟ .. ⎟ . ⎟ ⎟ ⎟ .. . ⎠ 𝑏𝑛 · · · 𝑏1 𝑏 0 ⎞ ⎫ ⎪ ⎪ ⎪ ⎬ ⎪ ⎪ ⎪ ⎭ ⎫ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎬ n linhas m linhas ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎭ onde as 𝑝-linhas são repetidas 𝑛 vezes e as 𝑞-linhas são repetidas 𝑚 vezes. A resultante entre 𝑝 e 𝑞 é o determinante de 𝑆(𝑝,𝑞) e é indicada por res(𝑝,𝑞). A seguir, enunciamos alguma propriedades algébricas das resultantes. Lema 2.1.1 ([11], Cap. 9, §5). Sejam 𝑅 um anel comutativo, 𝑝,𝑞 ∈ 𝑅[𝑥] polinômios de graus 𝑚 e 𝑛 respectivamente e 𝑐 ∈ 𝑅 não nulo. 1. res(𝑐,𝑞) = 𝑐𝑛 ; 2. res(𝑝,𝑝) = 0; 3. res(𝑝,𝑞) = (−1)𝑚𝑛 res(𝑞,𝑝); 4. res(𝑐𝑝,𝑞) = 𝑐𝑛 res(𝑞,𝑝); 5. res(𝑥𝑘 𝑝,𝑞) = 𝑏𝑘0 res(𝑝,𝑞) para 𝑘 > 0, onde 𝑏0 é o termo independente de 𝑞; Lema 2.1.2 ([15] Cap. IV §8, [11] Cap. 9 §5). Sejam 𝑅 um anel comutativo, 𝛼1 , . . . ,𝛼𝑚 ,𝛽1 , . . . ,𝛽𝑛 𝑎,𝑏 ∈ 𝑅 com 𝑎 ̸= 0, 𝑏 ̸= 0, e polinômios 𝑝 = 𝑎(𝑥 − 𝛼1 ) · · · (𝑥 − 𝛼𝑚 ) e 𝑞 = 𝑏(𝑥 − 𝛽1 ) · · · (𝑥 − 𝛽𝑛 ) em 𝑅[𝑥]. Então, res(𝑝,𝑞) = 𝑎𝑛 𝑏𝑚 𝑚 ∏︁ 𝑛 ∏︁ (𝛼𝑖 − 𝛽𝑗 ) = 𝑎𝑛 𝑖=1 𝑗=1 𝑚 ∏︁ 𝑖=1 𝑞(𝛼𝑖 ) = (−1)𝑚𝑛 𝑏𝑚 𝑛 ∏︁ 𝑝(𝛽𝑗 ). 𝑗=1 Como consequência do Lema 2.1.2, podemos deduzir facilmente o corolário abaixo, analisando as fatorações irredutíveis dos polinômios 𝑝 e 𝑞 abaixo, sobre o fecho algébrico destes polinômios. 13 2.1. Resultantes e Sequências de Restos Polinomiais Corolário 2.1.1 ([15] Cap. IV §8). Suponha que 𝐷 seja um domínio de integridade. Seja 𝐾 o corpo quociente de 𝐷 e 𝐾 o fecho algébrico de 𝐾. Então, dados quaisquer 𝑝,𝑞 ∈ 𝐷[𝑥] ∖ {0}, res(𝑝,𝑞) = 0 ⇐⇒ ∃𝛾 ∈ 𝐾 tal que 𝑝(𝛾) = 𝑞(𝛾) = 0. O Corolário 2.1.1 acima nos diz que dois polinômios em um domínio de integridade 𝐷 possuem raízes comuns no fecho algébrico do corpo quociente de 𝐷 se e só se a resultante entre eles é nula. Proposição 2.1.1 ([15] Cap. IV §8). Seja 𝑅 um anel comutativo. Para quaisquer 𝑝,𝑞 ∈ 𝑅[𝑥] de grau positivo, existem 𝜎,𝜏 ∈ 𝑅[𝑥], com grau(𝜎) < grau(𝑞) e grau(𝜏 ) < grau(𝑝) tais que res(𝑝,𝑞) = 𝜎𝑝 + 𝜏 𝑞. Em outras palavras, o Proposição 2.1.1 nos diz que a resultante de dois polinômios se encontra no ideal gerado por estes. Consequentemente, se 𝐷 é um DFU, então a resultante de dois polinômios em 𝐷 é nula se e só estes se possuem um fator comum não trivial. Formalmente temos o resultado abaixo. Corolário 2.1.2 (Critério de Sylvester, [11] Cap. 7 §3, [2] Cap. 1 §4). Suponha que 𝐷 seja um DFU. Então, dados quaisquer 𝑝,𝑞 ∈ 𝐷[𝑥] − {0}, res(𝑝,𝑞) = 0 ⇐⇒ grau(mdc(𝑝,𝑞)) > 0. Apresentamos agora as subresultantes, que são polinômios obtidos a partir de submatrizes da matriz de Sylvester. Sua definição formal segue abaixo. Definição 2.1.2. Sejam 𝑅 um anel comutativo, 𝑝,𝑞 ∈ 𝑅[𝑥] ∖ {0}, 𝑚 = grau(𝑝), 𝑛 = grau(𝑞), 𝑆 a matriz de Sylvester de 𝑝 e 𝑞, e 𝑗 um inteiro tal que 0 ≤ 𝑗 < min(𝑚,𝑛). Seja 𝑗 𝑆 a matriz 𝑚 + 𝑛 − 2𝑗 por 𝑚 + 𝑛 obtida deletando-se de 𝑆: 1. as linhas de 𝑛 − 𝑗 + 1 até 𝑛 (i.e. as 𝑗 últimas linhas correspondentes a 𝑝), 2. as linhas de 𝑛 + 𝑚 − 𝑗 + 1 até 𝑛 + 𝑚 (i.e. as 𝑗 últimas linhas de 𝑞). Além disso, para 0 ≤ 𝑖 ≤ 𝑗 seja 𝑗 𝑆𝑖 a matriz quadrada obtida deletando-se as colunas de 𝑚 + 𝑛 − 2𝑗 a 𝑚 + 𝑛 (i.e. as 2𝑗 + 1 últimas colunas) de 𝑗 𝑆, exceto pela Capítulo 2. Noções Preliminares 14 coluna 𝑚 + 𝑛 − 𝑖 − 𝑗. A 𝑗-ésima subresultante de 𝑝 e 𝑞 é definida por 𝑆𝑗 (𝑝,𝑞) = 𝑗 ∑︁ det(𝑗 𝑆𝑖 )𝑥𝑖 ∈ 𝑅[𝑥]. 𝑖=0 É evidente que grau(𝑆𝑗 (𝑝,𝑞)) ≤ 𝑗 para cada 𝑗. Quando 𝑆𝑗 (𝑝,𝑞) < 𝑗 dizemos que 𝑆𝑗 (𝑝,𝑞) é defectiva, e regular em caso contrário. Além disso, 0 𝑆0 = 𝑆, donde 𝑆0 (𝑝,𝑞) = res(𝑝,𝑞). Encerrando esta subseção, explicitamos o seguinte resultado a respeito das subresultantes (e, consequentemente, das resultantes), o qual revela uma importante propriedade sobre as mesmas. Proposição 2.1.2 ([23] §7.8). Sejam 𝑅 e 𝑆 anéis comutativos, 𝜎 : 𝑅 → 𝑆 um homomorfismo de anéis, 𝜎 : 𝑅[𝑥] → 𝑆[𝑥] o homomorfismo de anéis de polinômios induzido por 𝜎, isto é, satisfazendo 𝜎 (︁∑︁ )︁ 𝑎𝑗 𝑥 𝑗 = ∑︁ 𝜎(𝑎𝑗 )𝑥𝑗 , (2.1) e 𝑝,𝑞 ∈ 𝑅[𝑥] ∖ {0}. Se grau(𝜎(𝑝)) = grau(𝑞) então 𝜎(𝑆𝑗 (𝑝,𝑞)) = 𝜎(cl(𝑝))grau(𝑞)−grau(𝜎(𝑞)) 𝑆𝑗 (𝜎(𝑝),𝜎(𝑞)) para 0 ≤ 𝑗 < min(grau(𝑝), grau(𝜎(𝑞)). Em outras palavas, a Proposição 2.1.2 nos fornece um modo de calcular 𝑆𝑗 (𝜎(𝑝), 𝜎(𝑞)) a partir de 𝑆𝑗 (𝑝,𝑞), quando pelo menos um dos coeficientes líderes de 𝑝 ou 𝑞 não é levado em 0. Ainda, se o homomorfismo 𝜎 não diminui o grau de 𝑝 e de 𝑞, isto é, grau(𝜎(𝑝)) = grau(𝑝) e grau(𝜎(𝑞)) = grau(𝑞), ou se ambos 𝑝 e 𝑞 são mônicos, então as subresultantes 𝑆𝑗 (𝑝,𝑞), na verdade, comutam com o homomorfismo 𝜎. Ou seja, passamos a ter: 𝜎(𝑆𝑗 (𝑝,𝑞)) = 𝑆𝑗 (𝜎(𝑝),𝜎(𝑞)) A Proposição 2.1.2 constitui a chave para se demonstrar o Teorema 3.5.1, o qual é a base do algoritmo de Lazard-Rioboo-Trager para o cálculo da parte logarítmica da integral de uma função racional. Durante a demonstração do Teorema 3.5.1, 15 2.1. Resultantes e Sequências de Restos Polinomiais teremos o homomorfismo 𝜎 : K[𝑧] → K(𝛼) que é a identidade sobre K ⊆ C e leva 𝑧 em 𝛼, e mostraremos que, para calcular as subresultantes 𝑆𝑗 (𝑐,𝑎−𝛼𝑏) ∈ K(𝛼)[𝑥], onde 𝑎,𝑏,𝑐 ∈ K[𝑥] e 𝛼 é uma extensão algébrica sobre K, podemos simplesmente calcular 𝑆𝑗 (𝑐,𝑎 − 𝑧𝑏) ∈ K[𝑧][𝑥] e utilizar 𝑆𝑗 (𝑐,𝑎 − 𝛼𝑏) = 𝑆𝑗 (𝑐,𝑎 − 𝜎(𝑧)𝑏) = 𝜎(𝑆𝑗 (𝑐,𝑎 − 𝑧𝑏)), evitando, assim, cálculos sobre extensões algébricas do corpo de constantes K para se obter 𝑆𝑗 (𝑐,𝑎 − 𝛼𝑏). 2.1.2 Sequências de Restos Polinomiais Nesta seção, estudamos as sequências de restos polinomiais, que generalizam o algoritmo de Euclides para o cálculo de mdc. Nosso principal objetivo será desenvolver um método eficiente para o cálculo de resultantes e subresultantes. Ao longo desta seção, 𝐷 será um domínio de integridade. Definição 2.1.3. Sejam 𝑝,𝑞 ∈ 𝐷[𝑥] com 𝑞 = ̸ 0 e grau(𝑝) ≥ grau(𝑞). Uma Sequência de Restos Polinomiais (SRP) para 𝑝 e 𝑞 é uma sequência (𝑟𝑖 )𝑖≥0 em 𝐷[𝑥] satisfazendo 1. 𝑟0 = 𝑝, 𝑟1 = 𝑞, 2. Para 𝑖 ≥ 1, 𝛽𝑖 𝑟𝑖+1 = ⎧ ⎪ ⎨0 se 𝑟𝑖 = 0 ⎪ ⎩prem(𝑟𝑖−1 ,𝑟𝑖 ) se 𝑟𝑖 ̸= 0 onde (𝛽𝑖 )𝑖≥1 é uma sequência de elementos não nulos de 𝐷. Pela definição de SRP, é evidente que 𝑟𝑖+1 = 0 ou grau(𝑟𝑖+1 ) < grau(𝑟𝑖 ) para 𝑖 ≥ 1. Portanto, uma SRP sempre possui uma quantidade finita de elementos não nulos, e se 𝑟𝑖 ̸= 0, 𝑟𝑗 = ̸ 0, grau(𝑟𝑖 ) = grau(𝑟𝑗 ) e 𝑖,𝑗 ≥ 1, então 𝑖 = 𝑗. Em outras palavras o grau é estritamente decrescente na sequência, de modo que só 𝑟0 e 𝑟1 podem ter o mesmo grau. Capítulo 2. Noções Preliminares 16 A escolha de diferentes 𝛽𝑖 na Definição 2.1.3 origina tipos diferentes de SRP. A SRP euclidiana é obtida tomando-se 𝛽𝑖 = 1 para todo 𝑖, e é simplesmente a sequência de pseudo-restos sucessivos de 𝑝 e 𝑞, obtidos de modo semelhante ao que teríamos no algoritmo de Euclides em um domínio euclidiano. Outro exemplo de SRP é a SRP primitiva, obtida quando definimos 𝛽𝑖 = cont(prem(𝑟𝑖−1 ,𝑟𝑖 )) ∈ 𝐷. Definição 2.1.4. Sejam 𝑝,𝑞 ∈ 𝐷[𝑥]. Dizemos que 𝑝 é semelhante a 𝑞 se existem 𝛼,𝛽 ∈ 𝐷 ∖ {0} tais que 𝛼𝑝 = 𝛽𝑞. A similaridade é uma relação de equivalência. O seguinte resultado aponta para o fato importante de que, se 𝐷 é um DFU, então o último elemento não nulo de uma SRP do par 𝑝,𝑞 ∈ 𝐷[𝑥] é semelhante a mdc(𝑝,𝑞). Proposição 2.1.3 ([2] Cap. 1 §5). Suponha que 𝐷 seja um DFU e sejam 𝑝,𝑞 ∈ 𝐷[𝑥] com 𝑞 ̸= 0 e grau(𝑝) ≥ grau(𝑞). Seja (𝑟0 ,𝑟1 , . . . ,𝑟𝑘 ,0, . . . ) uma SRP qualquer de 𝑝 e 𝑞 com 𝑟𝑘 = ̸ 0. Então mdc(𝑟𝑖 ,𝑟𝑖+1 ) é semelhante a mdc(𝑟𝑗 ,𝑟𝑗+1 ) para quaisquer 0 ≤ 𝑖,𝑗 ≤ 𝑘. Em particular (fazendo 𝑖 = 0, 𝑗 = 𝑘), temos que 𝑟𝑘 é semelhante a mdc(𝑝,𝑞). Portanto, toda SRP de 𝑝 e 𝑞 contém mdc(𝑝,𝑞) (a menos de um elemento multiplicativo pertecente ao domínio de coeficientes). Dada uma SRP qualquer de 𝑝 e 𝑞, o teorema abaixo mostra que toda subresultante não nula de 𝑝 e 𝑞 é semelhante a algum elemento da SRP e traz fórmulas explicitas para os coeficientes de similaridade, isto é, mostra como as subresultantes de 𝑝 e 𝑞 podem ser recuperadas a partir de qualquer SRP gerada por 𝑝 e 𝑞. Teorema 2.1.1 (Teorema Fundamental das SRP, [11] Cap. 7 §3, [27]). Sejam 𝑝e𝑞= ̸ 0 polinômios em 𝐷[𝑥] com grau(𝑝) ≥ grau(𝑞), e seja (𝑟0 ,𝑟1 , . . . ,𝑟𝑘 ,0 . . . ) uma SRP de 𝑝 e 𝑞 com 𝑟𝑘 ̸= 0. Para 𝑖 = 1, . . . ,𝑘, sejam 𝑛𝑖 = grau(𝑟𝑖 ) e 𝜌𝑖 o coeficiente líder de 𝑟𝑖 . Então, para qualquer 𝑗 em {0, . . . , grau(𝑞) − 1}, 𝑆𝑗 (𝑝,𝑞) = ⎧ ⎪ ⎪ 𝜂𝑖 𝑟𝑖 ⎪ ⎪ ⎨ 𝜏𝑖 𝑟𝑖 ⎪ ⎪ ⎪ ⎪ ⎩0 se 𝑗 = 𝑛𝑖−1 − 1, se 𝑗 = 𝑛𝑖 , caso contrário 17 2.1. Resultantes e Sequências de Restos Polinomiais onde 1−𝑛 𝜂𝑖 = (−1)𝜑𝑖 𝜌𝑖−1 𝑖−1 +𝑛𝑖 𝑖−1 ∏︁ ⎡⎛ ⎤ ⎞1+𝑛𝑗 −𝑛𝑖 −1 𝛽𝑗 𝑛 −𝑛 ⎢⎝ ⎥ ⎠ 𝜌𝑗 𝑗−1 𝑗+1 ⎦ ⎣ 𝑙+𝑛𝑗−1 −𝑛𝑗 𝜌𝑗 𝑗=1 𝑛 𝜏𝑖 = (−1)𝜎𝑖 𝜌𝑖 𝑖−1 −𝑛𝑖 −1 𝑖−1 ∏︁ ⎡⎛ ⎣⎝ 𝑗=1 ⎞𝑛𝑗 −𝑛𝑖 𝛽𝑗 ⎤ −𝑛𝑗+1 ⎦ (2.2) (𝑛𝑗−1 − 𝑛𝑖 )(𝑛𝑗 − 𝑛𝑖 ). (2.3) 𝑛 𝑙+𝑛 −𝑛 𝜌𝑗 𝑗−1 𝑗 𝜌𝑗 𝑗−1 ⎠ e 𝜑𝑖 = 𝑖−1 ∑︁ (𝑛𝑗 − 𝑛𝑖−1 + 1)(𝑛𝑗−1 − 𝑛𝑖−1 + 1), 𝜎𝑖 = 𝑗=1 𝑖−1 ∑︁ 𝑗=1 A SRP das subresultantes de 𝑝 e 𝑞 é uma SRP que satisfaz 𝜂𝑖 = 1 no teorema anterior. É obtida através das seguintes regras de recursão: 𝑟0 = 𝑝, 𝑟1 = 𝑞, 𝛿1 = −1, 𝛽1 = (−1)𝛾1 +1 e ⎧ ⎨ 𝛿𝑖+1 = (− cl(𝑟𝑖 ))𝛾𝑖 𝛿𝑖1−𝛾𝑖 𝛾𝑖+1 ⎩ 𝛽 𝑖+1 = − cl(𝑟𝑖 )𝛿𝑖+1 para 𝑖 ≥ 1, onde 𝛾𝑖 = grau(𝑟𝑖−1 ) − grau(𝑟𝑖 ). Sua propriedade principal é dada pelo seguinte resultado. Teorema 2.1.2 ([4] §7, [7, 27]). Sejam 𝑝 e 𝑞 polinômios em 𝐷[𝑥] com grau(𝑝) ≥ grau(𝑞) e (𝑟0 ,𝑟1 , . . . ,𝑟𝑘 ,0, . . . ) a SRP das subresultantes de 𝑝 e 𝑞, com 𝑟𝑘 = ̸ 0e 𝑛𝑖 = grau(𝑟𝑖 ) para 𝑖 = 1, . . . ,𝑘. Então, ∀𝑗 ∈ {0, . . . , grau(𝑞) − 1}, 𝑆𝑗 (𝑝,𝑞) = ⎧ ⎪ ⎪ 𝑟𝑖 ⎪ ⎪ ⎨ 𝜏𝑖 𝑟𝑖 ⎪ ⎪ ⎪ ⎪ ⎩0 se 𝑗 = 𝑛𝑖−1 − 1 se 𝑗 = 𝑛𝑖 caso contrário onde 𝜏𝑖 é dado pela fórmula 2.2. O algoritmo das subresultantes, capaz de calcular a resultante de dois polinômios 𝑝 e 𝑞 deriva do resultado acima. Se grau(𝑝) ≥ grau(𝑞) então, por definição, temos que res(𝑝,𝑞) = 𝑆0 (𝑝,𝑞). Calculando a SRP das subresultantes Capítulo 2. Noções Preliminares 18 de 𝑝 e 𝑞, temos que se grau(𝑟𝑘 ) > 0 então 𝑝 e 𝑞 possuem um fator comum, de modo que res(𝑝,𝑞) = 0. Senão, pelo Teorema 2.1.2 temos que 𝑆0 (𝑝,𝑞) = 𝑟𝑘 se grau(𝑟𝑘−1 ) = 1, ou 𝑆0 (𝑝,𝑞) = 𝜏𝑘 𝑟𝑘 , se grau(𝑟𝑘−1 ) > 1. No segundo caso, como 𝜂𝑘 = 0, o cálculo de 𝜏𝑘 fica simplificado, pois 2.3 se torna 𝜎𝑘 = 𝑘−1 ∑︁ 𝑛𝑗−1 𝑛𝑗 𝑗=1 e, portanto, (−1)𝜎𝑘 = 𝑘−1 ∏︁ (−1)𝑛𝑗−1 𝑛𝑗 𝑗=1 No produto acima, um fator −1 so aparece se ambos 𝑛𝑗−1 e 𝑛𝑗 forem ímpares. Além disso, como grau(𝑟𝑘 ) = 0, 𝜌𝑘 = 𝑟𝑘 e a equação 2.2 se torna 𝜏𝑘 = 𝑛 −1 (−1)𝜎𝑘 𝑟𝑘 𝑘−1 𝑘−1 ∏︁ ⎡⎛ ⎣⎝ 𝑗=1 𝛽𝑗 𝑙+𝑛𝑗−1 −𝑛𝑗 𝜌𝑗 ⎞𝑛𝑗 ⎠ ⎤ 𝑛 −𝑛 𝜌𝑗 𝑗−1 𝑗+1 ⎦ . Por outro lado, se grau(𝑝) < grau(𝑞), podemos calcular a SRP de 𝑞 e 𝑝 e utilizar a fórmula 3 do Lema 2.1.1: res(𝑝,𝑞) = (−1)grau(𝑝) grau(𝑞) res(𝑞,𝑝). Na subseção 5.2.10, fornecemos um pseudocódigo, juntamente com um código para implementação no Maxima do algoritmo das subresultantes. 2.2 Fatoração Livre de Quadrados A fatoração livre de quadrados é um tipo especial de fatoração capaz de agrupar as raízes de um polinômio de acordo com a sua multiplicidade, mas de maneira que não seja necessário saber quais são estas raízes (e nem mesmo a fatoração irredutível do polinômio em questão). Isto é, o fator de potência 𝑘 em uma fatoração livre de quadrados contém todas as raízes (considerando o fecho algébrico do polinômio) de multiplicidade 𝑘, mas este fator não se decompõe completamente em termos de suas raízes (a menos que haja só uma raiz). Este tipo de fatoração possui propriedades especiais de fundamental importância, como veremos, para o algoritmo de Hermite e, de maneira indireta, para algoritmo e Horowitz-Ostrogradsky. O algoritmo de Lazard-Rioboo-Trager tam- 19 2.2. Fatoração Livre de Quadrados bém utiliza esta fatoração em certo ponto. Definição 2.2.1. Sejam 𝑝 ∈ 𝐷[𝑥] e pp(𝑝) = 𝑛 ∏︁ 𝑒𝑖 𝑝𝑖 a fatoração em fatores 𝑖=1 irredutíveis de sua parte primitiva, onde 𝑒𝑖 ≥ 1 para cada 𝑖. Definimos a parte livre de quadrados de 𝑝 como sendo 𝑝* = 𝑛 ∏︁ 𝑝𝑖 𝑖=1 e para cada 𝑘 ∈ Z, 𝑘 ≥ 0, definimos a 𝑘-deflação (ou 𝑘-ésima deflação, e apenas deflação quando 𝑘 = 1) de 𝑝 como sendo 𝑝−𝑘 = 𝑛 ∏︁ max(0,𝑒𝑖 −𝑘) 𝑝𝑖 𝑛 ∏︁ = 𝑖=1 𝑝𝑒𝑖 𝑖 −𝑘 . 𝑖|𝑒𝑖 >𝑘 Em outras palavras a 𝑘-deflação diminui em 𝑘 unidades a multiplicidade de cada raiz, mas apenas enquanto a potência da respectiva raiz não se tornar negativa. Observe que 𝑝−0 = pp(𝑝). Além disso, convencionamos 𝑝− = 𝑝−1 ou seja, 𝑝− = 𝑛 ∏︁ 𝑒𝑖 −1 𝑝𝑖 . 𝑖=1 Pela Definição 2.2.1, temos que 𝑝−𝑖+𝑗 = (𝑝−𝑖 )−𝑗 , para quaisquer 𝑖,𝑗 ≥ 0, e, portanto, 𝑝−𝑘+1 = (𝑝−𝑘 )− . (2.4) Além disso, 𝑝* 𝑝− = pp(𝑝). (2.5) As equações (2.4) e (2.5) combinadas fornecem 𝑝−𝑘+1 = 𝑝−𝑘 , para 𝑘 ≥ 0. (𝑝−𝑘 )* (2.6) Em 𝐷[𝑥], o cálculo da parte livre de quadrados e das deflações de um polinômio, apesar da definição, pode ser feito evitando-se a fatoração em fatores irredutíveis, bastando que recorramos cálculos de mdc (estamos em um DFU). O Teorema 2.2.1 a seguir nos diz que qualquer fator primo de 𝑝 ∈ 𝐷[𝑥] divide mdc(𝑝,𝑑𝑝/𝑑𝑥) Capítulo 2. Noções Preliminares 20 uma vez a menos. Além disso, a recíproca vale se 𝐷 tem característica 0, de modo que, se 𝑝 for primitivo, passamos a ter (︃ 𝑑𝑝 𝑝− = mdc 𝑝, 𝑑𝑥 )︃ (2.7) e, desta forma, 𝑝* pode ser calculado através de 2.5. As demais deflações de 𝑝 podem ser calculadas recursivamente através de 2.4. Lema 2.2.1 ([2], Cap. 1, §6). Sejam 𝐷 um DFU, 𝑝,𝑞 ∈ 𝐷[𝑥] ∖ 𝐷 e 𝑛 > 0 um inteiro. Então, 1. 𝑝𝑛+1 | 𝑞 =⇒ 𝑝𝑛 | mdc(𝑞,𝑑𝑞/𝑑𝑥), 2. se 𝑝 é irredutível e 𝐷 tem característica 0, então 𝑝𝑛 | mdc(𝑞,𝑑𝑞/𝑑𝑥) =⇒ 𝑝𝑛+1 | 𝑞. Sejam 𝐷 um DFU e 𝑥 uma indeterminada sobre 𝐷. As considerações anteriores nos permitem concluir que é mais fácil calcular partes livres de quadrados e deflações do que calcular a fatoração em fatores irredutíveis de um polinômio em 𝐷[𝑥]. Isto nos motiva a definir um tipo especial de fatoração. Definição 2.2.2. Um polinômio 𝑝 ∈ 𝐷[𝑥] é dito livre de quadrados, ou livre de fatores quadráticos se não existe 𝑞 ∈ 𝐷[𝑥] ∖ 𝐷 tal que 𝑞 2 | 𝑝 em 𝐷[𝑥]. Ou seja, um polinômio é livre de quadrados quando sua fatoração em fatores irredutíveis sobre 𝐷, ou sobre qualquer extensão de 𝐷 tem todos os expoentes iguais a 1. Definição 2.2.3. Seja 𝑝 ∈ 𝐷[𝑥]. Uma fatoração livre de quadrados (flq) de 𝑝 é uma fatoração da forma 𝑝 = 𝑘 ∏︁ 𝑝𝑖𝑖 onde cada 𝑝𝑖 é livre de quadrados e 𝑖=1 mdc(𝑝𝑖 ,𝑝𝑗 ) = 1 para 𝑖 ̸= 𝑗. Uma vez que os elementos de 𝐷, vistos como elementos de 𝐷[𝑥], são sempre livres de quadrados por definição, e que 𝑝 = cont(𝑝) pp(𝑝), se pp(𝑝) = 𝑘 ∏︁ 𝑖=1 flq de pp(𝑝), então 𝑝 = (cont(𝑝)𝑝1 ) 𝑘 ∏︁ 𝑖=2 𝑝𝑖𝑖 𝑝𝑖𝑖 é a 21 2.2. Fatoração Livre de Quadrados é uma flq de 𝑝. Portanto, só precisamos nos preocupar em calcular a flq da parte primitiva de um polinômio. Além disso, se 𝐷 possui característica 0, a flq de 𝑝 separa as suas raízes pelas multiplicidades, agrupando em 𝑝𝑖 aquelas com multiplicidade 𝑖, pois qualquer raiz de 𝑝 deve ser raiz de exatamente um destes 𝑝𝑖 (os 𝑝𝑖 são coprimos). Proposição 2.2.1 ([2], Cap. 1, §7, [25]). Sejam 𝑝 ∈ 𝐷[𝑥]∖𝐷, pp(𝑝) = 𝑛 ∏︁ 𝑒𝑖 𝑝𝑖 uma 𝑖=1 fatoração em fatores irredutíveis de pp(𝑝), 𝑚 = max(𝑒1 , . . . ,𝑒𝑛 ) e 𝑞𝑖 = ∏︁ 𝑝𝑗 𝑗|𝑒𝑗 =𝑖 para 1 ≤ 𝑖 ≤ 𝑚. Então, 1. 𝑝−𝑘 = 𝑚 ∏︁ 2 𝑚−𝑘 𝑞𝑖𝑖−𝑘 = 𝑞𝑘+1 𝑞𝑘+2 . . . 𝑞𝑚 para qualquer 𝑘 ≥ 0. 𝑖=𝑘+1 2. * 𝑞𝑖 = 3. pp(𝑝) = 𝑚 ∏︁ 𝑝−𝑖−1 para 1 ≤ 𝑖 ≤ 𝑚. 𝑝−𝑖 * (2.8) 𝑞𝑖𝑖 é uma fatoração livre de quadrados de pp(𝑝). 𝑖=1 Temos, portanto, uma maneira de calcular os fatores de uma flq de um polinômio em termos de suas deflações e vice-versa. Além disso, se 𝐷 tem característica 0, conseguimos o seguinte algoritmo para calcular a parte primitiva de um polinômio: como vimos na subseção anterior, vale em 𝐷[𝑥] a equação (2.7), isto é, 𝑝−1 = 𝑝− = mdc(𝑝,𝑑𝑝/𝑑𝑥), o que nos dá 𝑞1 = (𝑝−0 )* = 𝑝* = pp(𝑝)/𝑝− . Indutivamente, se temos (𝑝−𝑘 )* e 𝑝−𝑘+1 , então conseguimos calcular (︁ )︁ 2 𝑚−𝑘−1 mdc (𝑝−𝑘 )* ,𝑝−𝑘+1 = mdc(𝑞𝑘+1 · · · 𝑞𝑚 ,𝑞𝑘+2 𝑞𝑘+3 · · · 𝑞𝑚 ) = (𝑝−𝑘+1 )* , e 𝑞𝑘+1 e 𝑝−𝑘+2 podem ser obtidos respectivamente por 2.8 e 2.6. Seguimos até encontrar o primeiro 𝑘 inteiro positivo tal que 𝑝−𝑘+1 ∈ 𝐷, em qual caso teremos 𝑝−𝑘 livre de quadrados, com 𝑘 = 𝑚−1 e 𝑞𝑚 = 𝑝−𝑘 . Ou seja, conseguimos o algoritmo de Musser, que encontra uma flq para 𝑝 utilizando apenas operações racionais e cálculos de mdc em 𝐷[𝑥]. Há, porém, um algoritmo mais eficiente que o descrito acima, que atua através da redução de grau dos polinômios que aparecem nos mdc de cada iteração. É Capítulo 2. Noções Preliminares 22 chamado algoritmo de Yun [36]. Mantendo a notação, a ideia é considerar a seguinte sequência de polinômios: 𝑌𝑘 = 𝑚 ∑︁ (𝑖 − 𝑘 + 1) 𝑖=𝑘 = 𝑑𝑞𝑖 (𝑝−𝑘−1 )* 𝑑𝑥 𝑞𝑖 𝑚 ∑︁ (𝑖 − 𝑘 + 1)𝑞𝑘 · · · 𝑞𝑖−1 𝑖=𝑘 𝑑𝑞𝑖 𝑞𝑖+1 · · · 𝑞𝑚 para 𝑘 ≥ 1. 𝑑𝑥 (2.9) O lema abaixo traz algumas propriedades desta sequência. Proposição 2.2.2 ([2] Cap. 1, §7, [36]). Com a notação acima, * mdc((𝑝−𝑖−1 ) ,𝑌𝑖 ) ∈ 𝐷, 𝑑𝑝−𝑖−1 /𝑑𝑥 = 𝑝−𝑖 𝑌𝑖 , (2.10) e com 𝑞𝑖 como definido na Proposição 2.2.1, * 𝑑(𝑝−𝑖−1 ) 𝑌𝑖 − = 𝑞𝑖 𝑌𝑖+1 𝑑𝑥 (2.11) para 1 ≤ 𝑖 ≤ 𝑚. * * * Temos que (𝑝−𝑖−1 ) = 𝑞𝑖 (𝑝−𝑖 ) e mdc((𝑝−𝑖 ) ,𝑌𝑖+1 ) = 1, donde concluímos, por (2.11) que (︃ * )︃ 𝑑(𝑝−𝑖−1 ) −𝑖−1 * = 𝑞𝑖 . (2.12) mdc (𝑝 ) ,𝑌𝑖 − 𝑑𝑥 Esta é a base para o algoritmo de Yun, o qual descrevemos a seguir. Novamente, suponha que 𝑝 é primitivo. Temos que 𝑝− = mdc(𝑝,𝑑𝑝/𝑑𝑥) e, portanto, 𝑑𝑝/𝑑𝑥 * por (2.10). 𝑝−0 = 𝑝* = pp(𝑝)/𝑝− e 𝑌1 = 𝑝− * Indutivamente, se temos 𝑝−𝑘−1 e 𝑌𝑘 , 𝑞𝑘 pode ser calculado através de (2.12), e * 𝑌𝑘+1 e 𝑝−𝑘 são obtidos respectivamente por (2.11) e (2.8). Seguimos até que * 𝑌𝑘 = 𝑑𝑝−𝑘−1 /𝑑𝑥, quando temos que 𝑝−𝑘−1 é livre de quadrados, com 𝑘 = 𝑚 e * 𝑞𝑘 = 𝑝−𝑘−1 = 𝑝−𝑘−1 . Na subseção 5.3.2, fornecemos um pseudocódigo, juntamente com um código para implementação no Maxima do algoritmo de Yun. Observamos uma consequência da Proposição 2.2.1. Se o DFU 𝐷 possui 23 2.2. Fatoração Livre de Quadrados característica 0 e 𝑝 ∈ 𝐷[𝑥] ∖ 𝐷 é primitivo e livre de quadrados então, pelo item 1 da Proposição 2.2.1, mdc(𝑝,𝑑𝑝/𝑑𝑥) = 𝑝− = 1, pois, neste caso, 𝑚 = 1. Reciprocamente, se mdc(𝑝,𝑑𝑝/𝑑𝑥) = 1 então 𝑝 = 𝑝−0 é livre de quadrados. Ou seja, Teorema 2.2.1 ([11], Cap. 8, §2). Sejam 𝐷 um DFU de característica 0 e 𝑝 ∈ 𝐷[𝑥] ∖ 𝐷 um polinômio primitivo. Então, 𝑝 é livre de quadrados se e só se (︃ (︃ 𝑑𝑝 grau mdc 𝑝, 𝑑𝑥 )︃)︃ = 0. Evidentemente, se 𝑝 é um polinômio irredutível então grau(mdc(𝑝,𝑝′ )) = 0, do contrário, 𝑝 possuiria divisor não trivial. Assim, todo polinômio irredutível é livre de quadrados. Capítulo 2. Noções Preliminares 24 Capítulo 3 Integração Indefinida de Funções Racionais Complexas Apresentamos agora algoritmos de integração de funções racionais sobre um subcorpo dos complexos (portanto, de característica 0). O primeiro algoritmo a ser apresentado é o algoritmo de Bernoulli, que é comumente estudado nos cursos de Cálculo, mas não costuma ser o método utilizado pelos CAS da atualidade. Seguimos com o algoritmo de Hermite e suas variantes e o algoritmo de HorowitzOstrogradsky. Ambos são capazes de expressar a integral de uma função racional como sendo a soma entre uma função racional e a integral de uma função racional própria cujo denominador é livre de quadrados. Finalizamos apresentando os algoritmos de Rothstein-Trager e de Lazard-Rioboo-Trager, que efetivamente calculam a integral deixada pelos últimos algoritmos, expressando-a como uma combinação linear de logaritmos com certas propriedades desejáveis, como veremos. 3.1 O Algoritmo de Bernoulli Seja 𝑓 = 𝑝/𝑞 ∈ R(𝑥) uma função racional reduzida com coeficientes reais. A divisão polinomial nos permite expressar 𝑓 = 𝑠 + 𝑟/𝑞, onde 𝑠,𝑟 ∈ R[𝑥], com 𝑟/𝑞 reduzida e própria. Seja 𝑞= 𝑛 ∏︁ (𝑥 − 𝑎𝑖 )𝑒𝑖 𝑖=1 𝑚 ∏︁ (𝑥2 + 𝑏𝑗 𝑥 + 𝑐𝑗 )𝑓𝑗 𝑗=1 Capítulo 3. Integração Indefinida de Funções Racionais Complexas 26 a fatoração em fatores irredutíveis de 𝑞 sobre os reais, com todos 𝑎𝑖 ,𝑏𝑗 ,𝑐𝑗 ∈ R e 𝑒𝑖 ,𝑓𝑗 inteiros positivos. Decompondo 𝑓 em frações parciais completas, temos 𝑒𝑖 𝑛 ∑︁ ∑︁ 𝑓 𝑗 𝑚 ∑︁ ∑︁ 𝐴𝑖𝑘 𝐵𝑗𝑘 𝑥 + 𝐶𝑗𝑘 𝑓 =𝑠+ + 𝑘 2 𝑘 𝑖=1 𝑘=1 (𝑥 − 𝑎𝑖 ) 𝑗=1 𝑘=1 (𝑥 + 𝑏𝑗 𝑥 + 𝑐𝑗 ) (3.1) onde todos 𝐴𝑖𝑘 ,𝐵𝑗𝑘 ,𝐶𝑗𝑘 ∈ R. Portanto, pela linearidade da integração, ∫ 𝑓 é a soma das integrais das parcelas do lado direito da equação (3.1). A integral de 𝑠 ∈ R[𝑥] é fácil de ser calculada, pois 𝑠 é um polinômio. Para as outras parcelas, temos: ⎧ ⎪ ∫︁ ⎨𝐴𝑖𝑘 (𝑥 − 𝑎𝑖 )1−𝑘 /(1 − 𝑘) se 𝑘 > 1 𝐴𝑖𝑘 = (3.2) (𝑥 − 𝑎𝑖 )𝑘 ⎪ ⎩𝐴1𝑘 log(𝑥 − 𝑎𝑖 ) se 𝑘 = 1 e, notando que 𝑏2𝑗 − 4𝑐𝑗 < 0, uma vez que 𝑥2 + 𝑏𝑗 𝑥 + 𝑐𝑗 é irretdutível sobre os reais, ∫︁ 𝐵𝑗1 𝑥 + 𝐶𝑗1 𝐵𝑗1 = log(𝑥2 + 𝑏𝑗 𝑥 + 𝑐𝑗 ) 2 (𝑥 + 𝑏𝑗 𝑥 + 𝑐𝑗 ) 2 2𝐶𝑗1 − 𝑏𝑗 𝐵𝑗1 + √︁ 4𝑐𝑗 − 𝑏2𝑗 ⎛ ⎞ 2𝑥 + 𝑏𝑗 ⎠ arctg ⎝ √︁ 4𝑐𝑗 − 𝑏2𝑗 e para 𝑘 > 1, ∫︁ (2𝐶𝑗𝑘 − 𝑏𝑗 𝐵𝑗𝑘 )𝑥 + 𝑏𝑗 𝐶𝑗𝑘 − 2𝑐𝑗 𝐵𝑗𝑘 𝐵𝑗𝑘 𝑥 + 𝐶𝑗𝑘 = 𝑘 + 𝑏𝑗 𝑥 + 𝑐 𝑗 ) (𝑘 − 1)(4𝑐𝑗 − 𝑏2𝑗 )(𝑥2 + 𝑏𝑗 𝑥 + 𝑐𝑗 )𝑘−1 ∫︁ (2𝑘 − 3)(2𝐶𝑗𝑘 − 𝑏𝑗 𝐵𝑗𝑘 ) + . (𝑘 − 1)(4𝑐𝑗 − 𝑏2𝑗 )(𝑥2 + 𝑏𝑗 𝑥 + 𝑐𝑗 )𝑘−1 (𝑥2 (3.3) A regra explicitada por (3.3) pode ser aplicada recursivamente sobre a integral do lado direito desta equação, até que atinjamos 𝑘 = 1. Assim, completamos o algoritmo de Bernoulli. O método explicitado serve para funções racionais com coeficientes reais. Porém, uma variante pode ser obtida para funções cujos coeficientes estejam num subcorpo K qualquer dos complexos. Mantendo a notação, suponhamos 𝑓 = 𝑝/𝑞 ∈ K(𝑥) e consideremos a fatoração completa em termos lineares de 𝑞, 27 isto é 𝑞 = 3.1. O Algoritmo de Bernoulli 𝑛 ∏︁ (𝑥 − 𝑎𝑖 )𝑒𝑖 , onde os 𝑎𝑖 pertencem ao fecho algébrico de K. Temos a 𝑖=1 seguinte decomposição em frações parciais completas de 𝑓 : 𝑓 =𝑠+ 𝑒𝑖 𝑛 ∑︁ ∑︁ 𝐴𝑖𝑘 . 𝑘 𝑖=1 𝑘=1 (𝑥 − 𝑎𝑖 ) (3.4) Basta, então, aplicar (3.2) para cada termo cada termo próprio do lado direito. Esta abordagem é equivalente a expandir 𝑓 em sua série de Laurent em todos os seus polos finitos, uma vez que, em 𝑥 = 𝑎𝑖 , a série de Laurent é 𝑓= 𝐴𝑖𝑒𝑖 𝐴𝑖2 𝐴𝑖1 + ··· + · · · + + 𝑒 2 (𝑥 − 𝑎𝑖 ) 𝑖 (𝑥 − 𝑎𝑖 ) (𝑥 − 𝑎𝑖 ) onde os 𝐴𝑖𝑗 são os mesmos que em (3.4). Portanto, podemos perceber esta abordagem como a expansão do integrando em série em torno de seus polos (incluíndo ∞), seguida de integração termo a termo da série e interpolação, através da soma de todos os termos polares, obtendo, assim, a integral de (3.4). Dada a natureza desta variante do método de Bernoulli de se basear em expansão de séries, dizemos que sua abordagem é local. Em termos computacionais, a inconveniência deste método reside no fato de sermos levados a computar extensões de números algébricos sobre K que não necessariamente precisam aparecer na integral, a saber, os coeficientes da série de Laurent, além de precisarmos realizar cálculos de frações parciais envolvendo estes números algébricos. No Exemplo 3.1.2 a seguir, realizamos cálculos em Q(𝐼) e obtemos o resultado final a partir deste corpo, mas existe uma integral que pode ser expressa inteiramente sobre Q(𝑥). Por outro lado, certas integrais não são possíveis de serem expressas sem a introdução de novas extensões algébricas constantes, como ∫ 𝑑𝑥/(𝑥2 − 2), a qual √ necessita da extensão 2. Portanto, de maneira geral, é possivel que precisemos introduzir novas extensões algébricas de K em algum momento. Nosso objetivo, portanto, é conseguir um método que nos possibilite efetuar o máximo possível de cálculos permanecendo no corpo K(𝑥) do qual o integrando 𝑓 faz parte e, caso seja necessário realizar extensões sobre o corpo de constantes K, queremos fazer isto o mínimo possível. É exatamente isto que vamos conseguir nas próximas seções. Capítulo 3. Integração Indefinida de Funções Racionais Complexas 28 Na subseção 5.5.1, um código para implementação no Maxima do algoritmo de Bernoulli aplicado a integrandos reduzidos, próprios e com denominadores livres de quadrados. 3.1.1 Exemplos Exemplo 3.1.1 (extraído de [2], Cap 2, §1). Seja 𝑓 = 1/(𝑥2 + 1)2 ∈ Q(𝑥). Observe que o denominador já está fatorado em fatores irredutíveis sobre R, e portanto, 𝑓 já está decomposta em frações parciais. Portanto, nas fórmulas do algoritmo de Bernoulli, com 𝑗 = 1, 𝑘 = 1, 𝑏1 = 𝐵12 = 0 e 𝑐1 = 𝐶12 = 1, temos ∫︁ (𝑥2 1 2𝑑𝑥 𝑥 1 2𝑥 + = + arctg(𝑥). = 2 2 2 2 + 1) 4(𝑥 + 1) 4(𝑥 + 1) 2(𝑥 + 1) 2 Exemplo 3.1.2 (extraído de [2], Cap 2, §1). Seja 𝑓 = 1/(𝑥3 + 𝑥) ∈ Q(𝑥). O denominador se fatora em fatores irredutíveis em R na forma 𝑥3 + 𝑥 = 𝑥(𝑥2 + 1). Portanto, temos a seguinte decomposição em frações parciais de 𝑓 : 𝑥3 1 1 𝑥 = − 2 . +𝑥 𝑥 𝑥 +1 Seguindo as fórmulas do algoritmo de Bernoulli temos ∫︁ 𝑥3 1 1 = log(𝑥) − log(𝑥2 + 1). +𝑥 2 (3.5) Se tivéssemos escolhido fatorar 𝑓 sobre os complexos, a fatoração em fatores irredutíveis do denominador ficaria 𝑥3 + 𝑥 = 𝑥(𝑥 + 𝐼)(𝑥 − 𝐼), e a decomposição em frações parciais seria 𝑥3 1 1 1/2 1/2 = − − . +𝑥 𝑥 𝑥+𝐼 𝑥−𝐼 Portanto, uma representação alternativa para a integral de 𝑓 seria ∫︁ 1 1 1 = log(𝑥) − log(𝑥 + 𝐼) − log(𝑥 − 𝐼). 𝑥3 + 𝑥 2 2 Observamos, portanto, que a última expressão introduz números algébricos des- 29 3.2. O Algoritmo de Hermite necessários na representação da integral de 𝑓 , enquanto que a representação (3.5) evita esta introdução. Isto motivará o algoritmo de Rothstein-Trager, a ser estudado mais adiante. 3.2 O Algoritmo de Hermite Como vimos na seção 3.1, se 𝑓 ∈ K(𝑥), onde K é um subcorpo dos complexos, podemos expressar ∫︁ 𝑚 𝑐 ∑︁ 𝑓= + 𝛾𝑖 log(𝑣𝑖 ) (3.6) 𝑑 𝑖=1 onde 𝑐,𝑑,𝑣1 , . . . ,𝑣𝑚 ∈ K[𝑥] e 𝛾1 , . . . ,𝛾𝑚 ∈ K. No lado direito, a fração 𝑐/𝑑 ∈ K(𝑥) é chamada de parte racional da integral, sendo o restante a parte logarítmica ou transcendental, como já mencionamos no Capítulo 1. O algoritmo de Hermite permite encontrar completamente a parte racional da integral de 𝑓 , enquanto expressa a parte logarítmica implicitamente por ∫ 𝑎/𝑏, onde 𝑎/𝑏 ∈ K(𝑥) é uma fração reduzida, própria e de denominador livre de quadrados. 3.2.1 Versão Original do Algoritmo de Hermite Novamente, seja 𝑓 = 𝑝/𝑞 ∈ K(𝑥) uma fração reduzida. Valendo-nos da divisão euclidiana, escrevamos 𝑓 = 𝑠 + 𝑟/𝑞, onde 𝑠,𝑟 ∈ R[𝑥], com 𝑟/𝑞 própria. Seja 𝑞 = 𝑞11 · · · 𝑞𝑘𝑘 a flq de 𝑞. A decomposição em frações parciais em relação a esta fatoração é 𝑘 ∑︁ 𝑟𝑖 𝑓 =𝑠+ 𝑖 𝑖=1 𝑞𝑖 onde cada 𝑟𝑖 ∈ K[𝑥] e vale 0, ou grau(𝑟𝑖 ) < grau(𝑞𝑖𝑖 ). Como no algoritmo de Bernoulli, reduzimos o nosso problema a integrar cada uma das parcelas próprias por vez no lado direito da equação acima. Observando ainda que, como cada 𝑞𝑖 é livre de quadrados e, portanto, temos que mdc(𝑞𝑖 ,𝑞𝑖′ ) = 1, se 𝑖 > 1 então podemos utilizar o algoritmo de Euclides estendido (vide pseudocódigos e códigos das subseções 5.2.3, 5.2.4, 5.2.5, 5.2.6, 5.2.7, 5.2.8 e 5.2.9 para cálculo de mdc) Capítulo 3. Integração Indefinida de Funções Racionais Complexas 30 para encontrar 𝜎,𝜏 ∈ K[𝑥] tais que 𝑟𝑖 = 𝜎𝑞𝑖′ + 𝜏 𝑞𝑖 1−𝑖 com grau(𝜎) < grau(𝑞𝑖 ). Logo, grau(𝜎𝑞𝑖′ ) < grau(𝑞𝑖2 ) ≤ grau(𝑞𝑖𝑖 ) e, portanto, grau(𝜏 ) < grau(𝑞𝑖𝑖−1 ). Multiplicando ambos os lados por (1 − 𝑖)/𝑞𝑖𝑖 , temos 𝑟𝑖 (𝑖 − 1)𝜎𝑞𝑖′ (1 − 𝑖)𝜏 = − + . 𝑞𝑖𝑖 𝑞𝑖𝑖 𝑞𝑖𝑖−1 Adicionando e subtraindo 𝜎 ′ /𝑞𝑖𝑖−1 no lado direito, temos 𝑟𝑖 = 𝑞𝑖𝑖 (︃ 𝜎′ (𝑖 − 1)𝜎𝑞𝑖′ − 𝑞𝑖𝑖 𝑞𝑖𝑖−1 )︃ + (1 − 𝑖)𝜏 − 𝜎 ′ . 𝑞𝑖𝑖−1 Finalmente, integrando ambos os lados, ∫︁ ∫︁ 𝜎 (1 − 𝑖)𝜏 − 𝜎 ′ 𝑟𝑖 = + . 𝑞𝑖𝑖 𝑞𝑖𝑖−1 𝑞𝑖𝑖−1 (3.7) Uma vez que grau((1 − 𝑖)𝜏 − 𝜎 ′ ) < grau(𝑞𝑖𝑖−1 ), o integrando à direita em (3.7) é semelhante ao da esquerda, porém com a potência do denominador reduzida em uma unidade. De maneira semelhante ao algoritmo de Bernoulli, podemos repetir esta fórmula recursivamente à direita, até que a potência do denominador seja 1. Quando atingimos esta condição, obtemos 𝑐𝑖 ,𝑑𝑖 ,𝑎𝑖 ∈ K[𝑥] tais que grau(𝑎𝑖 ) < grau(𝑞𝑖 ) e 𝑟𝑖 /𝑞𝑖𝑖 = (𝑐𝑖 /𝑑𝑖 )′ + 𝑎𝑖 /𝑞𝑖 , para cada 𝑖. Portanto, obtemos 𝑔,ℎ ∈ K(𝑥) tais que 𝑓 = 𝑔 ′ + 𝑠 + ℎ, onde ℎ é uma fração própria cujo denominador é livre de quadrados (é o produto dos 𝑞𝑖 ) e, ∫ ℎ é a parte logarítmica da integral de 𝑓 . A parte racional, portanto, é 𝑔 + ∫ 𝑠. 3.2.2 Versão Quadrática do Algoritmo de Hermite Uma variante do algoritmo de Hermite nos permite chegar ao mesmo resultado sem a necessidade de se computar a decomposição em frações parciais de 𝑓 . Descrevemos esta variante a seguir. Mantendo a notação, supondo que na flq de 𝑞 tenhamos 𝑘 ≥ 2 (caso contrário 𝑞 31 3.2. O Algoritmo de Hermite já seria livre de quadrados), definamos 𝑞 = 𝑞/𝑞𝑘𝑘 . Como mdc(𝑞𝑞𝑘′ ,𝑞𝑘 ) = 1, podemos utilizar o algoritmo de Euclides estendido para calcular 𝜎,𝜏 ∈ K[𝑥] tais que 𝑝 = 𝜎𝑞𝑞𝑘′ + 𝜏 𝑞𝑘 1−𝑘 e grau(𝜎) < grau(𝑞𝑘 ). Multiplicando ambos os lados por (1 − 𝑘)/(𝑞𝑞𝑘𝑘 ), temos 𝑝 (1 − 𝑘)𝜎𝑞𝑘′ (1 − 𝑘)𝜏 = + . 𝑘 𝑘 𝑞𝑞𝑘 𝑞𝑘 𝑞𝑞𝑘𝑘−1 Logo, adicionando e subtraindo 𝜎 ′ /𝑞𝑘𝑘−1 do lado direito, temos 𝑝 = 𝑞𝑞𝑘𝑘 (︃ 𝜎′ 𝑞𝑘𝑘−1 (𝑘 − 1)𝜎𝑞𝑘′ − 𝑞𝑘𝑘 )︃ + (1 − 𝑘)𝜏 − 𝑞𝜎 ′ . 𝑞𝑞𝑘𝑘−1 Finalmente, integrando dos dois lados: ∫︁ ∫︁ 𝜎 𝑝 (1 − 𝑘)𝜏 − 𝑞𝜎 ′ = + . 𝑞𝑞𝑘𝑘 𝑞𝑘𝑘−1 𝑞𝑞𝑘𝑘−1 Novamente, a integral à direita é similar à integral à esquerda, com a redução de potência em uma unidade no denominador. O processo segue recursivamente até que se obtenha um denominador livre de quadrados. Como o expoente dos fatores livres de quadrados é reduzido em uma unidade em cada passo, no pior dos casos, o número de passos de redução e 1+2+· · ·+(𝑘−1), o que tem complexidade 𝑂(𝑘 2 ) e, portanto, chamamos esta variante de versão quadrática do método de Hermite. 3.2.3 Versão Linear do Algoritmo de Hermite Uma última variante do algoritmo de Hermite é fornecida a seguir e é devida a D. Mack [22]. Nela, não precisamos calcular nem a decomposição em frações parciais do integrando, nem, a priori a fatoração livre de quadrados de seu denominador (esta última sendo computada ao longo do processo). Como estamos trabalhando sobre um corpo K, podemos supor que o denominador 𝑞 da função 𝑓 é um polinômio primitivo. Como nos algoritmos de fatoração Capítulo 3. Integração Indefinida de Funções Racionais Complexas 32 livre de quadrados, calculamos 𝑞 − = mdc(𝑞,𝑞 ′ ) e 𝑞 * = 𝑞/𝑞 − . Se grau(𝑞 − ) = 0, * ′ então 𝑞 é livre de quadrados, senão, como 𝑞 − = 𝑞 − 𝑞 −2 por 2.5, 𝑞 − = 𝑞 −2 𝑌2 pela * Proposição 2.2.2, onde 𝑌2 é dado por (2.9) e 𝑞1 = 𝑞 * /𝑞 − pela Proposição 2.2.1, temos ′ 𝑞*𝑞− 𝑞 * 𝑞 − 2 𝑌2 𝑞 * 𝑞 −2 𝑌2 𝑞* = = = 𝑌2 = 𝑞1 𝑌2 ∈ K[𝑥]. (3.8) * 𝑞− 𝑞− 𝑞 − 𝑞 −2 𝑞−* * Além disso, como consequência da Proposição 2.2.1, mdc(𝑞1 ,𝑞 − ) = 1, e mdc(𝑌2 ,𝑞 − ) = 1 pela Proposição 2.2.2, o que implica que ′ 𝑞*𝑞− −* * mdc ,𝑞 = mdc(𝑞1 𝑌2 ,𝑞 − ) = 1. − 𝑞 (︃ )︃ Portanto, podemos utilizar o algoritmo de Euclides estendido para encontrar 𝜎,𝜏 ∈ K[𝑥] tais que (︃ ′ )︃ 𝑞*𝑞− * 𝑝=𝜎 − − + 𝜏 𝑞− . 𝑞 * Dividindo-se ambos os lados por 𝑞 = 𝑞 * 𝑞 − = 𝑞1 𝑞 − 𝑞 − , temos ′ 𝜎𝑞 − 𝑝 𝜏 = − −2 + . 𝑞 𝑞1 𝑞 − 𝑞 Adicionando e subtraindo 𝜎 ′ /𝑞 − do lado direito, temos 𝑝 = 𝑞 (︃ 𝜎𝑞 − 𝜎′ − 𝑞− 𝑞−2 ′ )︃ + 𝜏 − 𝑞1 𝜎 ′ . 𝑞1 𝑞 − Finalmente, integrando ambos os lados, temos ∫︁ ∫︁ 𝑝 𝜎 𝜏 − 𝑞1 𝜎 ′ = −+ . 𝑞 𝑞 𝑞1 𝑞 − (3.9) 𝑚−1 Como 𝑞1 𝑞 − = (𝑞1 𝑞2 )𝑞32 · · · 𝑞𝑚 , o integrando foi reduzido a um cujo denominador possui fatoração livre de quadrados com no máximo 𝑚−1 expoentes diferentes, ao invés de 𝑚 como no início do processo. Aplicando recursivamente o método para integral do lado direito da fórmula (3.9), terminamos o processo em no máximo 𝑚 − 1 passos, quando teremos um denominador livre de quadrados. Por causa desta complexidade linear, este método costuma ser chamado de versão linear 33 3.2. O Algoritmo de Hermite do algoritmo de Hermite. Notamos que uma melhoria pode ser feita à versão linear do método de Hermite. Podemos calcular os parâmetros do próximo passo a partir dos atuais. Seja 𝑝/𝑞 o integrando atual, com 𝑞* 𝑝 = 𝜏 − 𝑞1 𝜎 ′ = 𝜏 − − * 𝜎 ′ 𝑞 e 𝑚−1 . 𝑞 = 𝑞1 𝑞 − = 𝑞1 𝑞2 𝑞32 · · · 𝑞𝑚 Temos que 𝑞 * = 𝑞1 𝑞 − = 𝑞1 𝑞2 𝑞3 · · · 𝑞𝑚 = 𝑞 * , ou seja 𝑞 * permanece o mesmo ao longo da redução. Por outro lado, 𝑚−2 𝑞 − = 𝑞3 𝑞42 · · · 𝑞𝑚 = 𝑞 −2 , o que, de maneira geral, significa que, no 𝑖-ésimo (caso todos os expoentes sejam positivos) 𝑞 − é substituído por sua 𝑖-ésima deflação. Finalmente, observamos que todas as variantes do algoritmo de Hermite podem ser realizadas sobre um DFU, ao invés de um corpo, sendo o resultado expresso em seu corpo quociente. Neste caso, na variante linear, o denominador do integrando obrigatoriamente deve ser primitivo, ao contrário das demais variantes. Nas subseções 5.4.1, 5.4.2 e 5.4.3, fornecemos pseudocódigos, juntamente com códigos para implementação no Maxima, respectivamente, das versões original, quadrática e linear do método de Hermite. 3.2.4 Exemplos Aplicaremos as três versões do algoritmo de Hermite a uma mesma função. Exemplo 3.2.1 (gerado com dados obtidos pelo código 5.4.1, versão original da redução de Hermite). Sejam 𝐴 = 3𝑥6 −𝑥4 −6 ∈ Q[𝑥], 𝐷 = 𝑥8 −12𝑥6 +48𝑥4 −64𝑥2 ∈ Q[𝑥] e 𝑓 = 𝐴/𝐷 ∈ Q(𝑥), isto é, 3𝑥6 − 𝑥4 − 6 ∈ Q(𝑥). 𝑓= 8 𝑥 − 12𝑥6 + 48𝑥4 − 64𝑥2 Capítulo 3. Integração Indefinida de Funções Racionais Complexas 34 Temos que a fatoração em fatores irredutíveis do denominador é 𝐷 = 𝑥2 (𝑥 − 2)3 (𝑥 + 2)3 , enquanto que sua flq é 𝐷 = 𝑥2 (𝑥2 − 4)3 = 𝐷22 𝐷33 . A decomposição em frações parciais de 𝑓 sobre esta fatoração é 𝑓= 3 93𝑥4 + 4𝑥2 − 144 + . 32𝑥2 32(𝑥2 − 4)3 Aplicando a versão original do algoritmo de Hermite sobre 𝑓 , temos, nos termos da fórmula de recursão: 𝑖 𝑉 𝑗 𝐴𝑖 𝐵 𝐶 2 3 3 𝑥 𝑥 −4 𝑥2 − 4 1 2 1 3/32 (93𝑥 + 4𝑥2 − 144)/32 (93𝑥2 + 121)/32 −3/32 −85𝑥/82 −493𝑥/256 0 −(93𝑥 + 36)/64 121/128 2 4 2 Portanto, 493𝑥 85𝑥 3 ∫︁ 3𝑥6 − 𝑥4 − 6 251 =− − − + . 8 6 4 2 2 2 2 𝑥 − 12𝑥 + 48𝑥 − 64𝑥 256(𝑥 − 4) 32(𝑥 − 4) 32𝑥 256(𝑥2 − 4) ∫︁ Exemplo 3.2.2 (gerado com dados obtidos pelo código 5.4.2, versão quadrática da redução de Hermite). Com a versão quadrática, temos a seguinte tabela para 𝑓 : 𝑖 2 𝑉 𝑈 𝑥 𝐷33 𝑗 1 𝐵 −3/32 𝐶 5 𝐴 3 (93𝑥 + 4𝑥 − 144𝑥)/32 −(93𝑥 + 4𝑥 − 144𝑥)/32 3 5 3 3 𝐷3 𝑥 2 −85𝑥/32 −(93𝑥 + 36𝑥)/64 (93𝑥3 + 121𝑥)/32 3 𝐷3 𝑥 1 −493𝑥/256 121𝑥/128 251𝑥/256 Portanto, ∫︁ 3𝑥6 − 𝑥4 − 6 493𝑥 3 ∫︁ 85𝑥 251 =− − − . + 8 6 4 2 2 2 2 𝑥 − 12𝑥 + 48𝑥 − 64𝑥 256(𝑥 − 4) 32(𝑥 − 4) 32𝑥 256(𝑥2 − 4) da mesma maneira que na versão linear, porém não necessitamos da decomposição em frações parciais. 35 3.2. O Algoritmo de Hermite Exemplo 3.2.3 (gerado com dados obtidos pelo código 5.4.3, versão linear de Mack da redução de Hermite). Mantendo a função 𝑓 , temos: 1. 𝑔 ← 0; 2. 𝐷− ← mdc(𝐷,𝑑𝐷/𝑑𝑥) = 𝑥5 − 8𝑥3 + 16𝑥; 3. 𝐷* ← 𝐷/𝐷− = 𝑥3 − 4𝑥; 4. Entramos no primeiro passo da redução: 𝐷−2 ← mdc(𝑥5 − 8𝑥3 + 16𝑥,5𝑥4 − 24𝑥2 + 16) = 𝑥2 − 4; * 5. 𝐷− ← 𝐷− /𝐷−2 = 𝑥3 − 4𝑥; 6. (𝐵,𝐶) ← ExtendedEuclidean(−5𝑥2 + 4,𝑥3 − 4𝑥,𝐴) (︃ )︃ 73𝑥2 + 48 96𝑥3 − 13𝑥 = − , ; 32 32 7. 𝐴 ← (96𝑥3 − 13𝑥)/32 + 146𝑥/32 = (96𝑥3 + 133𝑥)/32; 8. 𝑔←𝑔+ 73𝑥2 + 48 𝐵 = − 𝐷− 32(𝑥5 − 8𝑥3 + 16𝑥) 9. 𝐷− ← 𝐷−2 = 𝑥2 − 4 10. Entramos no segundo passo da redução: 𝐷−2 ← mdc(𝑥2 + 2,2𝑥) = 1; * 11. 𝐷− ← 𝐷− /𝐷−2 = 𝑥2 − 4; 12. (𝐵,𝐶) ← ExtendedEuclidean(−2𝑥2 ,𝑥2 − 4,(96𝑥3 + 133𝑥)/32) = (−517𝑥/256, −133𝑥/128) 13. 𝑔←𝑔+ 14. 𝐷− ← 𝐷−2 = 1. 𝐵 73𝑥2 + 48 −517𝑥 = − − 𝐷− 32(𝑥5 − 8𝑥3 + 16𝑥) 256(𝑥2 − 4) Capítulo 3. Integração Indefinida de Funções Racionais Complexas 36 Portanto, ∫︁ 73𝑥2 + 48 3𝑥6 − 𝑥4 − 6 −517𝑥 = − − + 8 6 4 2 5 3 𝑥 − 12𝑥 + 48𝑥 − 64𝑥 32(𝑥 − 8𝑥 + 16𝑥) 256(𝑥2 − 4) ∫︁ 251𝑥 256(𝑥3 − 4𝑥) o que equivale ao que obtivemos nas duas outras versões do algoritmo de Hermite, mas precisamos de apenas dois passos de redução, ao invés de três. 3.3 O Algoritmo de Horowitz-Ostrogradsky O algoritmo de Hermite nos permite obter ∫︁ 𝑐 ∫︁ 𝑎 𝑝 = + , 𝑞 𝑑 𝑏 (3.10) com 𝑎,𝑏,𝑐,𝑑 ∈ K[𝑥], mdc(𝑐,𝑑) = mdc(𝑎,𝑏) = 1, 𝑎/𝑏 própria e 𝑏 livre de quadrados. O algoritmo de Horowitz-Ostrogradsky é uma alternativa ao método de Hermite. Ao invés de uma redução, calcula diretamente os polinômios 𝑑 e 𝑏 na equação (3.10), e, a partir disso, obtém os polinômios 𝑎 e 𝑐 através da resolução de um sistema linear cujas incógnitas são os coeficientes destes dois últimos polinômios. Dispensa completamente os cálculos de frações parciais e fatoração livre de quadrados. Teorema 3.3.1 ([11], Cap. 11, §4). Seja 𝑓 = 𝑝/𝑞 ∈ K(𝑥) uma função racional reduzida e própria. Sejam 𝑔 = 𝑐/𝑑 a parte racional de sua integral e ℎ = 𝑎/𝑏 o integrando aparecendo na parte transcendental, como encontramos pelo algoritmo de Hermite (note que 𝑠 = 0). Então 𝑑 = 𝑞− e 𝑏 = 𝑞*. Além disso, grau(𝑎) < grau(𝑏) e grau(𝑐) < grau(𝑑). Demonstração. Seja 𝑞= 𝑘 ∏︁ 𝑞𝑖𝑖 𝑖=1 a fatoração livre de quadrados de 𝑞. A demonstração é bastante direta e consiste, basicamente, de observar a contribuição da integral de cada fração parcial do 37 3.3. O Algoritmo de Horowitz-Ostrogradsky integrando original para os denominadores da parte racional e do integrando da parte transcendental no algoritmo de Hermite. Em suma, na equação (3.10), encontramos que 𝑏= 𝑘 ∏︁ 𝑞𝑖 , 𝑑 = 𝑖=1 𝑘 ∏︁ 𝑞𝑖𝑖−1 , 𝑖=2 com grau(𝑎) < grau(𝑏) e grau(𝑐) < grau(𝑑). Ou seja, 𝑑 = 𝑞− e 𝑏 = 𝑞*. O resultado acima é a base para o algoritmo de Horowitz-Ostrogradsky. Diferenciando a equação (3.10) aplicada à fração reduzida e própria 𝑝/𝑞, temos 𝑝 𝑑𝑐′ − 𝑐𝑑′ 𝑎 = + . 𝑞 𝑑2 𝑏 Multiplicando a equação acima por 𝑞 = 𝑏𝑑, temos 𝑝 = 𝑏𝑐′ − 𝑐 Seja 𝑞 = 𝑘 ∏︁ 𝑏𝑑′ + 𝑑𝑎. 𝑑 (3.11) 𝑞𝑖𝑖 a flq de 𝑞. Observe que 𝑖=1 𝑏𝑑′ = (︃ 𝑘 ∏︁ )︃ ⎛ 𝑘 𝑘 ∑︁ ∏︁ 𝑞𝑖 ⎝ (𝑖 − 1)𝑞 𝑖−2 𝑖 𝑖=1 𝑖=2 𝑖̸=𝑗≥2 ⎞ 𝑞𝑗𝑗−1 ⎠ = 𝑞1 𝑘 ∑︁ 𝑘 ∏︁ 𝑖=2 𝑖̸=𝑗≥2 (𝑖 − 1)𝑞𝑖𝑖−1 𝑞𝑗𝑗 . Portanto, 𝑏𝑑′ é divisível por 𝑑, donde a equação (3.11) constitui uma identidade polinomial. Definamos 𝑚 = grau(𝑏) e 𝑛 = grau(𝑑). Como os únicos polinômios que não conhecemos nesta identidade são 𝑎 e 𝑐, e como os limites superiores de seus graus são, respectivamente, 𝑚 − 1 = grau(𝑏) − 1 e 𝑛 − 1 = grau(𝑑) − 1, esta identidade polinomial origina um sistema linear cujas variáveis são os coeficientes destes polinômios, os quais se escrevem, para efeitos de resolução deste sistema, 𝑎 = 𝑎𝑚−1 𝑥𝑚−1 + ... + 𝑎1 𝑥 + 𝑎0 Capítulo 3. Integração Indefinida de Funções Racionais Complexas 38 e 𝑐 = 𝑐𝑛−1 𝑥𝑛−1 + ... + 𝑐1 𝑥 + 𝑐0 . O grau do polinômio do lado esquerdo da equação (3.11) é grau(𝑝) ≤ grau(𝑞) − 1 = grau(𝑏) + grau(𝑑) − 1 = 𝑚 + 𝑛 − 1 enquanto no lado direito, o limitante para o grau é max(𝑚 + 𝑛 − 2,𝑚 + 𝑛 − 2,𝑚 + 𝑛 − 1) = 𝑚 + 𝑛 − 1. Portanto, igualando os coeficientes dos dois lados da equação (3.11), obtemos um sistema linear determinado de 𝑚 + 𝑛 linhas e 𝑚 + 𝑛 incógnitas sobre K. Observe que este método é uma alternativa ao algoritmo de Hermite e não requer o cálculo da fatoração livre de quadrados de 𝑞 em momento algum. Enquanto a complexidade deste método é muito boa para funções racionais, sua generalização não é tão simples quanto o método de Hermite para classes maiores de funções, de modo que o algoritmo para funções elementares acaba por utilizar a versão linear do algoritmo de Hermite [2, p. 46]. Na subseção 5.4.4, fornecemos um pseudocódigo, juntamente com código para implementação no Maxima do algoritmo de Horowitz-Ostrogradsky. 3.3.1 Exemplos Continuamos utilizando a função 𝑓 dos exemplos da seção anterior. Exemplo 3.3.1 (gerado com dados obtidos pelo código 5.4.4, algoritmo de Horowitz-Ostrogradsky). Seguindo os passos do algoritmo de Horowitz-Ostrogradsky, temos: 𝐷− = 𝑥5 − 8𝑥3 + 16𝑥; 𝐷* = 𝐷/𝐷− = 𝑥3 − 4𝑥; 𝑚 = grau(𝐷* ) − 1 = 2, 𝑛 = grau(𝐷− ) − 1 = 4. Temos a identidade polinomial 39 3.4. O Algoritmo de Rothstein-Trager 𝐻 ← 𝐴 − 𝐷* (︃ 𝑛 ∑︁ )︃′ 𝑏𝑖 𝑥 𝑖 + (︃ 𝑛 ∑︁ 𝑖=0 )︃ 𝑏𝑖 𝑥 𝑖 𝑖=0 * ⎛ −′ ⎞ 𝑚 ∑︁ 𝑑𝐷 − 𝐷 − ⎝ 𝑐𝑗 𝑥 𝑗 ⎠ − 𝐷 𝑗=0 7 = (−𝑐2 )𝑥 + (𝑏4 − 𝑐1 + 3)𝑥6 + (2𝑏3 − 𝑐0 + 8𝑐2 )𝑥5 + (3𝑏2 + 12𝑏4 + 8𝑐1 − 1)𝑥4 + 4(𝑏1 + 2𝑏3 + 2𝑐0 − 4𝑐2 )𝑥3 + (5𝑏0 + 4𝑏2 − 16𝑐1 )𝑥2 + (−16𝑐0 )𝑥 + (−4𝑏0 − 6) Formamos o sistema onde cada coeficiente de 𝐻 equivale a 0. A solução é 517 251 3 371 ,0, − ,0, − ,0 . (𝑏0 ,𝑏1 ,𝑏2 ,𝑏3 ,𝑏4 ,𝑐0 ,𝑐1 ,𝑐2 ) = − ,0, 2 64 256 256 )︂ (︂ Portanto, ∫︁ 3𝑥6 − 𝑥4 − 6 73𝑥2 + 48 −517𝑥 = − − + 8 6 4 2 5 3 𝑥 − 12𝑥 + 48𝑥 − 64𝑥 32(𝑥 − 8𝑥 + 16𝑥) 256(𝑥2 − 4) ∫︁ 251𝑥 256(𝑥3 − 4𝑥) o que é coerente com a resposta dada pelo algoritmo de Hermite. 3.4 O Algoritmo de Rothstein-Trager Terminado o algoritmo de Hermite (ou Horowitz-Ostrogradsky), resta-nos calcular a parte logarítmica da integral de 𝑓 = 𝑝/𝑞, a saber, ∫ ℎ = ∫ 𝑎/𝑏, onde, como vimos, 𝑎/𝑏 é uma fração reduzida e própria, cujo denominador é livre de quadrados. Se considerarmos K o fecho algébrico de K, e se 𝑏 = 𝑛 ∏︁ (𝑥 − 𝛼𝑖 ), temos que ℎ deve 𝑖=1 ter a forma ℎ= 𝑛 ∑︁ 𝛾𝑖 𝑖=1 𝑥 − 𝛼𝑖 (3.12) onde 𝛾1 , . . . ,𝛾𝑛 ∈ K. Dessa forma, ∫︁ ℎ= 𝑛 ∑︁ 𝛾𝑖 log(𝑥 − 𝛼𝑖 ). (3.13) 𝑖=1 Uma vez que a soma de logaritmos é o logaritmo do produto de seus argumentos, quaisquer logaritmos sob um mesmo 𝛾𝑖 na expressão acima podem ser unificados Capítulo 3. Integração Indefinida de Funções Racionais Complexas 40 num único logaritmo. Em outras palavras, queremos encontrar um método de ∫︁ encontrar os resíduos distintos entre os 𝛾𝑖 necessários para expressar ℎ sem fatorar 𝑏 completamente. Os 𝛾𝑖 são os resíduos de ℎ que aparecem na expansão de Laurent de desta função em torno de cada ponto 𝑥 = 𝛼𝑖 , i.e. ℎ= 𝛾𝑖 + 𝑐0 + 𝑐1 (𝑥 − 𝛼𝑖 ) + 𝑐2 (𝑥 − 𝛼𝑖 )2 + · · · . 𝑥 − 𝛼𝑖 (3.14) Utilizando a equação (3.12), temos que 𝑎= 𝑛 ∑︁ 𝑖=1 𝛾𝑖 𝑛 𝑛 ∑︁ ∏︁ 𝑏 = 𝛾𝑖 (𝑥 − 𝛼𝑗 ). 𝑥 − 𝛼𝑖 𝑖=1 𝑗̸=𝑖 Portanto, para cada polo 𝛼𝑖 𝑎(𝛼𝑖 ) = 𝛾𝑖 𝑛 ∏︁ (𝛼𝑖 − 𝛼𝑗 ) = 𝛾𝑖 𝑏′ (𝛼𝑖 ) 𝑗̸=𝑖 Assim, se 𝛼 é um polo de ℎ para calcularmos o resíduo 𝛾 deste polo, podemos usar a fórmula 𝑎(𝛼) . (3.15) 𝛾= ′ 𝑏 (𝛼) Logo, encontrar todos os resíduos distintos equivale a resolver em 𝛾 a equação (3.15) para cada polo 𝛼. Ou seja, equivale a resolver 𝑎(𝛼) − 𝛾𝑏′ (𝛼) = 0 para todo 𝛼 | 𝑏(𝛼) = 0. Isto é o mesmo que encontrar todas as raízes distintas do polinômio ∏︁ 𝑅(𝑧) = (𝑎(𝛼) − 𝑧𝑏′ (𝛼)) 𝛼|𝑏(𝛼)=0 o que, pelo Lema 2.1.2 equivale a 𝑅(𝑧) = res𝑥 (𝑎(𝑥) − 𝑧𝑏′ (𝑥),𝑏(𝑥)). (3.16) 41 3.4. O Algoritmo de Rothstein-Trager Qualquer raiz repetida em (3.16) implicará em redução no número de logaritmos aparecendo em (3.13). Portanto, podemos escrever ∫︁ ℎ= 𝑘 ∑︁ 𝑐𝑖 log(𝑣𝑖 ) (3.17) 𝑖=1 onde os 𝑐𝑖 são as raízes distintas de (3.16) e os 𝑣𝑖 são mônicos, livres de quadrados e dois a dois coprimos. O seguinte resultado mostra que as raízes 𝑐𝑖 são todas necessárias e provê um mecanismo simples para calcular os 𝑣𝑖 . Teorema 3.4.1 (Algoritmo de Rothstein-Trager, [11], Cap. 11, §5, [31, 34]). Sejam 𝑎,𝑏 ∈ K* [𝑥] tais que mdc(𝑎,𝑏) = 1, com 𝑏 livre de quadrados e 𝑎/𝑏 reduzida e própria. Suponha que, para K* , seja possível escrever ∫︁ 𝑛 𝑎 ∑︁ 𝑐𝑖 log(𝑣𝑖 ) = 𝑏 𝑖=1 (3.18) onde os 𝑐𝑖 ∈ K* são constantes não nulas distintas e os 𝑣𝑖 ∈ K* [𝑥] são livres de quadrados e dois a dois coprimos de grau positivo. Então os 𝑐𝑖 são todas as raízes distintas do polinômio 𝑅(𝑧) = res𝑥 (𝑎 − 𝑧𝑏′ ,𝑏) ∈ K* [𝑧] e os 𝑣𝑖 são os polinômios 𝑣𝑖 = mdc(𝑎 − 𝑐𝑖 𝑏′ ,𝑏) ∈ K* [𝑥]. Demonstração. Diferenciando a equação (3.18), temos 𝑛 𝑣′ 𝑎 ∑︁ 𝑐𝑖 𝑖 . = 𝑏 𝑖=1 𝑣𝑖 Seja 𝑢𝑖 = 𝑛 ∏︁ 𝑗̸=𝑖 𝑣𝑗 , 1 ≤ 𝑖 ≤ 𝑛. (3.19) Capítulo 3. Integração Indefinida de Funções Racionais Complexas Multiplicando ambos os lados de (3.19) por 𝑏 𝑛 ∏︁ 42 𝑣𝑗 , temos 𝑗=1 𝑎 𝑛 ∏︁ 𝑛 ∑︁ 𝑣𝑗 = 𝑏 𝑗=1 𝑐𝑖 𝑣𝑖′ 𝑢𝑖 . (3.20) 𝑖=1 Mostraremos que, a menos de uma constante multiplicativa, 𝑏= 𝑛 ∏︁ (3.21) 𝑣𝑗 . 𝑗=1 Observe que mdc(𝑎,𝑏) = 1, donde (3.20) 𝑏 | 𝑛 ∏︁ 𝑣𝑗 . Por outro lado, para cada 𝑗, 𝑗=1 temos de (3.20) que 𝑣𝑗 | 𝑏 𝑛 ∑︁ 𝑐𝑖 𝑣𝑖′ 𝑢𝑖 . 𝑖=1 Por definição, cada 𝑣𝑗 divide 𝑢𝑖 para 𝑗 ̸= 𝑖. Isto quer dizer que 𝑣𝑗 | 𝑏𝑣𝑗′ 𝑢𝑖 . Como os 𝑣𝑖 são supostos livres de quadrados, temos que mdc(𝑣𝑗 ,𝑣𝑗′ ) = 1. Além disso, mdc(𝑣𝑗 ,𝑢𝑗 ) = 1, pela definição de 𝑢𝑗 e pelo fato de que os 𝑣𝑖 são dois a dois primos entre si. Resta, portanto, que 𝑣𝑗 | 𝑏 para 1 ≤ 𝑗 ≤ 𝑛. Portanto, 𝑛 ∏︁ 𝑣𝑗 | 𝑏, 𝑗=1 donde verificamos (3.21). As equações (3.20) e (3.21) combinadas implicam 𝑎= 𝑛 ∑︁ 𝑐𝑖 𝑣𝑖′ 𝑢𝑖 . 𝑖=1 A seguir, mostraremos que, para cada 𝑗, 𝑣𝑗 | (𝑎 − 𝑐𝑗 𝑏′ ). (3.22) 43 3.4. O Algoritmo de Rothstein-Trager Observe que, de (3.21), temos 𝑏′ = 𝑛 ∑︁ 𝑣𝑖′ 𝑢𝑖 . 𝑖=1 Portanto, 𝑎 − 𝑐 𝑗 𝑏′ = 𝑛 ∑︁ 𝑐𝑖 𝑣𝑖′ 𝑢𝑖 − 𝑐𝑗 𝑖=1 𝑛 ∑︁ 𝑣𝑖′ 𝑢𝑖 = 𝑖=1 𝑛 ∑︁ (𝑐𝑖 − 𝑐𝑗 )𝑣𝑖′ 𝑢𝑖 . (3.23) 𝑖=1 No último somatório, para cada termo com 𝑖 ̸= 𝑗, temos que 𝑣𝑗 | 𝑢𝑖 , enquanto que quando 𝑖 = 𝑗, o termo desaparece. Portanto, verificamos (3.22). De (3.21) e (3.22) temos que 𝑣𝑗 é um divisor comum de 𝑎 − 𝑐𝑗 𝑏′ e 𝑏 para cada 𝑗. Mostraremos que se trata de um mdc. É suficiente mostrar que para 𝑘 ̸= 𝑗, mdc(𝑎 − 𝑐𝑗 𝑏′ ,𝑣𝑘 ) = 1. Para isto, utilizando (3.23), temos que ′ mdc(𝑎 − 𝑐𝑗 𝑏 ,𝑣𝑘 ) = mdc (︃ 𝑛 ∑︁ )︃ (𝑐𝑖 − 𝑐𝑗 )𝑣𝑖′ 𝑢𝑖 ,𝑣𝑘 𝑖=1 = mdc((𝑐𝑘 − 𝑐𝑗 )𝑣𝑘′ 𝑢𝑘 ,𝑣𝑘 ). (3.24) A última igualdade acima se verifica porque 𝑣𝑘 é um fator de cada 𝑢𝑖 , para 𝑖 ̸= 𝑘. Porém, para 𝑘 = ̸ 𝑗, o mdc acima é 1, pois 𝑐𝑘 ̸= 𝑐𝑗 , mdc(𝑣𝑘 ,𝑣𝑘′ ) = 1 e mdc(𝑣𝑘 ,𝑢𝑘 ) = 1. Portanto, mostramos que 𝑣𝑗 = mdc(𝑎 − 𝑐𝑗 𝑏′ ,𝑏), 1 ≤ 𝑗 ≤ 𝑛. Logo, temos que res𝑥 (𝑎 − 𝑐𝑗 𝑏′ ,𝑏) = 0, uma vez que 𝑣𝑗 é um fator comum não trivial de 𝑎 − 𝑐𝑗 𝑏′ e 𝑏. Portanto, 𝑐𝑗 é uma raiz do polinômio 𝑅(𝑧). Reciprocamente, se 𝑐 é uma raiz qualquer de 𝑅(𝑧), com 𝑐 ∈ K*𝑅 (K*𝑅 é o corpo onde 𝑅 se fatora completamente), então res𝑥 (𝑎 − 𝑐𝑏′ ,𝑏) = 0. Portanto, mdc(𝑎 − 𝑐𝑏′ ,𝑏) = 𝐺 para algum 𝐺 com grau(𝐺) > 0. Seja 𝑔 um fator irredutível de 𝐺. Então, como 𝑔|𝑏= 𝑛 ∏︁ 𝑣𝑗 , existe apenas um 𝑣𝑗 para o qual 𝑔 | 𝑣𝑗 . Agora, temos que 𝑗=1 𝑔 | (𝑎 − 𝑐𝑏′ ) Capítulo 3. Integração Indefinida de Funções Racionais Complexas 44 implica, utilizando (3.23) que 𝑔| 𝑛 ∑︁ (𝑐𝑖 − 𝑐𝑗 )𝑣𝑖′ 𝑢𝑖 . 𝑖=1 Porém, 𝑔 | 𝑢𝑖 para cada 𝑖 ̸= 𝑗, uma vez que 𝑔 | 𝑣𝑗 . Portanto, 𝑔 | (𝑐𝑗 − 𝑐)𝑣𝑗′ 𝑢𝑗 . o que é verdade apenas se 𝑐𝑗 −𝑐 = 0. Portanto, 𝑐 é uma das constantes aparecendo em 3.18. Mostramos, desta forma, que o polinômio 𝑅(𝑧) ∈ K* [𝑧] se fatora completamente sobre K* , isto é, K*𝑅 = K* , sendo os 𝑐𝑗 todas as suas raízes distintas. Completando o resultado anterior, o seguinte nos diz que os 𝑐𝑖 e os 𝑣𝑖 que aparecem em (3.18) e que foram obtidos pelo método que encontramos pertencem à extensão de K(𝑥) que possui o menor corpo de constantes possível. Teorema 3.4.2 ([11], Cap. 11, §5, [31, 34]). Sejam 𝑎,𝑏 ∈ K[𝑥] tais que 𝑏 é livre de quadrados, e 𝑎/𝑏 é reduzida e própria. Seja K* a menor extensão algébrica de K tal que podemos escrever ∫︁ 𝑁 𝑎 ∑︁ 𝑐˜𝑖 log(˜ 𝑣𝑖 ) = 𝑏 𝑖=1 (3.25) onde 𝑐˜𝑖 ∈ K* ,˜ 𝑣𝑖 ∈ K* [𝑥]. Então K* = K(𝑐1 ,. . . ,𝑐𝑛 ) onde 𝑐𝑖 , 1 ≤ 𝑖 ≤ 𝑛 são as raízes distintas do polinômio 𝑅(𝑧) = res𝑥 (𝑎 − 𝑧𝑏′ ,𝑏) ∈ K[𝑧]. Ou seja, K* é o corpo sobre o qual 𝑅(𝑧) ∈ K[𝑧] se fatora completamente. Além disso, o Teorema 3.4.1 pode ser usado para calcular a integral com um corpo constante minimal. Demonstração. Seja a integral expressa na forma (3.25). Se 𝑐˜𝑖 e 𝑣˜𝑖 não satisfazem 45 3.4. O Algoritmo de Rothstein-Trager às condições do Teorema 3.4.1, então podemos reescrever a fórmula (3.25) de modo que passem a satisfazer. Primeiro, se algum 𝑣˜𝑖 não é livre de quadrados, então seja a sua fatoração livre de quadrados expressa por 𝑣˜𝑖 = 𝑘 ∏︁ 𝑗 𝑣𝑗 𝑗=1 e usemos algumas propriedades algébricas dos logaritmos para obter log(˜ 𝑣𝑖 ) = 𝑘 ∑︁ 𝑗 log(𝑣𝑗 ). 𝑗=1 Podemos realizar esta operação termo a termo até que todos os argumentos nos logaritmos sejam livres de quadrados. Desta forma, podemos assumir que os 𝑣˜𝑖 já são livres de quadrados e de grau positivo. Em seguida, se para algum para 𝑖,𝑗 temos mdc(˜ 𝑣𝑖 ,˜ 𝑣𝑗 ) = 𝑉 com grau(𝑉 ) > 1 então podemos escrever 𝑣˜𝑖 𝑣˜𝑗 log(˜ 𝑣𝑖 ) = log(𝑉 ) + log , log(˜ 𝑣𝑗 ) = log(𝑉 ) + log . 𝑉 𝑉 (︂ )︂ (︂ )︂ Observe que os argumentos dos logaritmos permanecem em K̃* . Utilizamos o mesmo procedimento repetidas vezes de modo a agrupar em um único termo todos os argumentos idênticos dos logaritmos, até estes argumentos se tornem dois a dois relativamente primos. Os polinômios continuam livres de quadrados e de graus positivos. Finalmente, se para algum 𝑖 ̸= 𝑗 tivermos 𝑐˜𝑖 = 𝑐˜𝑗 , então podemos escrever 𝑐˜𝑖 log(˜ 𝑣𝑖 ) + 𝑐˜𝑗 log(˜ 𝑣𝑗 ) = 𝑐˜𝑖 log(˜ 𝑣𝑖 𝑣˜𝑗 ), mais uma vez observando que as operações mantém a propriedade de que os argumentos dos logaritmos são livres de quadrados, dois a dois primos entre si e de grau positivo. Portanto mostramos que (3.25) pode ser reescrita em uma nova expressão, de modo que as hipóteses do Teorema 3.4.1 são satisfeitas. Por outro lado, o Teorema 3.4.1 nos diz que os 𝑐˜𝑖 são as raízes distintas do polinômio resultante 𝑅(𝑧) e os 𝑣˜𝑖 são aqueles neste teorema. Segue que K* é o corpo sobre o qual o polinômio 𝑅(𝑧) ∈ K[𝑧] se fatora completamente. Capítulo 3. Integração Indefinida de Funções Racionais Complexas 46 Em resumo, o método de Rothstein-Trager simplifica o problema da integração da parte logarítmica da seguinte forma. Para aplicarmos o método de Bernoulli a um integrando com denominador livre de quadrados, é preciso conhecer fatoração completa deste denominador, isto é, obter todas as suas raízes antes de integrar, o que implica conhecer um número de extensões maior do que o necessário para se resolver o problema. Além disso, realizamos os cálculos de frações parciais sobre a fatoração completa do denominador e integramos parcela a parcela. Em seguida, opcionalmente, pode-se agrupar logaritmos com coeficientes iguais, para fins de simplificação da resposta. No método de Rothstein-Trager, substituímos a necessidade de se conhecer todas as raízes do denominador pelo conhecimento apenas das raízes distintas de 𝑅(𝑧), as quais ocorrem em número menor ou igual ao das raízes do denominador do integrando original. Em seguida, como cada raiz 𝑐𝑖 corresponde a um resíduo distinto na decomposição em frações parciais do integrando, cada 𝑣𝑖 agrupa automaticamente e de maneira direta todas as raízes do denominador que se encontram sob o mesmo resíduo 𝑐𝑖 através, unicamente, de operações de mdc. Note que, conhecida a fatoração em fatores irredutíveis de 𝑅 = 𝑢 · 𝑅1𝑒1 · · · 𝑅𝑙𝑒𝑙 , cada raiz c só pode ser raiz de um de seus fatores, digamos, 𝑅𝑗 . Calculamos, portanto, 𝐺𝑗 (𝑧,𝑥) = mdc(𝑏,𝑎 − 𝑧𝑏′ ) em K(𝑧)[𝑥]/⟨𝑅𝑗 (𝑧)⟩ e, então, encontramos que 𝑐 log(𝐺𝑗 (𝑐,𝑥)) compõe a parte transcendental. Portanto, podemos dispensar o conhecimento explícito das raízes de 𝑅 na integral, obtendo, formalmente: ∫︁ ℎ= 𝑙 ∑︁ ∑︁ 𝑐 log(𝐺𝑗 (𝑐,𝑥)). 𝑖=1 𝑐|𝑅𝑗 (𝑐)=0 Assim, ∫ ℎ é determinado univocamente através dos 𝐺𝑗 e dos 𝑅𝑗 , sendo cada 𝐺𝑗 (𝑐,𝑥) equivalente a algum 𝑣𝑖 (𝑥), se 𝑐 é raiz de 𝑅𝑗 . Isto também mostra que só precisamos realizar os cálculos de mdc para cada fator irredutível de 𝑅, e não para cada raiz distinta, de modo que argumentos oriundos de raízes de um mesmo fator serão, formalmente, resultados de um mesmo cálculo de mdc. Na subseção 5.5.2, fornecemos um pseudocódigo, juntamente com código para implementação no Maxima do algoritmo de Rothstein-Trager. 47 3.4. O Algoritmo de Rothstein-Trager 3.4.1 Exemplos Exemplo 3.4.1 (extraído de [11], Cap. 11, §5). Retornemos à função 𝑓 = 𝑎/𝑏, com 𝑎 = 1 e 𝑏 = 𝑥3 + 𝑥. Como já vimos nos exemplos estudados na seção 3.1, referente ao algoritmo de Bernoulli, a integral desta função só possui parte logarítmica. Vimos duas possíveis representações para esta integral: uma que requer uma extensão do corpo constante Q para o corpo Q(𝐼), e outra que evita esta extensão. A segunda representação é aquela obtida pelo algoritmo de RothsteinTrager, como veremos a seguir. Calculamos o resultante de Rothstein-Trager, fazendo 𝐴 = 𝑎 e 𝐷 = 𝑏: 𝑅(𝑧) = res𝑥 (𝐴 − 𝑧𝐷′ ,𝐷) = res𝑥 ((1 − 𝑧) − (3𝑧)𝑥2 ,𝑥3 + 𝑥) ⎛ = ⎜ ⎜ ⎜ ⎜ ⎜ det ⎜ ⎜ ⎜ ⎜ ⎝ −3𝑧 0 1−𝑧 0 0 0 −3𝑧 0 1−𝑧 0 0 0 −3𝑧 0 1−𝑧 1 0 1 0 0 0 1 0 1 0 ⎞ ⎟ ⎟ ⎟ ⎟ ⎟ ⎟ ⎟ ⎟ ⎟ ⎠ = −4𝑧 3 + 3𝑧 + 1 ∈ Q[𝑧]. Temos que 𝑅(𝑧) se fatora completamente como −4(𝑧 − 1)(𝑧 + 1/2)2 ∈ Q[𝑧]. Portanto, não é necessário realizar extensões algébricas sobre o corpo constante Q. As raízes distintas de 𝑅(𝑧) são 𝑎 = 1 e 𝑎 = −1/2. Os argumentos polinomiais dos logaritmos aparecendo na integral de 𝑓 podem então ser calculados através de cálculos de mdc sobre Q[𝑥]: 𝑣1 = mdc(𝐴 − 1𝐷′ ,𝐷) = 𝑥 ∈ Q[𝑥], 𝑣2 = mdc(𝐴 − (−1/2)𝐷′ ,𝐷) = 𝑥2 + 1 ∈ Q[𝑥]. Logo, ∫︁ 𝑥3 1 1 = log(𝑥) − log(𝑥2 + 1). +𝑥 2 Ou seja, ∫ 𝑓 ∈ Q(𝑥, log(𝑥), log(𝑥2 + 1)), em conformidade com o algoritmo de Bernoulli. Exemplo 3.4.2 (gerado com dados obtidos pelo código 5.5.2, algoritmo de Rothstein-Trager). Sejam 𝐴 = 6𝑥5 + 12𝑥4 + 8𝑥3 − 12𝑥2 − 8𝑥 ∈ Q[𝑥], 𝐷 = Capítulo 3. Integração Indefinida de Funções Racionais Complexas 48 𝑥6 + 2𝑥5 + 2𝑥4 − 2𝑥3 − 4𝑥2 + 2 ∈ Q[𝑥] e 𝑓 = 𝐴/𝐷, isto é 𝑓= 6𝑥5 + 12𝑥4 + 8𝑥3 − 12𝑥2 − 8𝑥 ∈ Q(𝑥). 𝑥6 + 2𝑥5 + 2𝑥4 − 2𝑥3 − 4𝑥2 + 2 Observe que 𝐷 é livre de quadrados (além de ser irredutível sobre Q). Computamos a resultante de Rothstein-Trager: 𝑅(𝑧) = res𝑥 (𝑥6 +2𝑥5 + 2𝑥4 − 2𝑥3 − 4𝑥2 + 2,6𝑥5 + 12𝑥4 + 8𝑥3 − 12𝑥2 − 8𝑥− 𝑧(6𝑥5 + 10𝑥4 + 8𝑥3 − 6𝑥2 − 8𝑥)) = 203008(𝑧 2 − 2𝑧 + 2)3 ∈ Q[𝑧]. Neste caso, 𝑅(𝑧) já se encontra fatorado em fatores irredutíveis sobre Q[𝑧], mas não de maneira completa, de modo que não somos capazes de encontrar as raízes de 𝑅(𝑧) em Q. Precisamos adicionar números algébricos sobre o corpo de constantes. Mais precisamente, 𝑅(𝑧) se fatora completamente sobre Q(𝛼), onde 𝛼 é raiz de 𝑧 2 − 2𝑧 + 2. Nesta extensão do corpo de constantes, a fatoração completa de 𝑅(𝑧) é 𝑅(𝑧) = (𝑧 − 𝛼)(𝑧 − (2 − 𝛼)) ∈ Q(𝛼)[𝑧]. As raízes distintas de 𝑅(𝑧) são 𝑎 = 𝛼 e 𝑎 = 2 − 𝛼. Computamos 𝑣1 através de 𝑣1 = mdc(𝐴 − 𝛼𝐷′ ,𝐷) = −(8𝛼 + 19)𝑥3 − (35𝛼 − 16)𝑥2 + 35𝛼 − 16𝛼 = 𝑥3 + 𝛼𝑥2 − 𝛼 ∈ Q(𝛼)[𝑥] e o cálculo de 𝑣2 é essencialmente o mesmo, uma vez que 𝑣2 é uma raiz conjugada de 𝑣1 sobre os racionais. Dessa forma, não precisamos repetir as contas, bastando realizar uma substituição, de modo a obter 𝑣2 = 𝑥3 + (2 − 𝛼)𝑥2 − 2 + 𝛼. Portanto, conseguimos expressar ∫︁ 6𝑥5 + 12𝑥4 + 8𝑥3 − 12𝑥2 − 8𝑥 = 𝛼 log(𝑥3 + 𝛼𝑥2 − 𝛼) 𝑥6 + 2𝑥5 + 2𝑥4 − 2𝑥3 − 4𝑥2 + 2 + (2 − 𝛼) log(𝑥3 + (2 − 𝛼)𝑥2 − 2 + 𝛼) donde ∫ 𝑓 ∈ Q(𝛼)(𝑥, log(𝑣1 ), log(𝑣2 )). Caso não fosse possível representar o nú- 49 3.4. O Algoritmo de Rothstein-Trager mero algébrico 𝛼 em termos de radicais, então esta seria a melhor solução em forma fechada possível. Porém, neste exemplo, conseguimos uma representação de 𝛼 em termos de radicais. A saber, 𝛼=1+ √ −1 = 1 + 𝐼. Portanto, ∫︁ 6𝑥5 + 12𝑥4 + 8𝑥3 − 12𝑥2 − 8𝑥 = (1 + 𝐼) log(𝑥3 + (1 + 𝐼)𝑥2 − 1 − 𝐼) 6 5 4 3 2 𝑥 + 2𝑥 + 2𝑥 − 2𝑥 − 4𝑥 + 2 + (1 − 𝐼) log(𝑥3 + (1 − 𝐼)𝑥2 − 1 + 𝐼) Ou seja, ∫ 𝑓 ∈ Q(𝐼)(𝑥, log(𝑣1 ), log(𝑣2 )), onde 𝑣1 = 𝑥3 + (1 + 𝐼)𝑥2 − 1 − 𝐼 e 𝑣2 = 𝑥3 + (1 − 𝐼)𝑥2 − 1 + 𝐼. Exemplo 3.4.3 (extraído de [11]). O exemplo a seguir mostra um caso em que o algoritmo de Bernoulli não é capaz de fornecer, sequer parcialmente, uma resposta explícita uma vez que o denominador do integrando não pode ser fatorado nem mesmo sobre os reais de maneira explícita, isto é, não há raízes que possam ser obtidas por fórmulas conhecidas. O problema foi proposto em [33], em 1967, para demonstrar a necessidade de se obter um algoritmo que calculasse o resultado final utilizando o menor número de extensões algébricas, e só viria a ser resolvido apropriadamente com o algoritmo de Rothstein-Trager, na década seguinte. Sejam 𝐴 = 7𝑥13 +10𝑥8 +4𝑥7 −7𝑥6 −4𝑥3 −4𝑥2 +3𝑥+3, 𝐷 = 𝑥14 −2𝑥8 −2𝑥7 −2𝑥4 − 4𝑥3 − 𝑥2 + 𝑥 + 1 e 𝑓 = 𝐴/𝐷. Como 𝑓 é própria, reduzida e possui denominador livre de quadrados, temos apenas parte logarítmica. Temos a seguinte fatoração completa para a resultante 𝑅(𝑧) em Q[𝑧]: 𝑅(𝑧) = −23774396766245335552(𝑧 2 − 𝑧 − 1/4)7 . Portanto, 𝑅(𝑧) possui raízes irracionais. Se 𝛼 é uma dessas raízes, a fatoração completa de 𝑅(𝑧) sobre Q(𝛼)[𝑧] fica: 𝑅(𝑧) = −23774396766245335552(𝑧 − 𝛼)7 (𝑧 − (1 − 𝛼))7 . Capítulo 3. Integração Indefinida de Funções Racionais Complexas 50 Assim, se 𝛼 é raiz de 𝑅1 = 𝑧 2 − 𝑧 − 1/4, temos 𝐺1 (𝛼,𝑥) = mdc(𝐷,𝐴 − 𝛼𝐷′ ) = 𝑥7 + (1 − 2𝛼)𝑥2 − 2𝛼𝑥 − 1 ∈ Q(𝛼)[𝑥]. Uma das raízes de 𝑅1 é 𝛼 = (1 + ∫︁ 𝑓= ∑︁ √ √ 2)/2. A outra é 1 − 𝛼 = (1 − 2)/2. Portanto, 𝛼 log(𝑥7 + (1 − 2𝛼)𝑥2 − 2𝛼𝑥 − 1) 𝛼|𝑅1 (𝛼)=0 √ √ √ 1+ 2 = log(𝑥7 − 2𝑥2 − (1 + 2)𝑥 − 1) 2√ √ √ 1− 2 + log(𝑥7 + 2𝑥2 − (1 − 2)𝑥 − 1). 2 Isso mostra a importância do algoritmo de Rothstein-Trager. Algumas vezes é possível utilizar o algoritmo de Bernoulli e realizar simplificações para se chegar a uma resposta envolvendo o mínimo de extensões algébricas. Porém, isto não é possível neste exemplo: o algoritmo de Bernoulli requer que se conheça todas as extensões necessárias para se fatorar o denominador, pelo menos, sobre os reais, e este requerimento ocorre já na primeira etapa da integração, correspondente ao algoritmo de Hermite. O algoritmo de Rothstein-Trager, precedido pelo de Hermite, obtém o resultado final de maneira direta, utilizando o mínimo de extensões algébricas, sem passar por cálculos que seriam realizados pelo algoritmo de Bernoulli, os quais envolveriam mais extensões que o necessário para a forma final mínima da integral. 3.5 O Algoritmo de Lazard-Rioboo-Trager No método de Rothstein-Trager, além de ser necessário o conhecimento da fatoração em fatores irredutíveis de 𝑅(𝑧) = res𝑥 (𝑏,𝑎 − 𝑧𝑏′ ), os cálculos de mdc para se obter os polinômios 𝐺𝑗 (𝑐,𝑥) = 𝑣𝑖 , para algum par 𝑖,𝑗 e raiz 𝑐 de um fator irredutível 𝑅𝑗 de 𝑅, que aparecem em (3.18), são realizados sobre extensões K(𝑐). Em geral, como consequência destas considerações temos um aumento significativo de complexidade [11, p. 504]. O método adiante, conhecido como algoritmo de Lazard-Rioboo-Trager, 51 3.5. O Algoritmo de Lazard-Rioboo-Trager nos permite contornar este problema, evitando os cálculos de mdc realizados sobre extensões algébricas do corpo de coeficientes para determinação dos 𝐺𝑗 (𝑐,𝑥), substituindo estes cálculos por computação de subresultantes. É baseado no seguinte resultado. Teorema 3.5.1 ([2], Cap. 2, §6, [17, 24]). Seja K o fecho algébrico de K, 𝑧 uma indeterminada sobre K(𝑥) e 𝑎,𝑏,𝑐 ∈ K[𝑥] ∖ {0} tais que mdc(𝑎,𝑐) = mdc(𝑏,𝑐) = 1, grau(𝑎) < grau(𝑐) e 𝑐 livre de quadrados. Sejam 𝑅(𝑧) = res𝑥 (𝑐,𝑎 − 𝑧𝑏) ∈ K[𝑧] e (𝑟0 ,𝑟1 , . . . ,𝑟𝑘 = ̸ 0,0, . . . ) a SRP das subresultante com relação a 𝑥 de 𝑐 e 𝑎 − 𝑧𝑏 se grau(𝑏) < grau(𝑐) ou 𝑎 − 𝑧𝑏 e 𝑐 se grau(𝑏) ≥ grau(𝑐). Seja 𝛼 ∈ K uma raiz de multiplicidade 𝑛 > 0 de 𝑅(𝑧). Então uma das seguintes ocorre: 1. 𝑛 = grau(𝑐), em qual caso mdc(𝑐,𝑎 − 𝛼𝑏) = 𝑐 ∈ K(𝛼)[𝑥]. 2. 𝑛 < grau(𝑐), em qual caso, existe um único 𝑚 ≥ 1 tal que grau𝑥 (𝑟𝑚 ) = 𝑛 e mdc(𝑐,𝑎 − 𝛼𝑏) = pp𝑥 (𝑟𝑚 )(𝛼,𝑥) ∈ K(𝛼)[𝑥] onde pp𝑥 (𝑟𝑚 ) é a parte primitiva de 𝑟𝑚 com relação a 𝑥. Demonstração. Sejam 𝑅 = res𝑥 (𝑐,𝑎 − 𝑧𝑏) e (𝑟0 ,𝑟1 , . . . ,𝑟𝑘 ̸= 0,0, . . . ) a SRP subrestultante com respeito a 𝑥 (ou seja, em K[𝑧][𝑥]) de 𝑐 e 𝑎 − 𝑧𝑏, se grau(𝑏) < grau(𝑐), ou 𝑎 − 𝑧𝑏 e 𝑐, se grau(𝑏) ≥ grau(𝑐). Sejam ainda 𝑞 = grau(𝑐), 𝑝 = grau(𝑎 − 𝑧𝑏) e 𝛾 ∈ K ∖ {0} o coeficiente líder de 𝑐 e 𝑐 = 𝛾 𝑞 ∏︁ (𝑥 − 𝛽𝑖 ) a fatoração completa de 𝑐 𝑖=1 sobre K. (Note que os 𝛽𝑖 são distintos, pois 𝑐 é livre de quadrados). Temos, pelo Lema 2.1.2, que 𝑅 = 𝛾𝑝 𝑞 ∏︁ (𝑎(𝛽𝑖 ) − 𝑧𝑏(𝛽𝑖 )). 𝑖=1 Logo, o coeficiente líder de 𝑅 é ±𝛾 𝑝 𝑞 ∏︁ 𝑏(𝛽𝑖 ), o qual é não nulo, uma vez que 𝑖=1 mdc(𝑏,𝑐) = 1. Portanto, 𝑅 ̸= 0. Seja 𝛼 uma raiz de multiplicidade 𝑛 > 0 de Capítulo 3. Integração Indefinida de Funções Racionais Complexas 𝑅. Observe que o termo de menor grau de 𝑅 é 𝛾 𝑝 𝑞 ∏︁ 52 𝑎(𝛽𝑖 ), o qual é não nulo, 𝑖=1 uma vez que mdc(𝑎,𝑐) = 1. Assim, 𝛼 ̸= 0. Como 𝛼 possui multiplicidade 𝑛, há um subconjunto 𝐼𝛼 ⊆ {1, . . . 𝑞} de cardinalidade 𝑛 tal que 𝑎(𝛽𝑖 ) − 𝛼𝑏(𝛽𝑖 ) = 0 ∏︁ se e só se 𝑖 ∈ 𝐼𝛼 . Então, 𝑣𝛼 = (𝑥 − 𝛽𝑖 ) divide 𝑎 − 𝛼𝑏 em K[𝑥]. Por outro 𝑖∈𝐼𝛼 lado, 𝑥 − 𝛽𝑖 - 𝑎 − 𝛼𝑏 para 𝑖 ∈ / 𝐼𝛼 , donde 𝑣𝛼 = mdc(𝑐,𝑎 − 𝛼𝑏) ∈ K(𝛼)[𝑥]. Ou seja, grau𝑥 (𝑣𝛼 ) = 𝑛 e, portanto, 𝑛 ≤ grau(𝑐). Assim, 1. se 𝑛 = grau(𝑐), então 𝑣𝛼 divide 𝑐 e tem o mesmo grau de 𝑐, donde 𝑣𝛼 = 𝑐; 2. se 𝑛 < grau(𝑐). Então 𝑎 − 𝛼𝑏 ̸= 0, caso contrário, teríamos 𝑣𝛼 = mdc(𝑐,𝑎 − 𝛼𝑏) = mdc(𝑐,0) = 𝑐, cujo grau é maior que 𝑛. Continuando, sejam 𝑆𝑛 ∈ K[𝑧][𝑥] a 𝑛-ésima subresultante de 𝑐 e 𝑎−𝑧𝑏 com relação a 𝑥, 𝜎 : K[𝑧] → K(𝛼) o homomorfismo de anéis que é a identidade sobre K e leva 𝑧 em 𝛼 e 𝜎 : K[𝑧][𝑥] → K(𝛼)[𝑥] induzido por 𝜎, isto é, 𝜎(Σ𝑎𝑗 𝑥𝑗 ) = Σ𝜎(𝑎𝑗 )𝑥𝑗 . Como 𝑎,𝑏,𝑐 ∈ K[𝑥] (isto é, não envolvem 𝑧), temos que 𝜎(𝑐) = 𝑐 e 𝜎(𝑎−𝑧𝑏) = 𝑎−𝛼𝑏, donde grau(𝜎(𝑐)) = 𝑞, e a Proposição 2.1.2 nos permite escrever 𝜎(𝑆𝑛 ) = 𝛾 𝑟 𝑆𝑛 , onde 𝑟 é um inteiro não negativo e 𝑆𝑛 é a 𝑛-ésima subresultante de 𝑐 e 𝑎 − 𝛼𝑏. Seja (𝑠0 ,𝑠1 , . . . ,𝑠𝑙 ̸= 0,0, . . . ) a SRP das subresultantes de 𝑐 e 𝑎 − 𝑧𝑏 em K(𝛼)[𝑥], se grau(𝑏) < grau(𝑐), ou de 𝑎 − 𝛼𝑏 e 𝑐, se grau(𝑏) ≥ grau(𝑐). A Proposição 2.1.3 garante que 𝑠𝑙 = mdc(𝑐,𝑎 − 𝑧𝑏), donde grau𝑥 (𝑠𝑙 ) = 𝑛. Portanto, 𝜎(𝑆𝑛 ) é semelhante a 𝑠𝑙 pelo Teorema 2.1.1, o que significa que 𝜎(𝑆𝑛 ) ̸= 0 e que também temos 𝜎(𝑆𝑛 ) = mdc(𝑐,𝑎 − 𝛼𝑏), portanto grau(𝜎(𝑆𝑛 )) = 𝑛. Como grau𝑥 (𝑆𝑛 ) ≤ 𝑛 por definição e grau(𝜎(𝑆𝑛 )) ≤ grau𝑥 (𝑆𝑛 ), temos que grau𝑥 (𝑆𝑛 ) = 𝑛. Pelo Teorema 2.1.1, 𝑆𝑛 é similar a algum 𝑟𝑚 , para 𝑚 ≥ 0, o que significa que grau𝑥 (𝑟𝑚 ) = 𝑛. Uma vez que grau(𝑟0 ) ≥ grau(𝑐) > 𝑛, temos que 𝑚 ≥ 1, o que implica que 𝑚 é único, pois grau(𝑟𝑖 ) > grau(𝑟𝑖+1 ) para 𝑖 ≥ 1 em qualquer SRP. Escrevamos 𝜌1 𝑆𝑛 = 𝜌2 pp𝑥 (𝑟𝑚 ) com 𝜌1 ,𝜌2 ∈ K[𝑧] satisfazendo mdc(𝜌1 ,𝜌2 ) = 1. Então 𝜎(𝜌1 )𝜎(𝑆𝑛 ) = 𝜎(𝜌2 )𝜎(pp𝑥 (𝑟𝑚 )). Observe que 𝜎(𝑆𝑛 ) ̸= 0 e 𝜎(pp𝑥 (𝑟𝑚 )) ̸= 0, uma vez que pp𝑥 (𝑟𝑚 ) é primitivo. Além disso, não podemos ter 𝜎(𝜌1 ) = 𝜎(𝜌2 ) = 0, já que mdc(𝜌1 ,𝜌2 ) = 1. Logo, 𝜎(𝜌1 ) ̸= 0 e 𝜎(𝜌2 ) ̸= 0, donde 𝑣𝛼 = mdc(𝑐,𝑎 − 𝛼𝑏) = 𝜎(pp𝑥 (𝑟𝑚 )) = pp𝑥 (𝑟𝑚 )(𝛼,𝑥). 53 3.5. O Algoritmo de Lazard-Rioboo-Trager Utilizamos o Teorema 3.5.1 para calcular de ∫ 𝑎/𝑏, substituindo 𝑐 por 𝑏 e 𝑏 por 𝑏′ . Calculamos 𝑅(𝑧) através do algoritmo das subresultantes, como visto na subseção 2.1.2, aplicado a 𝑏 e 𝑎 − 𝑧𝑏′ (caso em que grau(𝑏) < grau(𝑐) no teorema anterior). Se 𝑣𝛼 = mdc(𝑏,𝑎 − 𝛼𝑏′ ), onde 𝛼 é uma raiz de 𝑅(𝑧), então 𝑣𝛼 = 𝑏 se a multiplicidade de 𝛼 for grau(𝑏), ou pp𝑥 (𝑟𝑚 ), se a multiplicidade de 𝛼 for menor que grau(𝑏), em qual caso 𝑚 ≥ 1 é o único inteiro positivo tal que grau𝑥 (𝑟𝑚 ) equivale à multiplicidade de 𝛼. Portanto, contornamos completamente o cálculo de mdc sobre extensões do corpo de coeficientes. Cada argumento dos logaritmos é, na verdade, algum resto da SRP das subresultantes e a expressão da integral é colocada em termos de uma extensão minimal de K. A seguir, alguns aspectos práticos do método. Ao implementarmos o algoritmo, calculamos a fatoração livre de quadrados de 𝑅 = 𝑛 ∏︁ 𝑄𝑖𝑖 , separando em 𝑄𝑖 as 𝑖=1 raízes de multiplicidade 𝑖 de 𝑅. Avaliar pp𝑥 (𝑟𝑚 )(𝑧,𝑥), para 𝑧 = 𝛼, onde 𝛼 é uma raiz de 𝑄𝑖 é o mesmo que reduzir cada coeficiente em relação a 𝑥 de pp𝑥 (𝑟𝑚 ) módulo 𝑄𝑖 . Não é preciso calcular de fato pp𝑥 (𝑟𝑚 ): em seu lugar, é necessário e suficiente que se tome algum polinômio similar a 𝑟𝑚 tal que não seja levado em 0 pelo homomorfismo 𝜎 no Teorema 3.5.1. A fonte [24] traz possibilidades para este polinômio e compara a eficiência do algoritmo de Lazard-Rioboo-Trager em relação à escolha. Na implementação deste algoritmo, no capítulo 5, utilizamos o polinômio 𝑆𝑖 (𝑧,𝑥) = 𝑟𝑚 / gcd(cl(𝑟𝑚 ),𝑄𝑖 ). Seus coeficientes (em 𝑥) não costumam ser tão pequenos quanto os de pp𝑥 (𝑟𝑚 ), mas sua computação é mais rápida. Observe que este é, de fato, um polinômio válido, pois, se 𝛼 é raiz de 𝑄𝑖 , além de 𝑆𝑖 ser similar a 𝑟𝑚 , é garantido que 𝜎(𝑆𝑖 (𝑧,𝑥)) = 𝑆𝑖 (𝛼,𝑥) ̸= 0, uma vez que o resto da divisão de 𝑆𝑖 por 𝑄𝑖 é não nulo. Uma normalização pode ser feita para simplificar a resposta, qual seja, multiplicar o argumento dos logaritmos em 3.18 por uma constante arbitrária para torná-los mônicos, uma vez que isto não alterará a derivada, o que requer uma computação de elemento inverso em K[𝛼], mas não um cálculo de mdc em K[𝛼][𝑥]. Como os 𝑄𝑖 não são necessariamente irredutíveis em K, o anel K[𝛼] pode ter divisores de 0, mas, devido às considerações do parágrafo anterior, os coeficientes líderes dos 𝑆𝑖 (𝛼,𝑥) (qualquer um válido que se escolha) são sempre invertíveis em K[𝛼], [2, p.51]. Para proceder com a computação de inverso sem gerar denomina- Capítulo 3. Integração Indefinida de Funções Racionais Complexas 54 dores, podemos simplesmente aplicar o algoritmo de Euclides estendido sobre o anel euclideano K[𝑡], de modo a obter polinômios 𝜎,𝜏 ∈ K[𝑡]/⟨𝑄𝑖 [𝑡]⟩ tais que: 𝜎 cl(𝑆𝑖 ) + 𝜏 𝑄𝑖 = 1. Isto significa que 𝜎 cl(𝑆𝑖 ) ≡ 1 − 𝜏 𝑄𝑖 ≡ 1 mod 𝑄𝑖 Portanto, 𝜎(𝛼) é o inverso procurado em K[𝛼] para cl(𝑆𝑖 )(𝛼). Detalhes acerca deste procedimento de computação de inversos podem ser encontrados em [11, Cap. 5, §5], mais precisamente, no Teorema 5.6. O mesmo procedimento de normalização pode ser aplicado ao algoritmo de Rothstein-Trager, com a respectiva fatoração em fatores irredutíveis de 𝑅(𝑧). Na subseção 5.5.3, fornecemos um pseudocódigo, juntamente com código para implementação no Maxima do algoritmo de Lazard-Rioboo-Trager. 3.5.1 Exemplos Exemplo 3.5.1 (gerado com dados obtidos pelo código 5.5.3, algoritmo de Lazard-Rioboo-Trager). Continuamos a considerar a função 𝑓 = 𝑎/𝑏 do Exemplo 3.4.2. A sequência das subresultantes para 𝑏 e 𝑎 − 𝑧𝑏′ na indeterminada 𝑥 é 55 3.5. O Algoritmo de Lazard-Rioboo-Trager 𝑖 0 1 2 3 4 5 6 𝑟𝑖 6 5 4 𝑥 + 2𝑥 + 2𝑥 − 2𝑥3 − 4𝑥2 + 2 (6 − 6𝑧)𝑥5 + (12 − 10𝑧)𝑥4 + (8 − 8𝑧)𝑥3 + (6𝑧 − 12)𝑥2 + (8𝑧 − 8)𝑥 (4𝑧 2 − 24𝑧 + 24)𝑥4 + (52𝑧 − 52𝑧 2 )𝑥3 + (−84𝑧 2 + 168𝑧 − 96)𝑥2 + (16𝑧 2 − 16𝑧)𝑥 + 72𝑧 2 − 144𝑧 + 72 (−568𝑧 3 + 1240𝑧 2 − 1216𝑧 + 512)𝑥3 (−808𝑧 3 + 2032𝑧 2 − 1888𝑧 + 576)𝑥2 + (208𝑧 3 − 624𝑧 2 + 832𝑧 − 416)𝑥+ 704𝑧 3 − 1824𝑧 2 + 1680𝑧 − 576 (−9456𝑧 4 + 40032𝑧 3 − 71648𝑧 2 + 63232𝑧 − 20992)𝑥2 + (−3392𝑧 4 + 8896𝑧 3 − 9856𝑧 2 + 1920𝑧 + 2304)𝑥 + 10016𝑧 4 − 39168𝑧 3 + 67776𝑧 2 − 57216𝑧 + 18944 (−49024𝑧 5 + 244608𝑧 4 − 586240𝑧 3 + 780288𝑧 2 − 584192𝑧 + 194048)𝑥+ 17728𝑧 5 − 73216𝑧 4 + 151040𝑧 3 − 160256𝑧 2 + 89344𝑧 − 9216 203008𝑧 6 − 1218048𝑧 5 + 3654144𝑧 4 − 6496256𝑧 3 + 7308288𝑧 2 − 4872192𝑧 + 1624064 Portanto: 1. 𝑅 = 𝑟6 na tabela acima. 2. flq de 𝑅: 𝑅 = 203008𝑄33 = 203008(𝑧 2 − 2𝑧 + 2)3 . 3. Dada a flq de 𝑅, o único resto da SRP que nos interessa é aquele que possui grau 3 na variável 𝑥. A saber, 𝑅3 na tabela acima. Além disso, temos que mdc(cl𝑥 (𝑟3 ),𝑄3 ) = mdc(−568𝑧 3 + 1240𝑧 2 − 1216𝑧 + 512,𝑧 2 − 2𝑧 + 2) = 1. Portanto, 𝑆3 = 𝑟3 (𝑟3 é primitivo na variável 𝑥). 4. Se 𝑎 é raiz de 𝑄3 , ou seja, se 𝑎2 − 2𝑎 + 2 = 0, temos que, ao avaliar 𝑆3 para 𝑎, algumas simplificações podem ser feitas nos coeficientes de 𝑆3 , de modo que 𝑆3 (𝑎,𝑥) = (128𝑎 + 304)𝑥3 + (560𝑎 − 256)𝑥2 − 560𝑎 + 256. 5. A integral fica em termos das raízes de 𝑄3 , isto é: ∫︁ ∑︁ 6𝑥5 + 12𝑥4 + 8𝑥3 − 12𝑥2 − 8𝑥 = 𝑎 log((128𝑎 + 304)𝑥3 + 𝑥6 + 2𝑥5 + 2𝑥4 − 2𝑥3 − 4𝑥2 + 2 𝑎|𝑄3 (𝑎)=0 (560𝑎 − 256)𝑥2 − 560𝑎 + 256). Capítulo 3. Integração Indefinida de Funções Racionais Complexas 56 6. Finalmente, podemos normalizar 𝑆3 (𝑎,𝑥): o multiplicador procurado é (35 − 8𝑎)/12688 e, portanto, 8𝑎 − 35 𝑆3 (𝑎,𝑥) 12688 1 =− ((64𝑎2 − 128𝑎 − 665)𝑥3 793 + (280𝑎2 − 1353𝑎 + 560)𝑥2 ) − (280𝑎2 − 1353𝑎 + 560) = 𝑥3 + 𝑎𝑥2 − 𝑎. 𝑆3 (𝑎,𝑥) ← − Ou seja, ∫︁ ∑︁ 6𝑥5 + 12𝑥4 + 8𝑥3 − 12𝑥2 − 8𝑥 = 𝑎 log(𝑥3 + 𝑎𝑥2 − 𝑎). 𝑥6 + 2𝑥5 + 2𝑥4 − 2𝑥3 − 4𝑥2 + 2 𝑎|𝑄3 (𝑎)=0 Observe que, pela separação do produto de logaritmos, a diferença entre o resultado normalizado e o resultado original é apenas uma constante aditiva, a saber, o logaritmo do multiplicador utilizado na normalização. Ambas as formas da integral são válidas, pois a derivada de uma constante é nula. Exemplo 3.5.2 (extraído de [24]). Vejamos o que acontece ao se tomar diretamente um 𝑆𝑖 = 𝑟𝑚 no algoritmo de Lazard-Rioboo-Trager, ao invés de realizar a alteração [24].√︁ Considere 𝐴 = 𝑥4 +𝑥3 +𝑥2 +𝑥+1 e 𝐷 = 𝑥5 +𝑥4 +2𝑥3 +2𝑥2 +2𝑥−2+4𝛽, √ com 𝛽 = −1 + 3. A SRP das subresultantes de 𝐷 e 𝐴 − 𝑧𝐷′ é 𝑟0 = 𝐷, 𝑟1 = 𝐴 − 𝑧𝐷′ , 𝑟2 = 𝑆3 (𝑧,𝑥), 𝑟3 = 𝑆1 (𝑧,𝑥) e 𝑟4 = 𝑅(𝑧) = res𝑥 (𝐷,𝐴 − 𝑧𝐷′ ), onde 𝑆3 e 𝑆1 são os restos de grau 3 e 1, e 𝑆3 (𝑧,𝑥) = (16𝑧 2 − 8𝑧 + 1)𝑥3 + (24𝑧 2 − 10𝑧 + 1)𝑥2 + (36𝑧 2 − 12𝑧 + 1)𝑥+ + (100𝛽 − 52)𝑧 2 − (40𝛽 − 21)𝑧 + 4𝛽 − 2, e 𝑆1 (𝑧,𝑥) = ((320𝛽 − 288)𝑧 3 − (224𝛽 − 184)𝑧 2 + (52𝛽 − 40)𝑧 − 4𝛽 + 3)𝑥 − (224𝛽 − 96)𝑧 3 + (104𝛽 − 32)𝑧 2 − (12𝛽 + 2)𝑧 + 1. Veja que 𝑅(𝑧) é livre de quadados e que 𝛼 = 1/4 é uma raiz (de multiplicidade 57 3.5. O Algoritmo de Lazard-Rioboo-Trager 1) de 𝑅(𝑧), e o resto de grau 1 na SRP das subresultantes em questão é 𝑆1 (𝑧,𝑥). Assim, o termo 1/4 log(𝑆1 (1/4,𝑥)) deve aparecer na fórmula da integral. Porém, é fácil ver que 𝑆1 (1/4,𝑥) = 0. Em outras palavras, temos um caso em que 𝜎(𝑆𝑖 ) = 0. Fazendo, porém, 𝑆1 = 𝑟3 / mdc(cl(𝑟3 ),𝑅) e tornando-o mônico, conseguimos 1 ( 76090729 − (3166362384896𝛽 3 − 9589146863104𝛽 2 + 5561008828160𝛽 + 25820852224)𝑧 4 𝑆𝑖 (𝑧,𝑥) = 𝑥 + + (2572043436032𝛽 3 − 7559719452928𝛽 2 + 4149998074624𝛽 + 152749784768)𝑧 3 − (782864496864𝛽 3 − 2219904899648𝛽 2 + 1116206990848𝛽 + 94889180832)𝑧 2 + (105949632800𝛽 3 − 288577921016𝛽 2 + 128975650144𝛽 + 19331983176)𝑧 − 5377952768𝛽 3 + 14063435544𝛽 2 − 5525914060𝛽 − 1188274675). Avaliando-o para 𝑧 = 1/4 temos 𝑆𝑖 (1/4,𝑥) = 𝑥 + 𝛽. Convém observar que o algoritmo original de Lazard-Rioboo-Trager tomava diretamente os restos da SRP das subresultantes, ao invés de assegurá-los como não nulos sob o homomorfismo 𝜎. Esta versão original é apresentada tanto em [4] quanto [11], de acordo com [24]. Portanto deve-se tomar cuidado ao se implementar o algoritmo a partir de uma dessas fontes. Capítulo 3. Integração Indefinida de Funções Racionais Complexas 58 Capítulo 4 Integração Indefinida de Funções Racionais Reais Seja K um subcorpo dos reais. Como vimos nos algoritmos que estudamos, pela equação (3.6), é possivel representar a integral de uma função racional de K(𝑥) como sendo a soma entre uma parte racional e outra logarítmica. É possível, ainda, que extensões algébricas novas sobre K sejam necessárias para representar a combinação linear de logaritmos que aparece em (3.6). Entre as extensões possíveis, estão números com unidade imaginária não nula, em qual caso, torna-se necessário realizar manipulações aritméticas sobre o corpo dos complexos para se calcular a integral definida da função racional em questão. Podemos, portanto, ter problemas na computação numérica ocasionados pelos ramos de logaritmos, uma vez que os argumentos dos logaritmos podem possuir raízes complexas (lembremos que os argumentos são polinômios), enquanto o integrando inicial não possui polos no intervalo da integração. Neste caso, o Teorema Fundamental do Cálculo pode, eventualmente, fornecer um valor incorreto para a integral definida, caso seja aplicado de maneira direta, uma vez que a antiderivada não é necessariamente contínua no intervalo de integração. O que queremos é obter uma integral indefinida que, no máximo, envolva coeficientes reais sempre que o integrando for real, ou seja, queremos eliminar qualquer extensão envolvendo a unidade imaginária que apareça na representação da integral. Para isto, temos o algoritmo de Rioboo, o qual será descrito neste Capítulo 4. Integração Indefinida de Funções Racionais Reais 60 capítulo. Este algoritmo expande a parte logarítmica da integral de uma função 𝑓 ∈ R(𝑥) sem a introdução de novos polos reais. Em suma, dada a parte logarítmica obtida pelos métodos de Rothstein-Trager ou Lazar-Rioboo-Trager, o método de Rioboo mantém os logaritmos reais originais e converte, aos pares de resíduos conjugados (raízes complexas de 𝑅(𝑧) ∈ R[𝑧]), os logaritmos complexos em uma soma de logaritmos e funções arco tangente, todos com argumento polinomial. Todos os coeficientes a aparecerem na forma convertida são reais. 4.1 O Algoritmo de Rioboo para Funções Racionais Reais Seja K ⊆ C um subcorpo dos complexos sobre o qual 𝑥2 + 1 é irredutível. Observamos que, para quaisquer 𝑝,𝑞 ∈ K[𝑥], temos 𝑝2 + 𝑞 2 = 0 =⇒ 𝑝 = 𝑞 = 0. (4.1) Em seguida, enunciamos o seguinte resultado, que serve de base para o algoritmo clássico para conversão de pares conjugados de logaritmos complexos em funções arco tangente reais. Lema 4.1.1 ([2], Cap. 2, §8). Seja 𝑢 ∈ K(𝑥) tal que 𝑢2 ̸= 𝛼2 , onde 𝑥2 −𝛼2 ∈ K[𝑥]. Então (︂ )︂ (︂ )︂ 𝑑 𝑢+𝛼 𝑑 𝑢 𝛼 log = 2𝛼 arctgh . (4.2) 𝑑𝑥 𝑢−𝛼 𝑑𝑥 𝛼 Demonstração. 𝑑 𝑢+𝛼 𝑢−𝛼 𝑑 𝑢+𝛼 =𝛼 𝛼 log 𝑑𝑥 𝑢−𝛼 𝑢 + 𝛼 𝑑𝑥 𝑢 − 𝛼 (︂ )︂ 𝑢 − 𝛼 (𝑢 − 𝛼) − (𝑢 + 𝛼) 𝑑𝑢 =𝛼 𝑢+𝛼 (𝑢 − 𝛼)2 𝑑𝑥 (︂ )︂ 𝛼 𝑑𝑢 𝑑 𝑢 . = −2𝛼 2 = 2𝛼 arctgh 2 𝑢 − 𝛼 𝑑𝑥 𝑑𝑥 𝛼 (︂ )︂ (︂ )︂ (︂ )︂ 61 4.1. O Algoritmo de Rioboo para Funções Racionais Reais Corolário 4.1.1. Seja 𝑢 ∈ K(𝑥) tal que 𝑢2 ̸= 1. Então 𝑢+𝐼 𝑑 log 𝑑𝑥 𝑢−𝐼 (︂ 𝐼 )︂ =2 𝑑 arctg(𝑢). 𝑑𝑥 (4.3) Demonstração. Basta notar que arctgh(𝑢/𝐼) = arctgh(−𝐼𝑢) = −𝐼 arctg(𝑢) Através do Lema 4.1.1 e do Corolário 4.1.1, se K ⊆ R, é possível substituir pares de logaritmos que contenham argumentos conjugados na extensão 𝛼 por funções arco tangente hiperbólico ou simples com coeficientes reais. Mais precisamente, se 𝑝,𝑞 ∈ K[𝑥] e (︃ )︃ 𝑝 , 𝐹1 = 𝛼 log(𝑝 + 𝛼𝑞) − 𝛼 log(𝑝 − 𝛼𝑞), 𝐹2 = 2𝛼 arctgh 𝛼𝑞 temos que 𝑑𝐹1 𝑑 = 𝛼 [log(𝑝 + 𝛼𝑞) − log(𝑝 − 𝛼𝑞)] 𝑑𝑥 𝑑𝑥 (︃ )︃ (︃ )︃ 𝑑 𝑝 + 𝛼𝑞 𝑑 𝑝/𝑞 + 𝛼 = 𝛼 log = 𝛼 log 𝑑𝑥 𝑝 − 𝛼𝑞 𝑑𝑥 𝑝/𝑞 − 𝛼 (︃ )︃ 𝑑 𝑑𝐹2 𝑝 = 2𝛼 arctgh = . 𝑑𝑥 𝛼𝑞 𝑑𝑥 (4.4) Por outro lado, note que 𝐹2 é descontínua nas raízes reais de 𝑞, de modo que, ainda que utilizemos o procedimento proposto por (4.4) para converter logaritmos conjugados em 𝛼 = 𝐼 na expressão da integral de uma função racional em funções arco tangente com coeficientes reais, ainda não seremos capazes de obter uma antiderivada contínua sobre a qual possamos aplicar corretamente o Teorema Fundamental do Cálculo para a integração contínua, devido aos polos reais gerados por cada função da forma 𝐹2 que encontrarmos com 𝛼 = 𝐼. Para resolver este problema, o seguinte resultado pode ser utilizado sempre que o argumento da função arco tangente no Corolário 4.1.1 é um polinômio, ao invés de uma fração. Teorema 4.1.1 ([2], Cap. 2, §8,[28]). Sejam 𝑝,𝑞 ∈ K[𝑥]∖{0} tais que 𝑝2 + 𝑞 2 = ̸ 0. Capítulo 4. Integração Indefinida de Funções Racionais Reais 62 Então, (︃ 𝑑 𝑝 + 𝛼𝑞 log 𝑑𝑥 𝑝 − 𝛼𝑞 )︃ (︃ 𝑑 𝛼2 𝑞 + 𝛼𝑝 = log 𝑑𝑥 𝛼2 𝑞 − 𝛼𝑝 )︃ e, para quaisquer 𝑟,𝑠 ∈ K[𝑥] tais que 𝑞𝑠 − 𝑝𝑟 = mdc(𝑝,𝑞), 𝑟 ̸= 0 e 𝑟2 + 𝑠2 ̸= 0, (︃ 𝑝 + 𝛼𝑞 𝑑 𝛼 log 𝑑𝑥 𝑝 − 𝛼𝑞 )︃ (︃ )︃ 𝑑 𝑝𝑠 − 𝛼2 𝑞𝑟 𝑑 𝑠 + 𝛼𝑟 = 2𝛼 arctgh + 𝛼 log . 𝑑𝑥 𝛼 mdc(𝑝,𝑞) 𝑑𝑥 𝑠 − 𝛼𝑟 (︂ )︂ Demonstração. Temos que 𝑝 + 𝛼𝑞 𝛼𝑝 + 𝛼2 𝑞 𝛼2 𝑞 + 𝛼𝑝 = =− 2 . 𝑝 − 𝛼𝑞 𝛼𝑝 − 𝛼2 𝑞 𝛼 𝑞 − 𝛼𝑝 tomando a derivada do logaritmo dos dois lados (lembrando que 𝑥 é uma variável complexa), temos (︃ 𝑑 𝑝 + 𝛼𝑞 log 𝑑𝑥 𝑝 − 𝛼𝑞 )︃ (︃ )︃ 𝑑 𝛼2 𝑞 + 𝛼𝑝 = log . 𝑑𝑥 𝛼2 𝑞 − 𝛼𝑝 Agora, sejam 𝐺 = mdc(𝑝,𝑞) e 𝑟,𝑠 ∈ K[𝑥] tais que 𝑟 ̸= 0, 𝑟2 + 𝑠2 ̸= 0 e 𝑞𝑠 − 𝑝𝑟 = 𝐺 Escrvamos 𝑢 = (𝑝𝑠 − 𝛼2 𝑞𝑟)/𝐺. Observamos que 𝑢 ∈ K[𝑥], uma vez que 𝐺 | 𝑝,𝑞. Temos que (︃ )︃ 𝑠 − 𝛼𝑟 𝑝 + 𝛼𝑞 𝑠 + 𝛼𝑟 𝑠 + 𝛼𝑟 𝑝 − 𝛼𝑞 𝑠 − 𝛼𝑟 )︃ (︃ 𝑝𝑠 − 𝛼2 𝑞𝑟 + 𝛼(𝑞𝑠 − 𝑝𝑟) 𝑠 + 𝛼𝑟 = 𝑝𝑠 − 𝛼2 𝑞𝑟 − 𝛼(𝑞𝑠 − 𝑝𝑟) 𝑠 − 𝛼𝑟 (︂ )︂ (︂ )︂ 𝑢+𝛼 𝑠 + 𝛼𝑟 = . 𝑢−𝛼 𝑠 − 𝛼𝑟 𝑝 + 𝛼𝑞 = 𝑝 − 𝛼𝑞 Logo, (︃ 𝑑 𝑝 + 𝛼𝑞 𝛼 log 𝑑𝑥 𝑝 − 𝛼𝑞 )︃ 𝑑 𝑢+𝛼 𝑑 𝑠 + 𝛼𝑟 = 𝛼 log + 𝛼 log . 𝑑𝑥 𝑢−𝛼 𝑑𝑥 𝑠 − 𝛼𝑟 (︂ )︂ (︂ )︂ Portanto, pelo Lema 4.1.1, (︃ 𝑑 𝑝 + 𝛼𝑞 𝛼 log 𝑑𝑥 𝑝 − 𝛼𝑞 )︃ 𝑑 𝑢 𝑑 𝑠 + 𝛼𝑟 = 2𝛼 arctgh + 𝛼 log . 𝑑𝑥 𝛼 𝑑𝑥 𝑠 − 𝛼𝑟 (︂ )︂ (︂ )︂ 63 4.1. O Algoritmo de Rioboo para Funções Racionais Reais Observe que se K é um subcorpo dos reais então por (4.1), podemos sempre aplicar em K[𝑥] o Teorema 4.1.1. Além disso, este resultado nos permite escrever (︃ 𝑝 + 𝛼𝑞 𝑔 = 𝛼 log 𝑝 − 𝛼𝑞 )︃ (4.5) como uma soma de funções arco tangente hiperbólico com argumentos polinomiais: se 𝐺 = mdc(𝑝,𝑞), temos que grau(𝐺) ≤ grau(𝑞). Se grau(𝐺) = grau(𝑞), então 𝑞 divide 𝑝, donde 𝐺 = 𝑞, e, portanto, 𝑠 = 1 e 𝑟 = 0, logo 𝑢 = (𝑝𝑠 − 𝛼2 𝑞𝑟)/𝐺 = 𝑝/𝑞 ∈ K[𝑥] e (︂ )︂ 𝑑𝑔 𝑑 𝑢 = 2𝛼 arctgh 𝑑𝑥 𝑑𝑥 𝛼 pelo Lema 4.1.1. Se grau(𝑝) < grau(𝑞), então (︃ 𝑑 𝛼2 𝑞 + 𝛼𝑝 𝑑𝑔 = 𝛼 log 𝑑𝑥 𝑑𝑥 𝛼2 𝑞 − 𝛼𝑝 )︃ pelo Teorema 4.1.1. Portanto, podemos supor que grau(𝑝) ≥ grau(𝑞) ≥ grau(𝐺). Utilizando o algoritmo de Euclides estendido, podemos encontrar 𝑟,𝑠 ∈ K[𝑥] tais que 𝑞𝑠 − 𝑝𝑟 = 𝐺 e grau(𝐺) ≤ grau(𝑝). Além disso, 𝑠 ̸= 0, uma vez que grau(𝑝) > grau(𝐺). Isto quer dizer que 𝑟 ̸= 0, pois grau(𝑞) > grau(𝐺) e, portanto 𝑟2 + 𝑠2 ̸= 0, como vimos acima. Pelo Teorema 4.1.1, temos que (︃ )︃ 𝑑 𝑠 + 𝛼𝑟 𝑝𝑠 − 𝛼2 𝑞𝑟 𝑑 + 𝛼 log 𝑔 = 2𝛼 arctgh 𝑑𝑥 𝛼 mdc(𝑝,𝑞) 𝑑𝑥 𝑠 − 𝛼𝑟 ′ (︂ )︂ Podemos aplicar o algoritmo recursivamente sobre o logaritmo restante. A terminação finita é garantida pelo fato de que máx(grau(𝑟), grau(𝑠)) < máx(grau(𝑝), grau(𝑞)). Conseguimos, portanto, o algoritmo de Rioboo que permite representar uma integral na forma (4.5) através de funções com coeficientes reais e sem polos. No caso em que 𝛼 = 𝐼, isto é possível pelo Corolário 4.1.1. Resta-nos incorporar este método ao algoritmo de integração de funções racionais que estudamos. Observe que os algoritmos de Rothstein-Trager, Lazard-Rioboo-Trager e Czichowski (o qual será visto no capítulo 5) nos fornecem a parte transcendental Capítulo 4. Integração Indefinida de Funções Racionais Reais 64 (logarítmica) da integral na forma ∑︁ ℎ= 𝜌 log(𝑆(𝜌,𝑥)) (4.6) 𝜌|𝑅(𝜌)=0 onde 𝑅 = ∑︁ 𝑟𝑗 𝑧 𝑗 ∈ K[𝑧] é livre de quadrados e 𝑆 = 𝑗 ∑︁ 𝑠𝑗𝑘 𝑧 𝑗 𝑥𝑘 ∈ K[𝑧,𝑥]. O 𝑗,𝑘 que nos resta para completar o algoritmo de Rioboo é converter a soma acima numa em que todos os termos conjugados em qualquer extensão 𝛼 conjugados na forma (4.5). Para o caso em que 𝛼 = 𝐼, separamos ℎ em duas parcelas: ∑︁ ℎ=𝑔+ 𝜌 log(𝑆(𝜌,𝑥)) (4.7) 𝜌∈R|𝑅(𝜌)=0 / com ∑︁ 𝑔= 𝜌 log(𝑆(𝜌,𝑥)). 𝜌∈R|𝑅(𝜌)=0 Em resumo, separamos ℎ em uma parte sobre as raízes reais e outra sobre as raízes contendo parte imaginária não nula. Observe que não ocorrem extensões complexas em 𝑔. Sejam 𝑢,𝑣 indeterminadas sobre K(𝑥). Calculamos os polinômios 𝑃,𝑄 ∈ K[𝑢,𝑣] tais que ∑︁ 𝑅(𝑢 + 𝐼𝑣) = 𝑟𝑗 (𝑢 + 𝐼𝑣)𝑗 = 𝑃 (𝑢,𝑣) + 𝐼𝑄(𝑢,𝑣), (4.8) 𝑗 e polinômios 𝐴,𝐵 ∈ K[𝑢,𝑣,𝑥] tais que 𝑆(𝑢 + 𝐼𝑣,𝑥) = ∑︁ 𝑠𝑗𝑘 (𝑢 + 𝐼𝑣)𝑗 𝑥𝑘 = 𝐴(𝑢,𝑣,𝑥) + 𝐼𝐵(𝑢,𝑣,𝑥). (4.9) 𝑗,𝑘 Como C = R(𝐼) é um espaço vetorial de dimensão 2 sobre R com base (1,𝐼), dado 𝛼 ∈ R temos que 𝑅(𝛼) = 0 se e só se 𝑃 (𝑎,𝑏) = 𝑄(𝑎,𝑏) = 0, onde 𝛼 = 𝑎 + 𝐼𝑏. Além disso, 𝛼 ∈ / R se e só se 𝑏 ̸= 0. Portanto, podemos reescrever (4.7) como ℎ=𝑔+ ∑︁ 𝑎,𝑏∈R,𝑏̸=0 𝑃 (𝑎,𝑏)=𝑄(𝑎,𝑏)=0 (𝑎 + 𝐼𝑏) log(𝑆(𝑎 + 𝐼𝑏,𝑥)) (4.10) 65 4.1. O Algoritmo de Rioboo para Funções Racionais Reais Seja 𝜎 o automorfismo de conjugação complexa de C, isto é, 𝜎(𝑎 + 𝑏𝐼) = 𝑎 − 𝑏𝐼, onde 𝑎,𝑏 ∈ R. Definimos 𝜎 : C[𝑥] → C[𝑥] por 𝜎 (︁∑︁ )︁ 𝑎𝑗 𝑥 𝑗 = ∑︁ 𝜎(𝑎𝑗 )𝑥𝑗 . (4.11) Sejam 𝑎,𝑏 ∈ R. Aplicando 𝜎 a (4.9), temos 𝐴(𝑎,𝑏,𝑥) − 𝐼𝐵(𝑎,𝑏,𝑥) = 𝜎(𝐴(𝑎,𝑏,𝑥) + 𝐼𝐵(𝑎,𝑏,𝑥)) = 𝜎(𝑆(𝑎 + 𝐼𝑏,𝑥)) = 𝑆(𝜎(𝑎 + 𝐼𝑏),𝑥) = 𝑆(𝑎 − 𝐼𝑏,𝑥). Aplicando 𝜎 a (4.8), temos 𝑃 (𝑎,𝑏) − 𝐼𝑄(𝑎,𝑏) = 𝜎(𝑃 (𝑎,𝑏) + 𝐼𝑄(𝑎,𝑏)) = 𝜎(𝑅(𝑎 + 𝐼𝑏)) = 𝑅(𝜎(𝑎 + 𝐼𝑏)) = 𝑅(𝑎 − 𝐼𝑏), o que significa que 𝑅(𝑎 + 𝐼𝑏) = 0 se e só se 𝑅(𝑎 − 𝐼𝑏) = 0. Portanto, para qualquer logaritmo correspondente ao par (𝑎,𝑏) aparecendo na soma (4.10) com 𝑏 = ̸ 0, o termo conjugado correspondente ao par (𝑎, − 𝑏) também deve aparecer, e é um par diferente, de modo que podemos reescrever (4.10) como ∑︁ ℎ=𝑔+ {(𝑎 + 𝐼𝑏) log(𝑆(𝑎 + 𝐼𝑏,𝑥)) + (𝑎 − 𝐼𝑏) log(𝑆(𝑎 − 𝐼𝑏,𝑥))} 𝑎,𝑏∈R,𝑏>0 𝑃 (𝑎,𝑏)=𝑄(𝑎,𝑏)=0 = 𝑔+ ∑︁ {𝑎(log(𝐴(𝑎,𝑏,𝑥) + 𝐼𝐵(𝑎,𝑏,𝑥)) + log(𝐴(𝑎,𝑏,𝑥) − 𝐼𝐵(𝑎,𝑏,𝑥))) 𝑎,𝑏∈R,𝑏>0 𝑃 (𝑎,𝑏)=𝑄(𝑎,𝑏)=0 + 𝐼𝑏(log(𝐴(𝑎,𝑏,𝑥) + 𝐼𝐵(𝑎,𝑏,𝑥)) − log(𝐴(𝑎,𝑏,𝑥) − 𝐼𝐵(𝑎,𝑏,𝑥)))}. Portanto, (︃ ℎ=𝑔+𝐺+ ∑︁ 𝑎,𝑏∈R,𝑏>0 𝑃 (𝑎,𝑏)=𝑄(𝑎,𝑏)=0 𝐴(𝑎,𝑏,𝑥) + 𝐼𝐵(𝑎,𝑏,𝑥) 𝐼𝑏 log 𝐴(𝑎,𝑏,𝑥) − 𝐼𝐵(𝑎,𝑏,𝑥) )︃ (4.12) Capítulo 4. Integração Indefinida de Funções Racionais Reais 66 onde 𝐺= 𝑎 log(𝐴(𝑎,𝑏,𝑥)2 + 𝐵(𝑎,𝑏,𝑥)2 ) ∑︁ 𝑎,𝑏∈R,𝑏>0 𝑃 (𝑎,𝑏)=𝑄(𝑎,𝑏)=0 é uma função real. Como os somandos complexos restantes em (4.12) estão na forma (4.5), podemos utilizar o Teorema 4.1.1 para convertê-los em funções reais. Observe que, uma vez que converter (4.5) em funções reais requer o cálculo do mdc entre 𝐴 e 𝐵, devemos, em tese, utilizar o algoritmo relativo ao Teorema 4.1.1 sobre uma extensão K(𝑎,𝑏) de K, onde 𝑃 (𝑎,𝑏) = 𝑄(𝑎,𝑏) = 0, o que siginfica que devemos resolver este sistema algébrico não linear. Porém, o resultado a seguir, devido a Rioboo, mostra que, quando logaritmos complexos a serem convertidos surgem da integração de uma função racional real, não é necessário resolver este sistema. Teorema 4.1.2 ([28]). Sejam K um subcorpo de R, 𝑟,𝑠 ∈ K[𝑥] com grau(𝑠) > 0, grau(𝑠) > grau(𝑟), 𝑠 livre de quadrados e mdc(𝑟,𝑠) = 1. Suponha que 𝑅 e 𝑆 de (4.6) sejam produzidos pelo algoritmo de Rothstein-Trager, Lazard-RiobooTrager ou Czichowski aplicado a 𝑟/𝑠 e sejam 𝑃,𝑄 dados por (4.8) e 𝐴,𝐵 dados por (4.9). Se 𝑎,𝑏 ∈ R satisfazem 𝑃 (𝑎,𝑏) = 𝑄(𝑎,𝑏) = 0 e 𝑏 ̸= 0, então mdc(𝐴(𝑎,𝑏,𝑥),𝐵(𝑎,𝑏,𝑥)) = 1 ∈ K(𝑎,𝑏)[𝑥]. Portanto, podemos realizar a conversão para arcos tangentes genericamente, isto é, aplicamos diretamente o algoritmo de Rioboo para a expressão (︃ 𝐴(𝑢,𝑣,𝑥) + 𝐼𝐵(𝑢,𝑣,𝑥) 𝐼 log 𝐴(𝑢,𝑣,𝑥) − 𝐼𝐵(𝑢,𝑣,𝑥) )︃ onde 𝑢 e 𝑣 são indeterminadas independentes, obtendo uma função real 𝜑(𝑢,𝑣,𝑥) (a combinação de arcos tangentes com coeficientes reais). Podemos reescrever (4.12) como ∑︁ ℎ=𝑔+𝐺+ 𝑏𝜑(𝑎,𝑏,𝑥) 𝑎,𝑏∈R,𝑏>0 𝑃 (𝑎,𝑏)=𝑄(𝑎,𝑏)=0 onde o Teorema 4.1.2 garante que 𝜑(𝑢,𝑣,𝑥) não possui divisões por zero quando substituímos 𝑢,𝑣 pelas várias soluções 𝑎 e 𝑏 > 0 em R para o sistema 𝑃 (𝑢,𝑣) = 𝑄(𝑢,𝑣) = 0. Ao representarmos a resposta em termos das somas formais, não precisamos de fato resolver este sistema, ou introduzir números algébricos. Porém, 67 4.1. O Algoritmo de Rioboo para Funções Racionais Reais na prática, sempre que as raízes reais de 𝑃 (𝑢,𝑣) = 𝑄(𝑢,𝑣) = 0 podem ser computadas de maneira eficiente (por exemplo, se forem todas números racionais), então pode ser mais eficiente calcular primeiro as raízes e só depois evocar o algoritmo do Teorema 4.1.1, ao invés de realizar a redução com parâmetros genéricos [2, p. 68]. Para o caso em que 𝛼 é uma extensão real, a mesma discussão pode ser aplicada para a detecção de logaritmos que sejam conjugados em 𝛼, de modo que obtemos (︃ ∑︁ ℎ=𝑔+𝐺+ 𝑎,𝑏∈K𝛼 ,𝑏>0 𝑃 (𝑎,𝑏)=𝑄(𝑎,𝑏)=0 𝐴(𝑎,𝑏,𝑥) + 𝛼𝐵(𝑎,𝑏,𝑥) 𝛼𝑏 log 𝐴(𝑎,𝑏,𝑥) − 𝛼𝐵(𝑎,𝑏,𝑥) )︃ (4.13) onde ∑︁ 𝐺= 𝑎 log(𝐴(𝑎,𝑏,𝑥)2 − 𝛼2 𝐵(𝑎,𝑏,𝑥)2 ), 𝑎,𝑏∈K𝛼 ,𝑏>0 𝑃 (𝑎,𝑏)=𝑄(𝑎,𝑏)=0 𝑔 é o restante da expressão da integral e K𝛼 ⊂ R é uma extensão de K que não contém 𝛼. Todavia, não estamos interessados agora em retirar a extensão algébrica 𝛼 da expressão da integral, como no caso 𝛼 = 𝐼, mas em simplificar a representação dos logaritmos. Note que se 𝐴(𝑎,𝑏,𝑥) - 𝐵(𝑎,𝑏,𝑥) então o algoritmo de Rioboo produzirá pelo menos dois termos. Assim, em geral, não se ganha muito em relação à representação original da integral, uma vez que o par de logaritmos originais já possuía representação com coeficientes reais e contínua. Por outro lado, se 𝐴(𝑎,𝑏,𝑥) | 𝐵(𝑎,𝑏,𝑥), só precisamos utilizar o Lema 4.1.1 para transformar o par de logaritmos em uma única função arco tangente hiperbólico. Nas subseções 5.6.2 e 5.8.2, fornecemos pseudocódigos, juntamente com códigos para implementação no Maxima do algoritmo de Rioboo e de um algoritmo para detecção de logaritmos conjugados, conforme discutido nesta seção. Nas subseção 5.6.1, fornecemos um código para implementação no Maxima do algoritmo clássico para obtenção de arcos tangentes hiperbólicos e simples, conforme discutido nesta seção. 4.1.1 Exemplos Exemplo 4.1.1 (gerado com dados obtidos pelos códigos 5.6.1 e 5.6.2, algoritmos clássico e de Rioboo para obtenção de arcos tangentes). Consideremos o problema Capítulo 4. Integração Indefinida de Funções Racionais Reais de calcular ∫︁ −3/4 −5/4 6𝑥5 + 12𝑥4 + 8𝑥3 − 12𝑥2 − 8𝑥 , 𝑥6 + 2𝑥5 + 2𝑥4 − 2𝑥3 − 4𝑥2 + 2 68 (4.14) onde o integrando 𝑓 pode ser provado como uma função contínua sobre os reais e negativa sobre o intervalo [−5/4, − 3/4], donde, portanto, a integral deve ser um número real negativo neste intervalo (vide figura 4.1). Como vimos no Exemplo Figura 4.1: Gráfico de 𝑓 próximo do intervalo [−5/4, − 3/4]. 3.4.2, a integral indefinida de f é ∫︁ 6𝑥5 + 12𝑥4 + 8𝑥3 − 12𝑥2 − 8𝑥 = (1 + 𝐼) log(𝑥3 + (1 + 𝐼)𝑥2 − 1 − 𝐼) 𝑥6 + 2𝑥5 + 2𝑥4 − 2𝑥3 − 4𝑥2 + 2 + (1 − 𝐼) log(𝑥3 + (1 − 𝐼)𝑥2 − 1 + 𝐼) (4.15) 69 4.1. O Algoritmo de Rioboo para Funções Racionais Reais Aplicando o Teorema Fundamental do Cálculo (incorretamente) à equação 4.15 para 𝑥 variando sobre [−5/4, − 3/4], temos ∫︁ −3/4 −5/4 −55 − 28𝐼 −55 + 28𝐼 𝑓 = (1 + 𝐼) log + (1 − 𝐼) log 64 64 )︂ (︂ )︂)︂ (︂ (︂ −89 + 36𝐼 −89 − 36𝐼 + (1 − 𝐼) log − (1 + 𝐼) log 64 64 ≈ 9,97. (︂ )︂ (︂ )︂ o que é inconsistente com as condições do integrando. Portanto, procuramos por uma integral que possa ser expressa apenas com funções reais. Utilizando diretamente o Lema 4.1.1, reescrevemos abaixo os logaritmos complexos de ∫ 𝑓 com funções arcos tangentes. A seguir, escrevemos 𝑓 ∼ 𝑔 se 𝑑𝑓 /𝑑𝑥 = 𝑑𝑔/𝑑𝑥: ∫︁ 𝑓 = (1 + 𝐼) log(𝑥3 + (1 + 𝐼)𝑥2 − 1 − 𝐼) + (1 − 𝐼) log(𝑥3 + (1 − 𝐼)𝑥2 − 1 + 𝐼) )︃ (︃ 𝑥3 + 𝑥2 − 1 + 𝐼(𝑥2 − 1) = log((𝑥 + 𝑥 − 1) + (𝑥 − 1) ) + 𝐼 log 3 𝑥 + 𝑥2 − 1 − 𝐼(𝑥2 − 1) (︃ )︃ 𝑥 3 + 𝑥2 − 1 3 2 2 2 2 ∼ log((𝑥 + 𝑥 − 1) + (𝑥 − 1) ) + 2 arctg = 𝐹1 (𝑥). (4.16) 𝑥2 − 1 3 2 2 2 2 Portanto, conseguimos expressar ∫ 𝑓 através de uma função real. Todavia, ao aplicarmos o Teorema Fundamental do Cálculo sobre esta nova função no intervalo em questão, temos novamente um valor incorreto (aproximadamente 3.68). Isto porque, claramente, o novo integrando possui descontinuidades em ±1. Dessa forma, ao invés de fazermos uso direto do Lema 4.1.1, utilizamos o Teorema 4.1.1. Por (4.16), temos ∫︁ (︃ )︃ 𝑥3 + 𝑥2 − 1 + 𝐼(𝑥2 − 1) . 𝑓 = log((𝑥 + 𝑥 − 1) + (𝑥 − 1) ) + 𝐼 log 3 𝑥 + 𝑥2 − 1 − 𝐼(𝑥2 − 1) 3 2 2 2 2 Aplicando o algoritmo de Rioboo, relativo ao Teorema 4.1.1 ao par 𝐴 = 𝑥3 +𝑥2 −1 e 𝐵 = 𝑥2 − 1, temos Capítulo 4. Integração Indefinida de Funções Racionais Reais Figura 4.2: Gráfico da forma descontínua de ∫ 𝑓 = 𝐹1 (𝑥). 𝐴 3 2 𝑥 +𝑥 −1 𝑥2 + 𝑥 + 1 𝑥+1 𝐵 2 𝐶 𝑥 −1 𝑥 1 𝑥 1 𝐷 2 𝑥 +𝑥+1 𝑥+1 (𝐴𝐷 + 𝐵𝐶)/𝐺 𝐺 −1 −1 5 −𝑥 − 2𝑥4 − 3𝑥3 + 2𝑥 + 1 −𝑥3 − 2𝑥2 − 3𝑥 − 1 e a integral se torna ∫︁ 𝑓 = log((𝑥3 + 𝑥2 −1)2 + (𝑥2 − 1)2 ) − 2 arctg(𝑥5 + 2𝑥4 + 3𝑥3 − 2𝑥 − 1) − 2 arctg(𝑥3 + 2𝑥2 + 3𝑥 + 1) + 2 arctg(𝑥 + 1) = 𝐹2 (𝑥). 70 71 4.1. O Algoritmo de Rioboo para Funções Racionais Reais Podemos, agora, calcular corretamente o valor de ∫ 𝑓 sobre [−5/4, − 3/4] através do Teorema Fundamental do Cálculo: ∫︁ −3/4 −5/4 3809 35 379 1 𝑓 = log + 2 arctg + 2 arctg + 2 arctg 4096 64 1024 4 (︂ (︂ )︂ (︂ )︂ (︂ )︂ (︂ )︂)︂ 9217 101 2589 1 − log + 2 arctg + 2 arctg − 2 arctg 4096 64 1024 4 ≈ −2,59. (︂ )︂ (︂ )︂ (︂ )︂ (︂ )︂ A figura 4.4 mostra comparação entre os gráficos de ∫ 𝑓 em forma descontínua e contínua. Observe que a diferença entre a integral indefinida fornecida pelo Lema 4.1.1 e a que acabamos de obter pelo Teorema 4.1.1 é apenas uma adição de constantes por intervalos as quais ocorrem nos pontos de descontinuidade da forma descontínua de ∫ 𝑓 e valem 2𝜋. De maneira geral, dado um par 𝐴(𝑎,𝑏,𝑥), 𝐵(𝑎,𝑏,𝑥) a diferença por intervalos entre o arco tangente obtido pelo Lema 4.1.1 e a combinação de arcos tangentes obtida pelo Teorema 4.1.1, se houver, é de 2𝜋 e ocorre em cada raiz real de 𝐵(𝑎,𝑏,𝑥). Na expressão final da integral, portanto, os polos de 𝐵(𝑎,𝑏,𝑥) geram uma diferença de 2𝑏𝜋 cada. (O exemplo 4.1.3 mostra um caso em que as duas formas da integral para um par 𝐴(𝑎,𝑏,𝑥),𝐵(𝑎,𝑏,𝑥) são contínuas). Exemplo 4.1.2 (gerado com dados obtidos pelo código 5.8.2, identificação de logaritmos complexos com conversão para funções reais). Para a integral (4.15), temos que 𝑅(𝑧) = 𝑧 2 − 2𝑧 + 2 ∈ Q[𝑧], 𝑆(𝑧,𝑥) = 𝑥3 + 𝑧𝑥2 − 𝑧 ∈ Q[𝑧,𝑥]. Além disso, 1. 𝑅(𝑢 + 𝐼𝑣) = (𝑢 + 𝐼𝑣)2 − 2(𝑢 + 𝐼𝑣) + 2 = 𝑢2 − 2𝑢 + 2 − 𝑣 2 + 𝐼(2𝑢𝑣 − 2𝑣), de modo que 𝑃 = 𝑢2 − 2𝑢 + 2 − 𝑣 2 e 𝑄 = (2𝑢𝑣 − 2𝑣). 2. 𝑆(𝑢 + 𝐼𝑣,𝑥) = 𝑥3 + 2(𝑢 + 𝐼𝑣)𝑥2 − (𝑢 + 𝐼𝑣) = 𝑥3 + 𝑢𝑥2 − 𝑢 + 𝐼(𝑣𝑥2 − 𝑣), de modo que 𝐴 = 𝑥3 + 𝑢𝑥2 − 𝑢 e 𝐵 = 𝑣𝑥2 − 𝑣. 3. Encontrar as soluções (𝑎,𝑏) para 𝑃 (𝑎,𝑏) = 𝑄(𝑎,𝑏) = 0 é o mesmo que Capítulo 4. Integração Indefinida de Funções Racionais Reais 72 Figura 4.3: Gráfico de ∫ 𝑓 = 𝐹2 (𝑥). resolver 𝑅(𝑎 + 𝐼𝑏) = 0 para 𝑎,𝑏 > 0 ∈ R, isto é, encontrar as raízes de 𝑅(𝑧) com parte imaginária positiva, donde sabemos que a única solução é (𝑎,𝑏) = (1,1). De outro modo, podemos adotar o seguinte procedimento: calculamos 𝐻 = res𝑣 (𝑃,𝑄) = 4(𝑢 − 1)2 (𝑢2 − 2𝑢 + 2). Observe que, para cada raiz 𝑎 de 𝐻, o sistema 𝑃 (𝑎,𝑣) = 𝑄(𝑎,𝑣) = 0 possui solução em 𝑣, pois, nesse caso, 𝐺 = mdc(𝑃 (𝑎,𝑣),𝑄(𝑎,𝑣)) é não trivial (resolver o sistema gerado pela raiz 𝑎 é o mesmo que achar as raízes de 𝐺). Por outro lado, apenas as raízes reais de 𝐻 nos importam, sendo a única 𝑎 = 1. Dessa forma, 𝑃 (1,𝑣) = 𝑣 2 − 1 e 𝑄(1,𝑣) = 0, donde 𝐺 = mdc(𝑃 (1,𝑣),𝑄(1,𝑣)) = 𝑣 2 − 1. As soluções reais de 𝐺 são ±1, sendo 𝑏 = 1 a única relevante. Logo, a única solução para o sistema é (𝑎,𝑏) = (1,1). 4. 𝐴(1,1,𝑥) = 𝑥3 +𝑥2 −1, 𝐵 = (1,1,𝑥) = 𝑥2 −1 e LogToAtan(𝑥3 +𝑥2 −1,𝑥2 −1) 73 4.1. O Algoritmo de Rioboo para Funções Racionais Reais Figura 4.4: Comparação das formas contínua e descontínua de ∫ 𝑓 . devolve −2 arctg(𝑥5 + 2𝑥4 + 3𝑥3 − 2𝑥 − 1) − 2 arctg(𝑥3 + 2𝑥2 + 3𝑥 + 1) + 2 arctg(𝑥 + 1) como visto no Exemplo 4.1.1. Poderíamos ter optado por obter uma solução formal, isto é, sem calcular efetivamente as soluções do sistema 𝑃 (𝑢,𝑣) = 𝑄(𝑢,𝑣) = 0, deixando a fórmula em termos de destas soluções, as quais seriam obtidas no passo 3. Em outras palavras, chamaríamos diretamente LogToAtan(𝑥3 + 𝑢𝑥2 − 𝑢,𝑣𝑥2 − 𝑣), obtendo (︃ 𝑥5 2𝑢𝑥4 (𝑣 2 + 𝑢2 + 1)𝑥3 (𝑣 2 + 𝑢2 )𝑥 𝑢 𝜑(𝑢,𝑣,𝑥) = −2 arctg + + − − 𝑣 𝑣 𝑣 𝑣 𝑣 (︃ )︃ (︂ )︂ 𝑥3 2𝑢𝑥2 (𝑣 2 + 𝑢2 + 1)𝑥 𝑢 𝑥 𝑢 − 2 arctg + + + + 2 arctg + 𝑣 𝑣 𝑣 𝑣 𝑣 𝑣 )︃ Capítulo 4. Integração Indefinida de Funções Racionais Reais 74 A integral seria retornada formalmente como ∫︁ 𝑓= ∑︁ 𝑎 log((𝑥3 + 𝑎𝑥2 − 𝑎)2 + (𝑏𝑥2 − 𝑏)2 ) + 𝑏𝜑(𝑎,𝑏,𝑥) 𝑎,𝑏∈R,𝑏>0 𝑎2 −2𝑎+2−𝑏2 =2𝑎𝑏−2𝑏=0 que é uma função com coeficientes reais. Fazendo a substituição 𝑎 = 1 e 𝑏 = 1 no resultado acima, temos a mesma integral que antes. Observe que a solução formal tende a ter uma representação maior que a solução explícita quando as soluções encontradas para o sistema 𝑃 = 𝑄 = 0 são todas racionais. Porém, se alguma solução envolve radicais, então o número de símbolos estranhos a Q envolvidos, tanto durante os cálculos, quanto na representação da solução final explícita, pode ser maior do que se representarmos a solução formalmente, o que deve ser levado em consideração ao se observar a eficiência do algoritmo em sua implementação. Exemplo 4.1.3 (gerado com dados obtidos pelos códigos 5.6.1, 5.6.2 e 5.8.2). Mostramos agora um exemplo em que o algoritmo de Rioboo não fornece uma solução significativamente melhor para a integração definida que o algoritmo clássico. Considere a função 𝑥4 + 3𝑥2 𝑓= 6 𝑥 + 𝑥4 + 2𝑥2 + 1 Integrando-se esta função utilizando os algoritmos de Rioboo e clássico temos, respectivamente, ∫︁ (︃ 𝑥3 𝑓 = − arctg(𝑥5 + 𝑥) + arctg(𝑥3 ) + arctg(𝑥) = arctg 2 𝑥 +1 )︃ Observe que a resposta obtida pelo algoritmo clássico não possui polos nos reais. Deste modo, esta forma da integral também é contínua sobre os reais e pode ser corretamente utilizada para a integração definida através do Teorema Fundamental do Cálculo. Este exemplo motiva a definir um critério para saber quando o algoritmo de Rioboo se faz necessário. A saber, mantendo a notação, devemos utilizar este algoritmo para a integração definida apenas para cada par 𝐴,𝐵 em que 𝐵(𝑎,𝑏,𝑥) possui raízes reais. Dessa forma, é vantajoso que se utilize um misto entre o algoritmo de Rioboo e o clássico para o caso da integração definida. 75 4.1. O Algoritmo de Rioboo para Funções Racionais Reais Exemplo 4.1.4 (gerado com dados obtidos pelos códigos 5.5.1, 5.6.1, 5.6.2 e 5.8.2). Este exemplo mostra o quanto é importante recorrer a alternativas diferentes do método de Bernoulli para a integração de funções racionais. Considere 𝐴 = 𝑥2 − 2𝑥, 𝐷 = 𝑥4 + 𝑥2 − 2𝑥 + 1 e 𝑓 = 𝐴/𝐷. O conjunto das raízes de 𝐷 é √ √ √ √ {︃ }︃ −𝐼 − 4𝐼 − 1 −𝐼 + 4𝐼 − 1 𝐼 − 4𝐼 − 1 𝐼 + 4𝐼 − 1 𝜌𝐷 = , , , 2 2 2 2 e sua fatoração em fatores irredutíveis sobre os reais é ⎞ √ √︁√ √ 17 − 1 2 17 + 1 + 17 + 1 ⎠· √ 𝐷 = ⎝𝑥2 + 𝑥+ 4 2 √︁√ ⎛ ⎞ √ √︁√ √ 17 − 1 2 17 + 1 − 17 − 1 ⎝𝑥2 − ⎠ √ 𝑥− 4 2 ⎛ √︁√ = (𝑥2 + 𝑏𝑥 + 𝑐1 )(𝑥2 − 𝑏𝑥 + 𝑐2 ). A versão complexa do método de Bernoulli retorna, formalmente, ∫︁ 𝑓= ∑︁ 𝛼∈𝜌𝐷 𝐴(𝛼) log(𝑥 − 𝛼), 𝐷′ (𝛼) donde obtemos a fórmula explícita para ∫ 𝑓 substituíndo 𝛼 pelos elementos de 𝜌𝐷 . Os algoritmos para a parte logarítmica que estudamos, porém, fornecem o seguinte resultado: ∫︁ 𝑓= 𝐼 𝐼 log(𝑥2 + 𝐼𝑥 − 𝐼) − log(𝑥2 − 𝐼𝑥 + 𝐼). 2 2 Percebemos facilmente a relativa simplicidade deste resultado diante do resultado explícito que seria fornecido pelo método de Bernoulli. Capítulo 4. Integração Indefinida de Funções Racionais Reais 76 Agora, a versão real do método de Bernoulli retorna ∫︁ )︃ (︃ 𝐵1 2𝐶1 − 𝑏𝐵1 2𝑥 + 𝑏 √ 𝑓= log(𝑥2 + 𝑏𝑥 + 𝑐1 ) + √ arctg 2 4𝑐1 − 𝑏2 4𝑐1 − 𝑏2 (︃ )︃ 𝐵2 2𝐶 + 𝑏𝐵 2𝑥 − 𝑏 2 2 + log(𝑥2 − 𝑏𝑥 + 𝑐2 ) + √ arctg √ . 2 4𝑐2 − 𝑏2 4𝑐2 − 𝑏2 É possível mostrar que a parte logarítmica na expressão acima equivale a 0, sobrando apenas arcos tangentes. Todavia, a parte restante envolve extensões que são obtidas a partir de fórmulas quárticas, enquanto que os algoritmos clássico e de Rioboo fornecem, respectivamente, ∫︁ (︃ 𝑥2 𝑓 = arctg 𝑥−1 )︃ ∼ − arctg(𝑥3 + 𝑥2 + 𝑥 − 1) + arctg(𝑥 + 1) Este ilustra que o algoritmo de Rioboo consegue conciliar simplicidade de fórmula com continuidade. O método de Bernoulli costuma falhar no primeiro quesito, enquanto que o método clássico costuma falhar no segundo. Exemplo 4.1.5 (gerado com dados obtidos pelos códigos 5.6.3 e 5.8.1). Um exemplo de conversão para arcos tangentes hiperbólicos. Considere o par 𝐴 = √ 𝑥3 + 𝑥2 − 1, 𝐵 = 𝑥2 − 1 e a extensão 𝛼 = 2. O algoritmo de Rioboo generalizado retorna √ 2 log(𝑥3 + 𝑥2 − 1 + √ (︃ (︃ = −2 2 arctgh √ 2(𝑥2 − 1)) − √ 𝑥5 + 2𝑥4 + 𝑥 − 1 √ 2 2 log(𝑥3 + 𝑥2 − 1 − )︃ (︃ + arctgh √ 2(𝑥2 − 1)) = 𝑥3 + 2𝑥2 + 1 √ 2 )︃ 𝑥+1 − arctgh √ 2 (︂ )︂)︃ Observe que a forma deste resultado é idêntica àquela obtida pelo Exemplo 4.1.1, a menos da extensão algébrica em questão. Observe ainda que não houve ganho algum em termos de representação, pelo contrário: a tornamos maior e fizemos com que mais polinômios distintos surgissem. Por outro lado, se 𝐴 = (𝑥3 − 1)2 , 𝐵 = 𝑥2 + 𝑥 + 1 e 𝛼 = √ 2 log((𝑥3 − 1)2 + √ = 2 2 arctgh (︃ √ 2(𝑥2 + 𝑥 + 1)) − )︃ 𝑥4 − 𝑥3 − 𝑥 + 1 √ , 2 √ √ 2, então 𝐵 | 𝐴 e, assim, temos 2 log((𝑥3 − 1)2 − √ 2 2(𝑥 + 𝑥 + 1)) = 77 4.1. O Algoritmo de Rioboo para Funções Racionais Reais donde diminuímos a representação da integral. Note que, de fato, 𝛼 pode pertencer ao corpo de coeficientes do integrando. O caso clássico é log(𝑥 + 1) log(𝑥 − 1) − = arctgh(𝑥) 2 2 Observe que mesmo transformar dois termos logarítmicos em apenas um arco tangente hiperbólico nem sempre é desejável, pois a última forma pode ter representação muito mais extensa. A expressão a seguir mostra isso quando temos, por exemplo, um primo inteiro positivo 𝑝 suficientemente grande: log((𝑥𝑝 − 1) + (𝑥 − 1)) log((𝑥𝑝 − 1) − (𝑥 − 1)) − = arctgh(𝑥𝑝−1 + 𝑥𝑝−2 + · · · + 𝑥 + 1) 2 2 Exemplo 4.1.6 (extraído de [14]). Finalmente, um exemplo em que os algoritmos de integração de funções racionais podem ser utilizados para integrar algumas 3 funções elementares. Seja 𝑓 (𝑥) = . Calculemos 5 − 4 cos(𝑥) ∫︁ 𝑓 (𝑥) 𝑑𝑥 = ∫︁ 3 𝑑𝑥 5 − 4 cos(𝑥) Aplicamos a mudança de variável 𝑢 = tg(𝑥/2), isto é 𝑥 = 2 arctg(𝑢) e, portanto, 𝑑𝑥 = 2 𝑑𝑢/(1 + 𝑢2 ). Temos ∫︁ 6 𝑑𝑢 (1 + − 4 cos(2 arctg(𝑢))) ∫︁ ∫︁ 6 6 = 𝑑𝑢 = 𝑑𝑢 (1 + 𝑢2 )5 − 4(1 − 𝑢2 ) 1 + 9𝑢2 (︂ )︂ (︂ )︂ (︂ (︂ )︂)︂ 𝐼 𝐼 𝑥 = 𝐼 log 𝑢 + − 𝐼 log 𝑢 − = 2 arctg(3𝑢) = 2 arctg 3 tg 3 3 2 𝑓 (𝑥) 𝑑𝑥 = ∫︁ 𝑢2 )(5 De modo geral integrandos que sejam racionais em sen(𝑥) e cos(𝑥) podem ser transformados em funções racionais em 𝑢 = tg(𝑥/2), de modo que os algoritmos de integração seguidos do algoritmo de Rioboo possam ser utilizados. Porém, diferente do caso puramente racional, o algoritmo de Rioboo pode gerar novas singularidades. É o caso deste exemplo. A função 𝑓 tem, aqui, singularidades 𝜋 + 2𝑘𝜋 para todo 𝑘 inteiro. A fim de obter uma integral contínua, é necessário aplicar uma transformação de retificação. A transformação que utilizamos aqui Capítulo 4. Integração Indefinida de Funções Racionais Reais 78 leva 𝐹1 = arctg(𝑎 tg(𝑥/2) + 𝑏) em: (︃ )︃ 𝑥 2𝑎𝑏 cos(𝑥) − (1 + 𝑏2 − 𝑎2 ) sen(𝑥) 𝐹2 = + arctg , 2 (1 + 𝑎)2 + 𝑏2 + (1 + 𝑏2 − 𝑎2 ) cos(𝑥) + 2𝑎𝑏 sen(𝑥) de modo que 𝑑𝐹1 /𝑑𝑥 = 𝑑𝐹2 /𝑑𝑥, isto é, 𝐹1 ∼ 𝐹2 . Porém, 𝐹1 claramente possui singularidades, enquanto que 𝐹2 , não, sendo contínua em R [14]. Segundo esta transformação, temos 𝑥 𝐹1 = 2 arctg 3 tg 2 (︂ (︂ )︂)︂ (︃ sen(𝑥) ∼ 𝑥 + 2 arctg 1 − cos(𝑥) )︃ = 𝐹2 , de modo que 𝐹2 é uma integral contínua para 𝑓 . Figura 4.5: Comparação das formas contínua e descontínua de ∫ 𝑓 . Capítulo 5 Pseudocódigos e Códigos em Maxima Este capítulo é dedicado a fornecer pseudocódigos e códigos para implementação no CAS Maxima dos algoritmos estudados neste trabalho. Com os presentes códigos, é possível programar um integrador de funções racionais completo, capaz de utilizar os algoritmos: de Hermite e sua variantes; Horowitz-Ostrogradsky; uma versão do algoritmo de Bernoulli aplicada a integrandos próprios, reduzidos e com denominador livre de quadrados; Rothstein-Trager; Lazard-Rioboo-Trager; Czichowski e Rioboo. É possível ainda realizar integrações explícitas, formais ou mistas: no primeiro caso, sempre que possível, são calculadas efetivamente todas as extensões algébricas necessárias para a representação da integral; no segundo caso, evitamos o cálculo efetivo de extensões algébricas, mas utilizamos expressões formais em termos das mesmas nas integrais e, no último caso, é possível escolher qual o nível de detalhamento que se deseja dar para a fórmula da integral em termos de suas extensões (podemos, por exemplo, escolher exibir, no máximo, extensões que possam ser obtidas pela fórmula de Bhaskara e deixar que dependam de fórmulas cúbicas e quárticas implícitas). Finalmente, para funções racionais reais, será possível escolher a expressão da parte transcendental apenas em termos logarítmicos, ou com conversão de logaritmos conjugados com parte imaginária em funções arco tangente, podendo os arcos tangentes ser encontrados pelo método de Bernoulli, clássico, ou Rioboo. Também fornecemos é códigos Capítulo 5. Pseudocódigos e Códigos em Maxima 80 para converter certos pares logaritmos para funções arco tangente hiperbólico. Exibiremos ainda pseudocódigos e códigos para alguns algoritmos complementares, necessários para a implementação dos algoritmos principais. A saber: (pseudo)divisão polinomial; o algoritmo de Euclides e variantes; decomposição em frações parciais; o algoritmo das subresultantes; fatorações livres de quadrados. Além destes serão fornecidos alguns códigos para simplificar alguns comandos rotineiros dentro dos códigos dos algoritmos acima. Quando um código estiver acompanhado de um pseudocódigo, o primeiro terá sido elaborado com base no segundo. Ainda assim, junto a cada código, alguns comentários serão lançados para seu melhor entendimento. 5.1 5.1.1 Funções para Manipulação de Polinômios Group Reescreve, se possível, a expressão 𝐴 de modo que se torne um polinômio na variável 𝑥, onde cada potência de 𝑥 ocorre apenas uma vez. Além disso, simplifica os coeficientes de cada termo em 𝑥. Código: Group(A,x):= block([a,l,simp,Ans], algebraic:true, simp:0, if A=0 then( Ans:0, algebraic:false, return(Ans) ), a:expandwrt(fullratsimp(A,x),x), l:hipow(a,x), for i:0 thru l do( simp:simp+fullratsimp(coeff(a,x,i))*x^i ), Ans:simp, algebraic:false, return(Ans) )$ 81 5.1.2 5.1. Funções para Manipulação de Polinômios LC O coeficiente líder do polinômio 𝐴 na variável 𝑥. Código: LC(A,x):= block([a,Ans], algebraic:true, if A=0 then( Ans:0, algebraic:false, return(Ans) ), a:Group(A,x), a:coeff(a,x,hipow(a,x)), Ans:a, algebraic:false, return(Ans) )$ 5.1.3 Mon O polinômio mônico de 𝐴 na varável 𝑥. Obtido pela divisão de 𝐴 por seu termo líder em 𝑥. Código: Mon(A,x):= block([a,Ans], algebraic:true, if A=0 then( Ans:0, algebraic:false, return(Ans) ), a:Group(A/LC(A,x),x), Ans:a, algebraic:false, return(Ans) )$ Capítulo 5. Pseudocódigos e Códigos em Maxima 5.1.4 82 Parts Retorna polinômios 𝐴 e 𝐵 tais que 𝑃 (𝑢 + 𝐼𝑣) = 𝐴(𝑢,𝑣) + 𝐼𝐵(𝑢,𝑣), com os coeficientes de 𝐴 e 𝐵 pertencentes ao mesmo domínio dos coeficientes de 𝑃 . Código: Parts(P,z):= block([u,v,p,Ans], algebraic:true, p:subst(u+%i*v,z,P), Ans:[realpart(p),imagpart(p)], algebraic:false, return(Ans) )$ 5.1.5 RPoly Gera polinômios inteiros aleatórios. 𝑑𝑒𝑔 é o grau desejado, 𝑙𝑖𝑚 é o limitante para o valor absoluto dos coeficientes e 𝑑𝑜𝑚 é o domínio: naturais ou inteiros. Código: RPoly(x,deg,lim,dom):= block([j,s,Poly,Ans], algebraic:true, Poly:0, for j:0 thru deg do( s:1, if random(2)=0 and dom="integers" then s:-1, Poly:Poly+s*random(lim+1)*x^j ), if hipow(Poly,x)<deg then Poly:Poly+x^deg, if Poly=0 then( Ans:1, algebraic:false, return(Ans) ), Ans:Poly, algebraic:false, return(Ans) )$ 83 5.2. MDC de Polinômios e Resultantes 5.2 5.2.1 MDC de Polinômios e Resultantes PDiv Retorna o quociente e o resto da divisão de 𝐴 por 𝐵 visto como polinômios em 𝑥. Pseudocódigo: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: função PolyDivide(𝐴,𝐵) descrição: Dado um corpo K e 𝐴,𝐵 ∈ K[𝑥] com 𝐵 ̸= 0, retorna 𝑄,𝑅 ∈ K[𝑥] tais que 𝐴 = 𝐵𝑄 + 𝑅, com 𝑅 = 0 ou grau(𝑅) < grau(𝐵). 𝑄←0 𝑅←𝐴 enquanto 𝑅 ̸= 0 e 𝛿 ← grau(𝑅) − grau(𝐵) ≥ 0 faça cl(𝑅) 𝛿 𝑇 ← 𝑥 cl(𝐵) 𝑄←𝑄+𝑇 𝑅 ← 𝑅 − 𝐵𝑇 fim enquanto devolve (𝑄,𝑅) fim função Código: PDiv(A,B,x):= block([b,q,r,t,delta,lcB,degB,Ans], algebraic:true, q:0, r:Group(A,x), b:Group(B,x), degB:hipow(b,x), delta:hipow(r,x)-degB, lcB:LC(b,x), while r#0 and delta>=0 do( t:fullratsimp(LC(r,x)/lcB)*x^delta, q:q+t, r:r-b*t, q:Group(q,x), r:Group(r,x), delta:hipow(r,x)-degB ), Ans:[q,r], algebraic:false, return(Ans) )$ Capítulo 5. Pseudocódigos e Códigos em Maxima 5.2.2 84 PPsDiv Retorna o pseudoquociente e o pseudoresto da divisão de 𝐴 por 𝐵 visto como polinômios em 𝑥. Pseudocódigo: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: função PolyPseudoDivide(𝐴,𝐵) descrição: Dado um domínio de integridade 𝐷 e 𝐴,𝐵 ∈ 𝐷[𝑥] com 𝐵 ̸= 0, retorna pquo(𝐴,𝐵) e prem(𝐴,𝐵). 𝑏 ← cl(𝐵) 𝑁 ← grau(𝑅) − grau(𝐵) + 1 𝑄←0 𝑅←𝐴 enquanto 𝑅 ̸= 0 e 𝛿 ← grau(𝑅) − grau(𝐵) ≥ 0 faça 𝑇 ← cl(𝑅)𝑥𝛿 𝑁 ←𝑁 −1 𝑄 ← 𝑏𝑄 + 𝑇 𝑅 ← 𝑏𝑅 − 𝐵𝑇 fim enquanto devolve (𝑏𝑁 𝑄,𝑏𝑁 𝑅) fim função Código: PPsDiv(A,B,x):= block([b,q,r,t,delta,lcB,degB,N], algebraic:true, q:0, r:Group(A,x), b:Group(B,x), degB:hipow(b,x), delta:max(hipow(r,x)-degB,-1), lcB:LC(b,x), N:delta+1, while r#0 and delta>=0 do( t:LC(r,x)*x^delta, N:N-1, q:lcB*q+t, r:lcB*r-b*t, q:Group(q,x), r:Group(r,x), delta:hipow(r,x)-degB ), q:Group(lcB^N*q,x), r:Group(lcB^N*r,x), Ans:[q,r], algebraic:false, return(Ans) )$ 85 5.2. MDC de Polinômios e Resultantes 5.2.3 GCD Cálculo de mdc de polinômios utilizando a SRP primitiva. Há a possibilidade de se realizar os cálculos módulo 𝑃 (𝑧). Isto se mostrará útil especialmente no algoritmo de Rothstein-Trager. Pseudocódigo: 1: 2: 3: 4: 5: 6: 7: 8: 9: função Euclidean(𝑎,𝑏) descrição: Dado um domínio euclidiano 𝐷 e 𝑎,𝑏 ∈ 𝐷, retorna mdc(𝑎,𝑏). enquanto 𝑏 ̸= 0 faça (𝑞,𝑟) ← EuclideanDivision(𝑎,𝑏) ◁ 𝑎 = 𝑏𝑞 + 𝑟 𝑎←𝑏 𝑏←𝑟 fim enquanto devolve 𝑎 fim função Código: GCD(A,B,x,P,z):= block([a,b,q,r,Ans], algebraic:true, a:Group(A,x), b:Group(B,x), if P#0 then( a:PPsDiv(a,P,z)[2], b:PPsDiv(b,P,z)[2] ), while b#0 do( [q,r]:PPsDiv(a,b,x), if P#0 then( r:PPsDiv(num(r),P,z)[2], if r#0 then r:content(Group(r,x),x)[2] ), a:b, b:content(r,x)[2], if r=0 then b:0 ), a:content(a,x)[2], if LC(a,x)<0 then( a:Group((-a),x) ), Ans:a, algebraic:false, return(Ans) Capítulo 5. Pseudocódigos e Códigos em Maxima 86 )$ 5.2.4 ExGCD Algoritmo de Euclides estendido. Aplicável a domínios euclidianos de polinômios. Pseudocódigo: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: função ExtendedEuclidean(𝑎,𝑏) descrição: Dado um domínio euclidiano 𝐷 e 𝑎,𝑏 ∈ 𝐷, retorna 𝑠,𝑡,𝑑 ∈ 𝐷 tais que 𝑑 = mdc(𝑎,𝑏) e 𝑠𝑎 + 𝑡𝑏 = 𝑑. 𝑎1 ← 1 𝑎2 ← 0 𝑏1 ← 0 𝑏2 ← 1 enquanto 𝑏 ̸= 0 faça (𝑞,𝑟) ← EuclideanDivision(𝑎,𝑏) ◁ 𝑎 = 𝑏𝑞 + 𝑟 𝑎←𝑏 𝑏←𝑟 𝑟1 ← 𝑎1 − 𝑞𝑏1 𝑟2 ← 𝑎2 − 𝑞𝑏2 𝑎1 ← 𝑏 1 𝑎2 ← 𝑏 2 𝑏1 ← 𝑟 1 𝑏2 ← 𝑟 2 fim enquanto devolve (𝑎1 ,𝑎2 ,𝑎) fim função Código: ExGCD(A,B,x):= block([a,b,q,r,a1,a2,b1,b2,r1,r2,Ans], algebraic:true, a:Group(A,x), b:Group(B,x), a1:1, a2:0, b1:0, b2:1, while b#0 do( [q,r]:PDiv(a,b,x), a:b, b:r, r1:a1-q*b1, r2:a2-q*b2, a1:b1, a2:b2, b1:r1, b2:r2 ), 87 5.2. MDC de Polinômios e Resultantes Ans:expand([a1,a2,a]), algebraic:false, return(Ans) )$ 5.2.5 HExGCD Algoritmo de Euclides semiestendido. Aplicável a domínios euclidianos de polinômios. Pseudocódigo: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: função HalfExtendedEuclidean(𝑎,𝑏) descrição: Dado um domínio euclidiano 𝐷 e 𝑎,𝑏 ∈ 𝐷, retorna 𝑠,𝑑 ∈ 𝐷 tais que 𝑑 = mdc(𝑎,𝑏) e 𝑠𝑎 + 𝑡𝑏 = 𝑑 para algum 𝑡 ∈ 𝐷. 𝑎1 ← 1 𝑏1 ← 0 enquanto 𝑏 ̸= 0 faça (𝑞,𝑟) ← EuclideanDivision(𝑎,𝑏) ◁ 𝑎 = 𝑏𝑞 + 𝑟 𝑎←𝑏 𝑏←𝑟 𝑟1 ← 𝑎1 − 𝑞𝑏1 𝑎1 ← 𝑏 1 𝑏1 ← 𝑟1 fim enquanto devolve (𝑎1 ,𝑎) fim função Código: HExGCD(A,B,x):= block([a,b,q,r,a1,b1,r1,Ans], algebraic:true, a:A, b:B, a1:1, b1:0, while b#0 do( [q,r]:PDiv(a,b,x), a:b, b:r, r1:a1-q*b1, a1:b1, b1:r1 ), Ans:[a1,a], algebraic:false, Capítulo 5. Pseudocódigos e Códigos em Maxima 88 return(Ans) )$ 5.2.6 HFExGCD Algoritmo de Euclides estendido calculado a partir do semiestendido. Aplicável a domínios euclidianos de polinômios. Pseudocódigo: 1: 2: 3: 4: 5: 6: função ExtendedEuclidean(𝑎,𝑏) descrição: Dado um domínio euclidiano 𝐷 e 𝑎,𝑏 ∈ 𝐷, retorna 𝑠,𝑡,𝑑 ∈ 𝐷 tais que 𝑑 = mdc(𝑎,𝑏) e 𝑠𝑎 + 𝑡𝑏 = 𝑑. (𝑠,𝑑) ← HalfExtendedEuclidean(𝑎,𝑏) ◁ 𝑠𝑎 + 𝑡𝑏 = 𝑑 para algum 𝑡 (𝑡,𝑟) ← EuclideanDivision(𝑑 − 𝑠𝑎,𝑏) ◁ 𝑟 deve ser 0 devolve (𝑠,𝑡,𝑑) fim função Código: HFExGCD(A,B,x):= block([a,b,s,r,g,t,Ans], algebraic:true, a:A, b:B, [s,g]:HExGCD(a,b,x), [t,r]:PDiv(g-s*A,B,x), Ans:[s,t,g], algebraic:false, return(Ans) )$ 5.2.7 DioExGCD Versão diofantina do algoritmo de Euclides estendido. Aplicável a domínios euclidianos de polinômios. Pseudocódigo: 1: 2: função ExtendedEuclidean(𝑎,𝑏,𝑐) descrição: Dado um domínio euclidiano 𝐷 e 𝑎,𝑏,𝑐 ∈ 𝐷 e 𝑐 múltiplo de mdc(𝑎,𝑏), retorna 𝑠,𝑡 ∈ 𝐷 tais que 𝑠𝑎 + 𝑡𝑏 = 𝑐, com 𝑠 = 0 ou 𝜈(𝑠) < 𝜈(𝑏). 89 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 5.2. MDC de Polinômios e Resultantes (𝑠,𝑡,𝑑) ← ExtendedEuclidean(𝑎,𝑏) (𝑞,𝑟) ← EuclideanDivision(𝑐,𝑑) se 𝑟 ̸= 0 então erro: “𝑐 não é múltiplo de mdc(𝑎,𝑏)” fim se 𝑠 ← 𝑞𝑠 𝑡 ← 𝑞𝑡 se 𝑠 ̸= 0 e 𝜈(𝑠) ≥ 𝜈(𝑏) então (𝑞,𝑟) ← EuclideanDivision(𝑠,𝑏) fim se 𝑠←𝑟 𝑡 ← 𝑡 + 𝑞𝑎 devolve 𝑠,𝑡 fim função ◁ 𝑑 = 𝑠𝑎 + 𝑡𝑏 ◁ 𝑐 = 𝑑𝑞 + 𝑟 ◁ 𝑠 = 𝑏𝑞 + 𝑟 Código: DioExGCD(A,B,C,x):= block([s,t,g,q,r,Ans], algebraic:true, [s,t,g]:HFExGCD(A,B,x), [s,t,g]:expand([s,t,g]), [q,r]:PDiv(C,g,x), if r#0 then( algebraic:false, error("c is not in the ideal generated by a and b") ), s:q*s, t:q*t, [s,t]:expand([s,t]), if s#0 and hipow(s,x)>=hipow(B,x) then( [q,r]:PDiv(s,B,x), s:r, t:t+q*A ), Ans:[s,t], algebraic:false, return(Ans) )$ 5.2.8 DioHExGCD Versão diofantina do algoritmo de Euclides semiestendido. Aplicável a domínios euclidianos de polinômios. Pseudocódigo: Capítulo 5. Pseudocódigos e Códigos em Maxima 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 90 função HalfExtendedEuclidean(𝑎,𝑏,𝑐) descrição: Dado um domínio euclidiano 𝐷 e 𝑎,𝑏,𝑐 ∈ 𝐷 e 𝑐 múltiplo de mdc(𝑎,𝑏), retorna 𝑠 ∈ 𝐷 tal que 𝑠𝑎 + 𝑡𝑏 = 𝑐 para algum 𝑡 ∈ 𝐷, com 𝑠 = 0 ou 𝜈(𝑠) < 𝜈(𝑏). (𝑠,𝑑) ← HalfExtendedEuclidean(𝑎,𝑏) ◁ 𝑠𝑎 + 𝑡𝑏 = 𝑑 para algum 𝑡 ∈ 𝐷 (𝑞,𝑟) ← EuclideanDivision(𝑐,𝑑) ◁ 𝑐 = 𝑑𝑞 + 𝑟 se 𝑟 ̸= 0 então erro: 𝑐 não é múltiplo de mdc(𝑎,𝑏) fim se 𝑠 ← 𝑞𝑠 se 𝑠 ̸= 0 e 𝜈(𝑠) ≥ 𝜈(𝑏) então (𝑞,𝑟) ← EuclideanDivision(𝑠,𝑏) ◁ 𝑠 = 𝑏𝑞 + 𝑟 fim se 𝑠←𝑟 devolve 𝑠 fim função Código: DioHExGCD(A,B,C,x):= block([s,g,q,r,Ans], algebraic:true, [s,g]:HExGCD(A,B,x), [s,g]:expand([s,g]), [q,r]:PDiv(C,g,x), if r#0 then( algebraic:false, error("c is not in the ideal generated by a and b") ), s:q*s, s:expand(s), if s#0 and hipow(s,x)>=hipow(B,x) then( [q,r]:PDiv(s,B,x), s:r ), Ans:s, algebraic:false, return(Ans) )$ 5.2.9 DioHFExGCD Versão diofantina do algoritmo de Euclides calculado a partir do semiestendido. Aplicável a domínios euclidianos de polinômios. 91 5.2. MDC de Polinômios e Resultantes Pseudocódigo: 1: 2: 3: 4: 5: 6: função ExtendedEuclidean(𝑎,𝑏) descrição: Dado um domínio euclidiano 𝐷 e 𝑎,𝑏,𝑐 ∈ 𝐷, com 𝑐 múltiplo de mdc(𝑎,𝑏) retorna 𝑠,𝑡 ∈ 𝐷 tais que 𝑠𝑎 + 𝑡𝑏 = 𝑐, com 𝑠 = 0 ou 𝜈(𝑠) < 𝜈(𝑏). 𝑠 ← HalfExtendedEuclidean(𝑎,𝑏,𝑐) ◁ 𝑠𝑎 + 𝑡𝑏 = 𝑐 para algum 𝑡 (𝑡,𝑟) ← EuclideanDivision(𝑐 − 𝑠𝑎,𝑏) ◁ 𝑟 deve ser 0 devolve (𝑠,𝑡) fim função Código: DioHFExGCD(A,B,C,x):= block([s,r,t,Ans], algebraic:true, s:DioHExGCD(A,B,C,x), [t,r]:PDiv(C-s*A,B,x), Ans:[s,t], algebraic:false, return(Ans) )$ 5.2.10 SubRes Algoritmo das subresultantes. Pseudocódigo: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: função SubResultant(𝐴,𝐵) descrição: Dado um domínio de integridade 𝐷 e 𝐴,𝐵 ∈ 𝐷[𝑥] com 𝐵 ̸= 0 e grau(𝐴) ≥ grau(𝐵), retorna res(𝐴,𝐵) e a SRP subresultante (𝑅0 ,𝑅1 , . . . ,𝑅𝑘 ,0) de 𝐴 e 𝐵. 𝑅0 ← 𝐴 𝑅1 ← 𝐵 𝑖←1 𝛾1 ← −1 𝛿1 ← grau(𝐴) − grau(𝐵) 𝛽1 ← (−1)𝛿1 +1 enquanto 𝑅𝑖 ̸= 0 faça 𝑟𝑖 ← cl(𝑅𝑖 ) (𝑄,𝑅) ← PolyPseudoDivide(𝑅𝑖−1 ,𝑅𝑖 ) Capítulo 5. Pseudocódigos e Códigos em Maxima 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 92 𝑅𝑖+1 ← 𝑅/𝛽𝑖 ◁ esta divisão é sempre exata 𝑖←𝑖+1 1−𝛿 𝛾𝑖 (−𝑟𝑖−1 )𝛿𝑖−1 𝛾𝑖−1 𝑖−1 𝛿𝑖 ← grau(𝑅𝑖−1 ) − grau(𝑅𝑖 ) 𝛽𝑖 ← −𝑟𝑖−1 𝛾𝑖𝛿𝑖 fim enquanto 𝑘 ←𝑖−1 se grau(𝑅𝑘 ) > 0 então devolve (0,(𝑅0 ,𝑅1 , · · · ,𝑅𝑘 ,0)) fim se se grau(𝑅𝑘−1 ) = 1 então devolve (𝑅𝑘 ,(𝑅0 ,𝑅1 , · · · ,𝑅𝑘 ,0)) fim se 𝑠←1 ◁ 𝑠 será (−1)𝜎𝑘 grau(𝑅𝑘−1 )−1 𝑐←1 ◁ 𝑠𝑅𝑘 𝑐 será 𝜏𝑘 para 𝑗 ← 1 até 𝑘 − 1 faça ◁ computa 𝜏𝑘 𝑅𝑘 se grau(𝑅𝑗−1 ) for ímpar e grau(𝑅𝑗 ) for ímpar então 𝑠 ← −𝑠 fim se grau(𝑅𝑗−1 )−grau(𝑅𝑗+1 ) 1+𝛿 ◁ divisão exata 𝑐 ← 𝑐(𝛽𝑗 /𝑟𝑗 𝑗 )grau(𝑅𝑗 ) 𝑟𝑗 fim para grau(𝑅𝑘−1 ) devolve (𝑠𝑐𝑅𝑘 ,(𝑅0 ,𝑅1 . . . ,𝑅𝑘 ,0)) fim função Código: SubRes(A,B,x):= block([R,i,gamma,delta,Res, beta,pq,pr,r,k,s,c,j,Ans], algebraic:true, R:[],gamma:[],delta:[],beta:[],r:[], push(Group(B,x),R), push(Group(A,x),R), i:2, push(-1,gamma), push(hipow(R[1],x)-hipow(R[2],x),delta), push((-1)^(delta[1]+1),beta), while R[i]#0 do( r:endcons(LC(R[i],x),r), [pq,pr]:PPsDiv(R[i-1],R[i],x), R:endcons(Group(pr/beta[i-1],x),R), gamma:endcons((-r[i-1])^delta[i-1]*gamma[i-1]^(1delta[i-1]),gamma), delta:endcons(hipow(R[i],x)-hipow(R[i+1],x),delta), beta:endcons(-r[i-1]*gamma[i]^delta[i],beta), i:i+1 93 5.2. MDC de Polinômios e Resultantes ), k:i-1, if hipow(R[k],x)>0 then( Ans:[0,rest(R,-1)], algebraic:false, return(Ans) ), if hipow(R[k-1],x)=1 then( Ans:[R[k],rest(R,-1)], algebraic:false, return(Ans) ), s:1, c:1, for j:1 thru k-2 do( if mod(hipow(R[j],x),2)=1 and mod(hipow(R[j+1],x),2)=1 then s:-s, c:c*(beta[j]/r[j]^(1+delta[j]))^hipow(R[j+1],x) *r[j]^(hipow(R[j],x)-hipow(R[j+2],x)) ), Res:s*c*R[k]^(hipow(R[k-1],x)), Ans:[Res,rest(R,-1)], algebraic:false, return(Ans) )$ 5.2.11 Normalize Normaliza o mdc entre dois polinômios para que seu coeficiente líder seja congruente a 1 mod 𝑃 (𝑧). Código: Normalize(A,x,P,z):= block([a,mult,Ans], algebraic:true, mult:HExGCD(LC(A,x),P,z)[1], a:mult*A, a:PDiv(a,P,z)[2], a:content(Group(a,x))[2], Ans:a, algebraic:false, return(Ans) )$ Capítulo 5. Pseudocódigos e Códigos em Maxima 5.3 5.3.1 94 Fatorações e Frações Parciais LFactor O mesmo que a função factor do Maxima, porém retorna uma lista com os fatores da fatoração prima do polinômio 𝑄, ao invés de um produto. 𝑒𝑥𝑝𝑎 deve ter valor 𝑡𝑟𝑢𝑒 caso se deseje expandir os fatores. Código: LFactor(Q,x,expa):= block([fac,l,i,c,q,listfac,Ans], algebraic:true, listfac:[], if hipow(Q,x)=0 then( Ans:[Q], algebraic:false, return(Ans) ), [c,q]:content(Q,x),q:Group(q,x), fac:factor(q), fac:2*fac^3, if op(fac)="-" then(c:-c,fac:-fac), l:length(fac), push(c,listfac), for i:2 thru l do( listfac:endcons(second(fac)^(1/3),listfac), fac:fac/second(fac), if expa then listfac[i]:Group(listfac[i],x) ), Ans:listfac, algebraic:false, return(Ans) )$ 5.3.2 SQFR Fatoração livre de quadrados pelo algoritmo de Yun. Pseudocódigo: 1: 2: função SquareFree(𝐴) descrição: Dado um domínio de fatoração única 𝐷 com característica 0 e 95 5.3. Fatorações e Frações Parciais 𝐴 ∈ 𝐷[𝑥], retorna 𝐴1 , . . . ,𝐴𝑚 ∈ 𝐷[𝑥] tais que 𝐴 = 𝑚 ∏︁ 𝐴𝑘𝑘 é uma fatoração 𝑘=1 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: livre de quadrados de 𝐴. 𝑐 ← cont(𝐴) 𝑆 ← 𝐴/𝑐 𝑆 ′ ← 𝑑𝑆/𝑑𝑥 𝑆 − ← mdc(𝑆,𝑆 ′ ) 𝑆 * ← 𝑆/𝑆 − 𝑌 ← 𝑆 ′ /𝑆 − 𝑘←1 enquanto (𝑍 ← 𝑌 − 𝑑𝑆 * /𝑑𝑥) ̸= 0 faça 𝐴𝑘 ← mdc(𝑆 * ,𝑍) 𝑆 * ← 𝑆 * /𝐴𝑘 𝑌 ← 𝑍/𝐴𝑘 𝑘 ←𝑘+1 fim enquanto 𝐴𝑘 ← 𝑆 * devolve (𝑐𝐴1 , . . . ,𝐴𝑘 ) fim função Código: SQFR(A,x):= block([S,Sd,Sf,Y,fac,Z,k,c,dS,Ans], algebraic:true, fac:[], [c,S]:content(A,x), dS:Group(diff(S,x),x), Sd:GCD(S,dS,x,0,0), Sf:Group(S/Sd,x), Y:Group(dS/Sd,x), Z:Group(Y-diff(Sf,x),x), k:1, while Z#0 do( fac:endcons(GCD(Sf,Z,x,0,0),fac), Sf:Group(Sf/fac[k],x), Y:Group(Z/fac[k],x), Z:Group(Y-diff(Sf,x),x), k:k+1 ), fac:endcons(Sf,fac), fac[1]:Group(c*fac[1],x), Ans:fac, algebraic:false, return(Ans) ◁ 𝑆 = pp(𝐴) * ◁ 𝑆 * = 𝐴−𝑘−1 , 𝑌 ← 𝑌𝑘 ◁ (2.12) * ◁ 𝑆 * = 𝐴−𝑘 ◁ 𝑌 = 𝑌𝑘+1 Capítulo 5. Pseudocódigos e Códigos em Maxima 96 )$ 5.3.3 PFrac Decomposição em frações parciais simples. Pseudocódigo: 1: 2: função PartialFraction(𝑎,𝑑1 , . . . ,𝑑𝑛 ) descrição: Dado um domínio euclidiano 𝐷 e 𝑎,𝑑1 , . . . ,𝑑𝑛 ∈ 𝐷 ∖ {0} com mdc(𝑑𝑖 ,𝑑𝑗 ) = 1 para 𝑖 ̸= 𝑗, retorna 𝑎0 ,𝑎1 , . . . ,𝑎𝑛 ∈ 𝐷 tais que 𝑛 ∑︁ 𝑎 𝑎𝑖 = 𝑎0 + 𝑑1 · · · 𝑑𝑛 𝑖=1 𝑑𝑖 3: 4: 5: 6: 7: 8: 9: 10: com 𝑎𝑖 = 0 ou 𝜈(𝑎𝑖 ) < 𝜈(𝑑𝑖 ) para 𝑖 ≥ 1. (𝑎0 ,𝑟) ← EuclideanDivision(𝑎,𝑑1 , . . . ,𝑑𝑛 ) se 𝑛 = 1 então devolve (𝑎0 ,𝑟) fim se (𝑎1 ,𝑡) ← ExtendedEuclidean(𝑑2 · · · 𝑑𝑛 ,𝑑1 ,𝑟) (𝑏0 ,𝑎2 , . . . ,𝑎𝑛 ) ← PartialFraction(𝑡,𝑑2 , . . . ,𝑑𝑛 ) devolve (𝑎0 + 𝑏0 ,𝑎1 ,𝑎2 , . . . ,𝑎𝑛 ) fim função Código: PFrac(A,Fac,x):= block([fac,len,Den,a,a0,r,aux,t,Ans], algebraic:true, a:makelist(0,1), fac:copylist(Fac), len:length(fac), Den:product(fac[i],i,1,len), [a0,r]:PDiv(A,Den,x), if len=1 then( Ans:[a0,r], algebraic:false, return(Ans) ), Den:Den/fac[1], [a[1],t]:DioHFExGCD(Den,fac[1],r,x), pop(fac), aux:PFrac(t,fac,x), ◁ 𝑎 = (𝑑1 · · · 𝑑𝑛 )𝑎0 + 𝑟 ◁ 𝜈(𝑎1 ) < 𝜈(𝑑1 ) 97 5.4. Hermite e Horowitz push(aux[1],a), pop(aux), a:append(a,aux), Ans:a, algebraic:false, return(Ans) )$ 5.4 5.4.1 Hermite e Horowitz HermO Versão original da redução de Hermite. Pseudocódigo: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: função HermiteReduce(𝐴,𝐷) descrição: Dado um corpo K e 𝐴,𝐷 ∈ K[𝑥] com 𝐷 não nulo e coprimo com 𝐴, retorna 𝑔,ℎ ∈ K(𝑥) tais que 𝐴/𝐷 = 𝑔 ′ + ℎ com ℎ possuindo um denominador livre de quadrados. (𝐷1 , . . . ,𝐷𝑚 ) ← SquareFree(𝐷) (𝑃,𝐴1 ,𝐴2 , . . . ,𝐴𝑛 ) ← PartialFraction(𝐴,𝐷1 ,𝐷22 , . . . ,𝐷𝑛𝑛 ) 𝑔←0 ℎ ← 𝑃 + 𝐴1 /𝐷1 para 𝑘 ← 2 até 𝑛 tal que grau(𝐷𝑘 ) > 0 faça 𝑉 ← 𝐷𝑘 para 𝑗 ← 𝑘 − 1 até 1 passo −1 faça (𝐵,𝐶) ← ExtendedEuclidean(𝑉 ′ ,𝑉, − 𝐴𝑘 /𝑗) 𝑔 ← 𝑔 + 𝐵/𝑉 𝑗 𝐴𝑘 ← −𝑗𝐶 − 𝐵 ′ fim para ℎ ← ℎ + 𝐴𝑘 /𝑉 fim para devolve (𝑔,ℎ) fim função Código: HermO(A,D,x):= block([SF,SFExp,PF,g,h,k,V,dV,B,C,j,n,Ans], algebraic:true, Capítulo 5. Pseudocódigos e Códigos em Maxima 98 if A=0 then( Ans:0, algebraic:false, return(Ans) ), SF:SQFR(D,x), n:length(SF), SFExp:makelist(SF[i]^i,i,1,n), PF:PFrac(A,SFExp,x), g:0, h:PF[1]+fullratsimp(PF[2])/SF[1], for k:2 thru n do( if hipow(SF[k],x)>0 then( V:SF[k], dV:diff(V,x), for j:k-1 thru 1 step -1 do( [B,C]:DioHFExGCD(dV,V,-expand (fullratsimp(PF[k+1]/j)),x), g:g+fullratsimp(B)/V^j, PF[k+1]:-j*C-diff(B,x) ), h:h+fullratsimp(PF[k+1])/V ) ), Ans:[g,h], algebraic:false, return(Ans) )$ 5.4.2 HermQ Versão quadrática da redução de Hermite. Pseudocódigo: 1: 2: 3: 4: 5: 6: 7: 8: função HermiteReduce(𝐴,𝐷) descrição: Dado um corpo K e 𝐴,𝐷 ∈ K[𝑥] com 𝐷 não nulo e coprimo com 𝐴, retorna 𝑔,ℎ ∈ K(𝑥) tais que 𝐴/𝐷 = 𝑔 ′ + ℎ com ℎ possuindo um denominador livre de quadrados. 𝑔←0 (𝐷1 , . . . ,𝐷𝑚 ) ← SquareFree(𝐷) para 𝑖 ← 2 até 𝑚 tal que grau(𝐷𝑖 ) > 0 faça 𝑉 ← 𝐷𝑖 𝑈 ← 𝐷/𝑉 𝑖 para 𝑗 ← 𝑖 − 1 até 1 passo −1 faça 99 9: 10: 11: 12: 13: 14: 15: 16: 5.4. Hermite e Horowitz (𝐵,𝐶) ← ExtendedEuclidean(𝑈 𝑉 ′ ,𝑉, − 𝐴/𝑗) 𝑔 ← 𝑔 + 𝐵/𝑉 𝑗 𝐴 ← −𝑗𝐶 − 𝑈 𝐵 ′ fim para 𝐷 ← 𝑈𝑉 fim para devolve (𝑔,𝐴/𝐷) fim função Código: HermQ(A,D,x):= block([SF,SFExp,a,d,g,h,k,V,dV,U,B,C,j,n,Ans], algebraic:true, a:A,d:D, if A=0 then( Ans:0, algebraic:false, return(Ans) ), g:0, SF:SQFR(D,x), n:length(SF), for k:2 thru n do( if hipow(SF[k],x)>0 then( V:SF[k], dV:expand(diff(V,x)), U:expand(fullratsimp(d/V^k)), for j:k-1 thru 1 step -1 do( [B,C]:DioHFExGCD(expand(U*dV), V,-expand(fullratsimp(a/j)),x), g:g+fullratsimp(B)/V^j, a:expand(fullratsimp(-j*C-U*diff(B,x))) ), d:U*V ) ), Ans:[g,fullratsimp(a)/d], algebraic:false, return(Ans) )$ 5.4.3 HermL Versão linear da redução de Hermite. Pseudocódigo: Capítulo 5. Pseudocódigos e Códigos em Maxima 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 100 função HermiteReduce(𝐴,𝐷) descrição: Dado um corpo K e 𝐴,𝐷 ∈ K[𝑥] com 𝐷 não nulo e coprimo com 𝐴, retorna 𝑔,ℎ ∈ K(𝑥) tais que 𝐴/𝐷 = 𝑔 ′ + ℎ com ℎ possuindo um denominador livre de quadrados. 𝑔←0 𝐷− ← mdc(𝐷,𝐷′ ) 𝐷* ← 𝐷/𝐷− enquanto grau(𝐷− ) > 0 faça ′ 𝐷−2 ← mdc(𝐷− ,𝐷− ) * 𝐷− ← 𝐷− /𝐷−2 ′ * (𝐵,𝐶) ← ExtendedEuclidean(−𝐷* 𝐷− /𝐷− ,𝐷− ,𝐴) * 𝐴 ← 𝐶 − 𝐵 ′ 𝐷* /𝐷− ◁ novo numerador − 𝑔 ← 𝑔 + 𝐵/𝐷 − 𝐷− ← 𝐷−2 ◁ 𝐷 = 𝐷−2 fim enquanto devolve (𝑔,𝐴/𝐷* ) fim função Código: HermL(A,D,x):= block([a,Dd,Dd2,Df,Ddf,degDd,dDd,g,B,C,Ans], algebraic:true, a:A, if A=0 then( Ans:0, algebraic:false, return(Ans) ), g:0, Dd:GCD(D,diff(D,x),x,0,0), Df:Group(D/Dd,x), degDd:hipow(Dd,x), while degDd>0 do( dDd:Group(diff(Dd,x),x), Dd2:GCD(Dd,dDd,x,0,0), Ddf:Group(Dd/Dd2,x), [B,C]:DioHFExGCD(Group(-Df*dDd /Dd,x),Ddf,a,x), a:Group(C-diff(B,x)*Df/Ddf,x), g:g+fullratsimp(B)/Dd, Dd:Dd2, degDd:hipow(Dd,x) ), Ans:[g,fullratsimp(a)/Df], 101 5.4. Hermite e Horowitz algebraic:false, return(Ans) )$ 5.4.4 HorOstro Método de Horowitz-Ostrogradsky. Pseudocódigo: 1: 2: 3: 4: 5: 6: 7: função HorowitzOstrogradsky(𝐴,𝐷) descrição: Dado um corpo K e 𝐴,𝐷 ∈ K[𝑥] com grau(𝐴) < grau(𝐷), 𝐷 não nulo e coprimo com 𝐴, retorna 𝑔,ℎ ∈ K(𝑥) tais que 𝐴/𝐷 = 𝑔 ′ + ℎ com ℎ possuindo um denominador livre de quadrados. 𝐷− ← mdc(𝐷,𝐷′ ) 𝐷* ← 𝐷/𝐷− 𝑛 ← grau(𝐷− ) − 1 𝑚 ← grau(𝐷* ) − 1 𝑑 ← grau(𝐷) 𝐵← 8: 𝑛 ∑︁ 𝑏𝑖 𝑥 𝑖 𝑖=0 𝐶← 9: 𝑚 ∑︁ 𝑐𝑗 𝑥 𝑗 𝑗=0 ′ 𝐻 ← 𝐴 − 𝐵 ′ 𝐷* + 𝐵𝐷* 𝐷− /𝐷− − 𝐶𝐷− ◁ divisão exata 𝑘 (𝑏0 , . . . ,𝑏𝑛 ,𝑐0 , . . . ,𝑐𝑛 ) ← solucionador(coeficiente(𝐻,𝑥 ) = 0,0 ≤ 𝑘 ≤ 10: 11: 𝑑) 12: devolve 13: fim função 𝑛 ∑︁ 𝑖=0 𝑏𝑖 𝑥𝑖 /𝐷− , 𝑚 ∑︁ 𝑐𝑗 𝑥𝑗 /𝐷* 𝑖=0 Código: HorOstro(A,D,x):= block([a,Dd,Df,dDd,n,m,d,C,B,dB,H,j,b,c,k,eq,listb, listc,listvar,sol,Rac,Log,Ans], algebraic:true, a:A, eq:[], linsolvewarn:false, if A=0 then( Ans:0, algebraic:false, Capítulo 5. Pseudocódigos e Códigos em Maxima 102 return(Ans) ), Dd:GCD(D,diff(D,x),x,0,0), if Dd=1 then( Ans:[0,A/D], algebraic:false, return(Ans) ), dDd:diff(Dd,x), Df:Group(D/Dd,x), n:hipow(Dd,x), m:hipow(Df,x), d:m+n-1, B:sum(b[i]*x^(i-1),i,1,n), C:sum(c[i]*x^(i-1),i,1,m), dB:expand(diff(B,x)), H:Group(A-dB*Df+B*Df*dDd/Dd-C*Dd,x), for k:0 thru d do eq:endcons(coeff(H,x,k)=0,eq), listb:makelist(b[i],i,1,n), listc:makelist(c[i],i,1,m), listvar:append(listb,listc), sol:solve(eq,listvar)[1], Rac:fullratsimp(sum(rhs(sol[i])*x^(i-1),i,1,n))/Dd, Log:fullratsimp(sum(rhs(sol[i])*x^(i-1-n),i,n+1,n+m))/Df, Ans:[Rac,Log], algebraic:false, linsolvewarn:true, return(Ans) )$ 5.5 5.5.1 Logaritmos Bern Algoritmo de Bernoulli. Esta versão é aplicada a funções com denominadores livres de quadrados. Além disso, é independente: diferente das demais funções desta seção, fornece diretamente a parte logarítmica e as funções arco tangente, efetivamente terminando a integração. Este código também prevê representações inertes das extensões, as quais são dadas sempre em termos das raízes do denominador, isto é, utilizando-se a fórmula dos resíduos. Dada uma função racional 𝑓 = 𝐴/𝐷 reduzida, própria e com denominador livre de quadrados, esta função utiliza a fórmula dos resíduos para o caso complexo, 103 5.5. Logaritmos isto é, ∫︁ 𝑓= 𝐴(𝛼) log(𝑥 − 𝛼) ′ (𝛼) 𝐷 𝛼|𝐷(𝛼)=0 ∑︁ Para o caso real, seguimos uma discussão semelhante àquela da seção 4.1: realizamos a separação 𝐴(𝑢 + 𝐼𝑣) = 𝑃 (𝑢,𝑣) + 𝐼𝑄(𝑢,𝑣), 𝐷′ (𝑢 + 𝐼𝑣) = 𝑆(𝑢,𝑣) + 𝐼𝑇 (𝑢,𝑣). Portanto, 𝐴(𝑢 − 𝐼𝑣) = 𝑃 (𝑢,𝑣) − 𝐼𝑄(𝑢,𝑣), 𝐷′ (𝑢 − 𝐼𝑣) = 𝑆(𝑢,𝑣) − 𝐼𝑇 (𝑢,𝑣). Em seguida, dada uma raiz complexa 𝛼 = 𝑎 + 𝐼𝑏 de 𝐷 com 𝑎,𝑏 > 0 ∈ R, notamos que 𝐴(𝑎 + 𝐼𝑏) 𝐴(𝑎 − 𝐼𝑏) log(𝑥 − (𝑎 − 𝐼𝑏)) + ′ log(𝑥 − (𝑎 + 𝐼𝑏)) = ′ 𝐷 (𝑎 − 𝐼𝑏) 𝐷 (𝑎 + 𝐼𝑏) 𝑃 − 𝐼𝑄 𝑃 + 𝐼𝑄 log(𝑥 − (𝑎 − 𝐼𝑏)) + log(𝑥 − (𝑎 + 𝐼𝑏)) = 𝑆 − 𝐼𝑇 𝑆 + 𝐼𝑇 𝑃 𝑆 + 𝑄𝑇 + 𝐼(𝑃 𝑇 − 𝑄𝑆) log(𝑥 − (𝑎 − 𝐼𝑏))+ 𝑆2 + 𝑇 2 𝑃 𝑆 + 𝑄𝑇 − 𝐼(𝑃 𝑇 − 𝑄𝑆) log(𝑥 − (𝑎 + 𝐼𝑏)) = 𝑆2 + 𝑇 2 𝑃 𝑆 + 𝑄𝑇 log((𝑥 − (𝑎 − 𝐼𝑏))(𝑥 − (𝑎 + 𝐼𝑏)))+ 𝑆2 + 𝑇 2 (︃ )︃ 𝑃 𝑇 − 𝑄𝑆 (𝑥 − 𝑎) + 𝐼𝑏 𝐼 log = 𝑆2 + 𝑇 2 (𝑥 − 𝑎) − 𝐼𝑏 (︂ )︂ 𝑥−𝑎 𝑃 𝑆 + 𝑄𝑇 𝑃 𝑇 − 𝑄𝑆 2 2 2 log(𝑥 − 2𝑎𝑥 + 𝑎 + 𝑏 ) + 2 2 arctg , 𝑆2 + 𝑇 2 𝑆 + 𝑇2 𝑏 onde os polinômios 𝑃 , 𝑄, 𝑆 e 𝑇 são aplicados sobre o par (𝑎,𝑏). Assim, esta versão Capítulo 5. Pseudocódigos e Códigos em Maxima do algoritmo de Bernoulli computa, para o caso real, ∫︁ 𝑓= 𝐴(𝛼) log(𝑥 − 𝛼) 𝐷′ (𝛼) 𝛼∈R|𝐷(𝛼)=0 ∑︁ ∑︁ + 𝐶1 (𝑎,𝑏) log(𝑥2 − 2𝑎𝑥 + 𝑎2 + 𝑏2 ) 𝑎,𝑏∈R,𝑏>0 𝐸(𝑎,𝑏)=𝐹 (𝑎,𝑏)=0 𝑥−𝑎 + 2𝐶2 (𝑎,𝑏) arctg 𝑏 (︂ )︂ onde 𝑃 𝑆 + 𝑄𝑇 𝑃 𝑇 − 𝑄𝑆 (𝑎,𝑏), 𝐶2 (𝑎,𝑏) = 2 (𝑎,𝑏) 2 2 𝑆 +𝑇 𝑆 + 𝑇2 e, além disso, 𝐸 e 𝐹 separam o denominador 𝐷, isto é, 𝐶1 (𝑎,𝑏) = 𝐷(𝑢 + 𝐼𝑣) = 𝐸(𝑢,𝑣) + 𝐼𝐹 (𝑢,𝑣). Código: Bern(A,D,x,mode,solvemethod):= block([fac,sols,a,dD,gamma,Log,ILog,Atan, pol,rea,ima,Num,expl,S,T,P,Q,Ans], algebraic:true, Log:0,ILog:0,Atan:0, dD:diff(D,x), if mode=real then( [P,Q]:Parts(A,x), [S,T]:Parts(dD,x), C1(a,b):=fullratsimp(subst(a,u,subst(b,v,(P*S+Q*T)/ (S^2+T^2)))), C2(a,b):=fullratsimp(subst(a,u,subst(b,v,(P*T-Q*S)/ (S^2+T^2)))) ), fac:LFactor(D,x,false), sols:Solve(fac,x,solvemethod), sols:RHS(sols), for i:1 thru length(sols) do( a:sols[i], if hipow(a,x)=0 then( if mode=complex then( gamma:fullratsimp(subst(a,x,A/dD)), Log:Log+gamma*log(x-a) ), if mode=real then( rea:fullratsimp(realpart(a)), ima:fullratsimp(imagpart(a)), 104 105 5.5. Logaritmos if ima=0 then( gamma:fullratsimp(subst(rea,x,A/dD)), Log:Log+gamma*log(x-rea) ), if ima>0 then( pol:Group(x^2-fullratsimp(2*rea)*x +fullratsimp(rea^2+ima^2),x), Log:Log+C1(rea,ima)*log(pol), Atan:Atan+2*C2(rea,ima)*atan( fullratsimp((x-rea)/ima)), Atan:fullratsimp(Atan) ) ) ) else( expl:PDiv(D,a,x)[1], Num:last(PFrac(A,[expl,a],x)), ILog:ILog+’lsum(subst(%alpha,x,fullratsimp(Num) /diff(a,x))*log(x-%alpha),%alpha,RootsOf(a)) ) ), Ans:[Log,Atan,ILog], algebraic:false, return(Ans) )$ 5.5.2 RothTra Algoritmo de Rothstein-Trager. Pseudocódigo: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: função IntRationalLogPart(𝐴,𝐷) descrição: Dado um corpo K de característica 0 e 𝐴,𝐷 ∈ K[𝑥] com grau(𝐴) < grau(𝐷), 𝐷 não nulo, livre de quadrados e coprimo com 𝐴, retorna ∫ 𝐴/𝐷. 𝑧 ← uma nova indeterminada sobre K 𝑅 ← res𝑥 (𝐷,𝐴 − 𝑧𝐷′ ) 𝑒𝑚 𝑢𝑅1𝑒1 · · · 𝑅𝑚 ← factoração(𝑅) ◁ fatoração em fatores irredutíveis para 𝑖 ← 1 até 𝑚 faça 𝑎 ← 𝑎 | 𝑅𝑖 (𝑎) = 0 𝐺𝑖 ← mdc(𝐷,𝐴 − 𝑎𝐷′ ) ◁ computação algébrica de mdc fim para devolve 𝑚 ∑︁ ∑︁ 𝑖=1 𝑎|𝑅𝑖 (𝑎)=0 𝑎 log(𝐺𝑖 ) Capítulo 5. Pseudocódigos e Códigos em Maxima 11: 106 fim função Código: RothTra(A,D,x):= block([k,expr,%Z,R,dD,Q,S,Ans], algebraic:true, Q:[],S:[], if hipow(D,x)=1 then( Ans:[[%Z-A/LC(D,x)],[Mon(D,x)]], algebraic:false, return(Ans) ), dD:expandwrt(diff(D,x),x), expr:Group(A-%Z*dD,x), R:content(SubRes(D,A-%Z*dD,x)[1])[2], Q:LFactor(R,%Z,false), Q:rest(Q), for i:1 thru length(Q) do( Q[i]:Q[i]^2, Q[i]:Group(first(Q[i]),%Z), S:endcons(GCD(D,expr,x,Q[i],%Z),S), S[i]:Normalize(S[i],x,Q[i],%Z) ), Ans:[Q,S], algebraic:false, return(Ans) )$ 5.5.3 LaRiTra Algoritmo de Lazard-Rioboo-Trager. Pseudocódigo: 1: 2: 3: 4: 5: 6: 7: 8: 9: função IntRationalLogPart(𝐴,𝐷) descrição: Dado um corpo K de característica 0 e 𝐴,𝐷 ∈ K[𝑥] com grau(𝐴) < grau(𝐷), 𝐷 não nulo, livre de quadrados e coprimo com 𝐴, retorna ∫ 𝐴/𝐷. 𝑧 ← uma nova indeterminada sobre K (𝑅,(𝑅0 ,𝑅1 , . . . ,𝑅𝑘 ,0)) ← SubResultant𝑥 (𝐷,𝐴 − 𝑧𝐷′ ) (𝑄1 , . . . ,𝑄𝑛 ) ← SquareFree(𝑅) para 𝑖 ← 1 até 𝑛 tal que grau𝑧 (𝑄𝑖 ) > 0 faça se 𝑖 = grau(𝐷) então 𝑆𝑖 ← 𝐷 senão 107 5.5. Logaritmos 10: 11: 12: 13: 14: 15: 16: 𝑆𝑖 ← 𝑅𝑚 onde grau𝑥 (𝑅𝑚 ) = 𝑖, 1 ≤ 𝑚 ≤ 𝑘 (𝐴1 , . . . ,𝐴𝑞 ) ← SquareFree(lc𝑥 (𝑆𝑖 )) para 𝑗 ← 1 até 𝑞 faça 𝑆𝑖 ← 𝑆𝑖 / mdc(𝐴𝑗 ,𝑄𝑖 )𝑗 fim para fim se fim para 17: devolve 𝑛 ∑︁ ∑︁ ◁ divisão exata 𝑎 log(𝑆𝑖 (𝑎,𝑥)) 𝑖=1 𝑎|𝑄𝑖 (𝑎)=0 18: fim função Código: LaRiTra(A,D,x):= block([%Z,Q,R,seqR,S,degSi,lcSi,dD, k,n,q,lcSi,i,j,j1,listA,Ans], algebraic:true, dD:expand(diff(D,x)), R:SubRes(D,Group((A-%Z*dD),x),x), R[1]:Group(R[1],%Z), seqR:R[2], k:length(seqR), Q:SQFR(content(R[1],%Z)[2],%Z), n:length(Q), S:makelist(1,n), for i:1 thru n do( if hipow(Q[i],%Z)>0 then( if i=hipow(D,x) then( S[i]:D ) else( for j:1 thru k do( if hipow(seqR[j],x)=i then( S[i]:seqR[j] ) ), degSi:hipow(S[i],x), lcSi:coeff(S[i],x,degSi), listA:SQFR(lcSi,%Z), q:length(listA), for j1:1 thru q do( S[i]:fullratsimp(S[i]/GCD(listA[j1], Q[i],t,0,0)^j1,%Z) ) ) ), S[i]:Group(S[i],x) Capítulo 5. Pseudocódigos e Códigos em Maxima 108 ), for i:1 thru length(Q) do( if hipow(Q[i],%Z)=0 then( Q[i]:1 )else( S[i]:Group(PDiv(S[i],Q[i],%Z)[2],x), S[i]:Normalize(S[i],x,Q[i],%Z) ) ), Q:delete(1,Q), S:delete(1,S), Ans:[Q,S], algebraic:false, return(Ans) )$ 5.5.4 Czi O algoritmo de Czichowski, o qual calcula a parte logaítmica da integral de uma função racional, da mesma forma que os algoritmos de Rothstein-Trager e Lazard-Rioboo-Trager. Este algoritmo utiliza bases de Gröbner e, por isso, não foi apresentado em detalhes neste trabalho (uma apresentação sobre bases de Gröbner estenderia bastante as considerações teóricas presentes no texto). O leitor interessado em um estudo das bases de Gröbner, deverá recorrer a [11, Cap. 10], [35, Cap. 21] ou [8, Cap. 5]. O teorema do qual deriva o algoritmo é o seguinte: Teorema 5.5.1 ([9]). Seja 𝑧 uma indeterminada K(𝑥), 𝑎,𝑏 ∈ K[𝑥] com grau(𝑏) > 0, 𝑏 livre de quadrados e 𝑎/𝑏 uma fração reduzida e própria, com 𝛽 sendo a base de Gröbner reduzida com relação à ordem lexicográfica pura (olp) 𝑥 > 𝑧 do ideal gerado por 𝑏 e 𝑎 − 𝑧𝑏′ em K[𝑧,𝑥]. Escrevamos 𝛽 = {𝑝1 , . . . ,𝑝𝑛 }, onde, para cada 𝑖 temos 𝑝𝑖 ∈ K[𝑧,𝑥] e o maior termo de 𝑝𝑖+1 é maior que o maior termo de 𝑝𝑖 com relação à ordem 𝑥 > 𝑧. Então, 1. cl𝑥 (pp𝑥 (𝑝𝑖 )) = 1 para 1 ≤ 𝑖 ≤ 𝑛. 2. cont𝑥 (𝑝𝑖+1 ) | cont𝑥 (𝑝𝑖 ) em K[𝑧] para 1 ≤ 𝑖 ≤ 𝑛. 3. ∫︁ ∑︁ ∑︁ 𝑎 𝑚−1 = 𝛼 log(pp𝑥 (𝑝𝑖+1 (𝛼,𝑥)) 𝑏 𝑖=1 𝛼|𝑄𝑖 (𝛼)=0 onde 𝑄𝑖 = cont𝑥 (𝑝𝑖 )/ cont𝑥 (𝑝𝑖+1 ) ∈ K[𝑡]. 109 5.5. Logaritmos Obseve que o item 1 do Teorema 5.5.1 implica que todos os argumentos polinomiais dos logaritmos já serão mônicos. Pseudocódigo: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: função IntRationalLogPart(𝐴,𝐷) descrição: Dado um corpo K de característica 0 e 𝐴,𝐷 ∈ K[𝑥] com grau(𝐴) < grau(𝐷), 𝐷 não nulo, livre de quadrados e coprimo com 𝐴, retorna ∫ 𝐴/𝐷. ◁ Cálculo da base Gröbner reduzida (𝑃1 , . . . ,𝑃𝑚 ) ← ReducedGröbner(𝐷,𝐴 − 𝑧𝐷′ , olp, 𝑥 > 𝑧) ◁ (𝑃1 , . . . ,𝑃𝑚 ) deve ter ordem crescente nos maiores termos para 𝑖 ← 1 até 𝑚 − 1 faça 𝑄𝑖 ← cont𝑥 (𝑃𝑖 )/ cont𝑥 (𝑃𝑖+1 ) ◁ divisão exata 𝑆𝑖 ← pp𝑥 (𝑃𝑖 ) fim para devolve 𝑚−1 ∑︁ ∑︁ 𝑎 log(𝑆𝑖 (𝑎,𝑥)) 𝑖=1 𝑎|𝑄𝑖 (𝑎)=0 11: fim função Código: O código para este algoritmo requer que se carregue o pacote grobner do Maxima, para computações envolvendo bases de Gröbner. load(grobner)$ Czi(A,D,x):= block([P,dD,m,i,Q,S,Ans], algebraic:true, P:[],Q:[],S:[], dD:expand(diff(D,x)), P:poly_reduced_grobner([D,expandwrt(A-%Z*dD,x)],[x,%Z]), P:sort(P), m:length(P), for i:1 thru m-1 do( Q:endcons(expandwrt(fullratsimp(content(P[i],x)[1] /content(P[i+1],x)[1]),%Z),Q), S:endcons(content(P[i+1],x)[2],S) ), Ans:[Q,S], algebraic:false, return(Ans) )$ Capítulo 5. Pseudocódigos e Códigos em Maxima 110 Exemplo 5.5.1 (gerado com dados obtidos pelo código 5.5.4, algoritmo de Czichowski). Considerando a função 𝑓 = 𝐴/𝐷 do Exemplo 3.4.2, temos que a base de Gröbner com olp 𝑥 > 𝑧 para o par 𝐷,𝐴 − 𝑧𝐷′ ∈ Q[𝑥,𝑧] é 𝛽 = {𝑃1 ,𝑃2 } = {𝑧 2 − 2𝑧 + 2,𝑥3 + 𝑧𝑥2 − 𝑧}. Logo, 𝑄1 = (𝑧 2 − 2𝑧 + 2)/1 = 𝑧 2 − 2𝑧 + 2 e 𝑆2 = 𝑃2 , donde ∫︁ 𝑓= ∑︁ 𝛼 log(𝑥3 + 𝛼𝑥2 − 𝛼). 𝛼|𝑄1 (𝛼)=0 5.6 5.6.1 Conversão Real Classic Algoritmo de clássico para obtenção de arcos tangentes. Código: Classic(A,B,x):= block([Ans], algebraic:true, Ans:2*atan(fullratsimp(A/B)), algebraic:false, return(Ans) )$ 5.6.2 Rioboo Algoritmo de Rioboo — caso complexo. Pseudocódigo: função LogToAtan(𝐴,𝐵) / K, e 𝐴,𝐵 ∈ K[𝑥] descrição: Dado um corpo K de característica 0 tal que 𝐼 ∈ com 𝐵 ̸= 0, retorna uma soma 𝑓 de funções arco tangente de polinômios em K[𝑥] tais que (︂ )︂ 𝑑𝑓 𝑑 𝐴 + 𝐼𝐵 . = 𝐼 log 𝑑𝑥 𝑑𝑥 𝐴 − 𝐼𝐵 3: se 𝐵 | 𝐴 então 1: 2: 111 5.6. Conversão Real 4: 5: 6: 7: 8: 9: 10: 11: devolve 2 arctg(𝐴/𝐵) fim se se grau(𝐴) < grau(𝐵) então devolve LogToAtan(−𝐵,𝐴) fim se (𝐷,𝐶,𝐺) ← ExtendedEuclidean(𝐵, − 𝐴) ◁ 𝐵𝐷 − 𝐴𝐶 = 𝐺 devolve 2 arctg((𝐴𝐷 + 𝐵𝐶)/𝐺) + LogToAtan(𝐷,𝐶) fim função Código: Rioboo(A,B,x):= block([a,b,D,C,G,Ans], algebraic:true, a:Group(A,x), b:Group(B,x), if PDiv(a,b,x)[2]=0 then( algebraic:false, return(2*atan(Group(a/b,x))) ), if hipow(a,x)<hipow(b,x) then( algebraic:false, return(Rioboo(-b,a,x)) ), [D,C,G]:HFExGCD(b,-a,x), Ans:2*atan(Group((a*D+b*C)/G,x))+Rioboo(D,C,x), algebraic:false, return(Ans) )$ 5.6.3 Rioboo2 Algoritmo de Rioboo — caso geral. Esta versão não é utilizada no algoritmo de integração, mas na geração alguns de exemplos do capítulo 4. A variável 𝑁 permite escolher que se realize a conversão apenas parcialmente, em 𝑁 passos. Para que nenhuma conversão seja feita, pomos 𝑁 = 0. Para a conversão completa, pomos 𝑁 = −1. Código: Rioboo2(A,B,alpha,x,N):= block([a,b,D,C,G,n,pol,Ans], algebraic:true, Capítulo 5. Pseudocódigos e Códigos em Maxima if N=0 then( Ans:alpha*log(A+alpha*B)-alpha*log(A-alpha*B), algebraic:false, return(Ans) ), a:Group(A,x), b:Group(B,x), if PDiv(a,b,x)[2]=0 then( pol:PDiv(Group(a/(alpha*b),x),alpha,x)[1], Ans:ratsimp(2*alpha*atanh(alpha*pol)), algebraic:false, return(Ans) ), if hipow(a,x)<hipow(b,x) then( Ans:Rioboo2(alpha^2*b,a,alpha,x,N), algebraic:false, return(Ans) ), [D,C,G]:HFExGCD(b,-a,x), n:N-1, pol:ratsimp(PDiv(Group((a*D-alpha^2*b*C)/(alpha*G),x), alpha,x)[1]), Ans:2*alpha*atanh(alpha*pol)+Rioboo2(D,C,alpha,x,n), algebraic:false, return(Ans) )$ 5.7 5.7.1 Manipuladores de Extensões Algébricas NoSolve Solvente inerte. Dado um polinômio irredutível 𝑃 , retorna a lista [0 = 𝑃 ]. Código: NoSolve(P,x):= block([Ans], algebraic:true, Ans:[0=P], algebraic:false, return(Ans) )$ 112 113 5.7.2 5.7. Manipuladores de Extensões Algébricas DomSolve Solvente de domínio. Dado um polinômio irredutível 𝑃 , resolve-o se ele puder se escrito na forma 𝑃 (𝑥) = 𝑎𝑥 + 𝑏, onde os coeficientes podem ser nulos. Código: DomSolve(P,x):= block([sols,Ans], algebraic:true, sols:NoSolve(P,x), if hipow(P,x)=1 then( Ans:solve(P,x), algebraic:false, return(Ans) ), Ans:sols, algebraic:false, return(Ans) )$ 5.7.3 LinSolve Solvente linear. Dado um polinômio irredutível 𝑃 , resolve-o se ele puder se escrito na forma 𝑃 (𝑥) = 𝑎𝑥𝑛 + 𝑏, onde os coeficientes podem ser nulos. Código: LinSolve(P,x):= block([sols,aux,Ans], algebraic:true, sols:DomSolve(P,x), if lhs(last(sols))=0 then( aux:P, aux:fullratsimp(aux-coeff(aux,x,0)), if hipow(aux,x)=lopow(aux,x) then( Ans:solve(P,x), algebraic:false, return(Ans) ) ), Ans:sols, algebraic:false, return(Ans) )$ Capítulo 5. Pseudocódigos e Códigos em Maxima 5.7.4 114 QuadSolve Solvente quadrático. Dado um polinômio irredutível 𝑃 , resolve-o se ele puder se escrito na forma 𝑃 (𝑥) = 𝑎𝑥2𝑛 + 𝑏𝑥𝑛 + 𝑐, onde os coeficientes podem ser nulos. Código: QuadSolve(P,x):= block([degP,sols,aux,Ans], algebraic:true, sols:LinSolve(P,x), if lhs(last(sols))=0 then( aux:P, aux:fullratsimp(aux-coeff(aux,x,0)), if length(aux)=2 then( degP:hipow(P,x), if mod(degP,2)=0 then( if (coeff(P,x,degP/2))#0 then( Ans:solve(P,x), algebraic:false, return(Ans) ) ) ) ), Ans:sols, algebraic:false, return(Ans) )$ 5.7.5 CubeSolve Solvente cúbico. Dado um polinômio irredutível 𝑃 , resolve-o se ele puder se escrito na forma 𝑃 (𝑥) = 𝑎𝑥3𝑛 + 𝑏𝑥𝑛 + 𝑐, 𝑃 (𝑥) = 𝑎𝑥3𝑛 + 𝑏𝑥2𝑛 + 𝑐, ou 𝑃 (𝑥) = 𝑎𝑥3𝑛 + 𝑏𝑥2𝑛 + 𝑐𝑥𝑛 + 𝑑, onde os coeficientes podem ser nulos. Código: CubeSolve(P,x):= block([degP,sols,aux,Ans], algebraic:true, sols:QuadSolve(P,x), if lhs(last(sols))=0 then( aux:P, aux:fullratsimp(aux-coeff(aux,x,0)), 115 5.7. Manipuladores de Extensões Algébricas if length(aux)=2 then( degP:hipow(P,x), if mod(degP,3)=0 then( if (coeff(P,x,degP/3))#0 or (coeff(P,x,2*degP/3))#0 then( Ans:solve(P,x), algebraic:false, return(Ans) ) ) ), if length(aux)=3 then( degP:hipow(P,x), if mod(degP,3)=0 then( if (coeff(P,x,degP/3))#0 and (coeff(P,x,2*degP/3))#0 then( Ans:solve(P,x), algebraic:false, return(Ans) ) ) ) ), Ans:sols, algebraic:false, return(Ans) )$ 5.7.6 Solve Solvente geral. 𝑓 𝑎𝑐 é uma lista de fatores de 𝑃 na variável 𝑥 obtida utilizando-se a função ListFactor. A função encontra cada uma das raízes de 𝑃 utilizando o método 𝑚𝑒𝑡ℎ𝑜𝑑 em cada um de seus fatores irredutíveis. 𝑚𝑒𝑡ℎ𝑜𝑑 pode ser: NoSolve, DomSolve, LinSolve, QuadSolve, CubeSolve ou solve, esta última sendo o solvente nativo do Máxima. É possivel, assim, escolher se desejamos explicitar as raízes 1. de nenhuma maneira (NoSolve); 2. até elementos do corpo quociente do domínio (DomSolve) 3. até raízes 𝑛-ésimas dos referidos elementos (LinSolve) 4. até raízes 𝑛-ésimas de fórmulas de Bhaskara (QuadSolve) Capítulo 5. Pseudocódigos e Códigos em Maxima 116 5. até raízes 𝑛-ésimas de fórmulas de Cardano (CubeSolve) 6. até raízes 𝑛-ésimas de fórmulas quárticas (solve) Esta rotina é importante para que possamos controlar a exibição final das integrais que queremos calcular. As extensões algébricas que obteremos para expressar a integral serão raízes de polinômios. Caso não estejamos interessados em expressar fórmulas muito difíceis de serem calculadas, ou simplesmente muito grandes, como fórmulas de cardano ou quárticas, podemos, por exemplo, escolher o método QuadSolve para encontrar, no máximo, extensões que possam ser expressas pela fórmula de Bhaskara. As demais extensões seriam dadas em termos dos respectivos polinômios dos quais são soluções. Código: Solve(fac,x,method):= block([P,l,i,solsfac,sols,unsolved,Ans], algebraic:true, l:length(fac),sols:[],unsolved:1, if l=1 then( algebraic:false, error("polynomial is constant or 0.") ), for i:2 thru l do( P:fac[i]^2, P:first(P), P:Group(P,x), solsfac:method(P,x), if lhs(last(solsfac))=0 then unsolved:unsolved *rhs(last(solsfac)) else sols:append(sols,solsfac) ), if unsolved=1 then( Ans:sols, algebraic:false, return(Ans) ) else( Ans:append(sols,[0=unsolved]), algebraic:false, return(Ans) ) )$ 117 5.7.7 5.7. Manipuladores de Extensões Algébricas RHS Converte uma lista cujos elementos são da forma 𝑙ℎ𝑠 = 𝑟ℎ𝑠 em uma lista cujos elementos são da forma 𝑟ℎ𝑠. Essa função se aplica a listas de soluções de um polinômio. Código: RHS(sols):= block([consts,i,Ans], algebraic:true, consts:[], for i:1 thru length(sols) do consts:endcons(rhs(sols[i]),consts), Ans:consts, algebraic:false, return(Ans) )$ 5.7.8 SolveSys Dada uma lista de números complexos, retorna uma lista cujos elementos são da forma [𝑎,𝑏], com 𝑎,𝑏 ∈ R, 𝑏 > 0 e tais que 𝑎 + 𝐼𝑏 pertence à lista original. Aplica-se ao sistema não linear que surge na discussão do algoritmo de Rioboo. Código: SolveSys(compl):= block([a,b,j,sols,Ans], algebraic:true, sols:[], for j:1 thru length(compl) do( a:fullratsimp(realpart(compl[j])), b:fullratsimp(imagpart(compl[j])), if b>0 then( sols:endcons([a,b],sols) ) ), Ans:sols, algebraic:false, return(Ans) )$ Capítulo 5. Pseudocódigos e Códigos em Maxima 5.7.9 118 Extensions Dada uma lista de fatores 𝑅 na variável 𝑧 resolve cada um dos fatores utilizando o método 𝑠𝑜𝑙𝑣𝑒𝑚𝑒𝑡ℎ𝑜𝑑 e armazena, respectivamente, nas listas 𝑟𝑒𝑖 , 𝑐𝑜𝑚𝑝𝑙𝑖 e 𝑖𝑛𝑒𝑟𝑡𝑖 as soluções reais, contendo unidade imaginária e o que não pôde ser resolvido do fator 𝑅𝑖 . Utilizada para encontrar as extensões que devem aparecer na expressão final da integral de uma função racional. Código: Extensions(R,z,solvemethod):= block([l,i,j,exts,re,compl,inert,fac,Ans], algebraic:true, l:length(R),re:[],compl:[],inert:[], for i:1 thru l do( fac:LFactor(R[i],z,false), exts:RHS(Solve(fac,z,solvemethod)), re:endcons([],re), compl:endcons([],compl), inert:endcons([],inert), for j:1 thru length(exts) do( if hipow(exts[j],z)#0 then inert[i]:endcons(exts[j],inert[i]) else if imagpart(exts[j])#0 then compl[i]:endcons(exts[j],compl[i]) else re[i]:endcons(exts[j],re[i]) ) ), Ans:[re,compl,inert], algebraic:false, return(Ans) )$ 5.7.10 VerifyRatSols Verifica se todos os elementos da lista 𝑠𝑜𝑙𝑠 possuem apenas elementos racionais em alguma das duas coordenadas. A resposta é um vetor booleano de dois elementos. O valor 𝑡𝑟𝑢𝑒 indica que todas os elementos das coordenadas correspondentes são racionais. Esta função é utilizada para decidir se e como RiobooAtan, calculará seus arcos tangentes: utilizando diretamente soluções do sistema não linear associado, ou genericamente, seguido de substituição. O primeiro caso só ocorrerá em 119 5.8. Montagem de Integrais de Funções Racionais caso de soluções racionais. Código: VerifyRatSols(sols):= block([i,signal1,signal2,a,b,Ans], algebraic:true, signal1:true,signal2:true, for i:1 thru length(sols) do( a:sols[i][1], b:sols[i][2], if (integerp(num(a)) and integerp(denom(a)))=false then signa1:false, if (integerp(num(b)) and integerp(denom(b)))=false then signa2:false ), Ans:[signal1,signal2], algebraic:true, return(Ans) )$ 5.8 Montagem de Integrais de Funções Racionais 5.8.1 RealLog Monta os logaritmos reais que aparecem na expressão final da integral, mas que não são obtidos a partir de extensões contendo unidade imaginária. Algumas conversões simples para funções arco tangente hiperbólico são realizadas quando temos a condição 𝐵(𝑎,𝑏,𝑥) | 𝐴(𝑎,𝑏,𝑥). Só são realizadas conversões para extensões 𝛼 tais que 𝛼2 ∈ K, onde K é o corpo dos coeficientes do integrando original. Além disso, se 𝑟1 ,𝑟2 ∈ K(𝛼) são as raízes de um fator quadrático da resultante 𝑅(𝑧), então a conversão é realizada apenas nos seguintes casos: 1. 𝛼 ∈ / K; 2. 𝑟1 = −𝑟2 . Se Q = ̸ K, então certas conversões podem não trazer ganho em relação à representação. Esta rotina foi projetada para funções racionais sobre Q. Como Capítulo 5. Pseudocódigos e Códigos em Maxima 120 última consideração, temos que, para o par a ser convertido 𝐴,𝐵, o polinômio 𝐵 é tomado de forma que 𝐵 ∈ K(𝛼) durante os cálculos. Código: RealLog(S,z,x,re,modei,atanhconv):= block([i,j,RLog,Atanh,expl,SubS,Swap,a,b,M,m,A,B,q], algebraic:true, RLog:0,expl:1,Atanh:0, for i:1 thru length(S) do( if length(re[i])=2 and atanhconv=true and (re[i][1]=-re[i][2] or rationalp(re[i][1])=false) then( a:(re[i][1]+re[i][2])/2, b:abs(re[i][1]-re[i][2])/2, M:max(re[i][1],re[i][2]), m:min(re[i][1],re[i][2]), A:Group((subst(M,z,S[i])+subst(m,z,S[i]))/2,x), B:Group((subst(M,z,S[i])-subst(m,z,S[i]))/2,x), if hipow(A,x)<hipow(B,x) then( Swap:A,A:b^2*B,B:b*Swap ), [q,r]:PDiv(A,B,x), if r=0 then( SubS:fullratsimp(A^2-B^2), RLog:RLog+a*log(SubS), if modei=den then expl:expl*SubS, Atanh:Atanh+2*b*atanh(q) ) else( for j:1 thru 2 do( a:fullratsimp(re[i][j]), SubS:content(subst(a,z,S[i]),x)[2], if modei=den then expl:expl*SubS, SubS:Mon(SubS,x), RLog:RLog+a*log(SubS) ) ) ) else( for j:1 thru length(re[i]) do( a:fullratsimp(re[i][j]), SubS:content(subst(a,z,S[i]),x)[2], if modei=den then expl:expl*SubS, SubS:Mon(SubS,x), RLog:RLog+a*log(SubS) ) ) ), 121 5.8. Montagem de Integrais de Funções Racionais RLog:ratsimp(RLog), Atanh:ratsimp(Atanh), Ans:[expl,RLog,Atanh], algebraic:false, return(Ans) )$ 5.8.2 ComplLog Se não estivermos interessados em realizar conversões para arcos tangentes, esta função monta os logaritmos complexos que aparecem na expressão final da integral. Caso contrário, monta os logaritmos e funções arco tangente que surgem de extensões contendo unidades imaginárias. No caso real, resolve o sistema 𝑃 (𝑢,𝑣) = 𝑄(𝑢,𝑣) encontrando diretamente as raízes complexas com parte imaginária positiva de 𝑅(𝑧). Pseudocódigo: 1: 2: função LogToReal(𝑅,𝑆) descrição: Dado um corpo K ⊆ R, 𝑅 ∈ K[𝑧] e 𝑆 ∈ K[𝑧,𝑥], retorna uma função real 𝑓 tal que 𝑑𝑓 𝑑 ∑︁ = 𝛼 log(𝑆(𝛼,𝑥)). 𝑑𝑥 𝑑𝑥 𝛼|𝑅(𝛼)=0 3: 4: 5: Escreva 𝑅(𝑢 + 𝐼𝑣) = 𝑃 (𝑢,𝑣) + 𝐼𝑄(𝑢,𝑣) Escreva 𝑆(𝑢 + 𝐼𝑣,𝑥) = 𝐴(𝑢,𝑣,𝑥) + 𝐼𝐵(𝑢,𝑣,𝑥) devolve ∑︁ 𝑎 log(𝐴(𝑎,𝑏,𝑥)2 + 𝐵(𝑎,𝑏,𝑥)2 )+ 𝑎,𝑏∈R,𝑏>0 𝑃 (𝑎,𝑏)=𝑄(𝑎,𝑏)=0 𝑏 LogToAtan(𝐴,𝐵)(𝑎,𝑏,𝑥) + ∑︁ 𝑎 log(𝑆(𝑎,𝑥)) 𝑎∈R,𝑅(𝑎)=0 6: fim função Código: ComplLog(S,R,z,x,expl,compl,mode,modei,atanmethod):= block([i,j,k,a,b,x,u,v,CLog,Atan,Expl, SubS,SubA,SubB,A,B,sols,signal1, Capítulo 5. Pseudocódigos e Códigos em Maxima signal2,auxatan,Ans], algebraic:true, CLog:0,Atan:0,Expl:expl, if mode=complex then( for i:1 thru length(S) do( for j:1 thru length(compl[i]) do( a:fullratsimp(compl[i][j]), SubS:content(subst(a,z,S[i]),x)[2], if modei=den then Expl:Expl*SubS, SubS:Mon(SubS,x), CLog:CLog+a*log(SubS) ) ) ), if mode=real then( for i:1 thru length(S) do( if length(compl[i])>0 then( [SubA,SubB]:Parts(S[i],z), A(a,b,x):=subst(a,u,subst(b,v,SubA)), B(a,b,x):=subst(a,u,subst(b,v,SubB)), sols:SolveSys(compl[i]), [signal1,signal2]:VerifyRatSols(sols), if (signal1 or signal2)=false then( auxatan:atanmethod(A(u,v,x),B(u,v,x),x) ), for j:1 thru length(sols) do( a:sols[j][1], b:sols[j][2], SubS:content(A(a,b,x)^2+B(a,b,x)^2,x)[2], SubS:Mon(SubS,x), if modei=den then Expl:Expl*SubS, CLog:CLog+a*log(SubS), if signal1=false and signal2=true then( auxatan:atanmethod(A(u,b,x), B(u,b,x),x) ), if signal1=true and signal2=false then( auxatan:atanmethod(A(a,v,x), B(a,v,x),x) ), if signal1=true and signal2=true then( auxatan:atanmethod(A(a,b,x), B(a,b,x),x) ), auxatan:subst(a,u,subst(b,v,auxatan)), Atan:Atan+b*auxatan, Atan:fullratsimp(Atan) ) ) ) 122 123 5.8. Montagem de Integrais de Funções Racionais ), Ans:[Expl,CLog,Atan], algebraic:false, return(Ans) )$ 5.8.3 InertLog Monta as expressões inertes da integral. Se certos resíduos não puderam ser encontrados durante o processo de integração, então a porção da integral que depende deles é deixada na forma inerte, isto é, como uma soma de logaritmos sobre as raízes de um determinado polinômio. Mais especificamente, se a parte logarítmica originalmente era dada por ∫ 𝑎/𝑏, então há duas possibilidades de representação para a parte inerte: 1. ∫︁ ∑︁ 𝑎 ˜(𝛼) 𝑎 ˜ = log(𝑥 − 𝛼) ˜𝑏 ˜ 𝑏′ (𝛼) 𝛼|˜𝑏(𝛼)=0 onde ˜𝑏 = 𝑏/ 𝑣𝑖 , onde os 𝑣𝑖 são todos os argumentos de logaritmos que puderam ser determinados, e 𝑎 ˜ é obtido realizando uma decomposição em ∏︁ ˜ frações parciais entre 𝑏 e 𝑣𝑖 da fração 𝑎/𝑏. Observe que esta representação baseia-se na discussão do início da seção 3.4; ∏︁ 2. ∫︁ 𝑎 ˜ ∑︁ ∑︁ 𝛾 log(𝑣𝑖 (𝛾,𝑥)) ˜𝑏 = 𝑖 ˜ 𝛾|𝑅𝑖 (𝛾)=0 onde 𝑅˜𝑖 é a parte de 𝑅𝑖 que não pôde ser resolvida e 𝑣𝑖 é obtido pelo algoritmo de Rothstein-Trager, Lazard-Rioboo-Trager ou Czichowski. Note que, das duas formas, apenas a primeira se aplica ao algoritmo de Bernoulli. A segunda costuma ter uma representação mais volumosa, mas não requer cálculos extras de frações parciais. Código: InertLog(S,z,x,h,inert,expl,modei):= block([i,j,ILog,SubS,impl,Num,Ans], algebraic:true, Capítulo 5. Pseudocódigos e Códigos em Maxima 124 ILog:0, if modei=den then( impl:Group(denom(h)/expl,x), if hipow(impl,x)=0 then( Ans:ILog, algebraic:false, return(Ans) ), Num:last(PFrac(num(h),[expl,impl],x)), ILog:’lsum(subst(%alpha,x,fullratsimp(Num)/ fullratsimp(diff(impl,x)))*log(x-%alpha), %alpha,RootsOf(content(impl,x)[2])) ), if modei=res then( for i:1 thru length(S) do( for j:1 thru length(inert[i])do( SubS:PPsDiv(S[i],inert[i][j],z)[2], SubS:content(Group(subst(%gamma,z,SubS), x),x)[2], if integerp(LC(SubS,x)) then SubS:Mon(SubS,x), ILog:ILog+’lsum(%gamma*log(SubS),%gamma, RootsOf(inert[i][j])) ) ) ), Ans:ILog, algebraic:false, return(Ans) )$ 5.8.4 GenList Converte um vetor de caracteres em uma lista que contém as opções para o funcionamento do algoritmo de integração. Serve para facilitar a mudança de opções, dispensando a necessidade de digitá-las por extenso, o que torna o processo de testes dos códigos mais rápidos. São escolhidos: grau de detalhamento das extensões; modo de integração real ou complexo; modo da representação da parte inerte da integral; método de obtenção da parte racional da integral e do integrando da parte transcendental; método de obtenção da parte transcendental e o método de conversão para arcos tangentes. Código: 125 5.8. Montagem de Integrais de Funções Racionais GenList(opt):= block([solvemethod,mode,modei,ratmethod,logmethod, atanmethod,Ans], algebraic:true, if opt[1]=N then solvemethod:NoSolve, if opt[1]=D then solvemethod:DomSolve, if opt[1]=L then solvemethod:LinSolve, if opt[1]=Q then solvemethod:QuadSolve, if opt[1]=C then solvemethod:CubeSolve, if opt[1]=A then solvemethod:solve, if opt[2]=C then mode:complex, if opt[2]=R then mode:real, if opt[3]=R then modei:res, if opt[3]=D then modei:den, if opt[4]=O then ratmethod:HermO, if opt[4]=Q then ratmethod:HermQ, if opt[4]=L then ratmethod:HermL, if opt[4]=S then ratmethod:HorOstro, if opt[5]=B then logmethod:Bern, if opt[5]=R then logmethod:RothTra, if opt[5]=L then logmethod:LaRiTra, if opt[5]=C then logmethod:Czi, if opt[6]=C then atanmethod:Classic, if opt[6]=R then atanmethod:Rioboo, if opt[7]=T then atanhconv:true, if opt[7]=F then atanhconv:false, Ans:[solvemethod,mode,modei,ratmethod,logmethod, atanmethod,atanhconv], algebraic:false, return(Ans) )$ 5.8.5 IRF Integrador de funções racionais. A saída é uma lista em que a primeira entrada contém dados separados de cada etapa do processo de integração e a segunda contém a fórmula da integral. Código: IRF(F,x,solvemethod,mode,modei,ratmethod,logmethod, atanmethod,atanhconv):= block([f,q,r,h,t,Poly,Rat,Log,ILog, compl,inert,R,S,Atan,Atanh,re, expl,impl,RLog,CLog,Int,Ans], algebraic:true, q:0,r:0,h:0,Poly:0,Rat:0,Log:0,ILog:0,re:[],compl:[], Capítulo 5. Pseudocódigos e Códigos em Maxima inert:[],R:[],S:[],Atan:0,Atanh:0,expl:1, impl:1,RLog:0,CLog:0,Int:0, f:Group(num(F),x)/Group(denom(F),x), [q,r]:PDiv(num(f),denom(f),x), Poly:integrate(q,x), Int:Int+Poly, if r=0 then( Ans:[[[Poly,Rat,h],[R,S],[re,compl,inert]],Int], algebraic:false, return(Ans) ), [Rat,h]:ratmethod(num(r),denom(f),x), h:rat(h,x), Int:Int+Rat, if h=0 then( Ans:[[[Poly,Rat,h],[R,S],[re,compl,inert]],Int], algebraic:false, return(Ans) ), if logmethod=Bern then( [Log,Atan,ILog]:logmethod(num(h),denom(h),x,mode, solvemethod), Int:Int+(Log+Atan)+ILog, Ans:[[[Poly,Rat,h],[R,S],[re,compl,inert]],Int], algebraic:false, return(Ans) ), [R,S]:logmethod(num(h),denom(h),x), [re,compl,inert]:Extensions(R,%Z,solvemethod), [expl,RLog,Atanh]:RealLog(S,%Z,x,re,modei,atanhconv), [expl,CLog,Atan]:ComplLog(S,R,%Z,x,expl,compl,mode,modei ,atanmethod), ILog:InertLog(S,%Z,x,h,inert,expl,modei), Int:Int+(RLog+CLog+Atan+Atanh)+ILog, Ans:[[[Poly,Rat,h],[R,S],[re,compl,inert]],Int], algebraic:false, return(Ans) )$ 126 127 5.8. Montagem de Integrais de Funções Racionais Exemplo 5.8.1. Sejam 𝐴 = 19𝑥11 − 456𝑥10 + 2254𝑥9 + 17096𝑥8 + 405664𝑥7 − 872288𝑥6 + 38901536𝑥5 − 411030528𝑥4 + 1560292864𝑥3 + 2634296320𝑥2 − 24589926400𝑥 + 24870912000 𝐷 = 𝑥12 − 75𝑥11 + 884𝑥10 − 3130𝑥9 − 14832𝑥8 − 396720𝑥7 − 144304𝑥6 − 24962080𝑥5 + 211912576𝑥4 − 691531520𝑥3 − 944844800𝑥2 + 7348224000𝑥 − 5898240000 e 𝑓 = 𝐴/𝐷. A rotina de RothTra fornece: 𝑅 = [𝑧 − 1,𝑧 2 − 2,𝑧 2 − 2𝑧 + 2,𝑧 3 − 12𝑧 2 − 48𝑧 − 64, 𝑧 4 − 4𝑧 3 + 8𝑧 2 − 8𝑧 + 16] 𝑆 = [𝑥 − 𝑧,𝑥 − 2𝑧,𝑥 − 3𝑧,𝑥 − 4𝑧,𝑥 − 5𝑧]. A função Extensions, fornece, com detalhamento máximo das extensões √ √ 𝑟𝑒 =[[1],[− 2, 2],[],[44/3 + 2 · 42/3 + 4],[]] ⎛ ⎛ √ ⎞ √ ⎞ −1 − 𝐼 3 𝐼 3 − 1 ⎠ + 2 · 42/3 ⎝ ⎠ + 4, 𝑐𝑜𝑚𝑝𝑙 =[[],[],[1 − 𝐼,1 + 𝐼],[44/3 ⎝ 2 2 ⎛ √ ⎞ ⎛ √ ⎞ √︁ √ 𝐼 3 − 1 −1 − 𝐼 3⎠ 4/3 ⎝ 2/3 ⎝ ⎠ 4 +2·4 + 4],[1 − −2𝐼 3 − 1, 2 2 √︁ √ √︁ √︁ √ √ 1 − 2𝐼 3 − 1,1 + −2𝐼 3 − 1,1 + +2𝐼 3 − 1]] 𝑖𝑛𝑒𝑟𝑡 =[[],[],[],[],[]] e com detalhamento mínimo, 𝑟𝑒 =[[],[],[],[],[]] 𝑐𝑜𝑚𝑝𝑙 =[[],[],[],[],[]] 𝑖𝑛𝑒𝑟𝑡 =[[𝑧 − 1],[𝑧 2 − 2],[𝑧 2 − 2𝑧 + 2],[𝑧 3 − 12𝑧 2 − 48𝑧 − 64], [𝑧 4 − 4𝑧 3 + 8𝑧 2 − 8𝑧 + 16]]. Capítulo 5. Pseudocódigos e Códigos em Maxima 128 Portanto, a solução em representação complexa com detalhamento máximo (utilizando solve em Extensions) é ∫︁ 𝑓 =𝑟𝑒11 log(𝑥 − 𝑟𝑒11 ) + 𝑟𝑒21 log(𝑥 − 2𝑟𝑒21 ) + 𝑟𝑒22 log(𝑥 − 2𝑟𝑒22 )+ 𝑐𝑜𝑚𝑝𝑙31 log(𝑥 − 3𝑐𝑜𝑚𝑝𝑙31 ) + 𝑐𝑜𝑚𝑝𝑙32 log(𝑥 − 3𝑐𝑜𝑚𝑝𝑙32 )+ 𝑟𝑒41 log(𝑥 − 4𝑟𝑒41 ) + 𝑐𝑜𝑚𝑝𝑙41 log(𝑥 − 4𝑐𝑜𝑚𝑝𝑙41 )+ 𝑐𝑜𝑚𝑝𝑙51 log(𝑥 − 5𝑐𝑜𝑚𝑝𝑙51 ) + 𝑐𝑜𝑚𝑝𝑙52 log(𝑥 − 5𝑐𝑜𝑚𝑝𝑙52 )+ 𝑐𝑜𝑚𝑝𝑙53 log(𝑥 − 5𝑐𝑜𝑚𝑝𝑙53 ) + 𝑐𝑜𝑚𝑝𝑙54 log(𝑥 − 5𝑐𝑜𝑚𝑝𝑙54 ), e com detalhamento mínimo (utilizando NoSolve em Extensions) é ∫︁ ∑︁ 𝑓= ∑︁ 𝛾 log(𝑥 − 3𝛾)+ 𝑅𝑜𝑜𝑡𝑠𝑂𝑓 (𝑧 2 −2𝑧+2) ∑︁ 𝛾 𝑖𝑛 𝛾 log(𝑥 − 4𝛾)+ 𝑅𝑜𝑜𝑡𝑠𝑂𝑓 (𝑧 3 −12𝑧 2 −48𝑧−64) ∑︁ 𝛾 𝑖𝑛 𝛾 log(𝑥 − 2𝛾)+ 𝛾 𝑖𝑛 𝑅𝑜𝑜𝑡𝑠𝑂𝑓 (𝑧 2 −2) 𝛾 𝑖𝑛 𝑅𝑜𝑜𝑡𝑠𝑂𝑓 (𝑧−1) 𝛾 𝑖𝑛 ∑︁ 𝛾 log(𝑥 − 𝛾) + 𝛾 log(𝑥 − 5𝛾). 𝑅𝑜𝑜𝑡𝑠𝑂𝑓 (𝑧 4 −4𝑧 3 +8𝑧 2 −8𝑧+16) Soluções intermediárias entre as duas representações são geradas de acordo com o nível de detalhamento desejado para as extensões. Finalmente, um exemplo de uma representação intermediária utilizando a fórmula do resíduo, ao invés dos fatores da resultante. Se escolhermos a rotina CubeSolve para o detalhamento das raízes, temos ∫︁ 𝑓 = 𝑟𝑒11 log(𝑥 − 𝑟𝑒11 ) + 𝑟𝑒21 log(𝑥 − 2𝑟𝑒21 ) + 𝑟𝑒22 log(𝑥 − 2𝑟𝑒22 )+ 𝑐𝑜𝑚𝑝𝑙31 log(𝑥 − 3𝑐𝑜𝑚𝑝𝑙31 ) + 𝑐𝑜𝑚𝑝𝑙32 log(𝑥 − 3𝑐𝑜𝑚𝑝𝑙32 )+ 𝑟𝑒41 log(𝑥 − 4𝑟𝑒41 ) + 𝑐𝑜𝑚𝑝𝑙41 log(𝑥 − 4𝑐𝑜𝑚𝑝𝑙41 ) 4𝛼3 − 80𝛼2 + 600𝛼 − 8000 log(𝑥 − 𝛼) 4𝛼3 − 60𝛼2 + 400𝛼 − 1000 𝑅𝑜𝑜𝑡𝑠𝑂𝑓 (𝑥4 −20𝑥3 +200𝑥2 −1000𝑥+10000) ∑︁ + 𝛼 𝑖𝑛 Os logaritmos que contêm elementos da lista 𝑟𝑒 foram montados pela rotina RealLog; os que contêm elementos da lista 𝑐𝑜𝑚𝑝𝑙 foram montados pela rotina 129 5.8. Montagem de Integrais de Funções Racionais ComplLog, neste caso, aplicada para integração complexa; finalmente, os logaritmos inertes foram montados com a rotina InertLog — primeiro utilizando o modo 𝑟𝑒𝑠 para expressar as soluções inertes em termos de fatores da resultante, em seguida utilizando o modo 𝑑𝑒𝑛 utilizando um fator do denominador original e, consequentemente, a fórmula do resíduo aplicada a cada uma das raízes deste fator. A rotina InertLog extrai informações da lista 𝑖𝑛𝑒𝑟𝑡. Capítulo 6 Considerações Finais 6.1 A Integração de Funções Elementares Este trabalho foi uma abordagem introdutória ao problema da integração indefinida de funções através do caso particular de funções racionais. A continuação natural do estudo é o problema da integração indefinida de funções elementares. Em resumo, as funções ditas elementares são aquelas que podem ser escritas como uma combinação entre logaritmos, exponenciais e funções algébricas (incluindo as triviais, como as próprias funções racionais) através de operações de corpo e composição, onde qualquer escalar que ocorra em sua fórmula é um elemento dos complexos. Portanto, as funções trigonométricas e suas inversas são também exemplos de funções elementares. Em outras palavras, estamos lidando com aquelas funções que, costumeiramente, são manipuladas nos cursos de Cálculo. Entre 1833 e 1835, J. Liouville publicou três trabalhos [18, 19, 20] cujos principais resultados podem ser condensados num de fundamental importância para a integração de funções elementares. Assemelha-se ao resultado obtido pelo algoritmo de Bernoulli: se uma função elementar possui uma integral também elementar então esta integral pode ser expressa como a soma entre outra função elementar pertencente ao mesmo corpo de funções elementares do integrando e uma combinação linear finita de logaritmos cujos argumentos também pertencem ao referido corpo. Este resultado, unido aos esforços de J. Ritt na década de Capítulo 6. Considerações Finais 132 1940 para o desenvolvimento da Álgebra Diferencial [30], formariam a base para demonstrar o fato importante de que o processo de integração para a classe de funções elementares também pode ser tornado algorítmico e não heurístico, ainda que dependa de certos critérios de decidibilidade. Mais especificamente, trata-se do algoritmo de Risch, um algoritmo recursivo capaz de encontrar a integral indefinida de funções elementares quando esta integral também existe como uma função elementar — caso contrário, o método é uma demonstração de que uma integral fechada não existe para o integrando. Foi proposto por R. Risch, em 1968 [29]. O estudo deste algoritmo evidencia a importância de se ter a integração de funções racionais como ponto de partida: a partir da definição apropriada de variáveis dependentes da variável de integração, qualquer função elementar pode ser vista como uma função racional cujos coeficientes são ainda funções elementares partencentes a um corpo de funções menor do que aquele ao qual o integrando original faz parte. Esta visualização possibilita extensões dos algoritmos de Hermite (e suas versões) e de Rothstein-Trager (e a melhoria de Lazard-Rioboo-Trager), que possuem um papel crucial no algoritmo de Risch. A respeito disto, observamos que o algoritmo de Horowitz, apesar de possuir maior eficiência para o caso de funções racionais que o algoritmo de Hermite [13], não generaliza facilmente como o último para a classe das funções elementares como um todo [2, p. 46]. Ainda não há algoritmos análogos ao de Rioboo para classes mais gerais de funções [2, p. 70]. Toda via, este algoritmo é utilizado em conjunto com transformações de retificação para se calcular as integrais de funções racionais em funções seno e cosseno, como vimos no Exemplo 4.1.6. 6.2 O Cenário da Computação Algébrica O conteúdo trazido por este trabalho faz parte do campo de estudo da Computação Álgebrica, também conhecida como Computação Simbólica. Em resumo, a Computação Algébrica é um ramo limítrofe da Matemática e da Ciência da Computação e estuda como as bases teóricas da Álgebra Abstrata podem ser utilizadas para a implementação de algoritmos que sejam capazes de efetuar cálculos exatos e simbólicos (cálculos de representação), além de estudar aplicações 133 6.3. Referências em Computação Algébrica para os mesmos algoritmos. Pode, portanto, ser vista como uma contraparte à Computação Numérica. O advento da Computação Algébrica como campo formal de estudo se dá por volta da década de 1960 e está intimamente ligado ao surgimento de linguagens de programação voltadas para a manipulação simbólica, como a linguagem LISP. Nesta época, surgiram os primeiros programas de Computação Algébrica e, efetivamente, os primeiros CAS. Estes programas, em geral, lidavam principalmente com o problema da integração indefinida de funções e com a manipulação algébrica de funções elementares. Ao longo dos anos, o estudo da Computação Algébrica foi se consolidando e hoje é um ramo de pesquisa com vasto campo teórico, tendo aplicabilidade em áreas que vão da Criptografia à Geometria Algébrica, por exemplo. Diversos CAS estão disoníveis no mercado e são capazes de executar diversas tarefas, como integração e somatório indefinidos de funções; cálculo de limites e diferenciação; fatoração de polinômios; cálculos de mdc; eliminação gaussiana; computação de bases de Gröbner, entre outras tarefas que incluem computação gráfica, cálculos estatísticos, otimização, etc. Alguns dos CAS mais conhecidos e ainda hoje atualizados são Maple, Mathematica, Axiom e o próprio Maxima, por exemplo. Atualmente, talvez o maior e mais completo repositório de informações gerais a respeito da Computação Algébrica seja o Special Interest Group on Symbolic and Algebraic Manipulation (http://www. sigsam.org). No sítio eletrônico do SIGSAM, podem ser encontradas notícias sobre eventos de Computação Álgebrica no pelo mundo; teses recém-defendidas; uma catalogação dos livros e periódicos de Computação Algébrica publicados ou mantidos até hoje; premiações; oportunidades de pesquisa e emprego na área de Computação Algébrica em todo o mundo; uma listagem dos programas de computação algébrica; links para outros sítios eletrônicos relacionados à área, entre outras informações. É também possível associar-se ao SIGSAM através do sítio e ter acesso a diversos benefícios. 6.3 Referências em Computação Algébrica Boas leituras generalistas de Computação Algébrica incluem [11], [35] e [8] (este último em língua portuguesa). Além de trazer conteúdos abrangentes, são repletos Capítulo 6. Considerações Finais 134 de ótimas referências. O estudo da Álgebra Diferencial e da integração de funções elementares (algoritmo de Risch e complementos), pode ser encontrado em [11, Cap. 12] e nos capítulos de 3 em diante de [2]. O algoritmo de Risch é encontrado originalmente em [29]. Uma versão deste algoritmo capaz de lidar com funções especiais como as funções de erro e integrais logaritmicas foi proposta por Cherry [5, 6]. O capítulo 23 de [35] traz uma interessante introdução ao problema do somatório indefinido de funções — um análogo discreto ao problema da integração de funções. Apresenta o algoritmo de Gosper, um análogo discreto ao algoritmo de Zeilberger-Almkvist, visto no apêndice A deste trabalho. Todos os algoritmos estudados no corpo principal deste trabalho podem ser encontrados nas fontes [2], [11] e [35]. Quanto aos algoritmos que optamos por omitir, estes podem ser encontrados em [2]: 1. Algoritmo de Czichowski: envolve bases de Gröbner, conteúdo que pode ser encontrado em [11, Cap. 10] e [8, Cap. 5]. O método pode ser encontrado originalmente, em [9]. 2. Algoritmo de Bronstein-Salvy: pode ser encontrado originalmente em [3]. Trata-se de um método capaz de calcular a expansão de Laurent nos polos de um integrando racional através de operações de corpo. Pode ser usado para melhorar o algoritmo de Bernoulli. As referências acima proporcionam um bom entendimento acerca do funcionamento dos CAS da atualidade. 6.4 Acerca dos Códigos para Implementação em Maxima De modo geral, as rotinas escritas no ambiente do CAS Maxima trazidas neste trabalho funcionam de maneira satisfatória, de modo a ser possível utilizá-las para complementar a rotina de integração nativa do próprio Maxima, a qual, 135 6.4. Acerca dos Códigos para Implementação em Maxima aparentemente, recorre ao algoritmo de Bernoulli para a integração de funções racionais e não trabalha com extensões que envolvam fórmulas cúbicas ou quárticas, oferecendo resultados muito limitados. Na verdade, os resultados obtidos pelas rotinas presentes neste trabalho têm apresentação muito semelhante à daqueles obtidos pelos CAS Wolfram Alpha e Maple. Porém, durante a elaboração dos códigos, o autor do presente trabalho objetivou apenas obter códigos estáveis e legíveis em uma primeira instância, isto é, apenas códigos que funcionassem e fossem fáceis de compreender. Isto refletiu na eficiência dos códigos. Por exemplo, em uma computação de resultante sobre 𝑄[𝑧][𝑥] de grau 34 na variável 𝑧 e conteúdo com cerca de 150 dígitos, o algoritmo das subresultantes implementado pelo autor, por exemplo, chegou a demorar 4.1 segundos e utilizar cerca de 550MB de memória, contra cerca de 0.2 segundos e 70MB de memória da rotina nativa do Maxima para o cálculo de resultantes através do algoritmo das subresultantes. O resultado obtido pelas duas implementações, todavia, foi idêntico. Isto sugere que não necessariamente há falhas no código, mas programação inapropriada, ou seja, os comandos poderiam ser reescritos de modo a aproveitar melhor as potencialidades de cálculo do Maxima, reduzindo drasticamente o tempo de execução. Corroborando com esta hipótese, após uma alteração dos códigos Group, PPsDiv e SubRes, todas relativas a simplificações de expressões, o código implementado passou a levar cerca de apenas 0.6 segundos e 135MB para o cálculo da mesma resultante mencionada acima. As alerações que resultaram num ganho de eficiência, contudo, não foram mantidas por uma questão de segurança — apesar de proporcionarem um resultado satisfatório dentro da rotina das subresultantes, não foi testado com segurança como afetariam a execução das demais rotinas. O autor pretende realizar estes testes e efetuar estas alterações para maior eficiência em breve. Finalmente, apontamos para o fato de que os códigos foram testados principalmente para funções racionais em Q(𝑥). Poucos testes foram feitos utilizando-se corpos K mais gerais. Além disso, é natural que, ao se utilizar os códigos propostos com a rotina CubeSolve, o tempo de computação aumente muito, ou Capítulo 6. Considerações Finais 136 a apresentação das funções fique muito extensa, especialmente no caso real. As configurações ideais para a função IRF, portanto, são 1. para o caso real: recomenda-se utilizar, no máximo, a rotina QuadSolve; apresentação inerte em termos dos fatores da resultante; versão linear do algoritmo de Hermite, ou algoritmo de Horowitz-Ostrogradsky; Algoritmo de Czichowski, ou Lazard-Rioboo-Trager, caso a computação de bases de Gröbner falhe por algum motivo; Algoritmo de Rioboo; conversão para arcos tangentes hiperbólicos; 2. para o caso complexo: recomenda-se utilizar, no máximo, a rotina CubeSolve; apresentação inerte em termos dos fatores da resultante; versão linear do algoritmo de Hermite, ou algoritmo de Horowitz-Ostrogradsky; Algoritmo de Czichowski, ou Lazard-Rioboo-Trager, caso a computação de bases de Gröbner falhe por algum motivo; Lançamos agora algumas considerações a respeito da integração de uma função 𝑓 com coeficientes reais. Digamos que a resultante encontrada durante o processo de obtenção da parte transcendental seja 𝑅. Quando (por opção ou impossibilidade) nem todas as raízes deste polinômio são determinadas, somos ˜ que é a divisão de 𝑅 por todos os fatores deixados com um polinômio, digamos 𝑅, 𝑥 − 𝛾, onde os 𝛾 são todas as raízes de 𝑅 que determinamos. A parte inerte de ˜ ∫ 𝑓 , como vimos, será escrita em termos das raízes de 𝑅. Este polinômio poderá conter raízes envolvendo parte imaginária ou não. No caso da integração real, seria desejável, portanto, saber se 𝑅 possui pelo menos uma raiz real pura e pelo menos uma raiz com unidade imaginária. Desse modo, poderíamos expressar ∫︁ 𝑓 = 𝐹1 + ∑︁ ˜ 𝑖 (𝛾)=0 𝛾∈R|𝑄 𝛾 log(𝑣𝑖 (𝛾,𝑥)) + ∑︁ 𝛾 log(𝐴2 + 𝐵 2 ) + 𝑏𝜑, ˜ (𝛾)=0 𝛾=𝑎+𝑏𝐼∈C|𝑄 𝑖 𝑏>0 onde 𝐹1 é a parte da integral que conseguimos expressar de modo explícito a partir da determinação de parte das raízes de 𝑅, a partir dos algoritmos que estudamos ˜ 𝑖 são fatores neste trabalho, 𝐴 = 𝐴(𝑎,𝑏,𝑥), 𝐵 = 𝐵(𝑎,𝑏,𝑥), 𝜑 = 𝜑(𝑎,𝑏,𝑥) e os 𝑄 cujas raízes não conseguimos determinar de 𝑅 que, como sabemos é sempre livre 137 6.4. Acerca dos Códigos para Implementação em Maxima de quadrados, independente do método que utilizamos. Para realizar esta determinação, é possível recorrer ao algoritmo de Sturm: um algoritmo capaz de calcular o número de raízes reais distintas de um polinômio. ˜ 𝑖 , de modo que se 𝜌 é o número de raízes Este algoritmo pode ser aplicado a 𝑄 ˜ 𝑖 então grau(𝑄 ˜ 𝑖 ) − 𝜌 é o número de raízes complexas distintas de 𝑄 ˜ 𝑖. reais de 𝑄 Este algoritmo não foi implementado, todavia, nos códigos deste trabalho, de modo que o somatório mais à direita é sempre dado em termos explícitos, não em termos de raízes não determinadas. A fonte original que fundamenta este algoritmo se encontra em [32]. Capítulo 6. Considerações Finais 138 Referências Bibliográficas [1] G. Almkvist and D. Zeilberger. The method of differentiating under the integral sign. Journal of Symbolic Computation, 10:571–591, 1990. [2] M. Bronstein. Symbolic Integration I: transcendental functions. Cambridge University Press, 2nd edition, 1997. [3] M. Bronstein and B. Salvy. Full partial fraction decomposition of rational functions. Proceedings of ISSAC‘93, pages 157–160, 1993. [4] W.S. Brown and J.F. Traub. On euclid’s algorithm and the theory of subresultants. Journal of the ACM, 18:505–514, 1971. [5] G.W. Cherry. Integration in finite terms with special functions: the error function. Journal of Symbolic Computation, 1:282–302, 1985. [6] G.W. Cherry. Integration in finite terms with special functions: the logarithmic function. SIAM J. Computing, 15:1–21, 1986. [7] G.E. Collins. Subresultants and reduced polynomial remainder sequences. Journal of the ACM, 14:128–142, 1967. [8] S. C. Coutinho. Polinômios e Computação Algébrica. IMPA, Rio de Janeiro, 2012. [9] G. Czichowski. A note on gröbner bases and integration of rational functions. Journal of Symbolic Computation, 20:163–167, 1995. [10] G.M. Fichtenholz. Differential- und Integralrechnung, volume 15. SpringerVerlag, New York, 1990. Referências Bibliográficas 140 [11] K.O. Geddes, S.R. Czapor, and G. Labahn. Algorithms for Computer Algebra. Kluwer Academic Publishers, Boston, Drodrecht, London, 1992. [12] C. Hermite. Sur l’intégration des fractions rationnelles. Annales scientifiques de l’École Normale Supérieure, 1:215–218, 1872. [13] E. Horowitz. Algorithms for partial fraction decomposition and rational function integration. In Proceedings of the Second ACM Symposium on Symbolic and Algebraic Manipulation, SYMSAC ’71, pages 441–457, New York, NY, USA, 1971. ACM. [14] D.J. Jeffrey. Rectifying transformations for the integration of rational trigonometric functions. Journal of Symbolic Computation, 24(5):563 – 573, 1997. [15] S. Lang. Algebra. Springer, New York, 3rd edition, 2002. [16] S. Lang. Undergraduate Algebra. Springer, New Haven, 3rd edition, 2005. [17] D. Lazard and R. Rioboo. Integration of rational functions: Rational computation of the logarithmic part. Journal of Symbolic Computation, 9(2):113–116, 1990. [18] J. Liouville. Premier mémoire sur la détermination des intégrales dont la valeur es algebrique. Journal de l’Ecole Polytechnique, 14:124–148, 1833. [19] J. Liouville. Second mémoire sur la détermination des intégrales dont la valeur es algebrique. Journal de l’Ecole Polytechnique, 14:149–193, 1833. [20] J. Liouville. Mémoire sur l’integration d’une classe de fonctions transcendantes. Journal für die reine und angewandte Mathematik, 13:93–118, 1835. [21] J. Luetzen. Studies in the history of mathematics and physical sciences, volume 15. Springer-Verlag, New York, 1990. [22] D. Mack. On rational function integration. Computer Science Department, University of Utah, UCP-38, 1975. [23] B. Mishra. Algorithmic Algebra. Springer-Verlag, New York, 1993. 141 Referências Bibliográficas [24] T. Mulders. A note on subresultants and a correction to the lazard-riobootrager formula in rational function integration. Journal of Symbolic Computation, 24(1):45–50, 1997. [25] D.R.R. Musser. Algorithms for polynomial factorization. PhD thesis, University of Wisconsin, 1971. [26] M.W. Ostrogradsky. De l’intégration des fractions rationnelles. Bulletin de la Classe Physico-Mathématiques de l’Académie Impériale des Sciences de St. Pétersbourg, IV:145–167,286–300, 1845. [27] Loos. R. Generalized polynomial remainder sequences. Springer-Verlag, New York, 1982. pages 115–137. [28] R. Rioboo. Quelques aspects du calcul exact avec des nombre réels. PhD thesis, Université de Paris 6, Informatique, 1991. [29] R.H. Risch. On the integration of elementary functions which are built up using algebraic operations. Sys. Dev. Corp., Santa Mônica, CA, Report SP-2801/002/00, 1968. [30] J.F. Ritt. Integration in Finite Terms. Columbia University Press, New York, 1948. [31] M. Rothstein. Aspects of Symbolic Integration and Simplification of Exponential and Primitive Functions. PhD thesis, University of Wisconsin-Madison, 1976. [32] Charles Sturm. Mémoire sur la résolution des équations numériques. Springer, 2009. [33] R.G. Tobey. Algorithms for Antidifferentiation of Rational Functions. PhD thesis, Harvard University, 1967. [34] Barry M. Trager. Algebraic factoring and rational function integration. In Proceedings of the Third ACM Symposium on Symbolic and Algebraic Computation, SYMSAC ’76, pages 219–226, New York, NY, USA, 1976. ACM. Referências Bibliográficas 142 [35] J. von zur Gathen and J. Gerhard. Algorithms for Computer Algebra. Cambridge University Press, Cambridge, 2nd edition, 2003. [36] D.Y.Y. Yun. On square-free decomposition algorithms. In Proceedings of the SYMSAC’76, pages 26–35, 1976. Apêndice A Integração de Funções Hiperexponenciais A.1 O Algoritmo de Almkvist-Zeilberger Apresentaremos aqui um algoritmo para integração das funções ditas hiperexponenciais. Brevemente, seriam aquelas funções cuja derivada logarítmica é racional, como veremos a seguir. O método calcula a integral deste tipo de função quando esta integral é um múltiplo racional da mesma. Este algoritmo se encontra originalmente em [1]. Definição A.1.1. Seja 𝑓 (𝑥) uma função na variável 𝑥. Se 𝑓 ′ /𝑓 ∈ K(𝑥), K ⊆ C então dizemos que 𝑓 é hiperexponencial sobre K(𝑥) (ou que é uma extensão hiperexponencial de K(𝑥)). Exemplos de funções hiperexponenciais sobre K(𝑥) (ou simplesmente hiperexponenciais) são: 1. as funções racionais, pois é evidente que se 𝑓 ∈ K(𝑥) então 𝑓 ′ /𝑓 ∈ K(𝑥); 2. exponenciais de funções racionais, pois, dada 𝑓 ∈ K(𝑥), temos que exp(𝑓 )′ / exp(𝑓 ) = 𝑓 ′ ∈ K(𝑥); 3. produtos finitos de funções exponenciais, pois se 𝑓 e 𝑔 são hiperexponenciais, então (𝑓 𝑔)′ /𝑓 𝑔 = 𝑓 ′ /𝑓 + 𝑔 ′ /𝑔 ∈ K(𝑥); Apêndice A. Integração de Funções Hiperexponenciais 144 4. potências de funções hiperexponenciais, pois se 𝑓 é hiperexponencial e 𝑟 ∈ K então (𝑓 𝑟 )′ /𝑓 𝑟 = 𝑟(𝑓 𝑟−1 )𝑓 ′ /𝑓 𝑟 = 𝑟𝑓 ′ /𝑓 ∈ K(𝑥). Considere o problema de encontrar a integral de uma função 𝑓 hiperexponencial sobre K(𝑥), isto é, encontrar uma função 𝑔 (não necessariamente pertencente a K(𝑥)) tal que 𝑔′ = 𝑓 Se assumirmos que o problema acima possui uma solução também hiperexponencial, o algoritmo de Almkvist-Zeilberger, o qual discutiremos nesta seção, nos mostra como obtê-la. Consequentemente, quando o algoritmo não é capaz de encontrar qualquer solução hiperexponencial, então não existe solução alguma do problema satisfazendo esta condição. Por este motivo, dizemos que este é um algoritmo de decisão. Primeiramente, observemos que se 𝑓 é hiperexponencial então temos que a sua derivada logaritmica 𝜎 = 𝑓 ′ /𝑓 pertence a K(𝑥). Se o problema admite solução 𝑔 hiperexponencial então 𝜌 = 𝑔 ′ /𝑔 e 𝑓 = 𝑔 ′ = 𝜌𝑔. Portanto, 𝑔 = 𝑓 /𝜌. Naturalmente, 𝜌 ̸= 0, ou teríamos 𝑓 = 0, pela equação acima. Portanto, se a solução 𝑔 existir, deve ser um múltiplo racional de 𝑓 , o que quer dizer que 𝑔 ∈ K(𝑥). Seja, portanto 𝑔 uma solução do para 𝑔 ′ = 𝑓 , isto é, 𝑔 = 𝜏 𝑓 para alguma função 𝜏 ∈ K(𝑥). Temos que 𝑔 ′ = (𝜏 𝑔)′ = 𝜏 ′ 𝑔 + 𝜏 𝑔 ′ = (𝜏 ′ + 𝜎𝜏 )𝑔. A equação acima possui solução se e só se 𝜏 é solução da equação diferencial de Risch 𝜏 ′ + 𝜎𝜏 = 1. (A.1) Na equação (A.1) acima, há apenas termos racionais, isto é, eliminamos todos os termos puramente hiperexponenciais do problema original e agora nossa questão 145 A.1. O Algoritmo de Almkvist-Zeilberger se reduz a encontrar soluções racionais. Mais além, se escrevermos 𝜎 = 𝑎/𝑏 em sua forma reduzida com 𝑎,𝑏 ∈ K[𝑥], e, de modo semelhante, 𝜏 = 𝑢/𝑣 em sua forma reduzida com 𝑢,𝑣 ∈ K[𝑥] e multiplicarmos a equação (A.1) por 𝑏𝑣 2 , vemos que o problema se reduz a encontrar polinômios 𝑢,𝑣 ∈ K[𝑥] tais que 𝑏𝑢′ 𝑣 − 𝑏𝑢𝑣 ′ + 𝑎𝑢𝑣 = 𝑏𝑣 2 . (A.2) Uma vez encontrados polinômios 𝑢,𝑣 ∈ K[𝑥] que satisfazem (A.2), temos uma solução para o problema original. Basta fazer 𝑔 = (𝑢/𝑣)𝑓 . Vamos, discutir como resolver a equação (A.2). Nossa abordagem será procurar primeiro algum múltiplo do polinômio 𝑣, tal que a equação (A.2) aplicada a este polinômio no lugar de 𝑣 possua solução em um múltiplo de 𝑢. Mostraremos que, para a obtenção do múltiplo de 𝑣, precisamos tão somente conhecer 𝑎 e 𝑏. Definimos, para tanto, 𝑣0 = 𝑣 * = 𝑣/𝑣 − e 𝑣1 = 𝑣 ′ /𝑣 − , ambos em K[𝑥]. Observe que 𝑣0 e 𝑣1 são relativamente primos. Dividindo (A.2) por gcd(𝑣,𝑣 ′ ), temos 𝑏𝑢′ 𝑣0 − 𝑏𝑢𝑣1 + 𝑎𝑢𝑣0 = 𝑏𝑣𝑣0 (A.3) Observe que 𝑣0 divide 𝑏𝑢𝑣1 e, como mdc(𝑢,𝑣) = mdc(𝑣𝑐 ,𝑣1 ) = 1, também divide 𝑏. Portanto, podemos dividir (A.3) por 𝑣0 obtendo (︃ )︃ 𝑏 𝑏𝑢 + 𝑎 − 𝑣1 𝑢 = 𝑏𝑣 ′ , 𝑣0 ′ donde podemos concluir que 𝑣0 divide 𝑎 − (𝑏/𝑣0 )𝑣1 , uma vez que 𝑣0 divide 𝑏 e é relativamente primo a 𝑢. Seja 𝑣 = ℎ11 · · · ℎ𝑘𝑘 a flq de 𝑣. Temos que 𝑣0 = ℎ1 · · · ℎ𝑘 e ∑︀𝑘 𝑣1 = ℎ𝑖𝑖 ′ ∏︀ 𝑗̸=𝑖 ∏︀𝑘 𝑖−1 𝑖=1 ℎ𝑖 𝑖=1 ℎ𝑗𝑗 ∑︀𝑘 = = 𝑖=1 𝑘 ∑︁ 𝑖=1 𝑖−1 𝑖=1 ℎ𝑖 ∏︀𝑘 𝑖−1 𝑖=1 ℎ𝑖 𝑘 ∏︁ ∑︁ 𝑖ℎ′𝑖 𝑖ℎ′𝑖 ∏︀𝑘 ℎ𝑗 = 𝑗̸=𝑖 ∏︀ 𝑗̸=𝑖 ℎ𝑗 𝑖ℎ′𝑖 𝑣0 . 𝑖=1 ℎ𝑖 Apêndice A. Integração de Funções Hiperexponenciais 146 Além disso, para cada ℎ𝑖 , (︃ (︃ 𝑏 𝑣0 𝑏 ′ 𝑏 𝑏 𝑏 𝑣1 ≡ 𝑖ℎ′𝑖 = 𝑖 ℎ′𝑖 ≡ 𝑖 ℎ𝑖 + 𝑣0 𝑣0 ℎ𝑖 ℎ𝑖 ℎ𝑖 ℎ𝑖 )︃′ )︃ ℎ𝑖 = 𝑖𝑏′ mod ℎ𝑖 . Cada ℎ𝑖 divide 𝑏 pelas contas acima e ambas as parcelas do lado esquerdo na equação )︃ (︃ )︃ (︃ 𝑏 𝑏 ′ 𝑣1 − 𝑖𝑏 = 𝑎 − 𝑖𝑏′ , 𝑎 − 𝑣1 + 𝑣0 𝑣0 portanto cada ℎ𝑖 divide mdc(𝑏,𝑎 − 𝑖𝑏′ ). Lançamos o seguinte teorema Teorema A.1.1 ([35], Cap. 22, §4). Sejam 𝑢,𝑣 ∈ K[𝑥] polinômios relativamente primos em K[𝑥] constituindo uma solução para (A.2), com 𝑣 ̸= 0 mônico e 𝑣 = ℎ11 · · · ℎ𝑘𝑘 sendo decomposição em fatores livres de quadrados de 𝑣. Definamos 𝑅(𝑧) = res𝑥 (𝑏,𝑎 − 𝑧𝑏′ ), 𝑑 = max{𝑖 ∈ N | 𝑖 = 0 ou 𝑅(𝑖) = 0}, 𝐻𝑖 = gcd(𝑏,𝑎 − 𝑖𝑏′ ), (1 ≤ 𝑖 ≤ 𝑑). Então, 𝑘 ≤ 𝑑 e ℎ𝑖 | 𝐻𝑖 , para 1 ≤ 𝑖 ≤ 𝑘. Demonstração. Podemos supor que grau(𝑣) ≥ 1. Temos que grau(ℎ𝑚 ) > 0, pela definição de decomposição livre de quadrados. Observe que, como já dissemos, ℎ𝑖 divide mdc(𝑏,𝑎−𝑖𝑏′ ) para todo 𝑖. Em particular, isto quer dizer que grau(mdc(𝑏,𝑎− 𝑚𝑏′ )) > 0 e, portanto 𝑅(𝑚) = res𝑥 (𝑏,𝑎 − 𝑚𝑏′ ) = 0. Logo, 𝑚 ≤ 𝑑 e ℎ𝑖 | 𝐻𝑖 para 1 ≤ 𝑖 ≤ 𝑚. Finalmente, 2 𝑚 2 𝑚 𝑚+1 𝑑 𝑣 = ℎ1 ℎ22 · · · ℎ𝑚 𝑚 | 𝐻1 𝐻2 · · · 𝐻𝑚 | 𝐻1 𝐻2 · · · 𝐻𝑚 𝐻𝑚+1 · · · 𝐻𝑑 = 𝑉. Portanto, alcançamos nosso objetivo de calcular um múltiplo 𝑉 = 𝐻1 · · · 𝐻𝑑𝑑 ∏︁ de 𝑣 conhecendo tão somente os polinômios 𝑎 e 𝑏. Observe que 𝑉 = 𝐻𝑖𝑖 é própria flq de 𝑉 : se 𝛾 ∈ K e 𝑝 é um fator irredutível de mdc(𝑏,𝑎 − 𝛾𝑏′ ), então 𝑝 | 𝑏, 𝑎 − 𝛾𝑏′ . Por outro lado, se ocorresse 𝑝2 | 𝑏, então teríamos 𝑝 | 𝑏′ e, portanto, 𝑝 | 𝑎, contrariando o fato de que 𝑎 e 𝑏 são primos entre si. Assim, 147 A.1. O Algoritmo de Almkvist-Zeilberger para todo 𝛾 ∈ K, mdc(𝑏,𝑎 − 𝛾𝑏′ ) é livre de quadrados. Então, dados 𝛾1 ,𝛾2 ∈ K, se 𝐺1 = mdc(𝑏,𝑎 − 𝛾1 𝑏′ ), 𝐺2 = mdc(𝑏,𝑎 − 𝛾2 𝑏′ ) e 𝐺 = mdc(𝐺1 ,𝐺2 ), então 𝐺 | 𝑏, 𝑎 − 𝛾1 𝑏′ , 𝑎 − 𝛾2 𝑏′ , donde 𝐺 | (𝛾1 − 𝛾2 )𝑏′ e, portanto, se 𝛾1 = ̸ 𝛾2 , 𝐺 | 𝑎, donde 𝐺 = 1. Concluímos que os 𝐻𝑖 são livres de quadrados e dois a dois primos entre si. O algoritmo sugerido pelo Teorema A.1.1 pode ser melhorado se a cada passo retirarmos 𝐻𝑖 de 𝑏 e 𝑎 − 𝑖𝑏′ : se 𝑎0 = 𝑎 e 𝑏0 = 𝑏, definimos as sequências 𝐻𝑖 = mdc(𝑏𝑖−1 ,𝑎𝑖−1 − 𝑏′𝑖−1 ), 𝑎𝑖 = 𝑎𝑖−1 − 𝑏′𝑖−1 𝑏𝑖−1 , 𝑏𝑖 = . 𝐻𝑖 𝐻𝑖 (A.4) Observe que, dado 1 ≤ 𝑖 ≤ 𝑑, se para algum par 𝑘 tal que 1 ≤ 𝑘 < 𝑖 temos que 𝐻𝑖 = mdc(𝑏𝑖−𝑘 ,𝑎𝑖−𝑘 − 𝑘𝑏′𝑖−𝑘 ) então 2 2 𝐻𝑖 = mdc(𝐻𝑖−𝑘 𝑏𝑖−𝑘 ,𝐻𝑖−𝑘 (𝑎𝑖−𝑘 − 𝑘𝑏′𝑖−𝑘 )) 2 = mdc(𝐻𝑖−𝑘 𝑏𝑖−𝑘−1 ,𝐻𝑖−𝑘 (𝑎𝑖−𝑘−1 − 𝑏′𝑖−𝑘−1 ) − 𝐻𝑖−𝑘 𝑘𝑏′𝑖−𝑘 ) ′ = mdc(𝐻𝑖−𝑘 𝑏𝑖−𝑘−1 ,𝐻𝑖−𝑘 𝑎𝑖−𝑘−1 − (𝑘 + 1)𝐻𝑖−𝑘 𝑏′𝑖−𝑘−1 − 𝑏𝑖−𝑘−1 𝐻𝑖−𝑘 ) = mdc(𝑏𝑖−(𝑘+1) ,𝑎𝑖−(𝑘+1) − (𝑘 + 1)𝑏′𝑖−(𝑘+1) ) onde utilizamos o fato de que 𝐻𝑖−𝑘 | 𝑏𝑖−𝑘−1 na última igualdade. O argumento acima é válido para 𝑘 = 1 e por indução, válido para qualquer 𝑘 tal que 1 ≤ 𝑘 < 𝑖, em particular para 𝑘 = 𝑖 − 1, donde concluímos que 𝐻𝑖 = mdc(𝑏,𝑎 − 𝑖𝑏′ ), para todo 𝑖. Assim, as sequências definidas em (A.4) também nos fornecem um modo mais eficiente de calcular o múltiplo 𝑉 fornecido pelo Teorema A.1.1 [35, Cap. 22, §4]. Damos prosseguimento à nossa abordagem, buscando um múltiplo 𝑈 do polinômio 𝑢 para o qual a equação (A.2) aplicada a 𝑈 e 𝑉 possua solução. Isto é, buscamos uma solução 𝑈 para a equação 𝑏𝑉 𝑈 ′ − (𝑏𝑉 ′ − 𝑎𝑉 )𝑈 = 𝑏𝑉 2 (A.5) cuja existência implica que 𝜏 = 𝑈/𝑉 ∈ K(𝑥) é solução de (A.1) e 𝑔 = 𝑈 𝑓 /𝑉 resolve o problema em questão. Reciprocamente, se 𝜏 = 𝑢/𝑣 satisfaz (A.1), com 𝑢 e 𝑣 primos entre si e 𝑣 ̸= 0 mônico, então 𝑈 = 𝑢𝑉 /𝑣 é uma solução para (A.5). Apêndice A. Integração de Funções Hiperexponenciais 148 Dividindo-se ambos os lados da equação (A.1) por ℎ = mdc(𝑏𝑉,𝑏𝑉 ′ −𝑎𝑉 ) ∈ K[𝑥], temos a equação equivalente 𝑟𝑈 ′ − 𝑠𝑈 = 𝑡, (A.6) onde 𝑟 = 𝑏𝑉 /ℎ,𝑠 = (𝑏𝑉 ′ − 𝑎𝑉 )/ℎ é mônico, e 𝑡 = 𝑟𝑉 é não nulo. A equação (A.6) é uma identidade polinomial à qual corresponde um sistema linear cujas incógnitas são os coeficientes de 𝑈 . A solubilidade desta equação, portanto, depende da solubilidade do seu sistema linear associado. Assim, tudo o que precisamos é determinar um limite superior para o grau de 𝑈 , a fim de que tenhamos as dimensões do sistema linear associado. Este limite é fornecido pelo seguinte resultado. Lema A.1.1 ([35], Cap. 22, §4). Sejam 𝑟,𝑠,𝑡,𝑈 ∈ K[𝑥] satisfazendo (A.6), com 𝑟,𝑈 não nulos e 𝑟 mônico, 𝑚 = max{grau(𝑟) − 1, grau(𝑠)}, e seja 𝛿 ∈ K o coeficiente de 𝑥𝑚 em 𝑠. (Como de costume, 𝛿 = 0 se 𝑚 < 0 ou grau(𝑠) < 𝑚.) Além disso, seja ⎧ ⎪ ⎪ grau(𝑡) − 𝑚 ⎪ ⎪ ⎨ se grau(𝑟) − 1 < grau(𝑠) ou ⎪ ⎪ ⎪ ⎩𝛿 caso contrário. 𝑒=⎪ 𝛿∈ / N − {0,1, . . . , grau(𝑡) − 𝑚}, Então, o seguinte se verifica. 1. Ou grau(𝑈 ) = grau(𝑡) − 𝑚, ou grau(𝑈 ) = 𝛿 > grau(𝑡) − 𝑚 e grau(𝑟) − 1 ≥ grau(𝑠). Em particular, grau(𝑈 ) ≤ 𝑒. 2. Se grau(𝑟) − 1 ≥ grau(𝑠), então grau(𝑡) − 𝑚 ̸= 𝛿. 3. Se 𝑡 = 0, então grau(𝑟) − 1 ≥ grau(𝑠) e grau(𝑈 ) = 𝛿 ∈ N. 4. Se grau(𝑟) − 1 < grau(𝑠) ou 𝛿 ∈ / N, então exatamente um 𝑈 ∈ 𝐹 [𝑥] satisfaz a equação (A.6). Lembramos que o polinômio nulo possui grau −∞, portanto grau(𝑡) − 𝑚 deve ser interpretado como −∞ se 𝑡 = 0. Temos que N ⊆ Q ⊆ K, então qualquer inteiro é também um elemento de K. 149 A.1. O Algoritmo de Almkvist-Zeilberger Demonstração. Faremos uma comparação de coeficientes e graus em (A.6). Primeiramente, temos que grau(𝑡) ≤ max{grau(𝑟𝑈 ′ ), grau(𝑠𝑈 )} max{grau(𝑟) + grau(𝑈 ) − 1, grau(𝑠) + grau(𝑈 )} = 𝑚 + grau(𝑈 ). Seja 𝛾 o coeficiente de 𝑥𝑚+1 em 𝑟. Temos que o coeficiente de 𝑥𝑚+grau(𝑈 ) em 𝑟𝑈 ′ é 𝛾𝜂 grau(𝑈 ), onde 𝜂 = cl(𝑈 ), e o coeficiente de 𝑥𝑚+grau(𝑈 ) de 𝑠𝑈 é 𝛿𝜂. Logo, o coeficiente de 𝑥𝑚+grau(𝑈 ) em 𝑡 é (𝛾 grau(𝑈 ) − 𝛿)𝜂, e grau(𝑡) < 𝑚 + grau(𝑈 ) se e só se esse coeficiente é 0. Se grau(𝑟)−1 < grau(𝑠), então 𝛾 = 0 e 𝛿 é o coeficiente (não nulo) de 𝑠, donde grau(𝑈 ) = grau(𝑡) − 𝑚. Caso contrário, temos que 𝛾 = cl(𝑟) = 1. Finalmente, temos que grau(𝑈 ) ≥ grau(𝑡) − 𝑚, onde a desigualdade estrita ocorre se e só se grau(𝑟) − 1 ≥ grau(𝑠) e grau(𝑈 ) = 𝛿. Com isto, provamos as afirmações 1,2 e 3. Agora, se 𝑈 * ∈ K[𝑥] é outra solução para (A.6), então 𝑈 − 𝑈 * satisfaz a equação homogênea 𝑟(𝑈 − 𝑈 * )′ − 𝑠(𝑈 − 𝑈 * ) = 0 e, portanto, a afirmação 4 segue da afirmação 3. Conhecidos os polinômios 𝑟,𝑠,𝑡 = 𝑟𝑉 , podemos, portanto, determinar um limite superior para o grau de 𝑈 . Se o valor de 𝑒 é inteiro e não negativo, e se grau(𝑟)−1 < grau(𝑠), ou se grau(𝑡)−𝑚 ̸= 𝛿, tudo o que precisamos fazer é montar e resolver o sistema linear associado a (A.6) cujas incógnitas são os coeficientes de 𝑈 . Neste caso, nossa solução para a equação (A.6) é 𝜏 = 𝑈/𝑉 ∈ K(𝑥), donde 𝑓 𝑈/𝑉 é uma integral hiperexponencial de 𝑓 . Se 𝑒 é negativo, ou se grau(𝑟) − 1 ≥ grau(𝑠) e grau(𝑡) − 𝑚 = 𝛿, ou se o sistema linear não possui solução, então (A.1) não possui solução racional em 𝜏 , e, portanto, o problema original não possui solução hiperexponencial. Note que, uma vez que encontramos 𝜏 = 𝑈/𝑉 ∈ K(𝑥), é interessante colocar 𝜏 em sua forma canônica, retirando mdc(𝑈,𝑉 ) do numerador e do denominador. Isto conclui o algoritmo de Almkvist-Zeilberger. A respeito do espaço de soluções do sistema linear associado a (A.6), este é vazio, possui exatamente um elemento, ou é uma variedade afim unidimensional. Neste último caso, em geral, é Apêndice A. Integração de Funções Hiperexponenciais 150 preferível escolher por uma solução deste espaço para a qual o polinômio 𝑈 possua o menor grau possível. O sistema linear em questão é triangular, de modo que pode ser resolvido tão somente através de substituição retroativa, dispensando a eliminação de Gauss, o que leva 𝑂(𝑒2 ) operações em K. Há, no máximo, um 0 na diagonal, o que ocorre apenas quando grau(𝑟) − 1 ≥ grau(𝑠). A equação A.6 pode ser reduzida ainda mais através das seguintes considerações. Temos que mdc(𝑟,𝑡) = mdc(𝑟,𝑟𝑉 ) = 𝑟 e mdc(𝑟,𝑠) = 1, onde 𝑡 = 𝑟𝑉 . Pela equação A.6, isso significa que 𝑟 | 𝑈 , isto é 𝑈 = 𝑈 * 𝑟. Assim, ′ 𝑟(𝑈 * 𝑟)′ − 𝑠(𝑈 * 𝑟) = 𝑟𝑉 =⇒ 𝑟(𝑈 * 𝑟 + 𝑈 * 𝑟′ ) − 𝑠𝑈 * 𝑟 = 𝑟𝑉 =⇒ 𝑟𝑈 * ′ − (𝑠 − 𝑟′ )𝑈 * = 𝑉. (A.7) A equação (A.7) pode ser utilizada no lugar da equação (A.6) durante o algoritmo de Almkvist-Zeilberger, de modo que só precisamos encontrar o polinômio 𝑈 * de grau 𝑒 − grau(𝑟) e então multiplicá-lo por 𝑟 para obter a solução da equação (A.6) e, consequentemente, do problema de integração. Evidentemente, isso diminui a quantidade de operações do algoritmo, uma vez que o sistema induzido pela (A.7) possui 𝑒 − grau(𝑟) equações e 𝑒 − grau(𝑟) incógnitas. A.1.1 Exemplos Exemplo A.1.1 (extraído de [35], Cap. 22, §4). Seja 𝑓 = 𝑥𝑛 exp(𝑥) ∈ Q(𝑥, exp(𝑥)), onde 𝑛 ∈ N. Como vimos, 𝑓 é hiperexponencial. Sua derivada logarítmica é 𝑥+𝑛 𝑔′ = , 𝑔 𝑥 donde 𝐴 = 𝑥 + 𝑛 e 𝐷 = 𝑥. 𝑅(𝑧) = res𝑥 (𝐷,𝐴 − 𝑧𝐷′ ) = res𝑥 (𝑥,𝑥 + 𝑛 − 𝑧) = 𝑛 − 𝑧, donde 𝑅(𝑖) = 0 apenas para 𝑖 = 𝑛 e, portanto, 𝑑 = 𝑛. O código A.2.1 calcula 𝐻𝑖 = 1 para 1 ≤ 𝑖 ≤ 𝑛, e 𝐻𝑛 = 𝑥, donde 𝑉 = 𝑥𝑛 . No código A.2.2, temos que 𝐷𝑉 = 𝑥𝑛+1 , 𝐷𝑉 ′ −𝐴𝑉 = −𝑥𝑛+1 e, portanto, ℎ = 𝑥𝑛+1 , 𝑟 = 1, 𝑠 = −1 e 𝑡 = 𝑥𝑛 . Assim, temos 𝑈 ′ + 𝑈 = 𝑥𝑛 (A.8) 151 A.1. O Algoritmo de Almkvist-Zeilberger Temos que 𝑚 = max{grau(𝑟)−1, grau(𝑠)} = 0 > grau(𝑟)−1 e, portanto, estamos no primeiro caso do Lema A.1.1, de modo que 𝑒 = grau(𝑡) − 𝑚 = 𝑛. Portanto, 𝐻 = (𝑈𝑛 − 1)𝑥𝑛 + (𝑛𝑈𝑛 + 𝑈𝑛−1 )𝑥𝑛−1 + · · · + (2𝑈2 + 𝑈1 )𝑥 + (𝑈1 + 𝑈0 ). O sistema linear a resolver se torna 𝑈𝑛 − 1 = 0 𝑛𝑈𝑛 + 𝑈𝑛−1 = 0 ... 2𝑈2 + 𝑈1 = 0 𝑈1 + 𝑈0 = 0. O sistema possui solução única e satisfaz 𝑈0 ̸= 0, donde mdc(𝑈,𝑉 ) = 1. A resposta retornada é 𝑢 = 𝑈 e 𝑣 = 𝑉 = 𝑥𝑛 , onde 𝑈 = 𝑥𝑛 + 𝑛−1 ∑︁ (−1)𝑛−𝑖 𝑖=0 𝑛! 𝑖 𝑥. 𝑖! Dessa forma, se 𝑛 = 3, temos que 𝑈 = 𝑥3 − 3𝑥2 + 6𝑥 − 6 e 𝑉 = 𝑥3 . Portanto, ∫︁ 𝑈 𝑥 exp(𝑥) = (𝑥3 exp(𝑥)) = 𝑉 3 (︃ )︃ 𝑥3 − 3𝑥2 + 6𝑥 − 6 (𝑥3 exp(𝑥)) 𝑥3 = 𝑥3 exp(𝑥) − 3𝑥2 exp(𝑥) + 6𝑥 exp(𝑥) − 6 exp(𝑥). De fato, (𝑥3 exp(𝑥) − 3𝑥2 exp(𝑥) + 6𝑥 exp(𝑥) − 6 exp(𝑥))′ = (3𝑥2 − 6𝑥 + 6) exp(𝑥) + (𝑥3 − 3𝑥2 + 6𝑥 − 6) exp(𝑥) = 𝑥3 exp(𝑥). Exemplo A.1.2 (extraído de [35], Cap. 22, §4). Seja 𝑓 = 1/𝑥 ∈ Q(𝑥). Temos que 𝑓 ′ /𝑓 = −1/𝑥 e 𝐴 = −1, 𝐷 = 𝑥, 𝑅(𝑧) = res𝑥 (𝑥, − 1 − 𝑧) = −(𝑧 + 1). Logo, 𝑑 = 0 e 𝑉 = 1. Assim, 𝑥𝑈 ′ − 𝑈 = 𝑥. Apêndice A. Integração de Funções Hiperexponenciais 152 Ou seja, 𝑟 = 𝑡 = 𝑥, 𝑠 = 1, 𝑚 = grau(𝑠) = grau(𝑟) − 1 = 0 e grau(𝑡) − 𝑚 = 1 = 𝛿. Estamos no caso 2 do Lema A.1.1 e a equação acima não possui solução 𝑈 ∈ Q[𝑥]. Logo ∫ (1/𝑥) não é hiperexponencial. Afinal, equivale a log(𝑥), e log(𝑥)′ / log(𝑥) = 1/(𝑥 log(𝑥)) ∈ / Q(𝑥). Exemplo A.1.3 (extraído de [35], Cap. 22, §4). Seja 𝑓 = √ Q(𝑥, 𝑥2 + 1). Temos −3𝑥 𝑓′ = 2 , 𝑓 𝑥 +1 √︁ 1/(𝑥2 + 1)3 ∈ de modo que 𝐴 = −3𝑥, 𝐷 = 𝑥2 + 1, 𝑅(𝑧) = res𝑥 (𝑥2 + 1, − 3𝑥 − 𝑧2𝑥) = (2𝑧 + 3)3 , 𝑑 = 0 e 𝑉 = 1. Assim (𝑥2 + 1)𝑈 ′ − 3𝑥𝑈 = 𝑥2 + 1. Ou seja, 𝑟 = 𝑡 = 𝐷 = (𝑥2 + 1), 𝑠 = −𝐴 = 3𝑥, 𝑚 = max{grau(𝑟) − 1, grau(𝑠)} = 1 e nos encontramos no caso 2 do Lema A.1.1. Agora 1 = grau(𝑡) − 𝑚 ̸= 𝛿 = 3, donde, pelo lema grau(𝑈 ) = 𝛿 = 3. Portanto, 𝐻 = (2𝑈2 − 3𝑈2 )𝑥3 + (𝑈1 + 3𝑈3 − 3𝑈1 − 1)𝑥2 + (2𝑈2 − 3𝑈0 )𝑥 + (𝑈1 − 1) O sistema a resolver é −𝑈2 = 0 3𝑈3 − 2𝑈1 − 1 = 0 2𝑈2 − 3𝑈0 = 0 𝑈1 − 1 = 0. A única solução é 𝑈3 = 𝑈1 = 1 e 𝑈2 = 𝑈0 = 0. Logo, 𝑈 = 𝑥3 + 𝑥, 𝑢 = 𝑈 e 𝑣 = 1. Assim, ∫︁ 1 𝑥 1 √︁ = (𝑥3 + 𝑥) √︁ = √︁ . (𝑥2 + 1)3 (𝑥2 + 1)3 (𝑥2 + 1) De fato, ⎛ ⎝ √︁ 𝑥 (𝑥2 + 1) ⎞′ ⎠ = 1 √︁ (𝑥2 − + 1) 𝑥2 √︁ (𝑥2 + 1)3 1 = √︁ . 2 (𝑥 + 1)3 153 A.1. O Algoritmo de Almkvist-Zeilberger Exemplo A.1.4 (gerado com dados obtidos pelos códigos de A.2.1 e A.2.2). Considere a função 𝑥3 − 3𝑥 + 2 𝑓= 5 𝑥 − 4𝑥3 + 4𝑥 Temos 𝑉 = (𝑥 + 2)(𝑥 − 1)2 ℎ = 𝑥5 + 𝑥4 − 5𝑥3 − 𝑥2 + 8𝑥 − 4 𝑟 = 𝑥3 − 2𝑥 𝑠 = 5𝑥2 − 2 𝑡 = 𝑥6 − 5𝑥4 + 2𝑥3 + 6𝑥2 − 4𝑥 𝑚=2 𝛿=5 𝑒 = 5. O sistema induzido pela equação (A.6) é −2𝑈0 = 0 −4 = 0 2𝑈2 + 5𝑈0 + 6 = 0 4𝑈3 + 4𝑈1 + 2 = 0 6𝑈4 + 3𝑈2 − 5 = 0 8𝑈5 + 2𝑈3 = 0 𝑈4 + 1 = 0, (A.9) o qual, evidentemente, não possui solução. De fato, para esta função, a rotina HorOstro, devolve parte logarítmica não nula. Mais precisamente, ∫︁ 𝑓= ∫︁ 𝑥−2 5𝑥 − 4 + , 4(𝑥2 − 2) 4(𝑥3 − 2𝑥) Apêndice A. Integração de Funções Hiperexponenciais 154 sendo 𝑥3 − 2𝑥 livre de quadrados. Pela equação (A.7), o sistema induzido é −2 = 0 2𝑈1 − 3 = 0 4𝑈2 + 2𝑈0 = 0 𝑈1 + 1 = 0 o qual, evidentemente, também não possui solução. Exemplo A.1.5 (gerado com dados obtidos pelos códigos de A.2.1 e A.2.2). Considere a função 8𝑥 𝑓= 4 𝑥 + 4𝑥2 + 4 Temos 𝑉 =𝑥 ℎ = 𝑥2 𝑟 = 𝑥2 + 2 𝑠 = 4𝑥 𝑡 = 𝑥3 + 2𝑥 𝑚=1 𝛿=4 𝑒 = 4. O sistema induzido pela equação (A.6) é −2𝑈1 = 0 −4𝑈2 + 4𝑈0 + 2 = 0 3𝑈1 − 6𝑈3 = 0 −8𝑈4 + 2𝑈2 + 1 = 0 𝑈3 = 0, 155 A.1. O Algoritmo de Almkvist-Zeilberger cujo espaço de soluções é }︃ {︃ 8𝜆 − 1 ,𝑈3 = 0,𝑈4 = 𝜆 . 𝑆 = 𝑈0 = 4𝜆 − 1,𝑈1 = 0,𝑈2 = 2 Portanto, 𝑈 = 𝜆𝑥4 + 8𝜆 − 1 2 𝑥 + 4𝜆 − 1. 2 escolhendo 𝜆 = 0 temos, portanto, 𝑈 = (−1/2)𝑥2 − 1 e ∫︁ 𝑓= 8𝑥 4 (−1/2)𝑥2 − 1 =− 2 4 2 𝑥 𝑥 + 4𝑥 + 4 𝑥 +2 Pela equação (A.7), o sistema induzido é −2𝑈1 = 0 −4𝑈2 + 2𝑈0 + 1 = 0 𝑈1 = 0 (A.10) cujo espaço de soluções é {︃ }︃ 4𝜆 − 1 𝑆 = 𝑈0 = ,𝑈1 = 0,𝑈2 = 𝜆 . 2 Portanto, 𝑈 = 𝜆𝑥2 + 4𝜆 − 1 . 2 escolhendo 𝜆 = 0 temos, portanto, 𝑈 = −1/2 e 𝑟𝑈 = (−1/2)𝑥2 − 1. Exemplo A.1.6 (gerado com dados obtidos pelos códigos de A.2.1 e A.2.2). Considere a função 𝑓= 6𝑥10 − 13𝑥8 + 16𝑥6 + 8𝑥4 + 10𝑥2 − 3 2 (𝑥 + 1)−2/3 exp(𝑥2 ), 3((𝑥4 + 1)(𝑥2 + 1))2 Isto é um produto entre uma função racional, uma algébrica não trivial sobre Apêndice A. Integração de Funções Hiperexponenciais Q(𝑥) e uma função exponencial, todas funções hiperexponenciais. Temos 𝑉 = 6𝑥10 − 13𝑥8 + 16𝑥6 + 8𝑥4 + 10𝑥2 − 3 ℎ = 36𝑥20 − 156𝑥18 + 361𝑥16 − 320𝑥14 + 168𝑥12 − 40𝑥10 + 462𝑥8 + 64𝑥6 + 52𝑥4 − 60𝑥2 + 9 𝑟 = 3𝑥6 + 3𝑥4 + 3𝑥2 + 3 𝑠 = −6𝑥7 + 34𝑥5 + 18𝑥3 + 10𝑥 𝑡 = 18𝑥16 − 21𝑥14 + 27𝑥12 + 51𝑥10 + 63𝑥8 + 93𝑥6 + 45𝑥4 + 21𝑥2 − 9 𝑚=7 𝛿 = −6 𝑒 = 9. 156 157 A.1. O Algoritmo de Almkvist-Zeilberger O sistema induzido pela equação (A.6) é −3𝑈1 − 9 = 0 10𝑈0 − 6𝑈2 = 0 −9𝑈3 + 7𝑈1 + 21 = 0 12𝑈4 + 4𝑈2 + 18𝑈0 = 0 −15𝑈5 + 𝑈3 + 15𝑈1 + 45 = 0 −18𝑈6 − 2𝑈4 + 12𝑈2 + 34𝑈0 = 0 −21𝑈7 − 5𝑈5 + 9𝑈3 + 31𝑈1 + 93 = 0 −24𝑈8 − 8𝑈6 + 6𝑈4 + 28𝑈2 − 6𝑈0 = 0 −27𝑈9 − 11𝑈7 + 3𝑈5 + 25𝑈3 − 6𝑈1 + 63 = 0 −14𝑈8 + 22𝑈4 − 6𝑈2 = 0 −17𝑈9 − 3𝑈7 + 19𝑈5 − 6𝑈3 + 51 = 0 −𝑈8 + 16𝑈6 − 6𝑈4 = 0 −9𝑈9 + 13𝑈7 − 6𝑈5 + 27 = 0 10𝑈8 − 6𝑈6 = 0 7𝑈9 − 6𝑈7 − 21 = 0 −6𝑈8 = 0 18 − 6𝑈9 = 0 cuja solução única é 𝑈1 = −3, 𝑈9 = 3 e os demais coeficientes nulos. Portanto, 𝑈 = 3𝑥9 − 3𝑥, donde ∫︁ 3𝑥9 − 3𝑥 𝑓 6𝑥10 − 13𝑥8 + 16𝑥6 + 8𝑥4 + 10𝑥2 − 3 𝑥3 − 𝑥 = 2 (𝑥2 + 1)−2/3 exp(𝑥2 ). (𝑥 + 1)(𝑥4 + 1) 𝑓= Apêndice A. Integração de Funções Hiperexponenciais 158 Pela equação (A.7), o sistema induzido é −3𝑈1 − 3 = 0 4𝑈0 − 6𝑈2 = 0 −9𝑈3 + 𝑈1 + 10 = 0 −2𝑈2 + 6𝑈0 = 0 −5𝑈3 + 3𝑈1 + 8 = 0 16𝑈0 = 0 −3𝑈3 + 13𝑈1 + 16 = 0 10𝑈2 − 6𝑈0 = 0 7𝑈3 − 6𝑈1 − 13 = 0 −6𝑈2 = 0 6 − 6𝑈3 = 0 cuja solução única é 𝑈1 = −1, 𝑈3 = 1 e os demais coeficientes nulos. Portanto, 𝑈 = 𝑥3 − 𝑥, e 𝑟𝑈 = 3𝑥9 − 3𝑥. A.2 Pseudocódigos e Códigos para o Algoritmo de Almkvist-Zeilberger Apresentamos agora pseudocódigos e códigos para implementação em Maxima para a integração de funções hiperexponenciais via algoritmo de Almkvist-Zeilberger. Os pseudocódigos foram extraídos de [35, Cap. 22, §4]. A.2.1 DenMult Calcula um polinômio 𝑉 tal que, caso a equação 𝑔 = (𝑢/𝑣)𝑓 , com 𝑔 ′ = 𝑓 possua solução no par 𝑢,𝑣, então 𝑉 é um múltiplo de 𝑣. Pseudocódigo: 159 A.2. Pseudocódigos e Códigos para o Algoritmo de Almkvist-Zeilberger 1: 2: função DenMult(𝐴,𝐷) descrição: Dado um corpo K de característica 0 e 𝐴,𝐷 ∈ K[𝑥] com grau(𝐴) < grau(𝐷), 𝐷 mônico e coprimo com 𝐴, retorna 𝑉 ∈ K[𝑥], tal que, para quaisquer coprimos 𝑢,𝑣 ∈ K[𝑥], a equação (A.2) implica que 𝑣 divide 𝑉 . 3: 4: 5: 6: 7: 8: 9: 10: 𝑅 ← res𝑥 (𝐷,𝐴 − 𝑧𝐷′ ) 𝑑 ← max{𝑖 ∈ N | 𝑖 = 0 ou 𝑅(𝑖) = 0} se 𝑑 = 0 então devolve 1 fim se 𝑎0 ← 𝐴, 𝑏0 ← 𝐷 para 𝑖 ← 1 até 𝑑 faça 𝐻𝑖 ← mdc(𝑏𝑖−1 ,𝑎𝑖−1 − 𝑏′𝑖−1 ), 𝑎𝑖 ← 11: 12: 13: 14: fim para devolve 𝐻1 𝐻22 · · · 𝐻𝑑𝑑 fim função 𝑎𝑖−1 − 𝑏′𝑖−1 𝑏𝑖−1 , 𝑏𝑖 ← 𝐻𝑖 𝐻𝑖 Código: DenMult(A,D,x):= block([expr,expr2,R,i,%Z,d,k,V,Hi,a,b,Ans], algebraic:true, expr:A-%Z*diff(D,x), d:0,k:1,V:1, R:SubRes(D,expr,x)[1], R:LFactor(R,%Z,false), if length(R)=1 then( Ans:1, algebraic:false, return(Ans) ), R:Solve(R,%Z,DomSolve), while (k<=length(R) and lhs(R[k])#0) do( i:rhs(R[k]), if integerp(i) and d<i then d:i, k:k+1 ), if d=0 then( Ans:V, algebraic:false, return(Ans) ), a:A, b:D, for i:1 thru d do( expr2:a-diff(b,x), Apêndice A. Integração de Funções Hiperexponenciais 160 Hi:GCD(b,a-diff(b,x),x,0,0), a:expr2/Hi, b:b/Hi, V:V*Hi^i ), Ans:V, algebraic:false, return(Ans) )$ A.2.2 IHF Algoritmo de Almkvist-Zeilberger. Encontra a integral de uma função hiperexponencial, desde que esta integral seja também uma função hiperexponencial. Pseudocódigo: 1: 2: função HyperIntegration(𝐴,𝐷) descrição: Dado um corpo K de característica 0 e 𝐴,𝐷 ∈ K[𝑥] com grau(𝐴) < grau(𝐷), 𝐷 mônico e coprimo com 𝐴, retorna 𝑢,𝑣 ∈ K[𝑥], com 𝑣 mônico, satisfazendo (A.2) 3: 4: 𝑉 ←DenMult(𝐴,𝐷) 5: ℎ ← mdc(𝐷𝑉,𝐵𝑉 ′ − 𝐴𝑉 ), 𝑟 ← 𝐷𝑉 ′ − 𝐴𝑉 𝐷𝑉 ,𝑠← , 𝑡 ← 𝑟𝑉 ℎ ℎ 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 𝑚 ← max{grau(𝑟) − 1, grau(𝑠)} 𝛿 ← coeficiente(𝑠,𝑥𝑚 ) se grau(𝑟) − 1 < grau(𝑠) ou 𝛿 ∈ / N então 𝑒 ← grau(𝑡) − 𝑚 senão se grau(𝑡) − 𝑚 = 𝛿 então devolve “insolúvel” senão 𝑒 ← max{grau(𝑡) − 𝑚,𝛿} fim se fim se se 𝑒 < 0 então devolve “insolúvel” fim se 20: 𝑈← 21: 𝐻 ← 𝑉 − 𝑟𝑈 ′ + (𝑠 − 𝑟′ )𝑈 𝑒−grau(𝑟) ∑︁ 𝑖=0 𝑢𝑖 𝑥𝑖 161 A.2. Pseudocódigos e Códigos para o Algoritmo de Almkvist-Zeilberger 22: (𝑈0 , . . . ,𝑈𝑒−grau(𝑟) ) ← solucionador(coeficiente(𝐻,𝑥𝑘 ) = 0,0 ≤ 𝑘 ≤ 𝑒 − grau(𝑟)) se @(𝑈0 , . . . ,𝑈𝑒−grau(𝑟) ) | 𝐻 = 0 então devolve “insolúvel” senão 𝑉 𝑟𝑈 , devolve mdc(𝑟𝑈,𝑉 ) mdc(𝑟𝑈,𝑉 ) fim se fim função 23: 24: 25: 26: 27: 28: Código: IHF(f,x):= block([A,D,h,r,s,t,m,delta,sigma, e,U,V,H,eq,listu,u,sol,G,Ans], algebraic:true, eq:[], sigma:ratsimp(diff(f,x)/f), A:num(sigma),D:denom(sigma), if (polynomialp(A,[x]) and polynomialp(D,[x]))=false then error("not a hyperexponential function."), V:DenMult(A,D,x), h:GCD(D*V,D*diff(V,x)-A*V,x,0,0), r:Group(D*V/h,x), s:Group((D*diff(V,x)-A*V)/h,x), t:Group(r*V,x), m:max(hipow(r,x)-1,hipow(s,x)), delta:coeff(s,x,m), if hipow(r,x)-1<hipow(s,x) or (integerp(delta) and delta>=0)=false then e:hipow(t,x)-m else if hipow(t,x)-m=delta then( Ans:"unsolvable", algebraic:false, return(Ans) ) else e:max(hipow(t,x)-m,delta), if e<0 then( Ans:"unsolvable", algebraic:false, return(Ans) ), U:sum(u[i]*x^(i-1),i,1,e-hipow(r,x)+1), H:Group(V-r*diff(U,x)+(s-diff(r,x))*U,x), for k:0 thru hipow(H,x) do( eq:endcons(coeff(H,x,k)=0,eq) ), listu:makelist(u[i],i,1,e-hipow(r,x)+1), sol:linsolve(eq,listu), Apêndice A. Integração de Funções Hiperexponenciais U:sum(rhs(sol[i])*x^(i-1),i,1,length(sol)), if sol=[] then( Ans:"unsolvable", algebraic:false, return(Ans) ), G:ratsimp(r*U/V), Ans:fullratsimp(G*f), algebraic:false, return(Ans) )$ 162