A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Tutorial PARI/GP (I)

Sex

22

Abr

2005


13:12

(6 votos, média 4.67 de 5) 


  • Outros tipos na biblioteca PARI

Digite p = x * exp(-x). Como seria de se esperar, à variável p é atribuída a expansão para uma série de potências de 16 termos (se você não tiver alterado o valor default). Agora digite pr = serreverse(p) para pedir a reversão da série de potências p, ou seja, a função inversa. Isto só é possível para séries de potências cujo primeiro coeficiente não zero seja o de x1. Para conferir se o resultado está correto, use subst(p, x, pr) ou subst(pr, x, p) para voltar ao x + 0(x^18).

Os coeficientes de pr seguem uma fórmula muito simples: multiplicando-se os coeficientes x^n por n! eles se transformam em inteiros. É exatamente isto o que a função serlaplace() faz. Digite ps = serlaplace(pr) para observar o resultado. Os coeficientes xn agora são iguais a nn - 1.

Vetores e Matrizes

A PARI não poderia deixar os vetores e as matrizes de fora. Por exemplo, digite [1, 2, 3, 4]. O resultado é o vetor da linha cujas coordenadas são 1, 2, 3 e 4. Se quisermos o vetor da coluna, basta pedir [1, 2, 3, 4]~, onde o til significa uma transposição. A não ser pelo til, o resultado não é muito diferente: obtemos [1, 2, 3, 4] e [1, 2, 3, 4]~. Então, qual é a vantagem que Maria leva? Experimente digitar [1, 2, 3, 4]~ e depois \b. A coluna agora é apresentada como

    [1]
    [2]
    [3]
    [4]

Agora peça m = [a, b, c; d, e, f]. Você acaba de definir uma matriz com duas linhas e três colunas. As matrizes são definidas por linhas separadas por ponto e vírgula ";". A matriz é mostrada em forma retangular, ou seja

    [a b c]
    [d e f]

Se você quiser vê-la na forma original, como foi definida, digite \a. Para manter este padrão de apresentação, digite default(output, 0). Se preferir a forma retangular, digite default(output, 1).

Uma vez que a matriz m está definida, experimente chamar alguns elementos. Abaixo estão alguns exemplos e os respectivos resultados:

    m[1,2]   .................   b
    m[1,]    .................   [a, b, c]
    m[,2]    .................   [b, e]~

A primeira referência é sempre a da linha e, a segunda, a da coluna. O primeiro índice é sempre 1 (e não o zero) e este valor default não pode ser alterado. Como temos acesso a todos os elementos da matriz, é lícito supor que estes elementos também possam ser modificados. Digite m[1, 2] = 5;. O ponto e vírgula, como já vimos, impede que o resultado seja mostrado na tela. Mas ele tem outras utilidades como, por exemplo, poder digitar vários comandos em uma só linha. Agora digite novamente m[1,] para obter [a, 5, c]. Nada impede que alteremos um vetor inteiro, por exemplo, m[1,] = [15, -17, 8]. Finalmente, tente m[,2] = [j, k]. Neste caso, obtemos uma mensagem de erro porque digitamos um vetor de linha para o vetor de coluna m[,2]. Corrija para m[,2] = [j, k]~ e deixe o til se encarregar da transposição.

A PARI possui várias matrizes "pre-calculadas" (veremos a construção mais genérica logo adiante), dentre elas a "Matriz de Hilbert" cujo coeficiente da linha i e coluna j é igual a (i + j - 1)-1. Chame, por exemplo, h = mathilbert(20) para ver um exemplo.

O que é interessante a respeito das matrizes de Hilbert é que seus inversos e determinantes podem ser calculados explicitamente - e o inverso possui coeficientes inteiros. Além disso, sabe-se que são matrizes numericamente muito instáveis... menos na PARI. Como os coeficientes são dados como números racionais, o cálculo será efetuado com exatidão de modo que não ocorra nenhum erro. Confira. Digite d = matdet(h) para obter como resultado um número racional cujo numerador é 1 e com um denominador de 226 dígitos. Não perca tempo contando cada um dos dígitos do denominador, use a função sizedigit(1/d) ou transforme o resultado numa string e peça seu comprimento com #Str(1/d).

Agora digite hr = 1. * h; (o ponto e vírgula é pra não entupir novamente a sua tela) e, em seguida, dr = matdet(hr). Aqui é preciso esclarecer duas coisas. A primeira é que o cálculo é muito mais rápido do que no caso dos racionais. A explicação para isto é que a PARI está lidando com números reais com precisão 28 enquanto que, no caso dos racionais, ele está lidando com inteiros com 226 dígitos.

A segunda coisa, mais importante que a primeira, é que o resultado está completamente errado! Compare os resultados obtidos com 1. * d e 1. * h para ver que a coisa está realmente feia. Esta é, justamente, a catastrófica instabilidade das matrizes de Hilbert mencionada acima. Na verdade, a situação é ainda pior. Digite norm12(1/h - 1/hr). O resultado é maior do que 1050, mostrando que alguns coeficientes de 1/hr mostram erros de até 1024 (na verdade, o maior erro é igual a 4224*1024 para o coeficiente da linha 15, coluna 15, que é um inteiro de 28 dígitos). Para obter o resultado correto, após arredondar o inverso, é preciso usar uma precisão de 56 dígitos (experimente). Ah, e a função norm12 dá o quadrado da norma L2, isto é, a soma dos quadrados dos coeficientes.

Apesar dos vetores poderem ser definidos manualmente, digitando explicitamente seus componentes, muitas vezes estes elementos satisfazem uma lei simples, o que permite usar uma sintaxe diferente. Por exemplo, assuma que você queira um vetor cuja i -ésima coordenada seja igual a i 2. Sem problemas. Neste caso entre com vector(10, i, i^2) se quiser um vetor de 10 elementos. De forma semelhante, se você digitar matrix(5, 5, i, j, 1/(i+j-1)) você obterá uma matriz de Hilbert de ordem 5 (ou seja, a função mathilbert é redundante). As variáveis i e j são variáveis que podem ser desprezadas. São usadas apenas para numerar, respectivamente, as linhas e as colunas (naturalmente, no caso de vetores, apenas uma delas estará presente). Não se esqueça de, juntamente com as dimensões do vetor ou matriz, indicar explicitamente o nome destas variáveis. Também é possível omitir as variáveis e a expressão final para se obter zero entradas, como em matrix(10, 20).

Observação: a letra I é reservada para o número complexo igual à raiz quadrada de -1. Portanto, é proibido usá-lo como variável. Existem mais dois nomes de variáveis reservados: Pi e Euler. Todos os nomes das funções também são proibidos. Por outro lado, não existem restrições em relação a i, pi ou euler.

Ao criar vetores ou matrizes, muitas vezes é útil usar operadores booleanos e a declaração if(). Na verdade, uma expressão if possui um valor que é igual à parte avaliada do if. Por exemplo, você pode digitar matrix(8, 8, i, j, if ((i-j)%2, 1, 0)) para obter uma matriz do tipo tabuleiro de 0 e 1. Mas, antes de usar uma matriz, esta precisa ser criada. Se, por exemplo, você digitar for (i = 1, 5, v[i] = 1/i) antes de criar o vetor v, vai obter uma mensagem de erro. O vetor v pode ser algo como v = vector(5).

Outro modo muito prático de criar vetores e matrizes é extraindo-os de outros maiores usando vecextract(). Por exemplo, se h é a matriz de Hilbert citada acima, vecextract(h, "11..20", "11.20") é seu quadrante inferior direito.

Informações adicionais