métodos numéricos em matemática aplicados à engenharia - ufpr.pdf

115
Métodos Numéricos em Matemática Aplicada à Engenharia Nelson Luís Dias Departamento de Engenharia Ambiental e Lemma — Laboratório de Estudos em Monitoramento e Modelagem Ambiental Universidade Federal do Paraná 18 de setembro de 2013

Upload: gregoritroina

Post on 18-Aug-2015

241 views

Category:

Documents


6 download

TRANSCRIPT

Mtodos Numricos em Matemtica Aplicada EngenhariaNelson Lus DiasDepartamento de Engenharia Ambiental eLemma Laboratrio de Estudos em Monitoramento eModelagem AmbientalUniversidade Federal do Paran18 de setembro de 2013

2

2013 Nelson Lus da Costa Dias. Todos os direitos deste documento esto reservados. Este documento no est em domnio pblico. Cpias para uso acadmico podemser feitas e usadas livremente, e podem ser obtidas em http://www.lemma.ufpr.br/wiki/index.php/Prof._Nelson_Lus_Dias Recursos de Internet. Este documento distribudo sem nenhuma garantia, de qualquer espcie, contra eventuais errosaqui contidos.

Sumrio0 Formalismos matemticos

13

1 Ferramentas computacionais1.1 Antes de comear a trabalhar, . . . . . . . . . . . . . . . .1.2 Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1.2.1 Strings e Inteiros . . . . . . . . . . . . . . . . . . .1.2.2 Nmeros de ponto flutuante reais e complexos1.2.3 Obteno de uma curva de permanncia . . . . . .1.2.4 Arquivos texto e arquivos binrios . . . . . . . . .1.3 Maxima . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.......

1515171718202426

..........

3131364046465051616567

.......

.......

.......

.......

.......

2 Um pouco de polinmios, integrais, sries e equaes diferenciais2.1 Integrao numrica: motivao . . . . . . . . . . . . . . . . . . . .2.2 A regra do trapzio . . . . . . . . . . . . . . . . . . . . . . . . . . .2.3 Aproximao de integrais com sries: a funo erro . . . . . . . . .2.4 Soluo numrica de equaes diferenciais ordinrias . . . . . . . .2.5 Soluo numrica; mtodo de Euler . . . . . . . . . . . . . . . . . .2.6 Um mtodo implcito, com tratamento analtico . . . . . . . . . . .2.7 Runge-Kutta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2.8 O mtodo de Runge-Kutta multidimensional . . . . . . . . . . . . .2.9 Soluo numrica de um problema no-linear . . . . . . . . . . . .2.10 Poluio orgnica em rios . . . . . . . . . . . . . . . . . . . . . . . .

.................

.................

3 Soluo numrica de equaes diferenciais parciais733.1 Adveco pura: a onda cinemtica . . . . . . . . . . . . . . . . . . . . . . 733.2 Difuso pura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 843.3 Difuso em 2 Dimenses: ADI, e equaes elticas . . . . . . . . . . . . . 103A Para as coisas funcionarem em Windows

111

B Dados de vazo mdia anual e vazo mxima anual, Rio dos Patos, 19311999113

3

Sumrio

4

Lista de Tabelas1.1

Vazes Mximas Anuais (m3 s1 ) no Rio dos Patos, PR, 19311999 . . . .

20

2.1

Estimativas numricas de I e seus erros relativos . . . . . . . . . . . . .

36

5

Sumrio

6

Lista de Figuras1.11.2

FDA emprica da vazo mxima anual no Rio dos Patos. . . . . . . . . . .A funo f (x) = x/(1 + x 7/3 ) . . . . . . . . . . . . . . . . . . . . . . . . .

2327

2.12.22.3

Integrao numrica de uma funo . . . . . . . . . . . . . . . . . . . .A regra do trapzio, com n = 4 e n = 8 trapzios. . . . . . . . . . . . . .Funo erf(x) calculada por integrao numrica, com trapepsilon e = 1 106 , versus a erf pr-definida no programa de plotagem. . . .Funo erf(x) calculada com srie de Taylor, com erf_1, versus a erfpr-definida no programa de plotagem. . . . . . . . . . . . . . . . . . .Soluo da equao (2.14). . . . . . . . . . . . . . . . . . . . . . . . . .Comparao da soluo analtica da equao (2.14) com a sada desucesso.py, para x = 0,01. . . . . . . . . . . . . . . . . . . . . . . .Comparao da soluo analtica da equao (2.14) com a sada desucesso.py, para x = 0,5. . . . . . . . . . . . . . . . . . . . . . . . .Comparao da soluo analtica da equao (2.14) com a sada desucimp.py, para x = 0,5. . . . . . . . . . . . . . . . . . . . . . . . . .Comparao da soluo analtica da equao (2.14) com a sada deeuler2.py, para x = 0,5. . . . . . . . . . . . . . . . . . . . . . . . . .Comparao da soluo analtica da equao (2.14) com a sada derungek4.py, para x = 0,5. . . . . . . . . . . . . . . . . . . . . . . . .O integrando (x , t) para x = 1, . . . , 5. . . . . . . . . . . . . . . . . . . .Clculo de (x) com o mtodo de Runge-Kutta: sada de intgam1 comparada com a funo (x) do programa de plotagem (Gnuplot) . . . . .Soluo numrica pelo Mtodo de Runge-Kutta de um sistema de 2 equaes diferenciais ordinrias . . . . . . . . . . . . . . . . . . . . . . . . .Drenagem de um macio poroso semi-infinito inicialmente totalmentesaturado. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Resultado da integrao numrica do problema de Boussinesq para umaqufero semi-infinito . . . . . . . . . . . . . . . . . . . . . . . . . . . .Soluo numrica do modelo de Streeter-Phelps com o mtodo deRunge-Kutta. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

..

3336

.

41

..

4447

.

49

.

51

.

52

.

54

..

5657

.

60

.

63

.

64

.

68

.

70

Condio inicial da equao 3.3. . . . . . . . . . . . . . . . . . . . . . . .Soluo numrica produzida por onda1d-ins.py, para t = 250t, 500te 750t. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Soluo numrica produzida por onda1d-lax.py, para t = 500t,1000t e 1500t. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

73

2.42.52.62.72.82.92.102.112.122.132.142.152.163.13.23.3

7

7783

