O cálculo da raiz de uma função, isto é, o valor de $x$ tal que $f(x) = 0$ pode ser calculado pelo método de Newton-Raphson:
$$ x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)} $$
Como o cálculo da derivada da função ($f'(x)$) pode ser trabalhoso ou difícil de calcular, em seu lugar pode ser usado uma aproximação numérica, como, por exemplo, a diferença dividida regressiva:
$$ f'(x_n) = \frac{f(x_{n-1}) - f(x_n)}{x_{n-1} - x_n}$$
que leva ao método da secante:
$$ x_{n+1} = x_n - \frac{f(x_n)(x_{n-1} - x_n)}{f(x_{n-1}) - f(x_n)} $$
Entretanto, a derivada de uma função também pode ser aproximada por:
$$ f'(x_n) = \frac{f(x_n+h)-f(x_n)}{h} $$
ou ainda
$$ f'(x_n) = \frac{f(x_n+h)-f(x_n-h)}{2h} $$
onde $h$ é um valor pequeno, por exemplo: $h = 10^{-3}$. O código Scilab abaixo mostra uma comparação entre essas formas de implementar o método da secante para o cálculo do zero da função $x e^{-x/2} - x^2/2$ que está entre $1,1$ e $1,2$.
Código:
function ff=fco(x) // função ff = x.*exp(-x/2) - x.*x/2; endfunction function ffd=dfco(x) // derivada da função h = 1e-6; ffd = exp(-x/2) - 0.5*x.*exp(-x/2) - x; endfunction clc; t = 0:0.01:1.5; y1 = t.*exp(-t/2); y2 = t.*t/2; y3 = dfco(t); close; plot(t,y1,t,y2,t,y1-y2,t,y3); xgrid; erromax = 1e-16; disp(' **** Secante: '); erro = 1; h = 1e-3; t1 = 1.2; t2 = 1.1; k = 1; while abs(erro) > erromax dff = fco(t1) - fco(t2); erro = fco(t2)*(t1 - t2)/dff; t1 = t2; t2 = t2 - erro; disp([k, t2, erro]); k = k + 1; if k>10 then erro = 0; end; end disp(' ***** Secante d1:'); erro = 1; h = 1e-3; t = 1.1 k = 1; while abs(erro) > erromax dff = (fco(t+h) - fco(t))/(h); erro = fco(t)/dff; t = t - erro; disp([k, t, erro]); k = k + 1; if k>10 then erro = 0; end; end disp(' ***** Secante d2:'); erro = 1; h = 1e-3; t = 1.1 k = 1; while abs(erro) > erromax dff = (fco(t+h) - fco(t-h))/(2*h); erro = fco(t)/dff; t = t - erro; disp([k, t, erro]); k = k + 1; if k>10 then erro = 0; end; end disp(' ***** Newton:'); erro = 1; h = 1e-3; t = 1.1 k = 1; while abs(erro) > erromax dff = dfco(t); erro = fco(t)/dff; t = t - erro; disp([k, t, erro]); k = k + 1; if k>10 then erro = 0; end; end
Resultados:
**** Secante:
1. 1.1325514 -0.0325514
2. 1.1343352 -0.0017838
3. 1.1342865 0.0000487
4. 1.1342866 -6.681D-08
5. 1.1342866 -2.568D-12
6. 1.1342866 0.
***** Secante d1:
1. 1.135246 -0.035246
2. 1.1342881 0.000958
3. 1.1342866 0.0000015
4. 1.1342866 1.173D-09
5. 1.1342866 9.277D-13
6. 1.1342866 8.737D-16
7. 1.1342866 0.
***** Secante d2:
1. 1.1352758 -0.0352758
2. 1.1342874 0.0009884
3. 1.1342866 0.0000008
4. 1.1342866 4.226D-13
5. 1.1342866 0.
***** Newton:
1. 1.1352758 -0.0352758
2. 1.1342874 0.0009884
3. 1.1342866 0.0000008
4. 1.1342866 4.727D-13
5. 1.1342866 0.
Conclusão.
Para este exemplo, o método da secante usando a aproximação da derivada $f'(x) = (f(x+h) - f(x-h))/(2h)$ (método d2) é tão rápido quanto o método de Newton. Já o método da secante usando a aproximação $f'(x) = (f(x+h) - f(x))/h$ (método d1) foi o mais lento. Se o passo $h$ usado fosse maior ($h = 10^{-2}$, por exemplo), o método d1 seria ainda mais lento.
Nenhum comentário:
Postar um comentário