Map0151
Conteúdo[ocultar] |
Números no Computador
Muitos dos algoritmos de cálculo numérico, por uma questão prática, deverão ser executados numa máquina real. Nestas máquinas, no entanto, a capacidade de memória para representação dos números é finita. Vários números reais (infinitos, de fato) terão a mesma representação no computador (ou calculadora), daí originando-se os erros de arredondamentos. Vamos ver qual é a técnica usada atualmente para diminuir os erros de arredondamentos.
Representação de números inteiros numa base
Seja β>1 um número natural. Então podemos representar qualquer número inteiro k como a soma k=sgn(k)∗a0β0+⋯+asβs
Exemplo: 39=[100111]2
Representação de números fracionários e decimais numa base
Seja novamente β>1 um número natural.
Se x∈(0,1) então x=b1β+⋯+bkβk+⋯
Exemplo: 0.9=[0.1110011001100...]2
Uma função para colocar um número decimal na forma binária
In[1]: | # -*- coding: utf-8 -*- """ |
Representação em ponto flutuante
Consideramos uma base fixa β>1. Um número real α∈R positivo pode ser escrito nesta base como: α=[ak⋯a0.b1b2⋯]β
- O número m=[0.ak⋯a0b1b2⋯]β∈[0.1,1) chamado de mantissa.
- O número e=k+1 chamado de expoente
- O sinal do número σ
Esta representação do número α como σm×βe chamaremos de representação normal em ponto flutuante na base β. Em geral a base fica clara pelo contexto!
Números de máquina
Continuamos com a base fixa (β), mas na representação normal em ponto flutuante vamos admitir apenas números com a mantissa limitada a D dígitos e o expoente limitado, em módulo, por um número inteiro M. O conjunto M={[0.d1⋯dD]β×βe:|e|≤M}
Se denotarmos por α_ o truncamento do número α, isto é, o maior número de máquina menor que α. E por ¯α o menor número de máquina maior que α. Temos que: ¯α−α_=βe−D
Aritmética de números em pontos flutuantes
A extensão das operações aritméticas de soma e multiplicação de números reais faz-se pelo arredondamento: α⊕β=rd(rd(α)+rd(β))
Aproximações usando polinômios de Taylor
Para fazer as avaliações de funções de variável real, utilizaremos apenas as operações aritméticas. Basicamente, isto significa que só usaremos polinômios. Em primeiro lugar veremos o método de avaliação de Horner.
Método de Horner
É a forma de se avaliar o polinômio num ponto dado executando o menor número de operações aritméticas. O polinômio da forma p(x)=anxn+an−1xn−1+⋯+a0
- A0=an
- Ak+1=Akx0+an−k até o An que é a avaliação.
Teorema de Taylor
Teorema: Seja f:(a,b)→R uma função de classe Cr, talque exista a derivada f(r+1)(c),∀c∈(a,b). Então para todo x do intervalo, e c fixado existe ξ∈|c,x| tal que: f(x)=f(c)+f′(c)(x−c)+⋯+f(r)(c)r!(x−c)r+f(r+1)(ξ)(r+1)!(x−c)r+1
Zeros de funções
Dada uma função f:(a,b)→R, queremos encontrar um r∈(a,b) tal que f(r)=0. Um tal número será chamado de zero da função f. Para assegurar a existência de zeros no intervalo, precisamos de alguma regularidade da função. Se f é uma função contínua, uma condição suficiente para a existência do zero é que f(a)∗f(b)<0, e uma técnica para chegar ao zero é ir contraindo este intervalo, mantento a relação f(a)∗f(b)<0, até chegarmos suficientemente próximo. No método da bissecção vamos dividindo o intervalo ao meio. Se (an,bn) é o intervalo com f(an)∗f(bn)<0, definimos xn+1=(an+bn)/2 e o novo intervalo como:
- (an+1,bn+1)=(xn+1,bn) se f(an)∗f(xn+1)<0
- (an+1,bn+1)=(an,xn+1) caso contrário
O tamanho do intervalo no n-ésimo passo é |b−a|/2n. A seguir uma função em python que implementa a bissecção.
Algoritmo da bissecção
In[2]: | #define a funcao bisseccao
|
Out[2]: | | k | x0 | x1 | xmid |f(x0)*f(xmid)| | 0 | 0.000000 | 2.000000 | 1.000000 | +2.00000000 | | 1 | 1.000000 | 2.000000 | 1.500000 | -0.25000000 | | 2 | 1.000000 | 1.500000 | 1.250000 | +0.43750000 | | 3 | 1.250000 | 1.500000 | 1.375000 | +0.04785156 | | 4 | 1.375000 | 1.500000 | 1.437500 | -0.00726318 | | 5 | 1.375000 | 1.437500 | 1.406250 | +0.00245667 | | 6 | 1.406250 | 1.437500 | 1.421875 | -0.00048804 | | 7 | 1.406250 | 1.421875 | 1.414062 | +0.00000960 | | 8 | 1.414062 | 1.421875 | 1.417969 | -0.00000454 | | 9 | 1.414062 | 1.417969 | 1.416016 | -0.00000218 | | 10 | 1.414062 | 1.416016 | 1.415039 | -0.00000100 | | 11 | 1.414062 | 1.415039 | 1.414551 | -0.00000041 | | 12 | 1.414062 | 1.414551 | 1.414307 | -0.00000011 | | 13 | 1.414062 | 1.414307 | 1.414185 | +0.00000004 | |
Algoritmo de Newton
O algoritmo de Newton-Raphson usa propriedades de diferenciabilidade da função f para criar uma sequência recorrente que converge ao zero da função que atrairá um ponto x0, que é uma estimativa inicial. A fórmula para gerar a sequêmcia é: xk+1=xk−f(xk)f′(xk)
In[3]: | # ilustra o processo de newton-raphson def newtonRaphson(f,flinha,x0,eps=0.0001): |
Out[3]: | | k | x_k | |x_k-xk-1| | |1 | 1.4166667 | 0.0833333 |2 | 1.4142157 | 0.0024510 |3 | 1.4142136 | 0.0000021 |
Algoritmo da secante
O método da secante pode ser visto como uma adaptação do método de Newton, onde a derivada da função f é computada pela fórmula de aproximação f′(xk)∼f(xk)−f(xk−1)(xk−xk−1)
O código em Python pode ser o seguinte
In[4]: | # Uma nova definição da secante usando o pseudo-código Kincaid def secante(f,x0,x1,eps=0.0001): |
Out[3]: | | k | x_k | f(xk) | |1 | 2.0000000 | 2.0000000 |1 | 1.0000000 | -1.0000000 |2 | 1.3333333 | -0.2222222 |3 | 1.4285714 | 0.0408163 |4 | 1.4137931 | -0.0011891 |5 | 1.4142114 | -0.0000060 |
Resolução de sistemas lineares
Do ponto de vista de algoritmos numéricos existem duas formas para se resolver um sistema de equações lineares da forma: a11x1+⋯+a1nxn=b1⋮an1x1+⋯+annxn=bn
Os Métodos Diretos têm, em geral, duas fases. Numa primeira fase, um sistema genérico é transformado, numa sequência finita de passos, num sistema de uma classe de sistemas, do qual se conhece um algoritmo eficiente para a solução. Na segunda fase, resolvemos o sistema gerado. O método da eliminação de Gauss (MEG) é um método direto que descreveremos a seguir.
Os Métodos Iterativos são obtidos por uma sequência de estimativas da solução. Esta sequência deve convergir para a solução, e muito raramente se obtem a solução exata. Mas tem-se um bom controle de erros. Descreveremos o método de Gauss-Seidel que ilustra esta técnica.
Método da Eliminação de Gauss
Em primeiro lugar vamos descrever os algoritmos para a resolução de sistemas triangulares. Uma matriz quadrada U=(uij) é triangular superior quando tivermos a condição uij=0 para i>j. Neste caso podemos resolver o sistema linear Ux=b,usando o algoritmo de baixo pra cima em n passos:
- Passo 1 : Encontro xn=bn/unn
- Passo k : Encontro xn−k+1=1un−k+1n−k+1(bn−k+1−∑nj=n−k+2un−k+1jxj)
A matriz L=(lij) é triangular inferior quando lij=0 e lii=1 para i<j. Para resolver os sistema Lx=b usando um algoritmo parecido com o anterior.
- Passo 1 : Encontro x1=b1/l11
- Passo k : Encontro xk=1ukk(bk−∑k−1j=1ukjxj)
No método da eliminação de Gauss (MEG), vamos transformar um sistema linear numa sistema equivalente triangular superior, isto é, quando a matriz dos coeficientes A é triangular superior. Faremos isso usando as operações elementares, que descrevemos a seguir:
- O(i,j) é a troca da linha i com a linha j
- O(i,α) é a multiplicação da linha i por um número, não nulo, α
- O(i,α,j) é a substituição da linha i pela soma desta com α multiplicado pela i−ésima linha.
O algoritmo é a aplicação sucessivas dos seguintes passos com k variando de 1 até n−1
Passo k: Caso akk≠0, faça de i=k+1 até i=nmik=aik/akke aplique ao sistema a operação elementar O(i,mik,k).
Ao fim do passo n−1 o sistema estará triangularizado. Para evitar a possibilidade de não se triangularizar o sistema, mesmo ele sendo possível e determinado, executamos a pivotação que é o seguinte procedimento: antes da execução do passo k do MEG. Buscamos, na k−ésima coluna, a partir da k−ésima linha o índice i tal que |aik| seja o maior possível, e executamos O(i,k). Com isto garantimos a triangularização de qualquer sistema que tenha solução única.
A seguir o código em python para a eliminação de Gauss
In[5]: | # gauss elimination as seen in the classroom import numpy as np |
Versão sem pivotação (não sei se precisa!)
In[6]: | # gauss elimination as seen in the classroom import numpy as np |
Decomposição LU
Diremos que uma matriz L é triangular inferior se L=(lij) com lij=0 se i<jlii=1
Por outro lado, a matriz U será triangular superior se U=(uij) com uij=0 se j<i
Uma matriz inversível tem decomposição LU se e somente se seus menores principais têm determinantes não nulos. Neste caso pode-se resolver o sistema Ax=b
Métodos Iterativos
A idéia dos métodos iterativos é produzir uma sequência de estimativas vetoriais x(k), que idealmente convirja para a solução x e cada passo é calculado a partir da estimativa anterior. Costumam ser bem mais rápidos no caso de matrizes muito grandes. Para construir recursivamente a sequência que dá origem ao método iterativo fazemos uma decomposição da matriz A de coeficientes do sistema como A=N−P
- Método de JacobiN=diag(a11,⋯,ann)
- Método de Gauss-Seidel N=(nij) com nij=aij se i≥jnij=0 se i<j
Método dos Mínimos Quadrados: Caso discreto
Consideremos uma tabela de pontos T={(x0,y0),⋯,(xk,yk)}. Podemos interpretar esta tabela de duas formas: 1. Pode ser um conjunto de informações aproximadas sobre uma função de determinado tipo. E neste caso procuraremos a função daquele tipo que melhor se ajuste à tabela. 2. Pode ser um conjunto de informações precisas sobre uma função diferenciável. Mas não sabemos mais o tipo da função.
No primeiro caso faremos um ajuste da função para a tabela pelo Método dos Mínimos quadrados. A função ajustada não respeita, necessariamente, a tabela dada. Para o segundo caso estudaremos a Interpolação polinomial
Comecemos com o método dos mínimos quadrados (MMQ). Lembremos que temos dadas uma tabela de pontos T={(x0,y0),⋯,(xk,yk)} e uma família de funções F onde o domínio de cada uma das funções de F contém os pontos xi da tabela T. O resíduo quadrático de uma função f com relação à tabela é: r(f,T)=k∑i=0(yi−f(xi))2