SumrioSoluo numrica produzida pelo esquema upwind, para t = 500t,1000t e 1500t. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3.5 Soluo analtica da equao de difuso para t = 0, t = 0,05, t = 0,10 et = 0,15. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3.6 Soluo numrica com o mtodo explcito (3.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 somostrados, para facilitar a comparao com a soluo analtica. . . . .3.7 Soluo numrica com o mtodo implcito (3.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 somostrados, para facilitar a comparao com a soluo analtica. . . . .3.8 Soluo numrica com o mtodo de Crank-Nicholson ( (3.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 numricaso mostrados, para facilitar a comparao com a soluo analtica. . .3.9 Comparao entre as solues analtica (linhas) e numrica com um esquema implcito (pontos) da equao da difuso-adveco com termo dedecaimento, para t = 0,333, t = 0,666 e t = 0,999. . . . . . . . . . . . . .3.10 Soluo analtica da equao da difuso bidimensional, para t = 0, t = 0,t = 0,1, t = 0,2 e t = 0,3 . . . . . . . . . . . . . . . . . . . . . . . . . . .3.11 Soluo numrica da equao da difuso bidimensional com o esquemaADI, para t = 0, t = 0, t = 0,1, t = 0,2 e t = 0,3 . . . . . . . . . . . . . .

8

3.4

.

84

.

88

.

91

.

95

.

98

. 101. 106. 109

Lista de Listagens1.11.21.31.41.51.61.71.81.91.101.112.12.22.32.42.52.62.72.82.92.102.112.122.132.142.152.162.172.18

binint.py exemplo de strings, e inteiros. . . . . . . . . . . . . . . . .floats.py exemplo de uso de float e complex. . . . . . . . . . . . .patos-medmax.dat vazes mdia e mxima anuais, Rio dos Patos . .fqiemp.py clculo de uma FDA emprica . . . . . . . . . . . . . . . .fqiemp.dat FDA emprica da vazo mxima anual no Rio dos Patos. .bintext.py Exemplo de arquivo texto e arquivo binrio . . . . . . . .writearr.py Escreve um arquivo binrio contendo 3 linhas, cadauma das quais com um array de 10 floats. . . . . . . . . . . . . . . . .readarr.py L um arquivo binrio contendo 3 linhas, cada uma dasquais com um array de 10 floats. . . . . . . . . . . . . . . . . . . . . .Obteno do ponto de mximo de uma funo com Maxima . . . . . . .mulambdak.max clculo da mdia da distribuio Weibull em em funo de seus parmetros e k . . . . . . . . . . . . . . . . . . . . . . . . .Sada do programa mulambdak.max . . . . . . . . . . . . . . . . . . . . .achapol.max Polinmio com propriedades definidas . . . . . . . . . .Sada de achapol.max . . . . . . . . . . . . . . . . . . . . . . . . . . . .Clculo da integral de um polinmio analiticamente, com Maxima . . . .passaquad.max parbola h(x) = ax 2 + bx + c passando por (1, f (1)),(3, f (3)) e (5, f (5)). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Sada de passaquad.max . . . . . . . . . . . . . . . . . . . . . . . . . . .numint.py Integrao numrica, regra do trapzio . . . . . . . . . . .quadraver1.py Integrao numrica de f (x) com 8 trapzios . . . . .numint.py Integrao numrica ineficiente, com erro absoluto prestabelecido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .quadraver2.py Integrao numrica ineficiente de f (x) com =0,0001 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .numint.py Integrao numrica eficiente, com erro absoluto prestabelecido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .quadraver3.py Integrao numrica eficiente de f (x) com = 0,000001 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .vererf.py Clculo da funo erro por integrao numrica . . . . . .Clculo de erf(x) com uma srie de Taylor. . . . . . . . . . . . . . . . . .vererf1.py Clculo da funo erro com srie de Taylor entre 0 e 3. .erfs.py Clculo de erf(x) com srie de Taylor, limitado a no mximo43 termos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .resolve-eqdif Soluo de uma EDO com Maxima . . . . . . . . . .fracasso.py Um programa com o mtodo de Euler que no funcionasucesso.py Um programa com o mtodo de Euler que funciona . . .9

1719212123242526282929323233343537373838393941434445464850

Sumrio2.192.202.212.222.232.242.252.262.27

sucimp.py Mtodo de Euler implcito . . . . . . . . . . . . . . . . .euler2 Um mtodo explcito de ordem 2 . . . . . . . . . . . . . . . .rungek4 Mtodo de Runge-Kutta, ordem 4 . . . . . . . . . . . . . . .Primeiro prottipo para o clculo de (x) . . . . . . . . . . . . . . . . .Programa definitivo para o clculo de (x) . . . . . . . . . . . . . . . .Listas em Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .tentaarray.py: arrays com Numpy . . . . . . . . . . . . . . . . . . .rungek4v.py: o mtodo de Runge-Kutta multidimensional . . . . . . .Soluo numrica do modelo de Streeter-Phelps com o mtodo deRunge-Kutta. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3.1 onda1d-ins.py Soluo de uma onda 1D com um mtodo explcitoinstvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3.2 surf1d-ins.py Seleciona alguns intervalos de tempo da soluo numrica para plotagem . . . . . . . . . . . . . . . . . . . . . . . . . . . .3.3 onda1d-lax.py Soluo de uma onda 1D com um mtodo explcitolaxtvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3.4 surf1d-lax.py Seleciona alguns intervalos de tempo da soluo numrica para plotagem . . . . . . . . . . . . . . . . . . . . . . . . . . . .3.5 difusao1d-ana.py Soluo analtica da equao da difuso . . . .3.6 divisao1d-ana.py Seleciona alguns instantes de tempo da soluoanaltica para visualizao . . . . . . . . . . . . . . . . . . . . . . . . .3.7 difusao1d-exp.py Soluo numrica da equao da difuso: mtodo explcito. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3.8 divisao1d-exp.py Seleciona alguns instantes de tempo da soluoanaltica para visualizao . . . . . . . . . . . . . . . . . . . . . . . . .3.9 alglin.py Exporta uma rotina que resolve um sistema tridiagonal,baseada em Press et al. (1992) . . . . . . . . . . . . . . . . . . . . . . . .3.10 difusao1d-imp.py Soluo numrica da equao da difuso: mtodo implcito. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3.11 difusao1d-ckn.py Soluo numrica da equao da difuso: esquema de Crank-Nicholson. . . . . . . . . . . . . . . . . . . . . . . . .sana.max . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3.12 Implementao de um esquema numrico implcito para a equao dadifuso-adveco. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3.13 difusao2d-ana.py Soluo analtica da equao da difuso bidimensional. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3.14 difusao2d-adi.py Soluo numrica da equao da difuso bidimensional, esquema ADI. . . . . . . . . . . . . . . . . . . . . . . . . . .patosmedmax.dat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10........

5254555859626264

.

71

.

75

.

76

.

81

..

8286

.

87

.

89

.

90

.

93

.

94

. 97. 100. 102. 105. 107. 113

PrefcioEste texto parte de um projeto maior, em preparao, que ambiciona cobrir o contedode duas disciplinas que o autor leciona na graduao da UFPR. No seria justo fazermeus alunos esperarem demais pelas partes que j esto razoavelmente prontas. Oleitor, ou a leitora, deve entretanto cuidar para o fato de que se trata de um excerto deum projeto maior, e que consequentemente pode haver falhas. Mesmo assim, creio que a hora de divulgar o contedo relacionado a um assunto absolutamente fascinante, queso os mtodos numricos. Note, leitor ou leitora, que se trata de uma introduo, e queno h nenhuma ambio de completude da parte do autor; mesmo assim. . . Divirta-se!

11

Sumrio

12

0Formalismos matemticosEste um livro sobre formalismos matemticos, e como eles podem ajudar voc, estudante, a resolver problemas mais rapidamente, e mais facilmente. O uso de matemticapara resolver problemas cada vez mais sofisticados e realistas relacionados ao meio fsico, qumico e biolgico que nos cerca um fato: o caminho do futuro com certeza umcaminho em que o contedo matemtico ser cada vez maior na soluo de problemasde Engenharia.Novos formalismos permitem resolver mais rapidamente problemas mais difceis,mas muitos estudantes tm dificuldade de ver as vantagens. No curto prazo, o aprendizado penoso, difcil, e cansativo. mesmo, e no minha inteno encobrir o grandeesforo envolvido. O ponto fundamental, entretanto, estar disposta(o) a entender queo formalismo novo, e que ele precisa ser aprendido antes que o retorno medido nasoluo de problemas de seu interesse possa vir. Pense nisso como um investimento.Como qualquer aluno que completou o ensino mdio antes de ingressar em um cursosuperior, isso j aconteceu na sua vida. Um dia, voc aprendeu um novo formalismomatemtico, muito difcil de entender (naquela ocasio), mas que lhe deu um gigantescopoder de resolver novos problemas. O poder to grande, que voc quase certamenteesqueceu a forma antiga.Exemplo 0.1 Maria possui o dobro das mas de Joo, e duas mas a mais que Jos. O nmerototal de mas que os trs possuem 18. Quantas mas Maria possui? Resolva esse problemasem usar lgebraSOLUOSem lgebra significa com Aritmtica apenas. A nica forma possvel por enumerao. Natabela abaixo, ns vamos aumentando o nmero de mas de Jos, e calculando as mas queMaria e que Joo tm, at que a soma produza o valor do enunciado. Observao: o nmero demas de Maria par; logo, o nmero de mas de Jos tambm . Variamos portanto o nmerode mas de Jos de 2 em 2.Jos

Maria

Joo

Total

0246

2468

1234

381318

Portanto, Maria tem 8 mas. Era assim que voc fazia at aprender lgebra. Tambm eraassim que o mundo inteiro fazia, at a lgebra ser inventada. Hoje, ela to corriqueira, que

13

14

Matemtica Aplicada

ningum mais se lembra de que, um dia, ser matemtico era ser aritmtico e gemetra, mas aindano era ser algebrista.

claro que existe uma outra forma. Se x o nmero de mas de Maria, y o de Joo,e z o de Jos,x = 2y,x = z + 2,x + y + z = 18.Ou:x + x/2 + (x 2) = 18,2x + x + 2x 4 = 36,5x = 40,x =8A superioridade da abordagem algbrica to gritante que a maioria de ns se esquece da soluo aritmtica que aprendemos. A lgebra um formalismo novo, que nosd tanto poder que vale a pena aprend-la ainda bem cedo, e utiliz-la para resolverquase tudo que aparece at o fim do ensino mdio. Nesse ponto, entretanto, o poder dalgebra d sinais de cansao. Novos formalismos so necessrios. Esses formalismos soo Clculo, e a lgebra Linear. Este livro trata do seu uso sistemtico, e intensivo, pararesolver todo tipo de problema. Mas eles so formalismos novos. Suas regras so diferentes das regras da lgebra elementar. Esse fato precisa ser aceito, para que o contedodo livro seja proveitosamente aprendido.Exerccios Propostos0.1 Resolva o mesmo problema, substituindo 18 por 33599999998.

1Ferramentas computacionaisNeste captulo ns fazemos uma introduo muito rpida a duas ferramentas computacionais.Python uma linguagem de programao, razoavelmente clssica, e da qual ns vamos explorar apenas uma parte chamada de programao procedural. A escolha dePython deve-se ao fato de ela ser uma linguagem fcil de aprender, e de existirem muitasbibliotecas de rotinas em Python que tornam muitas das tarefas de Matemtica Aplicadafceis de implementar em um computador.Maxima uma linguagem de processamento simblico. Da mesma maneira que nsfaremos contas com Python, ns faremos lgebra com Maxima. Os usos que faremosde Maxima estaro longe de explorar todo o seu potencial. Ns vamos apenas calcularalgumas integrais, algumas sries de Taylor, e resolver algumas equaes diferenciaisordinrias; entretanto, a rapidez com que faremos isso justifica amplamente o seu uso.Infelizmente, a verso de um programa de computador faz diferena, e s vezes fazmuita diferena. As verses que eu utilizei para este texto foram:Python:

2.7.2

Maxima:

5.24.0

Neste momento, existem duas linhagens de Python convivendo: 2.x, e 3.x. O futuro Python 3.x , e eu procurei usar uma sintaxe to prxima de 3.x quanto possvel. Isso facilitado por comandos do tipo

from __future__ import ,que voc encontrar diversas vezes ao longo do texto. Se voc (j) estiver usando Python3.x, remova esses comandos do incio de seus arquivos .py. Note que os colchetes acimano fazem parte do comando; eles apenas o delimitam, como se fossem aspas.

1.1 Antes de comear a trabalhar,Voc precisar de algumas condies de funcionamento. Eis os requisitos fundamentais:1) Saber que sistema operacional voc est usando.2) Saber usar a linha de comando, ou terminal, onde voc datilografa comandos queso em seguida executados.15

Matemtica Aplicada

16

3) Saber usar um editor de texto, e salvar seus arquivos com codificao ISO-8859-1.4) Certificar-se de que voc tem Python instalado.5) Certificar-se de que voc tem Numpy (um mdulo de Python que deve ser instalado parte, e que vamos utilizar seguidamente) instalado.6) Certificar-se de que voc tem Maxima instalada.Ateno! Um editor de texto no um processador de texto. Um editor de texto noproduz letras de diferentes tamanhos, no cria tabelas, e no insere figuras. Um editorde texto reproduz o texto que voc datilografa, em geral com um tipo de largura constante para que as colunas e espaos fiquem bem claros. Um editor de texto que vemcom Windows chama-se notepad, ou bloco de notas nas verses em Portugus; um excelente substituto chama-se notepad2 (http://www.flos-freeware.ch/notepad2.html). Em Linux, editores de texto simples so o gedit (http://projects.gnome.org/gedit/) que tambm funciona muito bem em Windows, e o kate. Programadores mais experientes costumam preferir o vim, ou o emacs. Esses dois ltimos possuemverses para os 3 sistemas operacionais mais comuns hoje em dia: Windows, Linux eMac OS X.Quando voc estiver praticando o uso das ferramentas computacionais descritasneste texto, suas tarefas invariavelmente sero:1) Criar o arquivo com o programa em Python, ou Maxima, usando o editor de texto, esalv-lo em codificao ISO-8859-1.Se no for bvio para voc, procure descobrir como voc pode configuraro seu editor para salvar em ISO-8859-1. Se isso for impossvel para voc,trabalhe normalmente, mas no use acentos: em lugar de impossvel,digite impossivel.2) Ir para a linha de comando.3) Executar o programa digitando o seu nome (e no clicando! ), possivelmente precedidopor python ou maxima.4) Verificar se o resultado est correto.5) Se houver erros, voltar para 1), e reiniciar o processo.Neste texto, eu vou partir do princpio de que todas estas condies esto cumpridaspor voc, mas no vou detalh-las mais: em geral, sistemas operacionais, editores detexto e ambientes de programao variam com o gosto do fregus: escolha os seuspreferidos, e bom trabalho!Exerccios Propostos1.1 Voc j devia estar esperando por isto: o que um sistema operacional? Qual o sistemaoperacional que voc usa?1.2 Como saber se Python est instalado?

17

1.2 Python

Listagem 1.1: binint.py exemplo de strings, e inteiros.1234567891011121314151617

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import unicode_literalsfrom __future__ import print_functiona = 'aafro '# a uma string# imprime a na telaprint(a)print(len(a))# imprime o nmero de caracteres de ai = 2**32 - 1# i o maior int s/ sinal que cabe em 32 bitsb = unicode (i)# converte i na string correspondente b# imprime b na telaprint(b)print('--- a:')# separa a sada do primeiro for# p/ cada c de a, imprime seu valor unicodefor c in a:print('ord(', c, ') = ', ord(c))print('--- b:')# separa a sada do segundo for# p/ cada c de b, imprime seu valor unicodefor c in b:print('ord(', c, ') = ', ord(c))print( unichr (227))# imprime o caractere unicode no 227

1.2 PythonPython reconhece os seguintes tipos bsicos de variveis: strings, nmeros inteiros, nmeros de ponto flutuante, e nmeros complexos.1.2.1 Strings e InteirosStrings, 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-seunicode em Python 2.x, e str em Python 3.x . O tipo dos nmeros inteiros chama-seint 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 onome do arquivo correspondente (aps um pouco de hesitao, eu decidi no disponibilizar estes arquivos; para testar os exemplos deste texto, voc precisar digitar osarquivos novamente: isto o (a) forar a praticar programao). A listagem um retratofiel 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 estoenfatizados 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. Amaior parte dos comandos de binint.py est explicada nos prprios comentrios. Alguns comentrios (sem inteno de trocadilho) adicionais, por linha:1

Este comentrio especial torna o arquivo executvel em Linux. O caminho/usr/bin/python pode variar com a instalao, e mais ainda com o sistemaoperacional.

2

Este comentrio informa que o arquivo est codificado em ISO-8859-1, no bvio?

3

Magia negra: tudo que escrito entre aspas passa a ser uma string to tipounicode.

4

Magia negra: print deixa de ser uma declarao, e passa a ser uma funo. Sevoc no entendeu nada, no se preocupe.

Matemtica Aplicada8

18

O operador ** significa exponenciao. Nesta linha, a varivel i torna-se umint, e recebe o valor 232 1. Este o maior valor sem sinal que um inteiro podeassumir, j que o maior inteiro que cabe em 32 bits 11111111111111111111111111111111 (binrio) =1 231 + 1 230 + 1 229 + . . . + 1 22 + 1 21 + 1 20 =4294967295 (decimal) .

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 fortem que ser indentado, e na listagem a indentao de 3 espaos. Desta forma,no caso da linha 13, o comando

print('ord(',c,') = ', ord(c)) executado 7 vezes, uma para cada caractere de a. A volta indentao anteriorna linha 14 define o fim do for.Vamos agora sada do programa binint.py:aafro74294967295--- a:ord( a ) =ord( ) =ord( a ) =ord( f ) =ord( r ) =ord( ) =ord( o ) =--- b:ord( 4 ) =ord( 2 ) =ord( 9 ) =ord( 4 ) =ord( 9 ) =ord( 6 ) =ord( 7 ) =ord( 2 ) =ord( 9 ) =ord( 5 ) =

972319710211422711152505752575455505753

print imprime com o formato apropriado inteiros e strings (e muito mais: quasetudo, 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 docaractere 231; a posio do caractere 4 52. Finalmente, o caractere Unicode denmero 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 qualvoc est executando este programa certamente esto utilizando codificaes diferentes(veja se o apndice A pode ajudar).1.2.2 Nmeros de ponto flutuante reais e complexosEm primeiro lugar, um esclarecimento: no computador, no possvel representartodos 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,

19

1.2 Python

Listagem 1.2: floats.py exemplo de uso de float e complex.1234567891011121314

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import unicode_literalsfrom __future__ import print_functionfrom math import pi , e, sin# pi , e, e seno# o seno de um nmero complexo vem com outrofrom cmath import sin as csin# nome , para no confundirfrom cmath import sqrt as csqrt# a raiz quadrada de um nmero complexo vem# com outro nome , para no confundir# imprime o valor de piprint('pi = ',pi)print('e = ',e)# imprime o valor de e# imprime sen(pi /2)print('sen(pi /2) = ',sin(pi /2))i = csqrt ( -1.0)# neste programa , i == sqrt ( -1)print('sen(i)= ',csin(i))# imprime sen(i)

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.2Eis a sada de floats.py:pi = 3.14159265359e = 2.71828182846sen(pi /2) = 1.0sen(i)= 1.17520119364 j

Os comentrios importantes seguem-se. Lembre-se de que na maioria dos casos vocest vendo aproximaes racionais de nmeros reais, e que o computador no pode lidarcom todos os nmeros reais.Como era de se esperar, sen /2 = 1. Por outro lado, o seno de i um nmeropuramente imaginrio, e vale 1,17520119364i. Note que Python usa a letra j paraindicar um valor imaginrio (e no i). Na linha 13, eu forcei a barra, e criei a varivelque, em notao matemtica se escreveria i = 1 (Ns adotamos a conveno deescrever i = 1 em tipo romano, e no i = 1 em tipo itlico; desta forma, nsenfatizamos, dentro das equaes, o nmero imaginrio i; o problema, como voc podenotar, que no texto ele fica confundido com a vogal i; da mesma forma, ns adotaremospara a base dos logaritmos naturais o smbolo e em tipo romano, em lugar de e em tipo itlico, com o mesmo problema). Mas eu tambm poderia ter simplesmenteeliminado essa linha, e substitudo a linha 14 por

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 rebatizeia funo sin complexa de csin, no ato da importao do mdulo, com o mecanismofrom ... import ... as ... (linha 6).Exerccios Propostos1.3 Usando Python, converta 7777 da base 10 para a base 2. Sugesto: estude a documentaoem www.python.org, e encontre a rotina pr-definida (built-in) que faz isto.

20

Matemtica AplicadaTabela 1.1: Vazes Mximas Anuais (m3 s1 ) no Rio dos Patos, PR, 19311999Ano

Vaz Mx

Ano

Vaz Mx

Ano

Vaz Mx

Ano

Vaz Mx

19311932193319341935193619371938193919401941194219431944194519461947194819491950

272.00278.0061.60178.30272.00133.40380.00272.00251.0056.10171.60169.40135.00146.40299.00206.20243.00223.0068.40165.00

19511952195319541955195619571958195919601961196219631964196519661967196819691970

266.00192.10131.80281.00311.50156.20399.50152.10127.00176.00257.00133.40248.00211.00208.60152.0092.75125.00135.60202.00

19711972197319741975197619771978197919801981198219831984198519861987198819891990

188.00198.00252.50119.00172.00174.0075.40146.80222.00182.00134.00275.00528.00190.00245.00146.80333.00255.00226.00275.00

199119921993199419951996199719981999

131.00660.00333.00128.00472.00196.00247.50451.00486.00

1.4 Como se faz para concatenar as strings "bom" e "demais"?

1.2.3 Obteno de uma curva de permannciaUma funo distribuio acumulada (FDA) de probabilidade uma funo que nosinforma qual a probabilidade de que uma varivel aleatria Q assuma um valor menorou igual que um certo nivel q. Os valores de Q variam de experimento para experimento.Por exemplo, se Q a vazo mxima diria em um rio em um ano qualquer, o valorobservado de Q varia de ano para ano.A tabela 1.1 d os valores da vazo mxima anual para o Rio dos Patos, PR, estaoANA (Agncia Nacional de guas do Brasil) 64620000, entre 1931 e 1999.Provavelmente, a maneira mais simples de se estimar uma FDA a partir de um conjunto de dados supor que os dados representam a totalidade das possibilidades, e queas observaes so equiprovveis (em analogia com os 6 nicos resultados possveis dolanamento de um dado no-viciado). No caso da tabela 1.1, se qi a vazo mxima doi-simo ano, teramos que a probabilidade de ocorrncia de qi 1,nonde n o nmero de observaes. Mas a FDA por definio P {Q = qi } =

F (q) = P {Q q }.

(1.1)

(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 queq 0 q 1 . . . qn1 .

21

1.2 Python

Listagem 1.3: patos-medmax.dat vazes mdia e mxima anuais, Rio dos Patos19311932193319341935

21.5725.654.7611.4628.10

272.00278.0061.60178.30272.00

Listagem 1.4: fqiemp.py clculo de uma FDA emprica123456789101112131415161718192021

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import unicode_literalsfrom __future__ import print_functionfrom __future__ import divisionfin = open('patos - medmax .dat ','rt ')#qmax = []#for linha in fin:#campo = linha . split ()##print( campo )qi = float ( campo [2])#qmax. append (qi)#fin. close ()#fou = open('fqiemp .dat ','wt')#qmax.sort ()#n = len(qmax)##for i in range (n):qi = qmax[i]#Fi = (i+1)/n#fou. write (' %8.2f %8.6f\n' % (qi ,Fi ))#fou. close ()#

abre o arquivo de dados ( entrada )uma lista vazialoop nas linhas do arquivosepara os campospara ver campo a campo na telaa vazo o terceiro campoadiciona qi lista qmaxfecha o arquivo de entradaabre o arquivo de sadaordena a listatamanho da listaloop nos elementos da lista ordenadavazoposio de plotagemimprime uma linhafim de papo

Note que a ordenao no altera (1.1). Aps a ordenao, o clculo de F (qi ) trivial:F (qi ) =

iX1k=0

n

=

i+1.n

(1.3)

(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 deplotagem 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 eEstatstica, 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 B).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 (quepossui 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. Essa , simplesmente, uma tabela de duas colunas: a vazo observada (em ordem crescente), e o valorde (i + 1)/n.Como antes, os comentrios em fqiemp.py explicam muito do que est acontecendo. Mas h necessidade de explicaes adicionais:5

Faz a diviso funcionar como em Python 3.x. Em Python 2.x, 3/4 == 0, e 3.0/4== 0.75. Em Python 3.x, / sempre produz um resultado do tipo float (oucomplex); e um novo operador // sempre produz diviso inteira.

Matemtica Aplicada

22

6

A funo pr-definida open abre o arquivo patos-medmax.dat, descrito acimae exemplificado na listagem 1.3. O segundo argumento de open, a string 'rt',diz duas coisas: com r, que se trata de uma operao de leitura, (read), de umarquivo que j existe: isto garante que patos-medmax.dat no ser modificadopor fqiemp.py; com t, que se trata de um arquivo texto. Um arquivo texto umarquivo formado por linhas, sendo cada linha uma string. As linhas so separadaspor caracteres (invisveis no editor de texto) de fim de linha, que convencionalmente ns indicamos por \n. Um arquivo texto um objeto itervel, que podeser acessado linha a linha.

7

Nesta linha, qmax inicializado como uma lista vazia. Uma lista uma sequnciade objetos quaisquer. Dada uma lista a, seus elementos so a[0], a[1], etc.. Umalista a com n objetos vai de a[0] at a[n-1].

8

Este o loop de leitura do programa. linha uma string que contm em cadaiterao uma das linhas de patos-medmax.dat.

9

preciso separar uma linha (veja a listagem 1.3) em seus 3 campos. O mtodo1split separa a string linha em 3 strings, e as coloca em uma lista campo == [campo[0], campo[1], campo[2] ], usando os espaos em branco como separadores (que so eliminados).

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 linha10 so:[ '1931 ',[ '1932 ',[ '1933 ',['1934 ',['1935 ',

'21.57 ', '272.00 ']'25.65 ', '278.00 ']'4.76', '61.60 ']'11.46 ', '178.30 ']'28.10 ', '272.00 ']

11

No entato, estes campos ainda so strings, e no floats. Aqui o terceiro campo convertido em um float e vai para a varivel qi.

12

Finalmente, qi includa na lista qmax.

13

bom estilo de programao fechar cada arquivo previamente aberto.

14

Agora o programa abre o arquivo de sada, fqiemp.dat. w significa aberturapara escrita (write); e t que o arquivo ser texto.

15

sort um mtodo pr-definido para qualquer lista, que a ordena (por default emordem crescente).

16

len uma funo pr-definida que retorna o nmero de elementos da lista.

17

loop para impresso no arquivo de sada.

18

Obtm o i-simo elemento de qmax, colocado na varivel qi, que re-utilizadapara este fim.1 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)

23

1.2 Python

Listagem 1.5: fqiemp.dat FDA emprica da vazo mxima anual no Rio dos Patos.56.1061.6068.4075.4092.75

0.0144930.0289860.0434780.0579710.072464

1.00.90.8

FDA emprica

0.70.60.50.40.30.20.10.00

100

200

300

400

500

600

700

Vazo mxima anual (m3 s 1 )

Figura 1.1: FDA emprica da vazo mxima anual no Rio dos Patos.19

Calcula a posio de plotagem, utilizando o operador / para dividir dois ints egerar um resultado correto do tipo float (veja comentrio sobre a linha 5).

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 inversodo 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 tupla2 (qi,Fi) com tantos elementos quantos so os camposde formatao. O primeiro elemento ser substitudo no primeiro campo de formatao por uma string com 8 caracteres, sendo 2 deles para casas decimais. Osegundo elemento ser substitudo no segundo campo de formatao por umastring 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 noarquivo de sada.

As primeiras 5 linhas do arquivo de sada fqiemp.dat so mostradas na listagem1.5; o seu grfico, plotado a partir de fqiemp.dat, mostrado na figura 1.12 Em

Python uma tupla uma lista imutvel

Matemtica Aplicada

24

Listagem 1.6: bintext.py Exemplo de arquivo texto e arquivo binrio12345678910111213141516171819

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import print_functioni = 673451bdet = bin(i)print(bdet)fot = open('i.txt ','wt')fot. write ('%6d' % i)fot. close ()from struct import packb = pack('i',i)fob = open('i.bin ','wb')fob. write (b)fob. close ()print(type(i))print(type(b))from os.path import getsizeprint('tamanho do arquivo txt = %d bytes ' % getsize ('i.txt '))print('tamanho do arquivo bin = %d bytes ' % getsize ('i.bin '))

Exerccios Propostos1.5 Dado um nmero inteiro p lido do terminal, escreva um programa Python para procurar ondice i de uma lista a de 10 nmeros inteiros definida internamente no programa tal que a[i]== p, e imprimir o resultado.

1.2.4 Arquivos texto e arquivos binriosArquivos texto so legveis por seres humanos. Qualquer representao interna primeiramente traduzida para uma string de caracteres antes de ser escrita em umarquivo texto. Arquivos binrios em geral armazenam informao com a mesma representao interna utilizada pelo computador para fazer contas, etc..Como sempre, um exemplo vale por mil palavras. Na listagem 1.6, temos o programabintext.py, que produz dois arquivos: o arquivo texto i.txt, e o arquivo binrioi.bin. Cada um destes arquivos contm o nmero inteiro i == 673451.Eis aqui a dissecao de bintext.py:5

A funo pr-definida bin produz a representao do objeto na base 2.

8

Escreve a varivel i no arquivo i.txt, usando um campo de 6 caracteres, que o tamanho necessrio para escrever i na base 10.

10

A nica maneira de ler ou escrever um arquivo binrio em Python por meio debyte strings: strings em que cada elemento um byte (8 bits). O mdulo structprov a converso de, e para, byte strings.

11

Converte i em uma byte string. Como a representao interna de i em 4 bytes,o tamanho de b ser de 4 bytes.

1516 Verifica os tipos de i e b.1819 Mostra o tamanho de cada um dos arquivos gerados.

25

1.2 Python

Listagem 1.7: writearr.py Escreve um arquivo binrio contendo 3 linhas, cadauma das quais com um array de 10 floats.12345678

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from numpy . random import randfob = open('a.bin ','wb')for k in range (3):a = rand (10)a. tofile (fob)fob. close ()

####

abre umloop emgera umescreve

arq binrio para escrita3 " linhas "array com 10 nmeros aleatriosuma " linha "

Finalmente, a sada de bintext.py 0 b10100100011010101011

tamanho do arquivo txt = 6 bytestamanho do arquivo bin = 4 bytes

Conte os bits na primeira linha (aps o prefixo 0b, que indica a representao nabase 2): eles correspondem aos 4 bytes que custa ao programa para guardar o nmreointeiro 673451 (apenas 20 bits so mostrados; os 12 bits esquerda desses so iguais azero). Repare que o arquivo binrio menor que o arquivo texto. Em geral, arquivosbinrios tendem a ser menores (para a mesma quantidade de informao). A outragrande vantagem que a leitura e a escrita de arquivos binrios muito mais rpida,porque no h necessidade de traduzir a informao de, e para, strings.Na prtica, arquivos binrios esto invariavelmente associados ao uso de arrays, pelomenos em Engenharia. O mdulo Numpy (http://numpy.scipy.org), que no vemcom Python, e necessita ser instalado parte, proporciona um tipo chamado array, epermite manipular com boa eficincia computacional vetores e matrizes em Python. Otipo permite na prtica substituir listas (tipo list); ademais, tudo ou quase tudo quefunciona com listas tambm funciona com arrays. Neste texto, ns faremos a partir deagora amplo uso de Numpy e de seu tipo array. A referncia completa de Numpy estdisponvel em domnio pblico (Oliphant, 2006), podendo tambm ser comprada pelaInternet.Alm de definir arrays, Numpy tambm proporciona seus prprios mtodos e funes para ler e escrever de e para arquivos binrios. Vamos ento dar dois exemplosmuito simples, porm muito esclarecedores.Primeiro, um programa para escrever um array. A listagem 1.7 mostra o programawritearr.py. O programa usa uma rotina disponvel em numpy, rand, para devolverum array com 10 nmeros aleatrios entre 0 e 1. writearr.py repete por 3 vezes agerao de a e a sua escritura no arquivo binrio a.bin: a escritura utiliza o mtodotofile. Repare que tofile um mtodo do array a; ele no precisa ser importado,pois ele j faz parte da varivel a a partir do momento em que ela criada. writearrroda silenciosamente: no h nenhuma sada na tela. No entanto, se procurarmos nodisco o arquivo gerado, teremos algo do tipo>ls -l a.bin-rw -r--r-- 1 nldias nldias 240 2011 -08 -28 14:08 a.bin

O arquivo gerado, a.bin, possui 240 bytes. Em cada uma das 3 iteraes dewritearr.py, ele escreve 10 floats no arquivo. Cada float custa 8 bytes, de modoque em cada iterao 80 bytes so escritos. No final, so 240.

26

Matemtica Aplicada

Listagem 1.8: readarr.py L um arquivo binrio contendo 3 linhas, cada uma dasquais com um array de 10 floats.123456789101112

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import print_functionfrom numpy import fromfile# para escrever na telafrom sys import stdoutfib = open('a.bin ','rb')# abre o arquivo binriofor k in range (3):# loop em 3 " linhas "a = fromfile (fib ,float ,10)# l um array com 10 floats# imprime com formato na telafor e in a:stdout . write (' %5.4f' % e)stdout . write ('\n')fib. close ()

importante observar que o arquivo a.bin no possui estrutura: ele no sabe quedentro 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 programareadarray.py, mostrado na listagem 1.8.O programa importa a rotina fromfile de Numpy, a partir da qual 3 instncias dea 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.08460.4301 0.9779 0.0322 0.4833 0.6097 0.4387 0.0639 0.1399 0.4350 0.77370.5809 0.0382 0.6567 0.8062 0.8427 0.2511 0.2897 0.5785 0.2892 0.0385

O que vemos so os nmeros aleatrios das 3 instncias de a escritas pelo programawritearr.py.

1.3 MaximaMaxima a linguagem de processamento simblico mais antiga que existe: ela sechamava, quando foi criada, MACSYMA. A mudana de nome ocorreu quando o cdigose tornou livre. Maxima capaz de fazer lgebra, derivar, integrar, resolver equaesdiferenciais, calcular transformadas de Laplace, etc., analiticamente. Por exemplo: vocsabe quanto (a + b)4 ? No? Digitando maxima na linha de comando voc obterMaxima 5.21.1 http :// maxima . sourceforge .netusing 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)

Continuando a digitar, voc encontrar:(% i1) (a+b)^4 ;4(% o1)(% i2) expand (%);

(b + a)4

(% o2)(% i3) quit ();

b

3+ 4 a b

2+ 6 a

O comando

quit();

o devolver para a linha de comando.

2b

3+ 4 a

4b + a

27

1.3 Maxima0.6

0.5

f (x)

0.4

0.3

0.2

0.1

0.00.01

0.1

1

10

100

x

Figura 1.2: A funo f (x) = x/(1 + x 7/3 )Vamos fazer algo um pouco mais sofisticado: quais so as razes deP (x) = x 4 10x 3 + 35x 2 50x + 24?Faa(% i1) P : x^4 - 10*x^3 + 35*x^2 - 50*x + 24 ;432(% o1)x - 10 x + 35 x - 50 x + 24(% i2) solve (P,x);(% o2)[x = 3, x = 4, x = 1, x = 2]

Uma outra maneira de obter o mesmo efeito teria sido(% i1) P : x^4 - 10*x^3 + 35*x^2 - 50*x + 24 ;432(% o1)x - 10 x + 35 x - 50 x + 24(% i2) factor (P);(% o2)(x - 4) (x - 3) (x - 2) (x - 1)

Maxima capaz de resolver muitas equaes quando a soluo algbrica existe. Porexemplo, considere o problema de encontrar o mximo da funof (x) =

x,1 + x 7/3

mostrada na figura 1.2: note que se trata de uma funo muito apertada em torno dex = 0; para vermos melhor a funo nas proximidades de zero, ns plotamos o eixodos x em escala logaritmica. evidente que s existe um mximo para a funo. Paraencontr-lo, ns derivamos f (x), igualamos a derivada a zero, e encontramos a raiz def 0(x) = 0. Com Maxima, isto fica mostrado na listagem 1.9.Note que existem 7 razes para f 0(x ) = 0, mas 6 delas so complexas! Por exemplo, aprimeira raiz encontrada por Maxima foix=

3/7 6i 3/7

336i6ie7 =cos+ i sen;4477

28

Matemtica AplicadaListagem 1.9: Obteno do ponto de mximo de uma funo com Maxima(% i1) f : x/(1 + x ^(7/3)) ;x-------7/3x+ 1

(% o1)

(% i2) diff(f,x);7/317 x-------- - ------------7/37/32x+ 13 (x+ 1)

(% o2)

(% i3) solve (%,x);6 %i %pi-------7

2 %i %pi- -------7

4 %i %pi-------7

3/73/73/73%e3%e3%e(% o3) [x = ---------------, x = -----------------, x = ---------------,3/73/73/74444 %i %pi2 %i %pi6 %i %pi- --------------- -------3/773/773/773/73%e3%e3%e3x = -----------------, x = ---------------, x = -----------------, x = ----]3/73/73/73/74444

observe que Maxima usa os smbolos %e para o nmero e, %i para o nmero i =%pi para o nmero . Alm disto, na linha (%i3), o comando

solve(%,x)

1, e

significa: resolva a expresso da linha anterior ((%o2)) em relao a x. A nica raizreal, portanto, (3/4)3/7 0.884005215243613, como pode ser confirmado visualmentena figura 1.2.Suponha agora que voc deseje calcular a integral

=

x0

dFdx .dx

onde

F (x) = 1 exp (x/)k .A derivada dentro da integral ficou intencionalmente indicada: estou supondo que nssomos preguiosos, e no queremos calcul-la manualmente, nem integral. A listagem1.10 mostra uma maneira de calcular , em funo de e de k, com Maxima.As explicaes se seguem:12

Declara que k e lam so variveis reais. O smbolo $ no fim de cada linha omitea resposta de Maxima; isto til quando executamos uma srie de comandosde Maxima em batch (em srie) a partir de um arquivo .max, e no estamos interessados em ver o resultado de cada um deles. Em sees interativas, o normal encerrar cada comando com ;.

34

Maxima supor que k e lam so positivos em seus clculos.

5

Sem a linha 5, Maxima vai parar e perguntar se k integer apesar da linha 1!

29

1.3 Maxima

Listagem 1.10: mulambdak.max clculo da mdia da distribuio Weibull em em funo de seus parmetros e k12345678

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

Listagem 1.11: Sada do programa mulambdak.maxMaxima 5.21.1 http :// maxima . sourceforge .netusing 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)batch ( mulambdak .max)read and interpret file: #p/home/ nldias /work/ graduacao / matap / aulas / mulambdak .max(% i2)declare ([k], real)(% i3)declare ([ lam], real)(% i4)assume (k > 0)(% i5)assume (lam > 0)(% i6)declare ([k], noninteger )x k(% i7)F : 1 - exp(- (---) )lam(% i8)fdp : diff(F, x)(% i9)mu : integrate (x fdp , x, 0, inf)k + 1(% o9)gamma (-----) lamk(% o9)mulambdak .max

6

Define F (F (x)): note que no F(x)! Note tambm que a atribuio, em Maxima,no feita com = (como em Python), mas sim com :; = fica reservado paraigualdade.

7

Armazena a derivada de F (x ).

8

Calcula a integral.

O resultado de rodar mulambdak.max, com o comando

maxima -b mulambdak.max

mostrado na listagem 1.11Na 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 analticoque ns obtivemos com Maxima !k+1 = .(1.4)kExerccios Propostos1.6 Com Maxima, calcule a derivada def (x ) = ln(sen(ex )).

30

Matemtica Aplicada1.7 Com Maxima, calcule

1

1x 3/2

dx .

1.8 Com Maxima, obtenha as razes de329x 3 + x 2 x + 15 = 0.22

2Um pouco de polinmios, integrais,sries e equaes diferenciais2.1 Integrao numrica: motivaoSuponha 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 listaacima. Portanto,f (x) = ax 4 + bx 3 + cx 2 + dx + e,df,(x) =dxf (0) = 0,f (1) = 5/2,f (2) = 7/2,f (4) = 4,(4) = 0.Agora, podemos obter facilmente a, b, c, d , e com Maxima, com o programaachapol.max da listagem 2.1.A dissecao de achapol.max a seguinte:12

Define f (x) e (x ).

37

Define o valor de f (x) em x = 0, 1, 2, 4, e o valor de (x ) em x = 4, em funo dea, b, c, d, e.

8

Resolve um sistema linear 5 5 em a, b, c, d , e.A sada de achapol.max mostrada na listagem 2.2Portanto,1131711f (x) = x 4 + x 3 x 2 + x .484812331

(2.1)

32

Matemtica Aplicada

Listagem 2.1: achapol.max Polinmio com propriedades definidas12345678

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]) ;

Listagem 2.2: Sada de achapol.maxMaxima 5.21.1 http :// maxima . sourceforge .netusing 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)batch ( achapol .max)read and interpret file: #p/home/ nldias /work/ graduacao / matap / aulas / achapol .max234(% i2)f : e + d x + c x + b x + a x432(% o2)a x + b x + c x + d x + e(% i3)g : diff(f, x)32(% o3)4 a x + 3 b x + 2 c x + d(% i4)ev(eq1 : f, x = 0)(% o4)e(% i5)ev(eq2 : f, x = 1)(% o5)e + d + c + b + a(% i6)ev(eq3 : f, x = 2)(% o6)e + 2 d + 4 c + 8 b + 16 a(% i7)ev(eq4 : f, x = 4)(% o7)e + 4 d + 16 c + 64 b + 256 a(% i8)ev(eq5 : g, x = 4)(% o8)d + 8 c + 48 b + 256 a57(% i9) solve ([ eq1 = 0, eq2 = -, eq3 = -, eq4 = 4, eq5 = 0], [a, b, c, d, e])221131711(% o9)[[a = - --, b = --, c = - --, d = --, e = 0]]4848123(% o9)achapol .max

Suponha agora que voc deseje calcular 5I =f (x) dx .1

claro que esta integral pode ser calculada analiticamente com Maxima, conforme podemos ver na listagem 2.3. Logo, I = 1321/90 14,6778 (ateno para o arredondamento). Entretanto, nem todas as integrais podem ser calculadas assim, por uma sriede motivos: a funo pode no possuir uma integral em forma fechada, a funo pode ser definida por pontos, mas no por uma frmula, a funo pode ser difcil de integrar analiticamente, e voc pode querer ter umaidia inicial do valor da integral, etc..

33

2.1 Integrao numrica: motivaoListagem 2.3: Clculo da integral de um polinmio analiticamente, com Maxima

(% i1) [ a : -1/48 , b : 13/48 , c : -17/12 , d : 11/3] ;11317 11(% o1)[- --, --, - --, --]48 4812 3(% i2) f : a*x^4 + b*x^3 + c*x^2 + d*x ;432x13 x17 x11 x(% o2)- -- + ----- - ----- + ---4848123(% i3) integrate (f,x ,1 ,5) ;1321(% o3)---90(% i4) bfloat (%);(% o4)1.467777777777778 b1

b

y54

f (x )

3h(x )210b

0

1

2

3

4

5

x

Figura 2.1: Integrao numrica de uma funoSuponha portanto que voc no soubesse que I = 1321/90, mas fosse capaz de calcular em princpio tantos pontos de f (x ) quantos fossem necessrios: qual a sua apostapara o valor de I ?Considere a figura 2.1: uma das aproximaes mais bvias mas tambm maisgrosseiras substituir a funo por uma reta ligando os pontos (1, f (1)) e (5, f (5)). Area do trapzio a nossa primeira aproximao para a integral:I0 =

f (1) + f (5) 4 = 12,50.2

Nada mal, considerando o valor verdadeiro 14,6778! Mas pode ser melhorada, com ouso de dois trapzios. Para isto, basta calcular f (3) e somar as reas dos dois trapziosresultantes:f (1) + f (3)f (3) + f (5)I1 = 2+ 2 = 14,000.22

34

Matemtica Aplicada

Note que estamos muito prximos do valor verdadeiro com apenas 2 trapzios.Mas existe uma alternativa analtica mais inteligente do que trapzios: como temos 3pontos, ns podemos aproximar a curva por uma parbola do 2o grau passando por estes3 pontos. O programa passaquad.max, mostrado na listagem 2.4, faz este trabalho, eacha os coeficientes a, b, c da parbolah(x) = ax 2 + bx + cque 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 htambm mostrada na figura 2.1.

Listagem 2.4: passaquad.max parbola h(x) = ax 2 + bx + c passando por (1, f (1)),(3, f (3)) e (5, f (5)).123456789101112

f : ( -1/48)*x^4 + (13/48)* x^3 - (17/12)* x^2 + (11/3)* x ;y1 : f,x=1$y3 : f,x=3$y5 : f,x=5$h : a*x^2 + b*x + c$eq1 : ev(h,x=1) = y1 ;eq2 : ev(h,x=3) = y3 ;eq3 : ev(h,x=5) = y5 ;solve ( [eq1 , eq2 , eq3 ],[a,b,c]) ;abc : % ;h : h,abc ;integrate (h,x ,1 ,5);

A sada de passaquad.max mostrada na listagem 2.5.Com os coeficientes a, b, c de h(x), ns podemos calcular analiticamente nossaprxima aproximao:

I2 =

1

=

1

2

2

h(x) dx

3 2 235 x + x+dx16164

29== 14,5000.2

At agora ns avaliamos 3 alternativas de integrao numrica de f (x): com umtrapzio, com dois trapzios, e com uma parbola. A tabela 2.1 d um resumo dosresultados alcanados. O erro relativo de cada estimativa =

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 onmero de elementos de integrao (no nosso caso foram trapzios) e/ou aumentar aordem do polinmio aproximador da funo por um certo nmero de pontos. Este ocontedo da prxima seo.

35

2.1 Integrao numrica: motivaoListagem 2.5: Sada de passaquad.max

batching /home/ nldias /work/ graduacao / matap / aulas / passaquad .max23411 x17 x13 x(- 1) x(% i2)f : ---- - ----- + ----- + -------3124848432x13 x17 x11 x(% o2)- -- + ----- - ----- + ---4848123(% i3)ev(y1 : f, x = 1)(% i4)ev(y3 : f, x = 3)(% i5)ev(y5 : f, x = 5)2(% i6)h : c + b x + a x(% i7)eq1 : ev(h, x = 1) = y15(% o7)c + b + a = 2(% i8)eq2 : ev(h, x = 3) = y331(% o8)c + 3 b + 9 a = -8(% i9)eq3 : ev(h, x = 5) = y515(% o9)c + 5 b + 25 a = -4(% i10)solve ([eq1 , eq2 , eq3], [a, b, c])3235(% o10)[[a = - --, b = --, c = -]]16164(% i11)abc : %3235(% o11)[[a = - --, b = --, c = -]]16164(% i12)ev(h : h, abc)23 x23 x5(% o12)- ---- + ---- + 16164(% i13)integrate (h, x, 1, 5)29(% o13)-2(% o13)passaquad .max

Exerccios Propostos2.1 Se f (x ) = sen x, qual a estimativa de I =

0

f (x ) dx = 2 com um trapzio ?

2.2 Provavelmente, voc no est muito contente com o resultado do Problema 2.1.a) Aproxime a integral I do Problema 2.1 com dois trapzios, entre x = 0 e /2, e entre x = /2e .b) Aproxime a integral pela integral da parbola quadrtica (x ) = ax 2 + bx + c passando pelospontos (0, 0), ( /2, 1) e ( , 0).c) Aproxime a integral de f (x) pela integral da parbola cbica h(x) = ax 3 +bx 2 +cx +d passandopelos mesmos pontos acima, e com h 0 ( /2) = 0.

