Interpolación

Este pequeño programa muestra la diferencia entre interpolación y regresión

x=0.5:0.5:3;
y=[0.7,1.2,1.3,1.2,0.8,0.3];
hold on
plot(x,y,'ro','markersize',4,'markerfacecolor','r')

%regresión
p=polyfit(x,y,2); %polinomio de segundo grado
z=@(xx) polyval(p,xx);
fplot(z,[x(1),x(end)])

%interpolación
z=@(xx) spline(x,y,xx);
fplot(z,[x(1),x(end)])

hold off
grid on
legend('datos','regresión','interpolación')
xlabel('x')
ylabel('y');
title('Interpolación, regresión')

Interpolación lineal

La interpolación lineal es muy sencilla. Disponemos de pares de datos (xk,yk) k=1,2...n. Queremos conocer el valor de y para un valor cualesquiera de x en el intervalo x1 a xn. Supongamos que x está en el intervalo (xk,xk+1) tal como se muestra en la figura. Trazamos la recta que pasa por los puntos (xk,yk) y (xk+1,yk+1), cuya ecuación es

y= (x x k ) y k+1 (x x k+1 ) y k ( x k+1 x k )

Creamos la función interpola_lineal para obtener el valor de y cuando se proporciona el valor de x.

function y0 = interpola_lineal(x,y,x0)
    y0=zeros(length(x0),1);
    for j=1:length(x0)
        indice=find(x>x0(j));
        k=indice(1)-1;
        y0(j)=((x0(j)-x(k))*y(k+1)-(x0(j)-x(k+1))*y(k))/(x(k+1)-x(k));
    end
end

Probamos la función para interpolar linealmente los siguientes pares de datos (0,0), (π/3, sin(π/3)), (2π/3, sin(2π/3)),(π, 0). Comprobamos que obtenemos los mismos resultado utilizando la función MATLAB interp1, pasándole la opción linear en el último parámetro.

x=0:pi/3:pi;  %datos
y=sin(x);
x0=[pi/6,pi/2,5*pi/6];  %interpolación lineal
y0=interpola_lineal(x,y,x0);
%y0=interp1(x,y,x0,'linear'); %esta es una función MATLAB
hold on
fplot('sin(x)',[0,pi])
plot(x,y)
plot(x,y,'bo','markersize',3,'markerfacecolor','b')
plot(x0,y0,'ro','markersize',4,'markerfacecolor','r')
set(gca,'XTick',0:pi/6:pi)
set(gca,'XTickLabel',{'0','\pi/6','\pi/3','\pi/2','2\pi/3','5\pi/6','\pi'})

hold off
grid on
xlabel('x');
ylabel('y')
title('Interpolación lineal')

Interpolación por un polinomio de grado n

Calculamos los coeficientes de un polinomio de tercer grado y=a1x3+a2x2+a3x+a4 que pase por los cuatro puntos. Obtenemos un sistema de cuatro ecuaciones con cuatro incógnitas.

