Escolar Documentos
Profissional Documentos
Cultura Documentos
Sned
Sned
Sumrio
Sumrio
1 Ferramentas computacionais
1.1 Antes de comear a trabalhar, . . . . . . . . . . . . . . .
1.2 Python . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.1 Strings e Inteiros . . . . . . . . . . . . . . . . . .
1.2.2 Nmeros de ponto flutuante reais e complexos
1.2.3 Obteno de uma curva de permanncia . . . . .
1.2.4 Arquivos texto e arquivos binrios . . . . . . . . .
1.3 Gnuplot . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.1 Ajuste de uma funo . . . . . . . . . . . . . . .
1.4 Python de novo: projeto probabilstico . . . . . . . . . .
1.5 Maxima . . . . . . . . . . . . . . . . . . . . . . . . . . .
2 Um
2.1
2.2
2.3
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
11
13
13
15
16
19
22
24
26
30
.
.
.
.
49
49
50
54
54
61
61
71
83
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
A Dados de vazo mdia anual e vazo mxima anual, Rio dos Patos,
19311999
89
Sumrio
Lista de Tabelas
1.1
2.1
Sumrio
Lista de Figuras
1.1
1.2
1.3
2.1
2.2
2.3
2.4
Funo erf(x) calculada com srie de Taylor, com erf_1, versus a erf
pr-definida em Gnuplot. . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.1
3.2
3.3
3.4
3.5
3.6
4.1
4.2
4.3
4.4
4.5
. . . . . . . . . . . . . . . . . . . . . . . . 50
Sumrio
Soluo numrica com o mtodo explcito (4.35) (crculos) versus a
soluo analtica (linha cheia) da equao de difuso para t = 0,
t = 0,05, t = 0,10 e t = 0,15. Apenas 1 a cada 5 pontos da grade
numrica so mostrados, para facilitar a comparao com a soluo
analtica. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.7 Soluo numrica com o mtodo implcito (4.39) (crculos) versus a
soluo analtica (linha cheia) da equao de difuso para t = 0,
t = 0,05, t = 0,10 e t = 0,15. Apenas 1 a cada 5 pontos da grade
numrica so mostrados, para facilitar a comparao com a soluo
analtica. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.8 Soluo numrica com o mtodo de Crank-Nicholson ( (4.45)) (crculos) versus a soluo analtica (linha cheia) da equao de difuso
para t = 0, t = 0,05, t = 0,10 e t = 0,15. Apenas 1 a cada 5 pontos
da grade numrica so mostrados, para facilitar a comparao com a
soluo analtica. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.9 Soluo analtica da equao da difuso bidimensional, para t = 0,
t = 0, t = 0,1, t = 0,2 e t = 0,3 . . . . . . . . . . . . . . . . . . . . .
4.10 Soluo numrica da equao da difuso bidimensional com o esquema
ADI, para t = 0, t = 0, t = 0,1, t = 0,2 e t = 0,3 . . . . . . . . . . .
4.6
. 77
. 80
. 83
. 87
. 88
Lista de Listagens
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
1.10
1.11
1.12
1.13
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
2.10
2.11
2.12
2.13
2.14
13
15
17
18
19
20
21
22
23
25
28
29
31
34
34
36
37
39
39
40
40
41
41
43
43
46
46
Sumrio
2.15 vererf1.plt Plotagem da funo erro calculada com srie de Taylor versus a erf(x) pr-definida em Gnuplot . . . . . . . . . . . . . . .
2.16 erfs.py Clculo de erf(x) com srie de Taylor, limitado a no
mximo 43 termos . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1 resolve-eqdif Soluo de uma EDO com Maxima . . . . . . . .
3.2 fracasso.py Um programa com o mtodo de Euler que no funciona
3.3 Sada de fracasso.py . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4 sucesso.py Um programa com o mtodo de Euler que funciona .
3.5 sucimp.py Mtodo de Euler implcito . . . . . . . . . . . . . . . .
3.6 euler2 Um mtodo explcito de ordem 2 . . . . . . . . . . . . . .
3.7 rungek4 Mtodo de Runge-Kutta, ordem 4 . . . . . . . . . . . . .
4.1 onda1d-ins.py Soluo de uma onda 1D com um mtodo explcito
instvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 surf1d-ins.py Seleciona alguns intervalos de tempo da soluo
numrica para plotagem . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 onda1d-lax.py Soluo de uma onda 1D com um mtodo explcito
laxtvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4 surf1d-lax.py Seleciona alguns intervalos de tempo da soluo
numrica para plotagem . . . . . . . . . . . . . . . . . . . . . . . . .
4.5 difusao1d-ana.py Soluo analtica da equao da difuso . . . .
4.6 divisao1d-ana.py Seleciona alguns instantes de tempo da soluo
analtica para visualizao . . . . . . . . . . . . . . . . . . . . . . . .
4.7 difusao1d-exp.py Soluo numrica da equao da difuso: mtodo explcito. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.8 divisao1d-exp.py Seleciona alguns instantes de tempo da soluo
analtica para visualizao . . . . . . . . . . . . . . . . . . . . . . . .
4.9 alglin.py Exporta uma rotina que resolve um sistema tridiagonal,
baseado em Press et al. (1992) . . . . . . . . . . . . . . . . . . . . . .
4.10 difusao1d-imp.py Soluo numrica da equao da difuso: mtodo implcito. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.11 difusao1d-ckn.py Soluo numrica da equao da difuso: esquema de Crank-Nicholson. . . . . . . . . . . . . . . . . . . . . . . .
patosmedmax.dat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
47
48
49
51
51
52
55
57
58
63
64
68
69
73
74
76
77
80
81
84
89
1
Ferramentas computacionais
Neste captulo ns fazemos uma introduo muito rpida a 3 ferramentas computacionais.
Python uma linguagem de programao, razoavelmente clssica, e da qual ns
vamos explorar apenas uma parte chamada de programao procedural. A escolha
de Python deve-se ao fato de ela ser uma linguagem fcil de aprender, e de existirem muitas bibliotecas de rotinas em Python que tornam muitas das tarefas de
Matemtica Aplicada fceis de implementar em um computador.
Gnuplot uma linguagem para gerar grficos. Ela bastante popular, fcil de
usar, e muito flexvel. Ns vamos gerar todos os nossos grficos bidimensionais
(grficos x y) com Gnuplot.
Maxima uma linguagem de processamento simblico. Da mesma maneira que
ns faremos contas com Python, ns faremos lgebra com Maxima. Os usos que
faremos de Maxima estaro longe de explorar todo o seu potencial. Ns vamos
apenas calcular algumas integrais, algumas sries de Taylor, e resolver algumas
equaes diferenciais ordinrias; entretanto, a rapidez com que faremos isto justifica
amplamente o seu uso.
Infelizmente, a verso de um programa de computador faz diferena, e s vezes
faz muita diferena. As verses que eu utilizei para este texto foram:
Python:
2.6.5
Gnuplot:
4.4
Maxima:
5.21.1
que voc encontrar diversas vezes ao longo do texto. Se voc (j) estiver usando
Python 3.x, remova estes comandos do incio de seus arquivos .py.
Matemtica Aplicada
12
13
1.2 Python
Listagem 1.1: binint.py exemplo de strings, e inteiros.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Exerccios Propostos
1.1 Voc j devia estar esperando por isto: o que um sistema operacional? Qual o
sistema operacional que voc usa?
1.2 Como saber se Python est instalado?
1.2 Python
Python reconhece os seguintes tipos bsicos de variveis: strings, nmeros
inteiros, nmeros de ponto flutuante, e nmeros complexos.
1.2.1 Strings e Inteiros
Strings, ou cadeias de caracteres, so criaturas do tipo 'abacaxi', e nmeros
inteiros so criaturas do tipo -1, 0, e 32767. O tipo das strings que vamos usar
chama-se unicode em Python 2.x, e str em Python 3.x. O tipo dos nmeros
inteiros chama-se int em Python.
A listagem 1.1 mostra o contedo do arquivo binint.py com alguns exemplos
simples do uso de inteiros e strings. A legenda de cada listagem se inicia sempre
com o nome do arquivo correspondente (aps um pouco de hesitao, eu decidi no
disponibilizar estes arquivos; para testar os exemplos deste texto, voc precisar
digitar os arquivos novamente: isto o (a) forar a praticar programao). A listagem
um retrato fiel do arquivo, com duas excees: as palavras reservadas de Python
esto sublinhadas na listagem (mas no no arquivo), e os espaos em branco dentro
das strings esto enfatizados pelo smbolo .
Ateno: os nmeros que aparecem esquerda da listagem no fazem parte do
arquivo. Em Python, um comentrio inicia-se com #, e prossegue at o fim de linha.
A maior parte dos comandos de binint.py est explicada nos prprios comentrios.
Alguns comentrios (sem inteno de trocadilho) adicionais, por linha:
1
14
Matemtica Aplicada
2
Magia negra: tudo que escrito entre aspas passa a ser uma string to tipo
unicode.
Magia negra: print deixa de ser uma declarao, e passa a ser uma funo.
Se voc no entendeu nada, no esquente.
1213 O comando for percorre em ordem um objeto itervel (no caso, a string
'aafro' itervel, com a[0] == 'a', a[1] == '', etc.). O corpo do
for tem que ser indentado, e na listagem a indentao de 3 espaos. Desta
forma, no caso da linha 13, o comando
h
97
231
97
102
114
227
111
52
50
57
52
57
54
55
50
57
53
print imprime com o formato apropriado inteiros e strings (e muito mais: quase
tudo, de alguma forma!). O maior inteiro que cabe em 32 bits sem sinal 4294967295
(como j vimos acima). A posio do caractere a na tabela Unicode 97; a posio
do caractere 231; a posio do caractere 4 52. Finalmente, o caractere Unicode
de nmero 227 o .
Se voc estiver vendo uma sada diferente da mostrada acima, com caracteres
estranhos, no se assuste (demais): o seu arquivo binint.py e o terminal dentro do
15
1.2 Python
Listagem 1.2: floats.py exemplo de uso de float e complex.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
qual voc est executando este programa certamente esto utilizando codificaes
diferentes (veja se o apndice ?? pode ajudar).
1.2.2 Nmeros de ponto flutuante reais e complexos
Em primeiro lugar, um esclarecimento: no computador, no possvel representar todos os nmeros x R do conjunto dos reais, mas apenas um subconjunto dos
racionais Q. Linguagens de programao mais antigas, como FORTRAN, ALGOL e
PASCAL, mesmo assim chamavam estes tipos de REAL. A partir de C, e continuando
com Python, em muitas linguagens passou-se a usar o nome mais adequado float.
Python vem com uma grande quantidade de mdulos predefinidos, e voc pode
adicionar seus prprios mdulos. Deles, importam-se variveis e funes (e outras
coisas) teis. Nosso primeiro exemplo do uso de nmeros de ponto flutuante (float)
e complexos (complex) no podia ser mais simples, na listagem 1.2
Eis a sada de floats.py:
pi = 3.14159265359
e = 2.71828182846
sen ( pi /2) = 1.0
sen ( i )
= 1.17520119364 j
print(sen(i) = ,csin(1j)) .
Note que existem dois mdulos, math e cmath, para variveis reais e complexas,
respectivamente. Em ambos, existe uma funo denominada sin, que calcula o
seno. Para poder usar estas duas funes diferentes em meu programa floats.py,
eu rebatizei a funo sin complexa de csin, no ato da importao do mdulo, com
o mecanismo from ... import ... as ... (linha 6).
16
Matemtica Aplicada
Tabela 1.1: Vazes Mximas Anuais (m3 s1 ) no Rio dos Patos, PR, 19311999
Ano
Vaz Mx
Ano
Vaz Mx
Ano
Vaz Mx
Ano
Vaz Mx
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
272.00
278.00
61.60
178.30
272.00
133.40
380.00
272.00
251.00
56.10
171.60
169.40
135.00
146.40
299.00
206.20
243.00
223.00
68.40
165.00
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
266.00
192.10
131.80
281.00
311.50
156.20
399.50
152.10
127.00
176.00
257.00
133.40
248.00
211.00
208.60
152.00
92.75
125.00
135.60
202.00
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
188.00
198.00
252.50
119.00
172.00
174.00
75.40
146.80
222.00
182.00
134.00
275.00
528.00
190.00
245.00
146.80
333.00
255.00
226.00
275.00
1991
1992
1993
1994
1995
1996
1997
1998
1999
131.00
660.00
333.00
128.00
472.00
196.00
247.50
451.00
486.00
Exerccios Propostos
1.3 Usando Python, converta 7777 da base 10 para a base 2. Sugesto: estude a documentao em www.python.org, e encontre a rotina pr-definida (built-in) que faz isto.
1.4 Como se faz para concatenar as strings bom e demais?
1
,
n
(1.1)
17
1.2 Python
Listagem 1.3: patos-medmax.dat vazes mdia e mxima anuais, Rio dos Patos
1931
1932
1933
1934
1935
21.57
25.65
4.76
11.46
28.10
272.00
278.00
61.60
178.30
272.00
(1.2)
Para obt-la, preciso considerar os valores iguais ou menores que o valor de corte
q. Portanto, ns devemos primeiro ordenar os qi s, de tal maneira que
q0 q1 . . . qn1 .
Note que a ordenao no altera (1.1). Aps a ordenao, o clculo de F (qi )
trivial:
i
X
1
i+1
F (qi ) =
=
.
(1.3)
n
n
k=0
(1.3) chamada de distribuio acumulada emprica de probabilidade. Em Hidrologia, muitas vezes (1.3) denominada curva de permanncia. O resultado (i + 1)/n
denominado uma posio de plotagem. Por diversos motivos, existem muitas outras posies de plotagem possveis para a FDA emprica. Uma muito popular
(i + 1)/(n + 1). A discusso detalhada de posies de plotagem deve ser feita em
um curso de Probabilidade e Estatstica, e no aqui, onde (1.3) serve (apenas) como
um exemplo motivador.
Os dados da tabela 1.1 esto digitados no arquivo patos-medmax.dat (Apndice
A). Este arquivo contm 3 colunas contendo, respectivamente, o ano, a vazo mdia
do ano, e a vazo mxima do ano. A listagem 1.3 mostra as 5 primeiras linhas do
arquivo (que possui 69 linhas).
O programa fqiemp.py, mostrado na listagem 1.4, calcula a curva de permanncia, ou FDA emprica, para as vazes mximas anuais do Rio dos Patos. Esta ,
simplesmente, uma tabela de duas colunas: a vazo observada (em ordem crescente),
e o valor de (i + 1)/n.
Como antes, os comentrios em fqiemp.py explicam muito do que est acontecendo. Mas h necessidade de explicaes adicionais:
5
18
Matemtica Aplicada
Nesta linha, qmax inicializado como uma lista vazia. Uma lista uma
sequncia de objetos quaisquer. Dada uma lista a, seus elementos so a[0],
a[1], etc.. Uma lista a com n objetos vai de a[0] at a[n-1].
10
Cada um dos campos agora ele mesmo uma string, com os valores separados.
As 5 primeiras linhas que aparecem na tela devido ao comando print da linha
10 so:
[ '1931 ' ,
[ '1932 ' ,
[ '1933 ' ,
[ '1934 ' ,
[ '1935 ' ,
11
12
13
14
Em Python, um mtodo uma rotina que pertence a uma varivel ou um tipo (a rigor, a
uma classe, mas este no um curso de programao)
19
1.2 Python
Listagem 1.5: fqiemp.dat FDA emprica da vazo mxima anual no Rio dos
Patos.
56.10
61.60
68.40
75.40
92.75
0.014493
0.028986
0.043478
0.057971
0.072464
15
sort um mtodo pr-definido para qualquer lista, que a ordena (por default
em ordem crescente).
16
17
18
19
20
write um mtodo do arquivo fou. write sempre escreve seu nico argumento, que tem que ser uma string, no arquivo. Trata-se portanto do
problema inverso do loop de leitura, que transformava strings em floats:
agora precisamos transformar floats em uma string. para isto que serve
o operador %: ele tem sua esquerda uma string com os campos de formatao especiais %8.2f e %8.6f; sua direita uma tupla 2 (qi,Fi) com tantos
elementos quantos so os campos de formatao. O primeiro elemento ser
substitudo no primeiro campo de formatao por uma string com 8 caracteres, sendo 2 deles para casas decimais. O segundo elemento ser substitudo
no segundo campo de formatao por uma string com 8 caracteres, sendo 6
deles para casas decimais. A string resultante, que precisa conter explicitamente o caractere de fim de linha \n, ser escrita no arquivo de sada.
Matemtica Aplicada
20
Como sempre, um exemplo vale por mil palavras. Na listagem 1.6, temos o
programa bintext.py, que produz dois arquivos: o arquivo texto i.txt, e o arquivo
binrio i.bin. Cada um destes arquivos contm o nmero inteiro i == 673451.
Eis aqui a dissecao de bintext.py:
5
10
11
Conte os 32 bits na primeira linha (aps o prefixo 0b, que indica a representao
na base 2): eles correspondem aos 4 bytes que custa ao programa para guardar o
nmreo inteiro 673451. Repare que o arquivo binrio menor que o arquivo texto.
Em geral, arquivos binrios tendem a ser menores (para a mesma quantidade de
informao). A outra grande vantagem que a leitura e a escritura de arquivos
binrios muito mais rpida, porque no h necessidade de traduzir a informao
de, e para, strings.
21
1.2 Python
#
#
#
#
abre um
loop em
gera um
escreve
O arquivo gerado, a.bin, possui 240 bytes. Em cada uma das 3 iteraes de
writearr.py, ele escreve 10 floats no arquivo. Cada float custa 8 bytes, de
modo que em cada iterao 80 bytes so escritos. No final, so 240.
importante observar que o arquivo a.bin no possui estrutura: ele no sabe
que dentro dele mora o array a; ele , apenas, uma linguia de 240 bytes. Cabe
a voc, programadora ou programador, interpretar, ler e escrever corretamente o
arquivo.
Prosseguimos agora para ler o arquivo binrio gerado. Isto feito com o programa
readarray.py, mostrado na listagem 1.8.
O programa importa a rotina fromfile de Numpy, a partir da qual 3 instncias
de a so lidas do arquivo a.bin e impressas com formato na tela. Eis a sua sada:
0.2327 0.6117 0.7713 0.5942 0.1799 0.3156 0.1473 0.4299 0.0870 0.0846
0.4301 0.9779 0.0322 0.4833 0.6097 0.4387 0.0639 0.1399 0.4350 0.7737
0.5809 0.0382 0.6567 0.8062 0.8427 0.2511 0.2897 0.5785 0.2892 0.0385
3
numpy.scipy.org
Matemtica Aplicada
22
O que vemos so os nmeros aleatrios das 3 instncias de a escritas pelo programa writearr.py.
1.3 Gnuplot
Mas como a cara da funo distribuio acumulada emprica? Ns gostaramos de ver a funo, isto , plot-la. para isto que serve Gnuplot. Um
programa Gnuplot especifica o arquivo de onde vm os dados; que colunas queremos
utilizar; que smbolos ou tipos de linhas, bem como espessuras ou tamanhos ns
desejamos, e o nome do arquivo de sada (na falta de um nome para o arquivo de
sada, uma tela com o grfico dever se abrir para visualizao interativa). Via de
regra, o arquivo de sada de um programa Gnuplot no um arquivo texto, mas
um arquivo com uma descrio grfica qualquer. Extenses comuns de nomes de
arquivos que indicam imagens so .jpg, .png, .eps, e .emf (esta ltima em Windows). Gnuplot permite gerar arquivos de imagem em qualquer um destes formatos
(e muitos outros!). Neste texto, ns vamos sempre gerar pares de arquivos (quase
idnticos) .eps e .emf. Em Linux, um arquivo a.eps facilmente conversvel no
arquivo a.pdf mediante o comando
h
epstopdf a.eps ;
em Windows, um arquivo a.emf est pronto para ser visualizado (com um clique),
inserido em documentos, etc..
Ns j temos a FDA emprica da vazo mxima anual no Rio dos Patos, no arquivo fqiemp.dat; agora, ns vamos plot-la com o programa Gnuplot fiqemp.plt:
Como sempre, preciso explicar:
5
Gera um arquivo de sada no padro Encapsulated Postscript, em preto-ebranco, com tipo Times Roman, no tamanho 18pt.
23
1.3 Gnuplot
Listagem 1.9: fiqemp.plt programa para plotar a FDA emprica do Rio dos
Patos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
10
11
Nome do eixo x.
12
Nome do eixo y.
13
17
Mude o tipo de arquivo de sada para emf, usando o tipo Times New Roman,
no tamanho 18 pt.
18
19
20
21
Finalmente, podemos ver a FDA emprica gerada por fqiemp.plt, na figura 1.2.
Uma ltima observao de cunho esttico. Neste texto, as figuras que so geradas
por programas Gnuplot descritos explicitamente, e cujas listagens .plt so dadas
no texto, utilizam o tipo postscript Times-Roman. Olhe bem para o tipo utilizado
nas figuras 1.1 e 1.2: este no o tipo utilizado no restante do texto (por exemplo,
compare com as legendas).
J as figuras geradas para fim ilustrativo utilizam o mesmo tipo que o texto; veja
por exemplo as figuras 2.1, e ??.
Utilizar um tipo de letra diferente nas figuras e no texto ligeiramente inconsistente, do ponto de vista tipogrfico. Entretanto, a escolha de Times-Roman para
24
Matemtica Aplicada
show ticscale
Terminal Test
te
d
by
+4
de
g
left justified
centre+d text
right justified
ro
ta
ro
d
te
ta
by
4
1
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
9 22
23
24
5
g
de
linewidth
lw 6
lw 5
lw 4
lw 3
lw 2
lw 1
pattern fill
3 4 5 6
(1.4)
No existe absolutamente nenhum motivo transcedental para utilizar (1.4): ela apenas atende aos requisitos fundamentais de uma FDA (tende a 0 em x ; e a
1 em x +). A rigor, a Weibull definida apenas para q 0, que o que se
espera de qualquer vazo em rios nenhum rio tem vazo negativa; nenhum rio
corre do mar para suas cabeceiras.
25
1.3 Gnuplot
1.0
0.9
0.8
FDA emprica
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0.0
0
100
200
300
400
500
Vazo mxima anual (m3/s)
600
700
Listagem 1.10: weibull.plt como ajustar uma FDA analtica (Weibull) aos
dados da FDA emprica
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
26
Matemtica Aplicada
: 67
: 0.0300336
: 0.000902019
lambda
k
+/ - 1.283
+/ - 0.05594
= 233.486
= 2.62023
(0.5495%)
(2.135%)
lambda
k
lambda = 1.0 ,
22
23
A figura 1.3 mostra o grfico gerado: note como a cauda da direita, ou seja, os
valores maiores de vazo mxima, so mal ajustados: F (q) subestima o valor de q
para probabilidades altas (prximas de 1): o uso da Weibull para este conjunto de
dados seria desastroso, uma vez que as maiores cheias seriam subestimadas!
Exerccios Propostos
1.6 Usando Gnuplot, plote em tons de cinza a rea debaixo da curva y = x para x = 2.
Quanto vale esta rea?
27
FDA
0.6
0.5
0.4
0.3
0.2
0.1
0.0
0
100
200
300
400
500
600
700
Vazo mxima anual (m3/s)
800
900
1000
Figura 1.3: Ajuste de uma FDA Weibull aos dados de vazo mxima anual do Rio
dos Patos
cuja probabilidade de excedncia em um ano qualquer seja = 0.05 (5%). Isto
significa que precisamos resolver a equao
P {Q > q} = 1 P {Q q} = ,
1 F (q) = ,
F (q) = 1 ,
(1.5)
para q.
Quando a F (q) a FDA emprica, no existe uma equao para se resolver, mas
sim uma tabela na qual devemos interpolar o valor desejado de q. Primeiramente
ns precisamos escrever uma funo que, dado um valor xc, procure o intervalo em
que ele se encontra na coluna x da tabela, e em seguida calcule o yc correspondente
interpolando linearmente entre os valores da coluna y para o mesmo intervalo. O
mdulo interp, arquivo interp.py, mostrado na listagem 1.11, faz isto.
interp no um programa: ele um mdulo que contm uma nica funo
(que possui tambm o nome interp). Esta rotina estar disponvel para qualquer
programa Python por meio de uma declarao do tipo
h
Matemtica Aplicada
28
Listagem 1.11: interp.py mdulo com funo para calcular uma interpolao
linear.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Agora que temos uma funo de interpolao linear, podemos escrever um programa que a utilize. Este programa, ppbemp.py (projeto probabilstico a partir da
distribuio emprica) mostrado na listagem 1.12, simplesmente l a tabela com a
FDA emprica (que, como sabemos, est no arquivo fqiemp.dat), e interpola um
valor qproj nesta tabela. O programa muito bvio, e no necessita de maiores
explicaes.
A vazo com risco de 5% de excedncia calculada q20 = 462,55m3 s1 . Como
5% = 1/20, comum em Hidrologia (e em outras disciplinas em que se utiliza
critrios de risco) dizer que q20 a vazo de 20 anos de tempo de recorrncia.
Para projetar a partir da F (x) analtica (isto , da Weibull com os valores de k
e de encontrados anteriormente), basta resolver (1.5) analiticamente:
29
F (q20 ) = 0,95,
30
Matemtica Aplicada
1.5 Maxima
Maxima a linguagem de processamento simblico mais antiga que existe: ela
se chamava, quando foi criada, MACSYMA. A mudana de nome ocorreu quando o
cdigo se tornou livre. Maxima capaz de fazer lgebra, derivar, integrar, resolver
equaes diferenciais, calcular transformadas de Laplace, etc., analiticamente. Por
exemplo: voc sabe quanto (a + b)4 ? No? Digitando maxima na linha de comando
voc obter
Maxima 5.21.1 http :// maxima . sourceforge . net
using Lisp GNU Common Lisp ( GCL ) GCL 2.6.7 ( a . k . a . GCL )
Distributed under the GNU Public License . See the file COPYING .
Dedicated to the memory of William Schelter .
The function bug_report () provides bug reporting information .
(% i1 )
(b + a)
b
+ 4 a b
+ 6 a
4
2
+ 4 a
b + a
O comando
h
quit();
34
31
1.5 Maxima
declare ( [ k ] , real ) $
declare ( [ lam ] , real ) $
assume ( k > 0) $
assume ( lam > 0) $
declare ( [ k ] , noninteger ) $
F : 1 - exp ( -( x / lam )^ k ) $
fdp : diff (F , x ) $
mu : integrate ( x * fdp ,x ,0 , inf ) ;
armazena a derivada de F (x), que em probabilidade se chama funo densidade de probabilidade, na varivel fdp.
maxima -b mulambdak.max
Na linha (%o9), gamma significa a funo gama (x), que ns vamos encontrar
muitas vezes neste curso, mas que no vem ao caso detalhar agora. O resultado
analtico que ns obtivemos com Maxima
k+1
=
.
k
!
Exerccios Propostos
1.9 Com Maxima, calcule a derivada de
f (x) = ln(sen(ex )).
(1.8)
32
Matemtica Aplicada
1.10 Com Maxima, calcule
x3/2
dx.
2
Um pouco de polinmios, integrais,
sries . . .
2.1 Integrao numrica: motivao
Suponha que voc deseje traar uma curva com as seguintes propriedades:
passar pelos pontos (0, 0), (1, 5/2), (2, 7/2) e (4, 4);
possuir derivada igual a 0 em x = 4.
Existem muitas curvas com estas propriedades, mas uma candidata natural um
polinmio de grau 5, uma vez que existem 5 propriedades ou graus de liberdade
na lista acima. Portanto,
f (x) = ax4 + bx3 + cx2 + dx + e,
df
,
g(x) =
dx
f (0) = 0,
f (1) = 5/2,
f (2) = 7/2,
f (4) = 4,
g(4) = 0.
Agora, podemos obter facilmente a, b, c, d, e com Maxima, com o programa
achapol.max da listagem 2.1.
A dissecao de achapol.max a seguinte:
12
37
(2.1)
34
Matemtica Aplicada
f : a * x ^4 + b * x ^3 + c * x ^2 + d * x + e ;
g : diff (f , x );
eq1 : f , x =0 ;
eq2 : f , x =1 ;
eq3 : f , x =2 ;
eq4 : f , x =4 ;
eq5 : g , x =4 ;
solve ([ eq1 = 0 , eq2 = 5/2 , eq3 = 7/2 , eq4 = 4 , eq5 = 0] , [a ,b ,c ,d , e ]) ;
Z 5
1
f (x) dx.
claro que esta integral pode ser calculada analiticamente com Maxima:
(% i1 ) [ a : -1/48 , b : 13/48 , c : -17/12 , d : 11/3] ;
1
13
17 11
(% o1 )
[ - --, --, - --, - -]
48 48
12 3
(% i2 ) f : a * x ^4 + b * x ^3 + c * x ^2 + d * x ;
4
3
2
x
13 x
17 x
11 x
(% o2 )
- -- + ----- - ----- + ---48
48
12
3
(% i3 ) integrate (f ,x ,1 ,5) ;
1321
(% o3 )
---90
35
4
f (x)
h(x)
1 . 4 6 7 7 7 7 7 7 7 7 7 7 7 7 8 b1
f (1) + f (5)
4 = 12,50.
2
Nada mal, considerando o valor verdadeiro 14,6778! Mas pode ser melhorada, com
o uso de dois trapzios. Para isto, basta calcular f (3) e somar as reas dos dois
trapzios resultantes:
I1 =
f (1) + f (3)
f (3) + f (5)
2+
2 = 14,000.
2
2
Note que estamos muito prximos do valor verdadeiro com apenas 2 trapzios.
Mas existe uma alternativa analtica mais inteligente do que trapzios: como temos
3 pontos, ns podemos aproximar a curva por uma parbola do 2 o grau passando
36
Matemtica Aplicada
por estes 3 pontos. O programa passaquad.max, mostrado na listagem 2.3, faz este
trabalho, e acha os coeficientes a, b, c da parbola
h(x) = ax2 + bx + c
que passa por (1, f (1)), (3, f (3)) e (5, f (5)). No embalo, passaquad.max redefine
h(x) com os coeficientes encontrados, e j calcula a integral de h(x) entre 1 e 5. A
parbola h tambm mostrada na figura 2.1.
Listagem 2.3: passaquad.max parbola h(x) = ax2 +bx+c passando por (1, f (1)),
(3, f (3)) e (5, f (5)).
1
2
3
4
5
6
7
8
9
10
11
12
Z 2
1
h(x) dx
Z 2
1
3
23
5
x2 + x +
dx
16
16
4
29
=
= 14,5000.
2
Ik I
.
I
(2.2)
Uma nica parbola foi capaz de estimar I com um erro relativo ligeiramente
superior a 1%. Um caminho geral para a integrao numrica est aberto: aumentar o nmero de elementos de integrao (no nosso caso foram trapzios) e/ou
aumentar a ordem do polinmio aproximador da funo por um certo nmero de
pontos. Este o contedo da prxima seo.
Exerccios Propostos
2.1 Se f (x) = sen x, qual a estimativa de I =
R
0
2.2 Provavelmente, voc no est muito contente com o resultado do Problema 2.1.
37
a) Aproxime a integral I do Problema 2.1 com dois trapzios, entre x = 0 e /2, e entre
x = pi/2 e .
b) Aproxime a integral pela integral da parbola quadrtica g(x) = ax2 + bx + c passando
pelos pontos (0, 0), (/2, 1) e (, 0).
c) Aproxime a integral de f (x) pela integral da parbola cbica h(x) = ax3 + bx2 + cx + d
passando pelos mesmos pontos acima, e com h0 (/2) = 0.
2.3 Com Gnuplot, plote f (x) = sen x e a aproximao g(x) obtida no Problema 2.2.
38
Matemtica Aplicada
Tabela 2.1: Estimativas numricas de I e seus erros relativos .
Integral
Valor
Exato
Um trapzio
Dois trapzios
Uma parbola
14,6778
0
12,5000 0,1483
14,0000 0,0461
14,5000 0,0121
f (x)
f (x)
x0
x1
x2
x3
x4
x5
x6
x7
x8
f (xi1 ) + f (xi )
x,
2
i=1
n
X
(2.3)
com
x0 = 1,
xn = 5,
xn x0
x =
.
n
(2.4)
(2.5)
(2.6)
(2.7)
39
com
Se = f (x0 ) + f (xn ),
Si =
n1
X
f (xi ).
(2.8)
(2.9)
i=1
Esta seo vale um mdulo de Python, que ns vamos denominar numint. Uma
implementao razoavelmente eficiente da regra do trapzio mostrada nas primeiras
21 linhas de numint.py, na listagen 2.5
Listagem 2.5: numint.py Integrao numrica, regra do trapzio
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
40
Matemtica Aplicada
do mdulo numint (listagem 2.7: note a continuao da numerao de linhas dentro do mesmo arquivo numint.py), denominada trapepsilonlento, e mostrada na
listagem 2.7.
Listagem 2.7: numint.py Integrao numrica ineficiente, com erro absoluto prestabelecido
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def t r a p e p s i l o n l e nt o ( epsilon ,a ,b , f ):
'''
t r a p e p s i l o n l en t o ( epsilon ,a ,b , f ): calcula a integral de f entre a e b com
erro absoluto epsilon , de forma ineficiente
'''
eps = 2* epsilon
n = 1
Iv = trapezio (1 ,a ,b , f )
while eps > epsilon :
n *= 2
In = trapezio (n ,a ,b , f )
eps = abs ( In - Iv )
Iv = In
return ( In , eps )
#
#
#
#
#
#
#
#
O programa quadraver2.py calcula a integral de f (x) com erro absoluto estipulado menor que 0,0001, e imprime a estimativa da integral, o erro absoluto e
o erro relativo (em relao ao valor exato conhecido) encontrados: I4 = 14,67777,
= 0,00003, = 0,00000075. Com 4 casas decimais, este um resultado exato!
Listagem 2.8: quadraver2.py Integrao numrica ineficiente de f (x) com =
0,0001
1
2
3
4
5
6
7
8
9
10
11
12
13
41
Listagem 2.9: numint.py Integrao numrica eficiente, com erro absoluto prestabelecido
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Exerccios Propostos
2.4 Usando Python e numint.trapezio, aproxime I =
com 10 trapzios.
R
0
R
0
42
Matemtica Aplicada
2.6 Dada f (x) definida no intervalo [x0 , x0 + 2h], deduza a regra de Simpson:
Z x0 +2h
f (x) dx
x0
h
[f0 + 4f1 + f2 ] ,
3
f (x) dx
x0
h
[f0 + 4f1 + 2f2 + 4f3 + f4 ] ;
3
generalize:
Z bx0 +2nh
f (x) dx
ax0
h
[f0 + 4f1 + 2f2 + . . . + 2f2n2 + 4f2n1 + f2n ] .
3
2.8 Estenda numint com uma rotina simpson para calcular a regra de Simpson com 2n
intervalos, e uma rotina simpepsilon para calcular uma integral numrica pela regra de
Simpson com preciso estipulada. Baseie-se em trapezio e trapepsilon.
e
du.
(2.10)
erf(x)
u=0
A funo erro est definida em Gnuplot e em Maxima, mas no em Python < 2.7.
Como obt-la? Uma maneira fora bruta utilizar trapepsilon com uma preciso
razovel (digamos, 106 ), gerar um arquivo, e plotar o resultado para ver a cara
da erf(x). O programa vererf.py (listagem 2.11) calcula a funo em um grande
nmero de pontos; gera um arquivo de dados vererf.dat, e ento o programa
vererf.plt (listagem 2.12) plota o resultado, mostrado na figura 2.3.
Observe que vererf.plt utiliza a funo erf pr-definida em Gnuplot e plota
uma comparao: a linha contnua a erf de Gnuplot, e os pontos so os valores
obtidos por vererf.py.
Existe uma maneira mais inteligente de calcular erf(x): ela se baseia em integrar
2
a srie de Taylor do integrando, eu . Maxima permite calcular os primeiros termos:
(% i1 ) taylor ( exp ( - u ^2) , u ,0 ,10) ;
(% o1 )/ T /
1 - u
4
6
8
10
u
u
u
u
+ -- - -- + -- - --- + . . .
2
6
24
120
43
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
de 0
a 3
em 100 passos
de dx
erf (0) = 0
arquivo de sada
limite inferior a partir de xmin
erf (0) = 0
loop
novo limite superior
integra mais uma fatia
acumula erf
imprime at aqui
atualiza limite inferior
fecha o arquivo de sada
44
Matemtica Aplicada
1.0
trapepsilon
Gnuplot
0.9
0.8
0.7
erf(x)
0.6
0.5
0.4
0.3
0.2
0.1
0.0
0
0.5
1.5
x
2.5
Figura 2.3: Funo erf(x) calculada por integrao numrica, com trapepsilon e
= 1 106 , versus a erf pr-definida em Gnuplot.
eu =
(1)n
n=0
u2n
.
n!
(2.11)
Portanto,
Z x
0
eu du =
Z xX
(1)n
0 n=0
u2n
du
n!
(1)n Z x 2n
=
u du
n!
0
n=0
=
=
(1)n x2n+1
n! 2n + 1
n=0
(1)n
n=0
x2n+1
.
(2n + 1)n!
(2.12)
45
erf_1
Gnuplot
0.9
0.8
0.7
erf(x)
0.6
0.5
0.4
0.3
0.2
0.1
0.0
0
0.5
1.5
x
2.5
Figura 2.4: Funo erf(x) calculada com srie de Taylor, com erf_1, versus a erf
pr-definida em Gnuplot.
Ainda falta encontrar uma maneira computacionalmente eficiente de passar do
termo n 1 para o termo n. Vamos a isto:
x2n+1
An
(2n + 1)n!
Bn Cn
=
=
=
(1)n x2(n1+1)+1
An1 (x2 )
(Bn1 + 2)(Cn1 n)
(2.13)
46
Matemtica Aplicada
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
mesma preciso
garante entrada no while
primeiro A
primeiro B
primeiro C
primeiro n
primeiro termo da srie
primeira soma da srie
loop
incrementa n
novo A
novo B
novo C
novo termo
seu valor absoluto
soma na srie
Listagem 2.14: vererf1.py Clculo da funo erro com srie de Taylor entre 0 e
3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#
#
#
#
#
#
#
#
#
de 0
a 3
em 100 passos
de dx
arquivo de sada
limite inferior a partir de xmin
erf (0) = 0
loop
novo limite superior
# imprime at aqui
# atualiza limite inferior
# fecha o arquivo de sada
47
Embora formalmente correta, a rotina erf_1 fica mais lenta medida em que
|x| cresce. Como j vimos nas figuras 2.3 e 2.4, erf(x) 1 para |x| & 3. Porm,
uma olhada em vererf1.dat, nos d
h
erf_1(3) = 0.999978 ,
erf_1(3.6) = 0.99999952358847277 ,
que igual a 1,0 para 6 casas decimais. Precisamos tambm saber com quantos
termos este clculo foi feito, e este o motivo de erf_1 devolver tambm n. Para
calcular erf(3,6) com erf_1, ns precisamos de n = 43 termos. A rotina erf na
listagem 2.16, tambm no arquivo erfs.py, usa este fato para impedir que o nmero
de termos continue crescendo. Verifique, voc mesmo(a), que erf(100) retorna 1.0,
mas que erf_1(100) d um erro de ponto flutuante.
preciso enfatizar que erf em erfs.py ainda no uma rotina profissional.
O nmero de termos usado ainda potencialmente muito grande; consequentemente,
h muitas operaes de ponto flutuante envolvendo A, B e C, e muitos testes dentro
do while.
possvel obter frmulas que aproximam erf(x) com menos termos, uniformemente, no intervalo (digamos) de 0 a 3,6: veja, por exemplo, Abramowitz e Stegun
(1972). Mesmo assim, erf uma opo vantajosa em relao integrao numrica.
A lio desta seo a seguinte: em geral, com esforo analtico adicional,
possvel obter uma mistura de mtodos analticos e numricos que costuma ser
amplamente superior ao uso de um mtodo numrico puro (por exemplo a regra
do trapzio) para a obteno de resultados semelhantes. Exemplos deste fato vo
reaparecer nos captulos seguintes.
48
Matemtica Aplicada
def erf ( x ):
if x > 3.6:
return 1.0
elif x < -3.6:
return -1.0
epsilon_erf = 1.0 e -6
eps_erf = 2* epsilon_erf
A = x
B = 1
C = 1
n = 0
termo = A /( B * C )
s = termo
while eps_erf > epsilon_erf :
n += 1
A *= ( - x * x )
B += 2
C *= n
termo = A /( B * C )
eps_erf = abs ( termo )
s += termo
return 2/ sqrt ( pi ) * s
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
mesma preciso
garante entrada no while
primeiro A
primeiro B
primeiro C
primeiro n
primeiro termo da srie
primeira soma da srie
loop
incrementa n
novo A
novo B
novo C
novo termo
seu valor absoluto
soma na srie
Exerccios Propostos
2.9 (Bender e Orszag (1978), seo 6.2, Exemplo 2) Obtenha uma srie para
F (x)
Z x
0
t1/2 et dt;
3
Soluo numrica de equaes
diferenciais ordinrias
3.1 Soluo numrica de equaes diferenciais ordinrias
Soluo analtica de uma EDO com Maxima. Considere uma equao diferencial
de 1a ordem simples, forada eternamente por um seno:
dy y
+ = sen x.
dx x
Na listagem 3.1, ns resolvemos esta equao com Maxima.
(3.1)
(% i2 )
(% o2 )
(% i3 )
(% o3 )
y
dy
- + -- = sin ( x )
x
dx
dy
y
-- + - = sin ( x )
dx
x
ode2 (% , y , x )
sin ( x ) - x cos ( x ) + % c
y = ---------------------x
sen x x cos x + c
.
x
evidente que, em geral, nem a equao diferencial nem sua soluo "existem"em
x = 0. Entretanto, para c = 0,
sen x
y(x) =
cos x.
x
Agora,
sen x
= 1,
x
de modo que existe uma soluo para a equao partindo de x = 0 se ns impusermos
a condio incial y(0) = 0. De fato:
lim
x0
sen x
lim
cos x = 1 1 = 0.
x0
x
49
50
Matemtica Aplicada
1.5
1.0
y(x)
0.5
0.0
0.5
1.0
1.5
10
20
30
40
50
xi = ix,
com os correspondentes
y0 , y1 , . . . , yn .
Como x ser fixo, podemos escrever nossa equao de diferenas finitas da seguinte
forma:
yi+1 yi y
+ = sen(x),
x
x
onde eu deixei, propositadamente,
x
. . . = sen(x)
y
ainda sem ndices. De fato: qual xi e qual yi usar aqui? A coisa mais simples, mas
tambm a mais instvel, usar i:
yi+1 yi yi
+
= sen(xi ).
x
xi
51
Note que agora possvel explicitar yi+1 em funo de todos os outros valores em i:
yi+1 = yi + sen(xi )
yi
x.
xi
x0
52
Matemtica Aplicada
{z
=0, lim x0 0
n
X
yi
i=1
y(xi )
y(xi )
53
1.5
x = 0,01
soluo numrica
soluo analtica
1.0
y(x)
0.5
0.0
-0.5
-1.0
-1.5
10
20
30
40
50
1.5
x = 0,5
soluo numrica
soluo analtica
1.0
y(x)
0.5
0.0
-0.5
-1.0
-1.5
10
20
30
40
50
54
Matemtica Aplicada
A figura 3.3 mostra o resultado de rodar sucesso.py com x = 0,5, muito maior
do que antes.
O erro mdio relativo agora pulou para = 1,11774, nada menos do que 111%,
e muito pior do que a figura acima faz parecer primeira vista!
3.1.2 Um mtodo implcito, com tratamento analtico
Nosso desafio desenvolver um mtodo numrico que melhore consideravelmente
a soluo mesmo com um x grosseiro, da ordem de 0,5. Nossa abordagem ser
propor um mtodo implcito:
xi + xi+1
yi+1 yi
yi + yi+1
+
= sen
.
x
xi + xi+1
2
Note que tanto o termo y/x quando sen x esto sendo agora avaliados no ponto
mdio entre xi e xi+1 .
Lembrando que x = xi+1 xi , yi+1 :
xi + xi+1
yi + yi+1
yi+1 yi
= sen
+
,
x
xi + xi+1
2
"
#
#
"
1
1
1
1
xi + xi+1
yi+1
+
+ yi
+
= sen
,
x xi + xi+1
x xi + xi+1
2
#
#
"
"
2xi+1
2xi
xi + xi+1
yi+1
yi
= sen
.
x(xi+1 + xi )
x(xi+1 + xi )
2
(3.2)
55
1.5
x = 0,5
soluo numrica
soluo analtica
1.0
0.5
y(x)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
0.0
-0.5
-1.0
-1.5
0
10
20
30
40
50
56
Matemtica Aplicada
1.5
x = 0,5
soluo numrica
soluo analtica
1.0
y(x)
0.5
0.0
-0.5
-1.0
-1.5
10
20
30
40
50
dy
dx
57
Matemtica Aplicada
58
ordem 2:
k1 = hf (xn , yn ),
h
k1
k2 = hf (xn + , yn + ),
2
2
k3 = hf (xn + h/2, yn + k2 /2),
k4 = hf (xn + h, yn + k3 ),
k1 k2 k3 k4
yn+1 = yn +
+
+
+ .
6
3
3
6
Para o nosso bem conhecido problema, o mtodo implementado no programa
rungek4, na listagem 3.7.
O resultado mostrado na figura 3.6.
Desta vez, o erro absoluto mdio foi = 0,00007: o campeo de todos os mtodos
tentados at agora, e uma clara evidncia da eficcia do mtodo de Runge-Kutta.
59
x = 0,01
soluo numrica
soluo analtica
1.0
y(x)
0.5
0.0
-0.5
-1.0
-1.5
0
10
20
30
40
50
y(0) = 0.
3.2 Resolva, usando o mtodo de Euler de ordem 2, e compare com a soluo analtica:
dy
+ y = x2 exp(x),
dx
y(0) = 1.
dy
y
2x
+ = sen
,
dx x
L
y(0) = 0,
3.3 Na equao
y(x) = 0.
y(0) = 1.
Matemtica Aplicada
60
4
Soluo numrica de equaes
diferenciais parciais
4.1 Adveco pura: a onda cinemtica
Considere a equao
u
u
+c
= 0,
t
x
u(x, 0) = g(x).
(4.1)
(4.2)
u
u
+2
= 0,
t
x
u(x, 0) = 2x(1 x).
(4.3)
(4.4)
A condio inicial, juntamente com u(x, 1), u(x, 2) e u(x, 3) esto mostrados na
figura 4.1. Observe que a soluo da equao uma simples onda cinemtica.
4
0.50
0.00
tempo
u(x, t)
10
62
Matemtica Aplicada
Vamos adotar a notao
uni u(xi , tn ),
xi = ix,
tn = nt,
(4.5)
(4.6)
(4.7)
com
x = L/Nx ,
t = T /Nt
(4.8)
(4.9)
(4.10)
uni+1 uni1
u
=
+ O(x2 ).
x i,n
x
(4.11)
(4.12)
onda1d-ins.py 3 250 ,
o que significa selecionar 3 sadas (alm da condio inicial), de 250 em 250 intervalos
de tempo t. Observe que para isto ns utilizamos uma lista (v), cujos elementos
so arrays.
O resultado dos primeiros 750 intervalos de tempo de simulao mostrado na
figura 4.2. Repare como a soluo se torna rapidamente instvel. Repare tambm
como a soluo numrica, em t = 750t = 0,375, ainda est bastante distante dos
tempos mostrados na soluo analtica da figura 4.1 (que vo at t = 4). Claramente,
o esquema explcito que ns programamos jamais nos levar a uma soluo numrica
satisfatria para tempos da ordem de t = 1!
63
0.500
0.250
0.50
0.00
tempo de simulao
0.375
u(x, t)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
0.125
0.000
10
Figura 4.2: Soluo numrica produzida por onda1d-ins.py, para t = 250t, 500t
e 750t.
Matemtica Aplicada
64
65
Por que o esquema utilizado em (4.12) fracassa? Uma forma de obter a resposta
fazer uma anlise de estabilidade de von Neumann.
A anlise de estabilidade de von Neumann consiste primeiramente em observar
que, em um computador real, (4.12) jamais ser calculada com preciso infinita. O
que o computador realmente calcula um valor truncado uni . Por enquanto, ns s
vamos fazer esta distino de notao, entre u e u, aqui, onde ela importa. O erro
de truncamento
ni uni uni .
(4.13)
Note que (4.12) se aplica tanto para u quanto para u; subtraindo as equaes resultantes para un+1
e un+1
, obtm-se a mesma equao para a evoluo de ni :
i
i
n+1
= ni
i
Co n
( ni1 ),
2 i+1
(4.14)
onde
ct
(4.15)
x
o nmero de Courant. Isto s foi possvel porque (4.12) uma equao linear em
u. Mesmo para equaes no-lineares, entretanto, sempre ser possvel fazer pelo
menos uma anlise local de estabilidade.
O prximo passo da anlise de estabilidade de von Neumman escrever uma
srie de Fourier para ni , na forma
Co
tn = nt,
xi = ix,
No captulo sobre
N/2
ni
l e
atn i kl xi
(4.16)
l=1
Co atn i kl (i+1)x
l e e
l eatn ei kl (i1)x ;
2
(4.17)
eat = 1
(4.18)
O lado direito um nmero complexo, de maneira que o lado esquerdo tambm tem
que ser! Como concili-los? Fazendo a = + i , e substituindo:
e(i )t = 1 i Co sen kl x;
et [cos(t) i sen(t)] = 1 i Co sen kl x;
et cos(t) = 1,
t
(4.19)
(4.20)
sries de Fourier,
mostre que isto
funciona, e discuta
o N/2
66
Matemtica Aplicada
i
1h n
(ui+1 + uni1 ) Co(uni+1 uni1 ) .
2
(4.21)
Agora que ns j sabemos que esquemas numricos podem ser instveis, devemos
fazer uma anlise de estabilidade antes de tentar implementar (4.21) numericamente.
Vamos a isto: utilizando novamente (4.16) e substituindo em (4.21), temos
1 h atn i kl (i+1)x
l e e
+ l eatn ei kl (i1)x
2
i
Co l eatn ei kl (i+1)x l eatn ei kl (i1)x ;
i
1 h +i kl x
e
+ ei kl x Co e+i kl x ei kl x ;
eat =
2
at
e
= cos(kl x) i Co sen(kl x)
(4.22)
l ea(tn +t) ei kl ix =
(4.24)
ui+1
du
1 d2 u
+ O(x2 ),
= ui x +
2
dx i
2 dx i
ui1
67
e some:
d2 u
= 2ui + 2 x2 + O(x2 ),
dx i
ui+1 + ui1
d2 u
ui+1 2ui + ui1
=
+ O(x2 ).
2
dx i
x2
(4.25)
Portanto, a equao (4.24) ou seja: o esquema de Lax (4.21) pode ser interpretada tambm como uma soluo aproximada da equao de adveco-difuso
u
2u
u
+c
= D 2,
t
c
x
com
x2
.
2t
!
D=
D xu2
c u
x
u
D x
2
u
c x
D
x
x2
2tx
ct
x
1,
1,
c,
c,
= Co
1
2
Em outras palavras, ns descobrimos que o critrio para que o esquema seja acurado
do ponto de vista fsico conflitante com o critrio de estabilidade: enquanto que
estabilidade demandava Co < 1, o critrio de que a soluo seja tambm fisicamente
acurada demanda que Co 1/2. Na prtica, isto significa que, para c = 2, ou o
esquema estvel com muita difuso numrica, ou ele instvel. Isto praticamente
elimina a possibilidade de qualquer uso srio de (4.21).
Mesmo assim, vamos program-lo! O programa onda1d-lax.py est mostrado
na listagem 4.3. Ele usa os mesmos valores t = 0,0005 e x = 0,01, ou seja,
Co = 0,10.
O programa gera um arquivo de sada binrio, que por sua vez lindo pelo
prximo programa na sequncia, surf1d-lax.py, mostrado na listagem 4.4. O nico
trabalho deste programa selecionar algumas linhas da sada de onda1d-lax.py;
Matemtica Aplicada
68
69
onda1d-lax.py 3 500 ,
o que significa selecionar 3 sadas (alm da condio inicial), de 500 em 500 intervalos
de tempo t. Com isto, ns conseguimos chegar at o instante 0,75 da simulao.
O resultado dos primeiros 1500 intervalos de tempo de simulao mostrado na
figura 4.3. Observe que agora no h oscilaes esprias: o esquema estvel no
tempo. No entanto, a soluo est agora amortecida pela difuso numrica!
Upwind
melhor o
esquema,
literatura
Co
u
u
un+1
i
i
i
i1 .
(4.26)
70
Matemtica Aplicada
1.000
0.500
0.50
0.00
tempo de simulao
u(x, t)
0.750
0.250
0.000
10
eat ei kl ix = ei kl ix Co ei kl ix ei kl (i1)x
h
eat = 1 Co 1 ei kl x
h
(4.27)
= 2Co2 (1 Ck ) + 2Co(Ck 1) + 1.
71
0.500
0.50
0.00
tempo de simulao
u(x, t)
0.750
0.250
0.000
10
Figura 4.4: Soluo numrica produzida pelo esquema upwind, para t = 500t,
1000t e 1500t.
A condio para que o esquema de diferenas finitas seja estvel , ento,
2Co2 (1 Ck ) + 2Co(Ck 1) + 1 1,
2Co [Co(1 Ck ) + (Ck 1)] 0,
(1 cos(kl x)) [Co 1] 0,
Co 1
Reencontramos, portanto, a condio (4.23), mas em um outro esquema de diferenas finitas. A lio no deve ser mal interpretada: longe de supor que (4.23)
vale sempre, a anlise de estabilidade que deve refeita para cada novo esquema de
diferenas finitas!
O esquema upwind, portanto, condicionalmente estvel, e tudo indica que podemos agora implement-lo computacionalmente, e ver no que ele vai dar. Ns
utilizamos os mesmos valores de t e de x de antes. As mudanas necessrias nos
cdigos computacionais so bvias, e so deixadas a cargo do(a) leitor(a).
A figura 4.4 mostra o resultado do esquema upwind. Note que ele muito melhor
(para esta equao diferencial) que o esquema de Lax. No entanto, a figura sugere
que algum amortecimento (difuso numrica?) tambm est ocorrendo, embora em
grau muito menor.
Exerccios Propostos
4.1 Escreva o programa onda1d-upw e surfa1d-upw, que implementam o esquema
upwind. Reproduza a figura 4.4.
4.2 Calcule a difusividade numrica introduzida pelo esquema upwind.
(4.28)
72
Matemtica Aplicada
com condies iniciais e de contorno
u(x, 0) = f (x)
u(0, t) = u(L, t) = 0.
(4.29)
(4.30)
A n e
n2 2 2
t
L2
sen
n=1
nx
,
L
2ZL
nx
An =
f (x) sen
dx.
L 0
L
(4.31)
(4.32)
Em particular, se
D = 2,
L = 1,
f (x) = 2x(1 x),
An = 2
Z 1
0
2x(1 x) sen(nx) dx =
3 n3
[1 (1)n ] .
X
16
(2(2n+1)2 2 )t
u(x, t) =
e
sen ((2n + 1)x)
3
3
n=0 (2n + 1)
A2n+1 =
3 (2n
(4.33)
un+1
= uni + Fo uni+1 2uni + uni1 ,
i
onde
Fo =
Dt
x2
(4.35)
(4.36)
73
74
Matemtica Aplicada
0.5
t = 0,00
0.4
0.3
u(x, t)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
0.2
t = 0,05
0.1
t = 0,10
t = 0,15
0.0
0.2
0.4
0.6
0.8
75
eat = 1 + Fo e+i kl x 2 + ei kl x
h
= 1 + 2Fo [cos(kl x) 1]
= 1 4Fo sen
kl x
2
(4.37)
at 2
| = 1 8Fo sen
kl x
kl x
+ 16Fo2 sen4
2
2
!
<1
ou
kl x
kl x
8Fo sen
+ 16Fo2 sen4
< 0,
2
2
!"
!#
2 kl x
2 kl x
1 + 2Fo sen
< 0,
8Fo sen
2
2
1
Fo < .
2
!
(4.38)
Podemos agora calcular o nmero de Fourier que utilizamos para plotar a soluo
analtica (verifique nas listagens 4.5 e 4.6):
Fo =
2 0,0005
= 1000.
(0,001)2
2 0,00001
= 0,2 < 0,5
(0,01)2
(OK).
Matemtica Aplicada
76
77
0.5
t = 0,00
0.4
0.3
u(x, t)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
0.2
t = 0,05
0.1
t = 0,10
t = 0,15
0.0
0.2
0.4
0.6
0.8
Figura 4.6: Soluo numrica com o mtodo explcito (4.35) (crculos) versus a
soluo analtica (linha cheia) da equao de difuso para t = 0, t = 0,05, t = 0,10 e
t = 0,15. Apenas 1 a cada 5 pontos da grade numrica so mostrados, para facilitar
a comparao com a soluo analtica.
78
Matemtica Aplicada
un+1 2un+1
+ un+1
un+1
uni
i
i1
i
= D i+1
,
t
x2
n+1
un+1
uni = Fo(un+1
+ un+1
i
i+1 2ui
i1 ),
n+1
n
Foun+1
Foun+1
i1 + (1 + 2Fo)ui
i+1 = ui
(4.39)
(1 + 2Fo)un+1
Foun+1
= un1 ,
1
2
n+1
n
Foun+1
Nx 2 + (1 + 2Fo)uNx 1 = uNx 1 .
(4.40)
(4.41)
1 + 2Fo
Fo
0
Fo
1 + 2Fo Fo
.
..
0
0
...
0
...
0
0
...
0
0
..
.
0 Fo 1 + 2Fo
Fo
...
0
Fo
1 + 2Fo
un+1
1n+1
u2
..
.
un+1
Nx 2
un+1
Nx 1
un1
un2
..
.
un
Nx 2
unNx 1
(4.42)
79
eat = 1 + eat Fo ei kl x 2 + ei kl x ,
at
kl x
2
=1e
at
4Fo sin
kl x
,
2
!
!#
= 1,
|eat | =
1
1 + 4Fo sin2
kl x
2
sempre.
(4.43)
Portanto, o esquema implcito (4.39) incondicionalmente estvel, e temos confiana de que o programa correspondente no se instabilizar.
Existem vrias coisas atraentes para um programador em (4.42). Em primeiro
lugar, a matriz do sistema uma matriz banda tridiagonal; sistemas lineares com
este tipo de matriz so particularmente simples de resolver, e esto disponveis
na literatura (por exemplo: Press et al., 1992, seo 2.4, subrotina tridag). Em
segundo lugar, a matriz do sistema constante: ela s precisa ser montada uma vez
no programa, o que torna a soluo numrica potencialmente muito rpida.
Ns vamos comear, ento, construindo um pequeno mdulo, convenientemente
denominado alglin.py, que exporta a funo tridag, que resolve um sistema tridiagonal, mostrado na listagem 4.9.
Em seguida, o programa difusao1d-imp.py resolve o problema com o mtodo
implcito. Ele est mostrado na listagem 4.10. A principal novidade est nas linhas
4246, e depois novamente na linha 56. Em Python e Numpy, possvel especificar sub-listas, e sub-arrays, com um dispositivo denominado slicing, que torna a
programao mais compacta e clara. Por exemplo, na linha 43, todos os elementos
A[0,1]. . . A[0,nx-1] recebem o valor -Fon.
Existe um programa divisao1d-imp.py, mas ele no precisa ser mostrado aqui,
porque as modificaes, por exemplo a partir de divisao1d-exp.py, so demasiadamente triviais para justificarem o gasto adicional de papel. Para t = 0,001, e
x = 0,01, o resultado do mtodo implcito est mostrado na figura 4.7
Nada mal, para uma economia de 100 vezes (em relao ao mtodo explcito) em
passos de tempo! (Note entretanto que a soluo, em cada passo de tempo, um
pouco mais custosa, por envolver a soluo de um sistema de equaes acopladas,
ainda que tridiagonal.)
Crank Nicholson A derivada espacial em (4.28) aproximada, no esquema implcito (4.39), por um esquema de O(x2 ). A derivada temporal, por sua vez,
80
Matemtica Aplicada
Listagem 4.9: alglin.py Exporta uma rotina que resolve um sistema tridiagonal,
baseado em Press et al. (1992)
# -* - coding : iso -8859 -1 -* # -----------------------------------------------------------------------------# alglin . py implementa uma soluo de um sistema linear com matriz tridiagonal
# -----------------------------------------------------------------------------from numpy import zeros
def tridag (A , y ):
# A , y tm que ser arrays !
m = A . shape [0]
# garante que A representa uma
n = A . shape [1]
# matriz tridiagonal
assert ( m == 3)
# garante que todos os tamanhos esto OK
o = y . shape [0]
assert ( n == o )
x = zeros (n , float )
# vetor de trabalho : vai retornar a soluo
gam = zeros (n , float )
# vetor de trabalho : vai ficar por aqui
if A [1 ,0] == 0.0 :
exit ( " Erro 1 em tridag " )
bet = A [1 ,0]
x [0] = y [0]/ bet
for j in range (1 , n ):
gam [ j ] = A [2 ,j -1]/ bet
bet = A [1 , j ] - A [0 , j ]* gam [ j ]
if ( bet == 0.0):
exit ( " Erro 2 em tridag " )
x [ j ] = ( y [ j ] - A [0 , j ]* x [j -1])/ bet
for j in range (n -2 , -1 , -1):
x [ j ] -= gam [ j +1]* x [ j +1]
return x
0.5
t = 0,00
0.4
0.3
u(x, t)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
0.2
t = 0,05
0.1
t = 0,10
t = 0,15
0.0
0.2
0.4
0.6
0.8
Figura 4.7: Soluo numrica com o mtodo implcito (4.39) (crculos) versus a
soluo analtica (linha cheia) da equao de difuso para t = 0, t = 0,05, t = 0,10 e
t = 0,15. Apenas 1 a cada 5 pontos da grade numrica so mostrados, para facilitar
a comparao com a soluo analtica.
81
82
Matemtica Aplicada
apenas de O(t). Mas possvel consertar isto! A idia substituir (4.39) por
n+1
un+1
uni
D uni+1 2uni + uni1 un+1
+ un+1
i
i+1 2ui
i1
=
,
+
t
2
x2
x2
i
Fo h n
n+1
+ un+1
= uni +
un+1
ui+1 2uni + uni1 + un+1
i1 .
i+1 2ui
i
2
"
(4.44)
Com esta mudana simples, a derivada espacial agora uma mdia das derivadas
em n e n + 1, ou seja: ela est centrada em n + 1/2. Com isto, a derivada temporal
do lado esquerdo torna-se, na prtica, um esquema de ordem 2 centrado em n + 1/2!
Como sempre, nosso trabalho agora verificar a estabilidade do esquema numrico. Para isto, fazemos
n+1
i
i
Fo h n+1
Fo h n
n
i+1 2n+1
+ n+1
i+1 2ni + ni1 ,
i
i1 = i +
2
2
l e
"
eat
"
Fo i kl (i+1)x
e
2ei kl ix + ei kl (i1)x =
2
#
"
Fo i kl (i+1)x
i kl ix
i kl (i1)x
atn
i kl ix
e
2e
+e
l e
e
+
2
#
i kl ix
Fo i kl x
Fo i kl x
1
e
2 + ei kl x = 1 +
e
2 + ei kl x
2
2
#
"
at
1 + 2Fo sin
kl x
2
!#
"
= 1 2Fo sin
eat =
kl x
2
!#
kl x
2
.
2 kl x
2Fo sin
2
1 2Fo sin2
1+
fcil notar que |eat | < 1, e o esquema numrico de Crank-Nicholson incondicionalmente estvel. O esquema numrico de Crank-Nicholson similar a (4.39):
Fo n+1
Fo
Fo n
Fo
ui1 + (1 + Fo)un+1
un+1
ui1 + (1 Fo)uni + uni+1
i
i+1 =
2
2
2
2
(4.45)
u
+ (1 + Fo)un+1
un
+ (1 Fo)unNx 1
Nx 1 =
2 Nx 2
2 Nx 2
(1 + Fo)un+1
1
(4.46)
(4.47)
83
t = 0,00
0.4
u(x, t)
0.3
0.2
t = 0,05
0.1
t = 0,10
t = 0,15
0.0
0.2
0.4
0.6
0.8
(4.48)
(4.49)
a soluo analtica
(x2 + y 2 )
u0
exp
u(x, y, t) =
.
1 + 4tD/L2
L2 + 4Dt
!
(4.50)
Matemtica Aplicada
84
85
Na verdade esta soluo se espalha por todo o plano xy, mas ns podemos trabalhar com um problema finito em x e y, por exemplo, fazendo L x L,
L y L, e impondo condies de contorno que se ajustem exatamente soluo analtica:
u(L, y, t) =
u(L, y, t) =
u(x, L, t) =
u(x, L, t) =
u0
1 + 4tD/L2
u0
1 + 4tD/L2
u0
1 + 4tD/L2
u0
1 + 4tD/L2
(L2 + y 2 )
,
2
L + 4Dt
!
(L2 + y 2 )
,
2
L + 4Dt
!
(x2 + L2 )
,
2
L + 4Dt
!
(x2 + L2 )
.
2
L + 4Dt
!
exp
exp
exp
exp
(4.51)
(4.52)
(4.53)
(4.54)
(4.55)
(4.56)
Examine cuidadosamente (4.55) e (4.56): na primeira, note que o esquema implcito em x; na segunda, a situao se reverte, e o esquema implcito em y. claro
que ns vamos precisar de duas anlises de estabilidade de von Neumann, uma para
cada equao.
2011-09-24T17:07:04 Por enquanto, vou supor que os dois esquemas so incondicionalmente estveis, e mandar ver.
Alm disto, por simplicidade vamos fazer x = y = , de maneira que s
haver um nmero de Fourier de grade no problema,
Fo =
Dt
,
2
(4.57)
n
n
n
n+1
n+1
n+1
n
un+1
i,j ui,j = Fo ui1,j 2ui,j + ui+1,j + ui,j1 2ui,j + ui,j+1 ,
n
n
n
n+1
n+1
n+1
n
un+1
i,j Fo ui1,j 2ui,j + ui+1,j = ui,j + Fo ui,j1 2ui,j + ui,j+1 ,
n+1
n+1
n
n
n
Foun+1
i1,j + (1 + 2Fo)ui,j Foui+1,j = Foui,j1 + (1 2Fo)ui,j + Foui,j+1 (4.58)
86
Matemtica Aplicada
Na dimenso y,
n+1
n+1
n+1
n+1
n+2
n+2
n+2
un+2
i,j ui,j = Fo ui1,j 2ui,j + ui+1,j + ui,j1 2ui,j + ui,j+1 ,
n+2
n+2
n+2
n+1
n+1
n+1
n+1
un+2
i,j Fo ui,j1 2ui,j + ui,j+1 = ui,j + Fo ui1,j 2ui,j + ui+1,j ,
n+2
n+2
n+1
n+1
n+1
Foun+2
i,j1 + (1 + 2Fo)ui,j Foui,j+1 = Foui1,j + (1 2Fo)ui,j + Foui+1,j
(4.59)
xi = L + i,
yj = L + j,
(4.60)
N=
i = 0, . . . , N,
j = 0, . . . , N,
(4.61)
(4.62)
87
Matemtica Aplicada
88
A
Dados de vazo mdia anual e vazo
mxima anual, Rio dos Patos,
19311999
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
21.57
25.65
4.76
11.46
28.10
14.30
22.09
24.09
22.29
7.48
27.49
19.11
15.62
16.25
16.57
26.75
21.88
20.68
8.36
21.62
24.72
14.59
15.31
27.33
28.23
15.64
41.70
20.04
14.50
22.61
30.82
15.22
22.49
24.23
36.80
21.60
13.25
9.05
22.94
25.95
32.82
34.13
30.33
17.81
26.77
32.50
13.63
13.26
26.97
272.00
278.00
61.60
178.30
272.00
133.40
380.00
272.00
251.00
56.10
171.60
169.40
135.00
146.40
299.00
206.20
243.00
223.00
68.40
165.00
266.00
192.10
131.80
281.00
311.50
156.20
399.50
152.10
127.00
176.00
257.00
133.40
248.00
211.00
208.60
152.00
92.75
125.00
135.60
202.00
188.00
198.00
252.50
119.00
172.00
174.00
75.40
146.80
222.00
89
Matemtica Aplicada
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
26.92
14.73
31.68
57.60
27.13
12.55
16.74
26.64
15.22
31.20
43.48
11.92
35.24
34.30
20.74
31.78
35.44
41.02
51.55
24.49
182.00
134.00
275.00
528.00
190.00
245.00
146.80
333.00
255.00
226.00
275.00
131.00
660.00
333.00
128.00
472.00
196.00
247.50
451.00
486.00
90
Referncias Bibliogrficas
Abramowitz, M. e Stegun, I. A., editores (1972). Handbook of mathematical functions. Dover Publications, Inc., New York.
Bender, C. M. e Orszag, S. A. (1978). Advanced Mathematical Methods for Scientists
and Engineers. McGraw-Hill.
El-Kadi, A. I. e Ling, G. (1993). The Courant and Peclet Number Criteria for the
Numerical Solution of the Richards Equation. Water Resour Res, 29:34853494.
Oliphant, T. E. (2006). Guide to Numpy. Trelgol Publishing.
Press, W. H., Teukolsky, S. A., Vetterling, W. T., e Flannery, B. P. (1992). Numerical
Recipes in C. Cambridge University Press, Cambridge, UK. 1020 pp.
91