36

Matemtica AplicadaTabela 2.1: Estimativas numricas de I e seus erros relativos .IntegralExatoUm trapzioDois trapziosUma parbola

Valor

14,677812,500014,000014,5000

00,14830,04610,0121b

y

f (x )

x0 x1 x2 x3 x4 x5 x6 x7 x8

x

b

Figura 2.2: A regra do trapzio, com n = 4 e n = 8 trapzios.

2.2 A regra do trapzioVamos comear a melhorar nossas estimativas de I pelo mtodo de fora bruta, deaumentar o nmero de trapzios. Isto nos levar ao mtodo talvez mais simples de integrao numrica que vale a pena mencionar, denominado Regra do Trapzio. A figura2.2 mostra a mesma funo f (x) da seo anterior; agora, entretanto, ns desenhamos 4e 8 trapzios sob a curva f (x). evidente que a rea sob f (x ) est agora muito bem aproximada com n = 8 trapzios. O seu valor pode ser estimado pornXf (xi1 ) + f (xi )x ,I3 =2i=1

(2.3)

comx 0 = 1,xn = 5,xn x 0x =.n

(2.4)(2.5)(2.6)

37

2.2 A regra do trapzio

Prosseguindo, (2.3) pode ser re-escrita:"#f (x 0 ) + f (x 1 ) f (x 1 ) + f (x 2 )f (xn1 ) + f (xn )I3 =++...+x222