{ a 1 x 1 3 + a 2 x 1 2 + a 3 x 1 + a 4 = y 1 a 1 x 2 3 + a 2 x 2 2 + a 3 x 2 + a 4 = y 2 a 1 x 3 3 + a 2 x 3 2 + a 3 x 3 + a 4 = y 3 a 1 x 4 3 + a 2 x 4 2 + a 3 x 4 + a 4 = y 4 ( x 1 3 x 1 2 x 1 1 x 2 3 x 2 2 x 2 1 x 3 3 x 3 2 x 3 1 x 4 3 x 4 2 x 4 1 )( a 1 a 2 a 3 a 4 )=( y 1 y 2 y 3 y 4 )

x=[0,pi/3,2*pi/3,pi];  %datos
y=sin(x);
xx=0:pi/90:pi;  %función
yy=sin(xx);
x0=[pi/6,pi/2,5*pi/6];  %interpolación lineal

A=vander(x);
p=A\y';  %coeficientes del polinomio

hold on
fplot('sin(x)',[0,pi])  % función
plot(x,y,'bo','markersize',3,'markerfacecolor','b')
z=@(xx) polyval(p,xx); %polinomio
fplot(z,[0,pi])
y0=polyval(p,x0); %valores interpolados
plot(x0,y0,'ro','markersize',4,'markerfacecolor','r')
set(gca,'XTick',0:pi/6:pi)
set(gca,'XTickLabel',{'0','\pi/6','\pi/3','\pi/2','2\pi/3','5\pi/6','\pi'})
hold off
xlabel('x');
ylabel('y')
grid on
title('Interpolación con un polinomio de tercer gardo')

Interpolación de Lagrange

Queremos encontrar los coeficientes de un polinomio de grado N

a1xN+a2xN-1+...+aNx+aN+1

que pase por todos los pares de datos (x1,y1), (x2,y2), ...(xN+1,yN+1). Los coeficientes se pueden obtener resolviendo el sistema de ecuaciones:

{ a 1 x 1 N + a 2 x 1 N1 + a N x 1 + a N+1 = y 1 a 1 x 2 N + a 2 x 2 N1 + a N x 2 + a N+1 = y 2 ..... a 1 x N+1 N + a 2 x N+1 N1 + a N x N+1 + a N+1 = y N+1

En forma matricial

( x 1 N x 1 N1 ... x 1 1 x 2 N x 2 N1 ... x 2 1 ... ... ... ... ... x N+1 N x N+1 N1 ... x N+1 1 )( a 1 a 2 ... a N+1 )=( y 1 y 2 ... y N+1 )

Esta matriz se conoce con el nombre de Vandermonde y se construye con el comando vander(x), como podemos leer en el sistema de ayuda de MATLAB, A=vander(v) devuelve una matriz de Vandermonde cuyas columnas son las potencias del vector v, esto es A(i,j)=v(i)^(n-j)

Sea la siguiente tabla de datos tomada de una experiencia

x 0.97 1.12 2.92 3.00 3.33 3.97 6.10 8.39 8.56 9.44
y 2.58 0.43 0.06 5.74 7.44 8.07 6.37 2.51 1.44 0.52

Cuando el número N+1 de datos es relativamente pequeño, las primeras columnas de la matriz A pueden guardar números muy grandes, los efectos del redondeo pueden afectar al valor de los coeficientes ai del polinomio.

Los valores del polinomio se puede obtener también utilizando la función polyfit que emplearemos más adelante en el ajuste por el procedimiento de mínimos cuadrados.

x=[0.97 1.12 2.92 3.00 3.33 3.97 6.10 8.39 8.56 9.44];
y=[2.58 0.43 0.06 5.74 7.44 8.07 6.37 2.51 1.44 0.52];
n=length(x); %número de pares de datos
%A=vander(x);
A=zeros(n); %líneas equivalentes a utilizar vander(x)
for j=1:n
    A(:,j)=(x').^(n-j);
end
p=A\y'; %sistema de ecuaciones lineales, y' es vector columna

%p=polyfit(x,y,n-1) %n-1 es el grado del polinomio
z=@(xx) polyval(p,xx);
hold on
plot(x,y,'bo','markersize',3,'markerfacecolor','b')
fplot(z,[x(1),x(end)])
xlabel('x')
ylabel('y')
grid on
title('Interpolación de Lagrange');
hold off

El script presenta opciones: La matriz A la obtenemos alternativamente, con el comando vander en vez de un bucle for. Los coeficientes del polinomio p, los obtenemos llamando a polyfit, en vez del operador división por la izquierda. Si llamamos a polyfit en la ventana de comandos aparece el siguiente mensaje

Warning: Polynomial is badly conditioned. Add points with distinct X
values, reduce the degree of the polynomial, or try centering and scaling
as described in HELP POLYFIT. 
> In polyfit (line 75)
  In xxx (line 11) 

p =   1.0e+04 *
0.0000 -0.0003 0.0057 -0.0595 0.3782 -1.4951 3.6430 -5.2142 3.9256 -1.1823

Un polinomio de Lagrange LN(x) de grado N es la expresión

L N (x)= (x x 2 )(x x 3 )...(x x N+1 ) ( x 1 x 2 )( x 1 x 3 )...( x 1 x N+1 ) y 1 + (x x 1 )(x x 3 )...(x x N+1 ) ( x 2 x 1 )( x 2 x 3 )...( x 2 x N+1 ) y 2 +...+ (x x 1 )(x x 2 )...(x x N ) ( x N+1 x 1 )( x N+1 x 2 )...( x N+1 x N ) y N+1

Este polinomio pasa por todos los puntos (xi,yi).

Elaboramos una función denominada lagrange_3 que devuelva el valor interpolado yy de xx cuando se le pasa los vectores x e y que guardan las abscisas y ordenadas (xi,yi) de los datos

function yy = lagrange_3(x,y,xx)
   n = length(x); 
   for i=1:n 
       w(i)=prod(xx-x([1:i-1 i+1:n]))*y(i)/prod( x(i)-x([1:i-1 i+1:n]) ) ;
   end
   yy=sum(w);   
end

Llamamos a la función lagrange_3 para conocer los valores interpolados de xx=1.0 y xx=2.0

>> x=[0.97 1.12 2.92 3.00 3.33 3.97 6.10 8.39 8.56 9.44];
>> y=[2.58 0.43 0.06 5.74 7.44 8.07 6.37 2.51 1.44 0.52];
>> yy=lagrange_3(x,y,1.0)
yy =   10.0725
>> yy=lagrange_3(x,y,2.0)
yy = -203.7000

Alternativamente, elaboramos una función denominada lagrange_p que devuelva los coeficientes del polinomio. El polinomio de Lagrange es la suma de N+1 términos. El numerador de cada término es el producto de N binomios (x-xi)

function p=lagrange_p(x,y)
    n=length(x); %n-1 es el grado del polinomio
    if length(y)~=n 
        error('x e y tienen que tener la misma longitud')
    end
    p=zeros(1,n);
    for i=1:n
        pol=[y(i)];
        for j=1:n
            if(i~=j)
%multiplica un polinomio por un binomio
                pol=conv([1 -x(j)],pol)/(x(i)-x(j)); 
            end
        end
        p=p+pol;
    end
end

Para obtener el producto de los binomios del numerador de cada término, utilizamos la función conv, véase la página Polinomios. Por ejemplo, queremos multiplicar los polinomios p1=x3-2x-4 y p2=x2+3x+4

>> p1=[1 0 -2 -4];
>> p2=[1 3 4];
>> p=conv(p1,p2)
p =     1     3     2   -10   -20   -16

Utilizamos la función lagrange_p para obtener los coeficientes del polinomio de Lagrange con los datos del ejemplo anterior.

>> x=[0.97 1.12 2.92 3.00 3.33 3.97 6.10 8.39 8.56 9.44];
>> y=[2.58 0.43 0.06 5.74 7.44 8.07 6.37 2.51 1.44 0.52];
>> p=lagrange_p(x,y)
p =  1.0e+004 *
0.0000 -0.0003 0.0057 -0.0595 0.3782 -1.4951 3.6430 -5.2142 3.9256 -1.1823

Obtenemos el mismo resultado, que resolviendo el sistema de N+1 ecuaciones lineales.

Una vez obtenido el polinomio de Lagrange calculamos el valor de y para valores de x que no están en la tabla.

>> xx=[1.0 2.0 3.5];
>> yy=polyval(p,xx)
yy =   10.0725 -203.7000    1.8338

Comparación

Como vamos a apreciar, la interpolación de Lagrange es un interesante ejercicio de programación, pero no poduce buenos resultados. Para probarlo, vamos a tomar nueve puntos de una función igualmente espaciados y vamos a comparar la gráfica de la función y la interpolación de los nueve puntos por el procedimiento de Lagrange. En la siguiente sección, explicamos un procedimiento mucho más exacto, los splines

Vamos a probar este procedimiento de interpolación, tomando nueve puntos equidistantes de la función

y= sin(x) x 2 +1

Ahora interpolamos mediante un polinomio de grado n-1 (ocho) que pasa por los n (nueve) puntos (xi,yi)

x=-4:4;
f=@(x) sin(x)/(1+x^2);
%dibuja los puntos
hold on
plot(x,y,'bo','markersize',3,'markeredgecolor','b','markerfacecolor','b')
n=length(x);
p=polyfit(x,y,n-1); %polinomio que pasa por los puntos
%p=lagrange_p(x,y); %se obtiene el mismo resultado
z=@(xx) polyval(p,xx);

fplot(z,[-4,4],'r')
fplot(f,[-4,4])
hold off
grid on
xlabel('x')
ylabel('y')
legend('función','interpolación')
title('Interpolación por Lagrange')

El resultado deja mucho que desear principalmente, en el primer y último intervalo.

Splines

Vamos a explicar mediante un ejemplo el procedimiento de interpolación denominado "splines", para generalizarlo después a cualquier conjunto de pares de datos.

Dado el conjunto de pares de datos (x1,y1), (x2,y2), (x3,y3), (x4,y4), (x5,y5) puntos de color rojo en la figura. Definimos la función S(x)

S(x)={ s 1 (x) x 1 x< x 2 s 2 (x) x 2 x< x 3 s 3 (x) x 3 x< x 4 s 4 (x) x 4 x< x 5 s i (x)= a i ( x x i ) 3 + b i ( x x i ) 2 + c i ( x x i )+ d i i=1,2,3,4

Cada una de las funciones si(x) en color azul en la figura, es un polinomio de tercer grado, cuya primera y segunda derivada es

d s i dx =3 a i ( x x i ) 2 +2 b i ( x x i )+ c i d 2 s i d x 2 =6 a i ( x x i )+2 b i i=1,2,3,4

Para calcular las 4×4=16 incógnitas a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3,c4, d1,d2,d3,d4, se imponen las siguientes condiciones:

  1. La función S(x) pasa por todos los puntos (xi,yi)  i=1,2,3,4,5
  2. s i ( x i )= y i { d 1 = y 1 d 2 = y 2 d 3 = y 3 d 4 = y 4 a 4 ( x 5 x 4 ) 3 + b 4 ( x 5 x 4 ) 2 + c 4 ( x 5 x 4 )+ d 4 = y 5

  3. La función S(x) es continua en x2, x3, x4.
  4. s i1 ( x i )= s i ( x i ){ a 1 ( x 2 x 1 ) 3 + b 1 ( x 2 x 1 ) 2 + c 1 ( x 2 x 1 )+ d 1 = d 2 a 2 ( x 3 x 2 ) 3 + b 2 ( x 3 x 2 ) 2 + c 2 ( x 3 x 2 )+ d 2 = d 3 a 3 ( x 4 x 3 ) 3 + b 3 ( x 4 x 3 ) 2 + c 3 ( x 4 x 3 )+ d 3 = d 4

  5. La derivada primera de la función S(x) es continua en x2, x3, x4.
  6. s ' i1 ( x i )=s ' i ( x i ){ 3 a 1 ( x 2 x 1 ) 2 +2 b 1 ( x 2 x 1 )+ c 1 = c 2 3 a 2 ( x 3 x 2 ) 2 +2 b 2 ( x 3 x 2 )+ c 2 = c 3 3 a 3 ( x 4 x 3 ) 2 +2 b 3 ( x 4 x 3 )+ c 3 = c 4

  7. Denominamos m1, m2, m3, m4, m5 al valor de la derivada segunda de si(x) en los puntos x1, x2, x3, x4, x5.
  8. s' ' i ( x i )= m i { 2 b 1 = m 1 2 b 2 = m 2 2 b 3 = m 3 2 b 4 = m 4 6 a 4 ( x 5 x 4 )+2 b 4 = m 5

  9. La derivada segunda de S(x) es continua en los puntos x2, x3, x4
  10. s' ' i1 ( x i )=s' ' i ( x i ){ 6 a 1 ( x 2 x 1 )+2 b 1 =2 b 2 6 a 2 ( x 3 x 2 )+2 b 2 =2 b 3 6 a 3 ( x 4 x 3 )+2 b 3 =2 b 4

Supongamos que el espaciado entre dos puntos consecutivos es constante h=xi-xi-1, i=2,3,4,5.

Vamos a expresar las incógnitas a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3,c4, d1,d2,d3,d4, en términos de h, el valor de las ordenadas yi y el valor de la derivada segunda de S(x), mi en cada punto xi, i=1,2,3,4,5.

De (4) y (5) expresamos a1,a2, a3, a4 en términos de m1, m2, m3, m4, m5.

a 1 = m 2 m 1 6h a 2 = m 3 m 2 6h a 3 = m 4 m 3 6h a 4 = m 5 m 4 6h

Teniendo en cuenta (1) y (4), las ecuaciones (2) se expresan

{ m 2 m 1 6h h 3 + m 1 2 h 2 + c 1 h+ y 1 = y 2 m 3 m 2 6h h 3 + m 2 2 h 2 + c 2 h+ y 2 = y 3 m 4 m 3 6h h 3 + m 3 2 h 2 + c 3 h+ y 3 = y 4

Que nos permite despejar c1, c2, c3 en términos de m1, m2, m3, m4, y1, y2, y3, y4

c 1 = y 2 y 1 h m 2 +2 m 1 6 h c 2 = y 3 y 2 h m 3 +2 m 2 6 h c 3 = y 4 y 3 h m 4 +2 m 3 6 h

La última ecuación de (1) nos permite despejar c4

m 5 m 4 6h h 3 + m 4 2 h 2 + c 4 h+ y 4 = y 5 c 4 = y 5 y 4 h m 5 +2 m 4 6 h

Las ecuaciones (3) se expresan

{ 3 m 2 m 1 6h h 2 + m 1 h+ y 2 y 1 h m 2 +2 m 1 6 h= y 3 y 2 h m 3 +2 m 2 6 h 3 m 3 m 2 6h h 2 + m 2 h+ y 3 y 2 h m 3 +2 m 2 6 h= y 4 y 3 h m 4 +2 m 3 6 h 3 m 4 m 3 6h h 2 + m 3 h+ y 4 y 3 h m 4 +2 m 3 6 h= y 5 y 4 h m 5 +2 m 4 6 h { m 1 +4 m 2 + m 3 = 6 h 2 ( y 1 2 y 2 + y 3 ) m 2 +4 m 3 + m 4 = 6 h 2 ( y 2 2 y 3 + y 4 ) m 3 +4 m 4 + m 5 = 6 h 2 ( y 3 2 y 4 + y 5 )

Tenemos tres ecuaciones y cinco incógnitas m1, m2, m3, m4, m5

Fijamos los valores de la derivada segunda m1 y m5 en los puntos extremos. Supongamos que m1=0 y m5=0.

Hay otras posibilidades que se pueden consultar en el documento http://online.redwoods.edu/instruct/darnold/laproj/Fall98/SkyMeg/Proj.PDF

Despejamos m2, m3, m4 del sistema de tres ecuaciones

{ m 1 +4 m 2 + m 3 = 6 h 2 ( y 1 2 y 2 + y 3 ) m 2 +4 m 3 + m 4 = 6 h 2 ( y 2 2 y 3 + y 4 ) m 3 +4 m 4 + m 5 = 6 h 2 ( y 3 2 y 4 + y 5 ) ( 4 1 0 1 4 1 0 1 4 )( m 2 m 3 m 4 )= 6 h 2 ( y 1 2 y 2 + y 3 y 2 2 y 3 + y 4 y 3 2 y 4 + y 5 )

Caso general

En general, con n pares de datos tendremos el sistema

( 4 1 0 0 ... 0 1 4 1 0 ... 0 0 1 4 1 ... 0 0 0 1 4 ... 0 .... ... ... ... ... ... 0 0 0 ... 1 4 )( m 2 m 3 m 4 m 5 ... m n1 )= 6 h 2 ( y 1 2 y 2 + y 3 y 2 2 y 3 + y 4 y 3 2 y 4 + y 5 y 4 2 y 5 + y 6 .... y n2 2 y n1 + y n )

Fijamos los valores de los extremos del vector de las incógnitas m: m1=0, mn-1=0, a continuación, obtenemos mediante el operador división por la izquierda los valores de m2, m3, ...mn-2, finalmente, se calculan:

a 1 = m 2 m 1 6h a 2 = m 3 m 2 6h a 3 = m 4 m 3 6h ....    a n1 = m n m n1 6h

b 1 = m 1 2 b 2 = m 2 2 b 3 = m 3 2 ....   b n1 = m n1 2

c 1 = y 2 y 1 h m 2 +2 m 1 6 h c 2 = y 3 y 2 h m 3 +2 m 2 6 h c 3 = y 4 y 3 h m 4 +2 m 3 6 h ..... c n1 = y n y n1 h m n +2 m n1 6 h

d 1 = y 1 d 2 = y 2 d 3 = y 3 ....   d n1 = y n1

Codificación

En primer lugar, vamos a entender como trabaja la función diag de MATLAB. La función diag extrae vectores diagonales de la matriz A.

>> A=[1,2,3;4,5,6;7,8,9]
A =
     1     2     3
     4     5     6
     7     8     9
>> diag(A) %diagonal principal
ans =
     1
     5
     9
>> diag(A,1) %diagonal superior
ans =
     2
     6
>> diag(A,-1) %diagonal inferior
ans =
     4
     8

La función diag nos permite crear una matriz a partir de los vectores de sus diagonales

A=diag(4*ones(3,1))+diag(ones(2,1),1)+diag(ones(2,1),-1)
A =
     4     1     0
     1     4     1
     0     1     4

La función diff calcula la diferencia entre dos elementos consecutivos del vector y

y=[ y 1 , y 2 , y 3 , y 4 , y 5 ] d 1 =diff(y)=[ y 2 y 1 , y 3 y 2 , y 4 y 3 , y 5 y 4 ] d 2 =diff( d 1 )=[ y 3 2 y 2 y 1 , y 4 2 y 3 y 2 , y 5 2 y 4 y 3 ]

El vector de los términos independientes se calcula aplicando dos veces la función diff al vector y de las ordenadas.

Estamos en condiciones de crear un script que calcule las incógnitas m2, m3, ... mn-1, aplicando el operador división por la izquierda.

Vamos a probar este procedimiento de interpolación, tomando nueve puntos equidistantes de la función

y= sin(x) x 2 +1

x=-4:4;
f=@(x) sin(x)./(1+x.^2);
y=f(x);
h=x(2)-x(1); %espaciado constante

n=length(x); %número de pares de datos
%matriz de dimensión n-2
A=diag(4*ones(n-2,1))+diag(ones(n-3,1),1)+diag(ones(n-3,1),-1); 
s=diff(diff(y))*6/h^2; %vector de los términos indpendientes
mm=A\s'; %vector de las incógnitas
m=[0;mm;0]; %ceros en los extremos
a=zeros(1,n-1);
b=zeros(1,n-1);
c=zeros(1,n-1);
d=zeros(1,n-1);
for i=1:n-1
    a(i)=(m(i+1)-m(i))/(6*h);
    b(i)=m(i)/2;
    c(i)=(y(i+1)-y(i))/h-(m(i+1)+2*m(i))*h/6;
    d(i)=y(i);
end

hold on
plot(x,y,'bo','markersize',3,'markeredgecolor','b','markerfacecolor','b')
for i=1:n-1
    z=@(xx) a(i)*(xx-x(i)).^3+b(i)*(xx-x(i)).^2+c(i)*(xx-x(i))+d(i);
    fplot(z,[x(i),x(i+1)],'r')
end
fplot(f,[-4,4])
hold off
grid on
xlabel('x')
ylabel('y')
legend('función','interpolación')
title('Interpolación por splines')

con los nueve puntos unidos mediante polinomios de tercer grado vemos que la curva interpolada y la exacta están próximas.

Los puntos de color azul, son los nueve pares de datos, cada una de las curvas de color rojo entre dos puntos azules consecutivos es un polinomio de tercer grado que pasa por dichos puntos y cumple las condiciones de continuidad de su derivada primera y segunda.

Función spline de MATLAB

Utilizamos la función spline de MATLAB, pero es posible que las condiciones en los extremos que en el ejemplo anterior se han establecido en m1=0, mn-1=0, sean ahora diferentes.

x=-4:4;
f=@(x) sin(x)./(1+x.^2);
y=f(x);
%dibuja los puntos
hold on
plot(x,y,'bo','markersize',3,'markeredgecolor','b','markerfacecolor','b')

z=@(xx) spline(x,y,xx); %interpolación
fplot(z,[-4,4],'r')
fplot(f,[-4,4]) %función
hold off
grid on
xlabel('x')
ylabel('y')
title('Interpolación por splines de MATLAB')

Comparando ambas gráficas, vemos que el resultado que hemos obtenido creando nuestra propia función spline y utilizando la función spline de MATLAB es muy parecido

Aproximación de funciones mediante un polinomio

Muchas funciones matemáticas tales como sin(x), exp(x), se pueden representar cerca de x=0 por un desarrollo en serie de Taylor. Si el desarrollo en serie converge rápidamente, tomando los primeros términos se puede aproximar la función f(x) por un polinomio de grado n no muy elevado.

Puntos igualmente espaciados

Tomamos n valores de la función yi=f(xi) con i=1...n. y determinamos el polinomio de grado n-1 que pasa a través de los puntos (xi,yi). Sea la función

y= 1 x 2 +1

Tomamos diez abscisas xi espaciadas 0.8 en el intervalo [-4,4]. Representamos la función (en color rojo), los puntos (xi,yi) y el polinomio que pasa por dichos puntos (en color azul). Dado que la función es simétrica solamente representamos la parte positiva.

f=@(x) 1./(x.^2+1);
n=10;
a=-4;
b=4;

xx=linspace(a,b,n+1);
yy=f(xx);
p=polyfit(xx,yy,n);

x1=linspace(0,b,100);
y1=polyval(p,x1); %aproximación mediante el polinomio p
y2=f(x1);		%función
hold on
plot(x1,y1,'b')
plot(x1,y2,'r')
plot(xx(xx>=0),yy(xx>=0),'ro','markersize',3,'markerfacecolor','r')
hold off
xlabel('x')
ylabel('y')
title('Aproximación de una función')

Puntos espaciados mediante la fómula de Chebyshev

Sorprendentemente, si los puntos no están igualmente espaciados, obtenemos una mejor aproximación. Si tomamos los puntos en el intervalo [a,b] espaciados de acuerdo a la fórmula denominada puntos de Chebyshev.

x i = a+b 2 + ab 2 cos( π n ( i 1 2 ) )1in

La función linspace, nos crea un vector de abscisas xi igualmente espaciados entre a y b. La función que hemos denominado lincheby crea un vector de abscisas xi, espaciados de acuerdo a la fórmula anterior.

f=@(x) 1./(x.^2+1);
lincheby=@(a,b,n) (a+b)/2+(a-b)/2*cos(pi/n*(1/2:n));
n=10; 
a=-4;
b=4;

xx=lincheby(a,b,n+1);
yy=f(xx);
p=polyfit(xx,yy,n); 

x1=linspace(0,b,100);
y1=polyval(p,x1); %aproximación mediante el polinomio p
y2=f(x1);		  %función
hold on
plot(x1,y1,'b')
plot(x1,y2,'r')
plot(xx(xx>=0),yy(xx>=0),'ro','markersize',3,'markerfacecolor','r')
hold off
xlabel('x')
ylabel('y')
title('Aproximación de una función')

Como podemos apreciar la mejora es importante