% rutero para responder a preg1, lab 7, 521230, S2-2011

% datos a interpolar por polinomio de grado menor o igual que 10
x = 0:1:10;
y = sin(x);
% calculando polinomio con polyfit
p10 = polyfit(x,y,10);
% graficando
% puntos
plot(x,y,'o');
hold on
% funcion sin(x), x entre 0 y 10
x = linspace(0,10);
plot(x,sin(x),'b');
plot(x,polyval(p10,x),'r');
legend('puntos','f(x)=sin(x)','pol. interpolacion');
% el polinomio pasa por cada uno de los puntos dados, por tanto, es el
% polinomio de grado menor o igual que 10 
% que interpola a la funcion en esos puntos
% error de interpolacion y cota del error de interpolacion
figure(2)
plot(x,abs(sin(x)-polyval(p10,x)));
hold on
coef = 1/factorial(11);
plot(x,coef*abs(x.*(x-1).*(x-2).*(x-3).*(x-4).*(x-5).*(x-6).*(x-7).*(x-8).*(x-9).*(x-10)),'r');
legend('error interp. exacto','cota del error de interp.');

% 2da parte de pregunta 1
x = -5:1:5;
% valores de funcion dada en esos puntos
fx = 1./(1+x.^2);
% calculando polinomios que ajustan a los datos
% de grado 6 (no es polinomio de interpolacion)
p6 = polyfit(x,fx,6);
% de grado 10, dado que tengo 11 pares de valores, el polinomio de grado 10
% es el que interpola a f
p10 = polyfit(x,fx,10);
% graficando puntos, funcion y polinomios 
figure(3);
plot(x,fx,'o');
hold on
% generando nuevo vector para evaluar f, p6, p10
x = linspace(-5,5);
plot(x,1./(1+x.^2),'r');
plot(x,polyval(p6,x),'k');
plot(x,polyval(p10,x),'g');
legend('puntos','f','p de grado <= 6','p de grado <= 10');
% observar en grafico que p6 no interpola a los datos
% observar las oscilaciones en p10, son mas fuertes en los extremos del
% intervalo
% en la expresion para el error de interpolacion en un x entre x0 y xn
% aparece el producto (x-x0)...(x-xn) 
% si los puntos xi son igualmente espaciados (como es el caso aqui)
% esta funcion alcanza sus valores maximo y minimo en puntos cercanos a
% a x0 y xn y a medida que n crece, los valores maximo y minimo de la
% funcion crecen tambien, veamos el comportamiento de este producto para
% los puntos x0=-5, x1 = -4, ..., x10 = 5
figure(4);
plot(x,(x+5).*(x+4).*(x+3).*(x+2).*(x+1).*x.*(x-1).*(x-2).*(x-3).*(x-4).*(x-5));
% para remediar esto, se pueden escoger los puntos de interpolacion de
% forma que (x-x0)...(x-xn) no alcance valores muy grandes en (x0,xn). Esto
% se logra con los nodos de Tschebyscheff, pero no es objetivo de estudio
% de este curso. 
% Otra opcion es usar interpolacion polinomial a tramos, si el grado del
% polinomio en cada tramo es pequeño, no se produciran las oscilaciones que
% observamos antes. Los splines cubicos son un ejemplo de interpolacion
% polinomial a tramos, en cada tramo ellos son un polinomio de grado menor
% o igual que 3.
% en matlab podemos hallar el spline cubico natural que interpola a un
% conjunto de datos dado mediante el comando spline
x = -5:1:5;
fx = 1./(1+x.^2);
% el ultimo parametro de entrada indica que la 2da derivada en x0 y xn debe
% ser igual a fx(1), fx(end) (si fx tiene 2 elementos mas que x)o a cero si
% fx tiene la misma longitud que x. Como queremos un spline cubico natural,
% la 2da derivada en los extremos del intervalo debe ser cero y basta que
% hagamos el ultimo parametro de entrada igual a [2,2].
cs = csape(x,fx,[2 2]);
figure(5)
plot(x,fx,'o');
hold on
x = linspace(-5,5);
plot(x,1./(1+x.^2),'r');
plot(x,polyval(p6,x),'k');
plot(x,polyval(p10,x),'g');
fnplt(cs,'m',1,[-5 5]);
% tambien puedo evaluar el spline y usar plot para graficarlo
% plot(x,fnval(cs,x),'m');
legend('puntos','f','p de grado <= 6','p de grado <= 10','spline cub. nat');