x= f (x 0 ) + 2 f (x 1 ) + f (x 2 ) + . . . + f (xn1 ) + f (xn )2x= (Se + 2Si ),2comSe = f (x 0 ) + f (xn ),n1XSi =f (xi ).

(2.7)

(2.8)(2.9)

i=1

Esta seo vale um mdulo de Python, que ns vamos denominar numint. Umaimplementao razoavelmente eficiente da regra do trapzio mostrada nas primeiras21 linhas de numint.py, na listagen 2.6Listagem 2.6: numint.py Integrao numrica, regra do trapzio12345678910111213141516171819

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import unicode_literalsfrom __future__ import print_functionfrom __future__ import divisiondef trapezio (n,a,b,f):'''trapezio (n,a,b,f): integra f entre a e b com n trapzios'''deltax = (b-a)/nSe = f(a) + f(b)# define SeSi = 0.0# inicializa Sifor k in range (1,n):# calcula Sixk = a + k* deltaxSi += f(xk)I = Se + 2* Si# clculo de II *= deltaxI /= 2return I

O programa quadraver1.py calcula a integral de f (x) com 8 trapzios (listagem2.7).Listagem 2.7: quadraver1.py Integrao numrica de f (x) com 8 trapzios12345678910

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import unicode_literalsfrom __future__ import print_functionfrom __future__ import divisionfrom numint import trapeziodef f(x):return (( -1/48)*x**4 + (13/48)* x**3 + ( -17/12)*x**2 + (11/3)* x)I3 = trapezio (8,1,5,f)print('I3 = %8.4f\n' % I3)

