Roteiro para o Terceiro Laboratório de Cálculo Numérico - 2008/1 Prof. Dr. Waldeck Schützer June 23, 2008 DM/UFSCar Nesta terceira aula de laboratório, vamos utilizar o Octave para aproximar funções e integrais. Todos os comandos que usaremos nesta aula poderiam também ser digitados no MatLab com os mesmos resultados. 1. Interpolação Polinomial Vamos começar definindo a tabela da função que desejamos interpolar. Seja Definimos essa função no Octave do seguinte modo: f(x) = 1 1 + x 2 octave:1> function y=f(x); y = 1./ (1 + x.^2); endfunction octave:2> Agora, primeiro definimos os valores dos x e depois os dos y utilizando vetores (não se esqueça do ponto-e-vírgula para omitir a saída): octave:2> y = -10:0.1:10; octave:3> x = f(x); octave:4> Para adquirirmos uma boa intuição acerca dessa função, talvez seja uma boa idéia plotar seu gráfico: octave:4> plot(x,y) octave:5> O intervalo que escolhemos, [-10, 10] foi conveniente para plotarmos o gráfico, mas pode ser um pouco grande demais para estudarmos a interpolação dessa função. Vamos começar com algo mais modesto, escolhendo 5 pontos no intervalo [-1, 1] e calculando a função nesses pontos (note que agora não precisamos usar o ponto-evírgula): octave:5> x = -1:0.5:1 x = -1.0000-0.5000 0.0000 0.5000 1.0000 octave:6> y=f(x) y = 0.50000 0.80000 1.00000 0.80000 0.50000 octave:7> Eis ai os pontos x e os respectivos valores de y = f(x). Vamos plotar novamente: octave:7> plot(x,y) octave:8> Note como agora o gráfico da função se parece com uma linha poligonal. Isso é por causa de termos apenas 5 pontos para plotar. Isso parece ser pouca informação, mas como veremos é o suficiente para fazermos a interpolação. Inicialmente, vamos interpolar um valor, digamos, de x = 0.75 usando interpolação do segundo grau usando a fórmula de Newton. Para isso, vamos usar apenas os três últimos pontos da tabela, os das posições 3 a 5, ou seja vamos trabalhar apenas com x 3, x 4, x 5 e y 3, y 4, y 5. Para calcularmos as diferenças finitas de primeira ordem, escrevemos: 1
octave:8> dy1 = y(4:5)-y(3:4) dy1 = -0.20000-0.30000 octave:9> Note que 1 y 3 = y 4 y 3 e 1 y 4 = y 5 y 4. Agora as difereças de segunda ordem (de fato apenas um elemento): octave:9> dy2 = dy1(2)-dy1(1) dy2 = -0.10000 octave:10> Este é o valor de 2 y 3. Para achar o valor desejado vamos usar a fórmula: f(x) p 2 (x) = y 3 + (x x 3 ) 1 y 3 1!h + (x x 3)(x x 4 ) 2 y 3 2!h 2 octave:11> h = x(2)-x(1) h = 0.50000 octave:12> t = 0.75 t = 0.75000 octave:13> y(3)+(t-x(3))*dy1(1)/h+(t-x(3))*(t-x(4))*dy2(1)/(2*h^2) ans = 0.66250 octave:14> Obtemos a aproximação f(0.75) 0.66250, que está bem perto do valor correto: 0.64. Uma melhor aproximação pode ser conseguida se usarmos um polinômio do terceiro grau. Para isso precisaremos dos pontos 2 a 5. Para isso calculamos novamente as diferenças finitas de primeira ordem: octave:14> dy1 = y(3:5)-y(2:4) dy1 = 0.20000-0.20000-0.30000 octave:15> depois as de segunda ordem: octave:15> dy2 = dy1(2:3)-dy1(1:2) dy2 = -0.40000-0.10000 octave:16> e finalmente as de terceira ordem: octave:16> dy3 = dy2(2)-dy2(1) dy3 = 0.30000 octave:17> Agora usamos a fórmula de Newton do terceiro grau: f(x) p 3 (x) = y 2 + (x x 2 ) 1 y 2 1!h + (x x 2)(x x 3 ) 2 y 2 2!h 2 + (x x 2)(x x 3 )(x x 4 ) 3 y 2 3!h 3 ou na linguagem do Octave: octave:17> y(2) + (t-x(2))*dy1(1)/h + (t-x(2))*(t-x(3))*dy2(1)/(2*h^2)+(t-x(2) )*(t-x(3))*(t-x(4))* ans = 0.64375 octave:18> Agora obtivemos uma aproximação muito melhor, 0.64375. O Octave dispõe de um comando bastante conveniente para fazer todas essas contas numa tacada só: octave:18> interp1(x(2:5),y(2:5),0.75, cubic ) ans = 0.64375 octave:19> 2
O comando interp1(x,y,xf,method) realiza interpolação da função tabelada por x e y nos pontos indicados pelo vetor (ou escalar) xf. O argumento method designa método a utilizar. Por padrão o valor linear é empregado, mas também são possíveis nearest, cubic, pchip, e spline. Se a tabela tem mais pontos do que os necessários, os pontos mais próximos de onde se deseja interpolar são escolhidos. Vamos interpolar pontos no intervalo [-1,1] a intervalos de 0.1: octave:19> xf=-1:0.1:1; octave:20> yf=interp1(x,y,xf, cubic ); octave:21> plot(xf,yf) octave:22> Note como a interpolação de muitos pontos produziu um gráfico mais suave do que o anterior, mas ainda assim não é exatamente igual ao da função original. Você consegue perceber onde estão as diferenças? 2. Mínimos Quadrados Agora vamos utilizaro método dos mínimos quadrados para aproximar os dados de uma função. Consideremos os seguintes dados: octave:22> x=0:10; octave:23> y=[1.00000 0.99005 0.96079 0.91393 0.85214 > 0.77880 0.69768 0.61263 0.52729 0.44486 0.36788 ]; octave:24> Vamos ajustar esses dados por um polinômio do segundo grau: F(x) = a 0 + a 1 x + a 2 x 2 isto é, vamos trabalhar com as funções g 0 (x) = 1, g 1 (x) = x e g 2 (x) = x 2 : octave:24> function y=g0(x); y=x.^0; endfunction octave:25> function y=g1(x); y=x; endfunction octave:26> function y=g2(x); y=x.^2; endfunction octave:27> Agora vamos montar o sistema linear do MMQ: octave:27> A = [ > [ g0(x)*g0(x) g0(x)*g1(x) g0(x)*g2(x) ]; > [ g1(x)*g0(x) g1(x)*g1(x) g1(x)*g2(x) ]; > [ g2(x)*g0(x) g2(x)*g1(x) g2(x)*g2(x) ]; > ] A = 11 55 385 55 385 3025 385 3025 25333 octave:28> b = [ g0(x)*y ; g1(x)*y ; g2(x)*y ] b = 8.1460 33.3313 207.8661 Agora vamos resolver esse sistema para encontrarmos os valores de a 0,a 1 e a 2 : octave:28> a = A\b a = 1.0199390-0.0293123-0.0037951 octave:29> Assim, obtivemos o polinômio: F(x) = 1.0199390 0.0293123x 0.0037951x 2 Para calcular o valor desse polinômio nos pontos tabelados podemos escrever: 3
octave:29> F = g0(x)*a(1)+g1(x)*a(2)+g2(x)*a(3) F = Columns 1 through 7: 1.01994 0.98683 0.94613 0.89785 0.84197 0.77850 0.70744 Columns 8 through 11: 0.62879 0.54256 0.44873 0.34731 octave:30> Então a diferença em cada ponto é dada por: octave:31> delta=f-y ans = Columns 1 through 6: 1.9939e-02-3.2182e-03-1.4655e-02-1.6085e-02-1.0175e-02-3.0021e-04 Columns 7 through 11: 9.7661e-03 1.6168e-02 1.5263e-02 3.8690e-03-2.0571e-02 octave:32> Portanto o erro quadrático é facilmente calculado: octave:32> e2 = delta*delta e2 = 0.0020129 octave:33> Que parece ajustar muito bem a função dada. No entanto, o seguinte modelo deve se ajustar melhor a esses dados: F(x) = a 0 e a1x+a2x2 O único problema é que esse modelo não está expresso como uma combinação linear. O que fazer? Muito simples: fazendo G(x) = ln F(x), temos: G(x) = ln(a 0 e a1x+a2x2 ) = lna 0 + a 1 x + a 2 x 2 que é polinomial de segundo grau. Devemos ajustar esse modelo à tabela z = ln(f(x)): octave:33> z=log(y); octave:34> plot(x,z) octave:35> Note como, de fato, o gráfico de z = ln(f(x)) se parece com o de uma parábola com concavidade voltada para baixo. A matriz A de coeficientes do nosso novo problema é exatamente a mesma do anterior, pois esta independe de y (ou de z). Devemos apenas recalcular b: octave:35> b = [ g0(x)*z ; g1(x)*z ; g2(x)*z ] b = -3.8500-30.2499-253.3294 octave:36> Agora vamos resolver o sistema Aa = b para encontrar os valores dos coeficientes: octave:36> a = A\b a = -4.0148e-07-3.9787e-08-1.0000e-02 octave:37> Notamos que os dois primeiros valores são muito pequenos perto do terceiro, e isso provavelmente significa que devemos considerá-los como zero. Assim, lembrando que o primeiro valor dessa lista é igual a ln a 0, devemos tomar a exponencial desse valor para achar a 0. Como estamos assumindo ln a 0 0, devemos ter a 0 1. Com isso chegamos à solução: F(x) = e x2 100 e podemos calcular F e o erro quadrático como antes: 4
octave:37> F=exp(-x.^2./100) F = Columns 1 through 7: 1.00000 0.99005 0.96079 0.91393 0.85214 0.77880 0.69768 Columns 8 through 11: 0.61263 0.52729 0.44486 0.36788 octave:38> delta=f-y delta = Columns 1 through 6: 0.0000e+00-1.6625e-07-5.6085e-07 1.1853e-06 3.7890e-06 7.8307e-07 Columns 7 through 11: -3.6739e-06-3.6058e-06 2.4240e-06-1.9338e-06-5.5883e-07 octave:39> e2 = delta*delta e2 = 5.3144e-11 octave:40> O valor extremamente baixo desse erro confirma que o segundo modelo é melhor do que o primeiro para esses dados. 3. Integração Numérica Vamos integrar numericamente a função y = f(x) definida do seguinte modo: octave:41> x=0:0.1:1; octave:42> y=[ 1.00000 0.99005 0.96079 0.91393 0.85214 > 0.77880 0.69768 0.61263 0.52729 0.44486 0.36788 ]; octave:43> Como temos um número ímpar de pontos igualmente espaçados, com h = 0.1, parece conveniente usarmos a regra 1 3 de Simpson repetida. Definimos o vetor de pesos: octave:43> p=[ 1 4 2 4 2 4 2 4 2 4 1 ]; octave:44> e agora podemos obter o valor da integral aplicando a fórmula: ˆ 1 0 f(x)dx h 3 (y 0 + 4y 1 + 2y 2 + + 4y 10 + y 11 ) o que na linguagem do Octave se escreve simplesmente como: octave:44> 0.1/3*p*y ans = 0.74682 octave:281> Final da Áula de Laboratório 3. Que todos tenham um estudo bem produtivo! 5