Exemplo de funções com múltiplas raízes. |
Muitos problemas envolvem o cálculo das raízes de uma função qualquer. Existem métodos numéricos eficientes para o cálculo dessas raízes, entretanto, esses métodos encontram apenas uma raiz dentro de um intervalo conhecido. Nesta postagem, mostramos como encontrar todas as raízes dentro de um dado intervalo. O método é bem simples e consiste nos seguintes passos:
- definir um intervalo (x1, x2), com x2 > x1;
- dividir esse intervalo em N trechos (N > 10), d = (x2-x1)/N;
- varrer esse intervalo fazendo x variar de x1 a x2 com passo d;
- se $f(x).f(x+d) < 0$, calcular xr dentro deste intervalo e guardar esses valores;
- usar o método (quase) Newton com esse valor xr para encontrar a raiz próxima a xr.
\[ xr = \frac{(x.abs(f(x+d)) + (x+d).abs(f(x)))}{(abs(f(x)) + abs(f(x+d)))} \]
A derivada de uma função pode ser calculada de forma numérica por:
\[ \frac{df}{dx} = \frac{f(x+h) - f(x-h)}{2h} \]
sendo $h$ um valor pequeno (ex: 0,00001).
O código Scilab completo para resolver esse problema é:
clc; close(winsid());
function ff=funcf(x) /// exemplo de funções:
//ff = (2.^x + x).*(x-2.95).*(exp(-(x.*x)/4))+0.5;
//ff = xd.*xd + exp(-x/2) + sin(x+0.3) - 5;
//ff = cos(sqrt(abs(15*x))).*exp(-abs(x)/4);
//ff = sin(x.*sqrt(abs(2*x))).*exp(-abs(x)/4);
n = (x+3.92).*(x+2.07).*(x-0.66).*(x-3.37);
d = x.*x + 2;
ff = n./d;
endfunction
x1 = -4.5; // definindo o intervalo
x2 = 4.5;
a = x1:0.05:x2;
y = funcf(a);
plot(a,y); xgrid; // gráfico da função
p = [];
xr = 0;
dd = (x2-x1)/20;
disp('[k, k+dd, k+dd/2, xr]');
for k=x1:dd:x2 /// procurando pelas raízes
y1 = funcf(k);
y2 = funcf(k+dd);
if y1*y2 < 0 then
xr = (k*abs(y2) + (k+dd)*abs(y1))/(abs(y1) + abs(y2));
p = [p, xr];
disp([k, k+dd, k+dd/2, xr]);
end;
end
//disp(p);
rr = [];
for n=1:max(size(p)) /// calculando as raízes
e=1;
emin = 1e-6;
xk = p(n);
h = 1e-5;
h2 = 2*h;
kk = 0;
while abs(e)>emin
dff = (funcf(xk+h) - funcf(xk-h))/(h2);
e = funcf(xk)/dff;
xk = xk - e;
kk = kk + 1;
//disp([xk, kk]);
end
rr = [rr; xk, kk];
end
disp(rr);
plot(rr(:,1),rr(:,1)*0,'ro');
xlabel('x'); ylabel('f(x)');
title('Função f(x) e suas raízes');
Nenhum comentário:
Postar um comentário