A sada de quadraver1.py I 3 14,6328. O erro est agora na 2a casa decimal, e oerro relativo = 0,0031, ou 0,3%.

38

Matemtica Aplicada

O problema com numint.trapezio que ns no temos uma idia do erro queestamos cometendo, porque, se estamos utilizando integrao numrica, porque noconhecemos o valor exato de I ! Um primeiro remdio para este problema ficar recalculando a regra do trapzio com um nmero dobrado de trapzios, at que a diferenaabsoluta entre duas estimativas sucessivas fique abaixo de um valor estipulado. Isto implementado, de forma muito ineficiente, na prxima rotina do mdulo numint (listagem2.8: note a continuao da numerao de linhas dentro do mesmo arquivo numint.py),denominada trapepsilonlento, e mostrada na listagem 2.8.Listagem 2.8: numint.py Integrao numrica ineficiente, com erro absoluto prestabelecido202122232425262728293031323334

def trapepsilonlento (epsilon ,a,b,f):'''trapepsilonlento (epsilon ,a,b,f): calcula a integral de f entre a e b comerro absoluto epsilon , de forma ineficiente'''eps = 2* epsilonn = 1Iv = trapezio (1,a,b,f)while eps > epsilon :n *= 2In = trapezio (n,a,b,f)eps = abs(In - Iv)Iv = Inreturn (In ,eps)

