Me enseñaron que se debe utilizar la fórmula de avance cuando se calcula el valor de un punto cercano a x0 y el de atrás cuando se calcula cerca de xn . Sin embargo, el polinomio de interpolación es único, por lo que el valor debería ser el mismo. Entonces, ¿hay alguna diferencia entre los dos, o mi profesor está equivocado?
Aquí están los fórmulas :
- Interpolación diferencial Gregory-Newton o Newton Forward P(x0+hs)=f0+sΔf0+s(s−1)2!Δ2f0+⋯+s(s−1)(s−2)...(s−n+1)n!Δnf0 donde s=(x−x0)h;f0=f(x0);Δkfi=k∑j=0(−1)jk!j!(k−j)!fi+k−j
- Interpolación por diferencia hacia atrás Gregory-Newton o Newton P(xn+hs)=fn+s∇fn+s(s+1)2!∇2fn+⋯+s(s+1)(s+2)...(s+n−1)n!∇nfn donde s=(x−xn)h;fn=f(xn);∇kfi=k∑j=0(−1)jk!j!(k−j)!fi−j
Ejemplo: Para interpolar en los puntos x0=−3,−2.9,−2.8,...,2.9,3=xn con f(x)=ex usando MATLAB tenemos
>> x = -3:0.1:3; y = exp(x);
>> frwrdiffdata = frwrdiff(x, y, 0.1, -3:0.5:3);
>> bckwrdiffdata = bkwrdiff(x, y, 0.1, -3:0.5:3);
>> mostAccurateData = exp(-3:0.5:3)';
>> [abs(frwrdiffdata-mostAccurateData)./mostAccurateData ...
abs(bckwrdiffdata-mostAccurateData)./mostAccurateData]
ans =
1.0e-03 *
0 0.672871398134864
0.000000000000169 0.001123487151044
0.000000000000205 0.000000247108705
0 0.000000006452206
0.000000000000302 0.000000000010412
0.000000000000366 0.000000000005491
0.000000000000222 0.000000000001776
0.000000000000135 0
0.000000000000327 0.000000000000327
0.000000000093342 0
0.000000006938894 0
0.000003364235903 0
0.000053772150047 0
donde la primera columna es el error relativo de la diferencia hacia delante de Newton y la segunda columna es el error relativo de la diferencia hacia atrás de Newton para los puntos de muestra x=−3,−2.5,−2,...,2.5,3 . Como se ve en la tabla anterior y en la siguiente figura, el error relativo de la primera columna aumenta a medida que x→xn y el error relativo de la segunda columna disminuye como x→xn .
Las funciones de MATLAB frwrdiff
y bkwrdiff
utilizados arriba son
function polyvals = frwrdiff(x, y, h, p) % Newton Forward Difference function
n = length(x);
ps = length(p);
polyvals = zeros(ps, 1);
dd = zeros(n,n);
dd(:, 1) = y(:);
for i = 2: n % divided diference table
for j = 2: i
dd(i,j) = (dd(i, j-1) - dd(i-1, j-1));
end
end
a = diag(dd); %y_0, delta_0, ..., delta_n
for k = 1: ps
s = (p(k) - x(1))/h; %(x - x_0) / h
t = s;
polyvals(k) = a(1) + s*a(2); %y_0 + s * delta_0
for i = 1: n-2
t = t * (s - i);
polyvals(k) = polyvals(k) + t*a(i+2)/factorial(i+1);
end
end
y
function polyvals = bkwrdiff(x, y, h, p) % Newton Backward Difference function
n = length(x);
ps = length(p);
polyvals = zeros(ps, 1);
dd = zeros(n,n);
dd(:, 1) = y(:);
for i = 2: n % divided diference table
for j = 2: i
dd(i,j) = (dd(i, j-1) - dd(i-1, j-1));
end
end
a = dd(n,:); %y_n, nabla_0, ..., nabla_n
for k = 1: ps
s = (p(k) - x(n))/h; %(x - x_n) / h
t = s;
polyvals(k) = a(1) + s*a(2); %y_0 + s * nabla_0
for i = 1: n-2
t = t * (s + i);
polyvals(k) = polyvals(k) + t*a(i+2)/factorial(i+1);
end
end
Nota: Los resultados parecen diferentes cuando al principio obtenemos los polinomios y luego sustituimos los puntos x=−3,−2.5,−2,...,2.5,3 a los polinomios:
ans =
1.0e+02 *
0.000000132146955 1.528566476043447
0.000000000047960 0.000683674054800
0.000000000000000 0.000000095605754
0.000000000000000 0.000000000002139
0.000000000000000 0.000000000000000
0.000000000000000 0.000000000000000
0.000000000000000 0
0.000000000000000 0
0.000000000000000 0.000000000000000
0.000000000000331 0.000000000000000
0.000000004277456 0.000000000000000
0.000006632407337 0.000000000000896
0.001154767626752 0.000000000785245
Los resultados anteriores se han obtenido modificando las dos funciones de matlab ya mencionadas en esta pregunta.
0 votos
¡debe ser por la aritmética finita que implica el cálculo del polinomio y el valor del mismo en un punto concreto !