########

estabelece um erro inicial grandeum nico trapzioprimeira estimativa , " velha "loopdobra o nmero de trapziosestimativa "nova", recalculada do zerocalcula o erro absolutoatualiza a estimativa " velha "

O programa quadraver2.py calcula a integral de f (x) com erro absoluto estipuladomenor que 0,0001, e imprime a estimativa da integral, o erro absoluto e o erro relativo(em relao ao valor exato conhecido) encontrados: I 4 = 14,67777, = 0,00003, =0,00000075. Com 4 casas decimais, este um resultado exato!Listagem 2.9: quadraver2.py Integrao numrica ineficiente de f (x ) com =0,000112345678910111213

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import unicode_literalsfrom __future__ import print_functionfrom __future__ import divisionfrom numint import trapepsilonlentodef f(x):return (( -1/48)*x**4 + (13/48)* x**3 + ( -17/12)*x**2 + (11/3)* x)(I4 ,eps) = trapepsilonlento (0.0001 ,1 ,5 ,f)print('I4 = %8.5f eps = %8.5f' % (I4 ,eps ))II = 14.677777777777777delta = (I4 - II )/ IIprint('delta = %10.8 f' % delta )

O problema com trapepsilonlento que todos os pontos que j haviam sidocalculados por trapezio so recalculados em cada iterao (verifique). Nosso ltimoesforo, a rotina trapepsilon em numint.py, corrige este problema, reaproveitandotodos os clculos. Volte um pouco figura 2.2: nela, ns vemos a integrao numricade f (x ) com n = 4 e depois com n = 8 trapzios. Repare que Si para n = 4 parte dovalor de Si para n = 8. De fato, para n = 4, Si = f (x 2 ) + f (x 4 ) + f (x 6 ) (note que osndices j esto definidos para o caso n = 8). Esta soma j foi calculada na integral com

39

2.2 A regra do trapzio

4 trapzios, e no precisa ser recalculada. O que ns precisamos fazer agora somarf (x 1 ) + f (x 3 ) + f (x 5 ) + f (x 7 ) ao Si que j tnhamos. Se permanece o mesmo, e depoisbasta aplicar (2.7). Isto feito na ltima rotina de numint, denominada trapepsilon,na listagem 2.10.

Listagem 2.10: numint.py Integrao numrica eficiente, com erro absoluto prestabelecido3536373839404142434445464748495051525354555657585960

def trapepsilon (epsilon ,a,b,f):'''trapepsilon (epsilon ,a,b,f): calcula a integral de f entre a e b comerro absoluto epsilon , de forma eficiente'''eps = 2* epsilon# estabelece um erro inicial granden = 1# n o nmero de trapziosSe = f(a) + f(b)# Se no mudadeltax = (b-a)/n# primeiro deltaxdx2 = deltax /2# primeiro deltax /2Siv = 0.0# Si " velho "Iv = Se*dx2# I " velho "# executa o loop pelo menos uma vezwhile eps > epsilon :Sin = 0.0# Si "novo"n *= 2# dobra o nmero de trapziosdeltax /= 2# divide deltax por doisdx2 = deltax /2# idem para dx2for i in range (1,n ,2):# apenas os mpares ...xi = a + i* deltax# pula os ptos j calculados !Sin += f(xi)# soma sobre os novos ptos internosSin = Sin + Siv# aproveita todos os ptos j calculadosIn = (Se + 2* Sin )* dx2# I "novo"eps = abs(In - Iv)# calcula o erro absolutoSiv = Sin# atualiza SivIv = In# atualiza Ivreturn (In ,eps)

O programa quadraver3.py (listagem 2.11) calcula a integral de f (x) com erroabsoluto estipulado menor que 0,000001, e imprime a estimativa da integral, o erroabsoluto e o erro relativo (em relao ao valor exato conhecido) encontrados: I 5 =14.6777776, = 0.0000005, = 0.00000001. Note que I 5 exato at a 6a casa decimal, conforme estipulado.

Listagem 2.11: quadraver3.py Integrao numrica eficiente de f (x) com =0,00000112345678910111213

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import unicode_literalsfrom __future__ import print_functionfrom __future__ import divisionfrom numint import trapepsilondef f(x):return (( -1/48)*x**4 + (13/48)* x**3 + ( -17/12)*x**2 + (11/3)* x)(I5 ,eps) = trapepsilon (0.000001 ,1 ,5 ,f)print('I5 = %12.7 f eps = %12.7 f' % (I5 ,eps ))II = 14.677777777777777delta = (I5 - II )/ IIprint('delta = %12.8 f' % delta )

40

Matemtica AplicadaExerccios Propostos2.3 Usando Python e numint.trapezio, aproxime I =10 trapzios.

0

sen(x ) dx pela regra do trapzio com

2.4 Usando Python e numint.trapepsilon, aproxime I =com preciso absoluta menor ou igual a 1 10 5 .

0

sen(x ) dx pela regra do trapzio

2.5 Dada f (x ) definida no intervalo [x 0 , x 0 + 2h], deduza a regra de Simpson: x 0 +2hhf (x) dx [f 0 + 4f 1 + f 2 ] ,3x0com fn = f (xn ), xn = x 0 + nh, interpolando a funo (x ) = ax 2 + bx + c atravs dos pontos(x 0 , f 0 ), (x 1 , f 1 ) e (x 2 , f 2 ) e calculando sua integral.2.6 Dobrando o nmero de pontos de 2 para 4, obtenha a regra de Simpson para 5 pontos, x 0 +4hhf (x ) dx [f 0 + 4f 1 + 2f 2 + 4f 3 + f 4 ] ;3x0generalize:

b x 0 +2nh

ax 0

f (x ) dx

h[f 0 + 4f 1 + 2f 2 + . . . + 2f 2n 2 + 4f 2n 1 + f 2n ] .3

2.7 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 compreciso estipulada. Baseie-se em trapezio e trapepsilon.

2.3 Aproximao de integrais com sries: a funo erroIntegraes numricas tais como as mostradas na seo 2.2 podem ser muito custosas em termos do nmero de operaes de ponto flutuante necessrias. Algumas vezes, possvel ser mais inteligente. Um exemplo disto foi o clculo de I 2 com uma nicaparbola quadrtica1 no fim da seo 2.1, que foi capaz de baixar o erro relativo parapouco mais de 1%.Considere agora o clculo de uma integral particularmente importante, a funo erro,definida por x22eu du.(2.10)erf(x) u=0A funo erro est definida em Maxima e em Python 2.7. Como obt-la? Uma maneirafora bruta utilizar trapepsilon com uma preciso razovel (digamos, 106 ), gerarum arquivo, e plotar o resultado para ver a cara da erf(x). O programa vererf.py(listagem 2.12) calcula a funo em um grande nmero de pontos; gera um arquivo dedados vererf.dat. O resultado mostrado com pontos na figura 2.3 em comparaocom uma implementao padro (mostrada em linha contnua) de erf(x) do programade plotagem.Existe uma maneira mais inteligente de calcular erf(x): ela se baseia em integrar a2srie de Taylor do integrando, eu . Maxima permite calcular os primeiros termos:1 Sim!

existem parbolas cbicas, qurticas, etc..

41

2.3 Aproximao de integrais com sries: a funo erro

Listagem 2.12: vererf.py Clculo da funo erro por integrao numrica#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import unicode_literalsfrom __future__ import print_functionfrom __future__ import divisionfrom math import exp , sqrt , pifrom numint import trapepsilondef f(x):return exp(-x*x)xmin = 0.0xmax = 3.0nx = 100dx = (xmax - xmin )/ nxerf = 0.0fou = open('vererf .dat ','wt')xl = xminfou. write ('%8.6f %8.6f\n' % (xl ,erf ))for k in range (nx ):xu = xl + dx(I,eps) = trapepsilon (1.0e-6,xl ,xu ,f)erf = erf + (2.0/ sqrt(pi ))*Ifou. write ('%8.6f %8.6f\n' % (xu ,erf ))xl = xufou. close ()

###############

de 0a 3em 100 passosde dxerf (0) = 0arquivo de sadalimite inferior a partir de xminerf (0) = 0loopnovo limite superiorintegra mais uma fatiaacumula erfimprime at aquiatualiza limite inferiorfecha o arquivo de sada

1.0trapepsilonpr-definida

0.90.80.70.6erf(x)

123456789101112131415161718192021222324

0.50.40.30.20.10.00

0.5

1

1.5

2

2.5

3

x

Figura 2.3: Funo erf(x ) calculada por integrao numrica, com trapepsilon e =1 106 , versus a erf pr-definida no programa de plotagem.

42

Matemtica Aplicada

(% i1) taylor (exp(-u^2) ,u ,0 ,10) ;46810uuuu+ -- - -- + -- - --- + . . .2624120

2(% o1 )/T/

1 - u

A expanso em torno de u = 0, e feita at o 10o termo. No muito difcil reconhecernos denominadores os fatoriais de 0, 1, 2, 3, 4 e 5, e as potncias dos dobros destes valoresnos expoentes de u. Em geral,e

u 2

=

X

(1)n

n=0

u 2n.n!

(2.11)

Portanto,

0

x

e

u 2

du ==

xX

0Xn=0

(1)n

n=0

(1)nn!

0

u 2ndun!

x

u 2n du

X(1)n x 2n+1=n! 2n + 1n=0

=

Xn=0

(1)n

x 2n+1.(2n + 1)n!

(2.12)

Cuidado: no toda srie que permite a troca impune da ordem de integrao eda soma (infinita) da srie. Em princpio, devemos procurar os teoremas relevantesque nos permitem esta troca de ordem. Admitindo que est tudo bem, entretanto, nsconseguimos a srie de Taylor de erf(x)!Ainda falta encontrar uma maneira computacionalmente eficiente de passar dotermo n 1 para o termo n. Vamos a isto:Anx 2n+1(2n + 1)n! BnCn=

(1)n x 2(n1+1)+1

2(n 1 + 1) + 1) n(n 1)!

(1)n1x 2(n1)+1 [x 2 ]

2(n 1) + 1) + [2] [n](n 1)!An1 (x 2 )=.(Bn1 + 2)(Cn1 n)=

(2.13)

Em outras palavras, o numerador An de cada novo termo da srie o anterior vezesx 2 . O denominador mais complicado; ele formado pelo produto BnCn , e as relaescompletas de recurso soAn = x 2n+1 = An1 (x 2 ),Bn = 2n + 1 = Bn1 + 2,Cn = n! = Cn1 n.

43

2.3 Aproximao de integrais com sries: a funo erro

Listagem 2.13: Clculo de erf(x) com uma srie de Taylor.123456789101112131415161718192021222324

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import unicode_literalsfrom __future__ import print_functionfrom __future__ import divisionfrom math import sqrt , pidef erf_1 (x):epsilon_erf = 1.0e -6eps_erf = 2* epsilon_erfA = xB = 1C = 1n = 0termo = A/(B*C)s = termowhile eps_erf > epsilon_erf :n += 1A *= (-x*x)B += 2C *= ntermo = A/(B*C)eps_erf = abs( termo )s += termoreturn (2/ sqrt(pi) * s,n)

################

mesma precisogarante entrada no whileprimeiro Aprimeiro Bprimeiro Cprimeiro nprimeiro termo da srieprimeira soma da srieloopincrementa nnovo Anovo Bnovo Cnovo termoseu valor absolutosoma na srie

Mais uma coisa: a srie de erf(x) s contm potncias mpares: portanto, erf(x) umafuno mpar, e vale a relaoerf(x ) = erf(x).Com isto, temos uma rotina em Python para calcular erf(x), chamada erf_1(x), no mdulo erfs, do arquivo erfs.py. As linhas correspondentes a erf_1(x) so mostradasna listagem 2.13Agora, podemos escrever vererf1.py (listagem 2.14), gerar um arquivo de sadavererf1.dat e plotar a sada, mostrada na figura 2.4.Embora formalmente correta, a rotina erf_1 fica mais lenta medida que |x | cresce.Como j vimos nas figuras 2.3 e 2.4, erf(x) 1 para |x | & 3. Porm, uma olhada emvererf1.dat, nos d

erf_1(3) = 0.999978 ,que ainda est acima da preciso especificada de 0,000001. Precisamos descobrir o valorde x para o qual erf_1 produz 0,999999. Por tentativa e erro, encontramos

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 listagem2.15, 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 queerf_1(100) d um erro de ponto flutuante. preciso enfatizar que erf em erfs.py ainda no uma rotina profissional. Onmero de termos usado ainda potencialmente muito grande; consequentemente, hmuitas operaes de ponto flutuante envolvendo A, B e C, e muitos testes dentro dowhile.

44

Matemtica Aplicada

Listagem 2.14: vererf1.py Clculo da funo erro com srie de Taylor entre 0 e 3.#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import unicode_literalsfrom __future__ import print_functionfrom __future__ import divisionfrom math import exp , sqrt , pifrom erfs import erf_1xmin = 0.0xmax = 3.0nx = 100dx = (xmax - xmin )/ nxfou = open('vererf1 .dat ','wt')xl = xminfou. write ('%8.6f %8.6f\n' % (xl ,0.0))for k in range (nx ):xu = xl + dx(erf ,n) = erf_1 (xu)fou. write ('%8.6f %8.6f\n' % (xu ,erf ))xl = xufou. close ()

#########

de 0a 3em 100 passosde dxarquivo de sadalimite inferior a partir de xminerf (0) = 0loopnovo limite superior

# imprime at aqui# atualiza limite inferior# fecha o arquivo de sada

1.0erf_1pr-definida

0.90.80.70.6erf(x)

1234567891011121314151617181920

0.50.40.30.20.10.00

0.5

1

1.5

2

2.5

3

x

Figura 2.4: Funo erf(x) calculada com srie de Taylor, com erf_1, versus a erf prdefinida no programa de plotagem.

45

2.3 Aproximao de integrais com sries: a funo erro

Listagem 2.15: erfs.py Clculo de erf(x) com srie de Taylor, limitado a no mximo43 termos25262728293031323334353637383940414243444546

def erf(x):if x > 3.6:return 1.0elif x < -3.6:return -1.0epsilon_erf = 1.0e -6eps_erf = 2* epsilon_erfA = xB = 1C = 1n = 0termo = A/(B*C)s = termowhile eps_erf > epsilon_erf :n += 1A *= (-x*x)B += 2C *= ntermo = A/(B*C)eps_erf = abs( termo )s += termoreturn 2/ sqrt(pi) * s

# limita o nmero de termos a 43

################

mesma precisogarante entrada no whileprimeiro Aprimeiro Bprimeiro Cprimeiro nprimeiro termo da srieprimeira soma da srieloopincrementa nnovo Anovo Bnovo Cnovo termoseu valor absolutosoma na srie

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, a nossa erf j uma opo vantajosa em relao integrao numrica.A lio desta seo a seguinte: em geral, com esforo analtico adicional, possvelobter uma mistura de mtodos analticos e numricos que costuma ser amplamentesuperior ao uso de um mtodo numrico puro (por exemplo a regra do trapzio) paraa obteno de resultados semelhantes. Exemplos deste fato vo reaparecer nos captulosseguintes.Exerccios Propostos2.8 (Bender e Orszag (1978), seo 6.2, Exemplo 2) Obtenha uma srie para xF (x ) t 1/2 e t dt;0

compare o resultado obtido com integrao numrica.2.9 Considere a funo F (x ) definida pela integral x te 1dt ,F (x) t0

x 0.

Obtenha uma srie para o clculo de F (x ). Sugesto: expanda et em srie de Taylor em torno det = 0, etc., e em seguida integre termo a termo.2.10 Escreva um programa em Python para calcular a srie de Taylor de f (x ) = x sen(x) emtorno de x = 0. Utilize Maxima para obter os primeiros termos da srie, e desta forma, reconhecendo o padro, encontrar o termo geral.

46

Matemtica Aplicada

2.4 Soluo numrica de equaes diferenciais ordinriasConsidere uma equao diferencial de 1a ordem simples, forada eternamente porum seno:dy y+ = sen x .(2.14)dx xNa listagem 2.16, ns resolvemos esta equao com Maxima. Maxima nos informade que a soluo geral da formay(x ) =

sen x x cos x + c.x

(2.15)

evidente que, em geral, nem a equao diferencial nem sua soluo existem emx = 0. Entretanto, para c = 0,y(x ) =

sen x cos x .x

(2.16)

Agora,

sen x= 1,x0 xde modo que existe uma soluo para a equao partindo de x = 0 se ns impusermos acondio incial y(0) = 0. De fato:

sen x cos x = 1 1 = 0.(2.17)limx0xlim

Listagem 2.16: resolve-eqdif Soluo de uma EDO com Maxima(% i1) 'diff(y,x) + y/x = sin(x) ;dyy(% o1)-- + - = sin(x)dxx(% i2) ode2 (%,y,x);sin(x) - x cos(x) + %c(% o2)y = ---------------------x

O resultado est mostrado na figura 2.5.Claramente, existe uma parte transiente da soluo, dada por sen x/x, que morre medida que x cresce, e existe uma parte peridica (mas no permanente!) da soluo,dada por cos x, que domina y(x) quando x se torna grande. Ns dizemos que cos x parte estacionria da soluo.

2.5 Soluo numrica; mtodo de EulerA coisa mais simples que pode ser pensada para resolver a equao diferencial emquesto transformar a derivada em uma diferena finita:y y+ = sen xx xIsso um comeo, mas no suficiente. Na verdade, o que desejamos que o computador gere uma lista de xs (uniformemente espaados por x ), e uma lista de ys

47

2.5 Soluo numrica; mtodo de Euler1.5

1.0

y(x )

0.5

0.0

0.5

1.0

1.50

10

20

30

40

50

x

Figura 2.5: Soluo da equao (2.14).correspondentes. Obviamente, como os ys devem aproximar a funo, no podemosesperar deles que sejam igualmente espaados!Desejamos ento:x 0 , x 1 , . . . , xnondexi = ix ,com os correspondentesy0 , y1 , . . . , yn .Como x ser fixo, podemos escrever nossa equao de diferenas finitas da seguinteforma:yi+1 yi y+ = sen(x),xxonde eu deixei, propositadamente,...

x= sen(x)y

ainda sem ndices. De fato: qual xi e qual yi usar aqui? A coisa mais simples, mastambm a mais instvel, usar i:yi+1 yi yi+ = sen(xi ).xxiNote que agora possvel explicitar yi+1 em funo de todos os outros valores em i:"#yiyi+1 = yi + sen(xi ) x .(2.18)xiEsse um exemplo de um mtodo explcito: o novo valor da funo em xi+1 (yi+1 ) sdepende de valores calculados no valor anterior, xi . Um olhar um pouco mais cuidadoso

48

Matemtica Aplicada

Listagem 2.17: fracasso.py Um programa com o mtodo de Euler que no funciona123456789101112131415161718192021

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*from __future__ import unicode_literalsfrom __future__ import print_function# ---------------------------------------------------------# cria listas com condies iniciais# ---------------------------------------------------------x = [0.0]y = [0.0]dx = 0.01n = int (50/0.01)from math import sinfor i in range (0,n): # de 0 at ... n -1 !!!!xn = (i+1)* dxyn = y[i] + (sin(x[i]) - y[i]/x[i])* dxx. append (xn)y. append (yn)fou = open('fracasso .out ','wt')for i in range (n):fou. write ('%12.6 f %12.6 f\n' % (x[i],y[i]))fou. close ()

ser capaz de prever o desastre: na frmula acima, se partirmos de x 0 = 0, teremos umadiviso por zero j no primeiro passo!Muitos no veriam isso, entretanto, e nosso primeiro programa para tentar resolvera equao diferencial numericamente se chamar fracasso.py, e est mostrado nalistagem 2.17O resultado o seguinte fracasso:Traceback (most recent call last ):File "./ fracasso .py", line 15, in yn = y[i] + (sin(x[i]) - y[i]/x[i])* dxZeroDivisionError : float division by zero

Isso j era previsvel: quando i == 0 no loop, x[0] == 0 no denominador, e oprograma para com uma diviso por zero. Para conseguir fazer o mtodo numricofuncionar, ns vamos precisar de mais anlise!De volta equao diferencial, na verdade possvel conhecer uma boa parte docomportamento prximo da origem de y(x ), a soluo de (2.14) (para a condio inicialy(0) = 0) sem resolv-la! Para tanto, expanda tanto y(x) quanto sen(x) em srie deTaylor em torno de x = 0:y = a + bx + cx 2 + . . . ,dy= b + 2cx + . . . ,dxsen(x) = x + . . .Substituindo na equao diferencial,b + 2cx +

a+ b + cx + . . . = x + . . .x

Note que a srie de Taylor de sen(x) foi truncada corretamente, porque o maior expoentede x em ambos os lados da equao acima 1. Simplificando,a+ 2b + 3cx + . . . = x + . . .x

49

2.5 Soluo numrica; mtodo de Euler1.5

x = 0,01soluo numricasoluo analtica

1.0

y(x )

0.50.0

0.5

1.0

1.5

0

10

20

30

40

50

x

Figura 2.6: Comparao da soluo analtica da equao (2.14) com a sada desucesso.py, para x = 0,01.A igualdade acima s possvel se a = 0 e b = 0; nesse caso, c = 1/3. Esse o valorcorreto! De fato, a expanso em srie de Taylor da soluo analtica em torno de x = 0dx2 x4 x6sen(x)/x cos(x) =+...330 840Esse resultado nos informa que, prximo da origem, y(x) se comporta como x 2 /3. Nsvamos utilizar a notaox 0 y x 2 /3(2.19)para indicar esse fato.Na verdade, (2.19), obtida sem recurso soluo analtica, suficiente para tratarnumericamente o problema da singularidade na origem. Note quey(x)1 x2= lim= x/3 = 0;x0 xx0 3 xlim

Vamos ento reescrever a equao de diferenas (2.18) usando o limite:"#y0y1 = y0 + sen(x 0 ) x = 0.x0|{z}=0, lim x 0 0

Na prtica, isto significa que ns podemos comear o programa do ponto x 1 = x,y1 = 0! Vamos ento reescrever o cdigo, que ns agora vamos chamar, claro, desucesso.py, que pode ser visto na listagem 2.18A sada de sucesso.py gera o arquivo sucesso.out, que ns utilizamos para plotaruma comparao entre a soluo analtica e a soluo numrica, mostrada na figura 2.6Na verdade, o sucesso estrondoso: com x = 0,01, ns conseguimos produzir umasoluo numrica que visualmente indistinguvel da soluo analtica. Uma das coisas

Matemtica Aplicada

50

Listagem 2.18: sucesso.py Um programa com o mtodo de Euler que funciona1234567891011121314151617181920212223242526272829303132

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*# ---------------------------------------------------------# sucesso : resolve a equao diferencial# dy/dx + y/x = sen(x)# pelo mtodo de Euler . Uso:## ./ sucesso .py # ---------------------------------------------------------from __future__ import print_functionfrom __future__ import divisionfrom sys import argvdx = float (argv [1])# tamanho do passox = [0.0 , dx]# condies inciais em xy = [0.0 , 0.0]# condies iniciais em yn = int (50/ dx)from math import sin , cos# soluo numricafor i in range (1,n):xn = (i+1)* dxyn = y[i] + (sin(x[i]) - y[i]/x[i])* dxx. append (xn)y. append (yn)erro = 0.0# calcula o erro relativo mdiofor i in range (1,n+1):yana = sin(x[i])/x[i] - cos(x[i])erro += abs( (y[i] - yana )/ yana )erro /= n ;print ( 'erro relativo mdio = ', '%10.5 f' % erro )fou = open(argv [2] ,'wt ')for i in range (0,n+1):# imprime o arquivo de sadafou. write ( '%12.6 f %12.6 f\n' % (x[i],y[i]) )fou. close ()

que o programa sucesso.py calculou foi o erro absoluto relativo mdio

n X yi y(xi )

y(xi ) i=1(onde yi a soluo numrica, e y(xi ) a soluo exata no mesmo ponto xi ). Parax = 0,01, = 0,02619, ou seja: menos de 3%.O preo, entretanto, foi alto: ns precisamos de um x bem pequeno, e de50/0,01 = 5000 pontos para gerar a soluo. Ser possvel gerar uma soluo to boacom, digamos, 100 pontos?A figura 2.7 mostra o resultado de rodar sucesso.py com x = 0,5, muito maiordo que antes.O erro mdio relativo agora pulou para = 1,11774, nada menos do que 111%, emuito pior do que a figura acima faz parecer primeira vista!

2.6 Um mtodo implcito, com tratamento analticoNosso desafio desenvolver um mtodo numrico que melhore consideravelmentea soluo mesmo com um x grosseiro, da ordem de 0,5. Nossa abordagem ser proporum mtodo implcito:

yi+1 yi yi + yi+1xi + xi+1+= sen.xxi + xi+12Note que tanto o termo y/x quando sen x esto sendo agora avaliados no ponto mdioentre xi e xi+1 .

51

2.7 Runge-Kutta1.5

x = 0,5soluo numricasoluo analtica

1.0

y(x )

0.50.0

0.5

1.0

1.5

0

10

20

30

40

50

x

Figura 2.7: Comparao da soluo analtica da equao (2.14) com a sada desucesso.py, para x = 0,5.Lembrando que x = xi+1 xi ,

yi+1 yi yi + yi+1xi + xi+1+= sen,xxi + xi+12##""

111xi + xi+11++yi+1+ yi = sen,x xi + xi+1x xi + xi+12##""

xi + xi+12xi+12xiyi+1 yi= sen.x(xi+1 + xi )x(xi+1 + xi )2Uma rpida rearrumao produz

x(xi+1 + xi )xi + xi+1yi+1xi+1 yi xi =sen,22

xi + xi+1xix(xi+1 + xi )yi+1 = yi+sen.xi+12xi+12

(2.20)

Repare que a condio inicial y(0) = 0 no produz nenhuma singularidade em (2.20)para i = 0 x 0 = 0, y0 = 0, pois os denominadores em (2.20) no contm xi . Oprograma que implementa este esquema o sucimp.py, mostrado na listagem 2.19.O resultado um sucesso mais estrondoso ainda, e pode ser visto na figura 2.8.Agora, o erro mdio relativo baixou para = 0,02072, que ainda menor do que odo mtodo de Euler com x = 0,01, ou seja: com um x 50 vezes menor!

2.7 Runge-KuttaO preo que ns pagamos pelo mtodo extremamente acurado implementado emsucimp.py foi trabalhar analiticamente a equao diferencial, at chegar verso dedicada (2.20). Isto bom! Porm, s vezes no h tempo ou no possvel melhorar omtodo por meio de um pr-tratamento analtico. Nossa discusso agora nos levar aum mtodo excepcionalmente popular, denominado mtodo de Runge-Kutta.

52

Matemtica Aplicada

Listagem 2.19: sucimp.py Mtodo de Euler implcito#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*# ---------------------------------------------------------# sucimp : resolve a equao diferencial# dy/dx + y/x = sen(x)# usando um mtodo implcito sob medida# ---------------------------------------------------------from __future__ import print_functionfrom __future__ import divisiondx = 0.5# passo em xx = [0.0]# x inicialy = [0.0]# y inicialn = int (50/ dx)# nmero de passosfrom math import sin , cosfor i in range (0,n):# loop na soluo numricaxn = (i+1)* dxxm = x[i] + dx /2.0yn = y[i]*x[i]/ xn + (dx*xm/xn )* sin ((x[i]+ xn )/2)x. append (xn)y. append (yn)erro = 0.0# calcula o erro relativo mdiofor i in range (1,n+1):yana = sin(x[i])/x[i] - cos(x[i])erro += abs( (y[i] - yana )/ yana )erro /= n ;print ( 'erro relativo mdio = ', '%10.5 f' % erro )fou = open('sucimp .out ','wt')for i in range (0,n+1):# imprime o arquivo de sadafou. write ( '%12.6 f %12.6 f\n' % (x[i],y[i]) )fou. close ()

1.5

x = 0,5soluo numricasoluo analtica

1.00.5y(x )

123456789101112131415161718192021222324252627282930

0.0

0.5

1.0

1.5

0

10

20

30

40

50

x

Figura 2.8: Comparao da soluo analtica da equao (2.14) com a sada desucimp.py, para x = 0,5.

53

2.7 Runge-KuttaDada a equao

dy= f (x , y)dxns podemos tentar estimar a derivada no meio do intervalo h (estamos mudando anotao: at agora, usvamos x, mas h uma forma usual de explicitar o passo quandose trata do mtodo de Runge-Kutta, ou mtodos similares):

dy = f (x + h/2, y(x + h/2))

dx x+h/2

O problema que ns no conhecemos y em x + h/2! Isto pode ser contornado, entretanto, usando o mtodo de Euler de 1a ordem para primeiro estimar y(x + h/2):yn+1/2 yn + hf (xn , yn )/2.Um mtodo mais acurado ser portantok 1 = hf (xn , yn ),k 2 = hf (xn + h/2, yn + k 1 /2),yn+1 = yn + k 2 .Vamos tentar este mtodo e ver como ele se compara com nossos esforos anteriores.Vamos manter h = 0,5 como antes. No entanto, ns ainda sofremos do clculo daderivada em x = 0; por isto, ns vamos mudar o clculo da derivada, colocando um ifna funo ff que a calcula. Note que, do ponto de vista de eficincia computacional,isto pssimo, porque o if ser verificado em todos os passos, quando na verdade eles necessrio no passo zero. No entanto, o programa resultante, euler2.py (listagem2.20), fica mais simples e fcil de entender, e esta nossa prioridade aqui.O resultado mostrado na figura 2.9.O resultado muito bom, com um erro absoluto mdio = 0,02529. Mas ns podemos fazer melhor, com o mtodo de Runge-Kutta de 4a ordem! No vamos deduzir asequaes, mas elas seguem uma lgica parecida com a do mtodo de ordem 2:k 1 = hf (xn , yn ),hk1k 2 = hf (xn + , yn + ),22k 3 = hf (xn + h/2, yn + k 2 /2),k 4 = hf (xn + h, yn + k 3 ),k1 k2 k3 k4+++ .yn+1 = yn +6336Para o nosso bem conhecido problema, o mtodo implementado no programarungek4, na listagem 2.21.O resultado mostrado na figura 2.10.Desta vez, o erro absoluto mdio foi = 0,00007: o campeo de todos os mtodostentados at agora, e uma clara evidncia da eficcia do mtodo de Runge-Kutta.

54

Matemtica Aplicada

Listagem 2.20: euler2 Um mtodo explcito de ordem 2#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*# ---------------------------------------------------------# euler2 : resolve a equao diferencial# dy/dx + y/x = sen(x)# usando um mtodo expltico de ordem 2 ( Euler )# ---------------------------------------------------------from __future__ import print_functionfrom __future__ import divisionh = 0.5# passo em xx = [0.0]# x inicialy = [0.0]# y inicialn = int (50/h)# nmero de passosfrom math import sin , cosdef ff(x,y):if x == 0.0:# implementa a condio inicialreturn 0.0else:return sin(x) - y/xdef eul2(x,y,h,ff ):k1 = h*ff(x,y)k2 = h*ff(x+h/2,y+k1 /2)yn = y + k2return ynfor i in range (0,n):# loop da soluo numricaxn = (i+1)*hyn = eul2(x[i],y[i],h,ff)x. append (xn)y. append (yn)erro = 0.0# calcula o erro relativo mdiofor i in range (1,n+1):yana = sin(x[i])/x[i] - cos(x[i])erro += abs( (y[i] - yana )/ yana )erro /= n ;print ( 'erro relativo mdio = ', '%10.5 f' % erro )fou = open('euler2 .out ','wt')for i in range (0,n+1):# imprime o arquivo de sadafou. write ( '%12.6 f %12.6 f\n' % (x[i],y[i]) )fou. close ()

1.5

x = 0,5soluo numricasoluo analtica

1.00.5y(x )

123456789101112131415161718192021222324252627282930313233343536373839

0.0

0.5

1.0

1.5

0

10

20

30

40

50

x

Figura 2.9: Comparao da soluo analtica da equao (2.14) com a sada deeuler2.py, para x = 0,5.

55

2.7 Runge-Kutta

Listagem 2.21: rungek4 Mtodo de Runge-Kutta, ordem 412345678910111213141516171819202122232425262728293031323334353637383940414243444546

#!/ usr/bin/ python# -*- coding : iso -8859 -1 -*# ---------------------------------------------------------# rungek4 : resolve a equao diferencial# dy/dx + y/x = sen(x)# usando o mtodo de Runge - Kutta de ordem 4# ---------------------------------------------------------from __future__ import print_functionh = 0.5# passo em xx = [0.0]# x inicialy = [0.0]# y inicialn = int (50/h)# nmero de p