1. Problema
Si consideri la funzione
3x 2 + 2
f (x ) =
1+ x 2 ⋅ (1+ 2/ 3x 2 )
x X [a,b] = [-2,1]. Si vuole:
2. Introduzione
Per svolgere le operazioni richieste sono stati implementati vari programmi in
Matlab, elencati di seguito, in appendice è presente il codice completo:
Funzione Descrizione
fcalc(x) Calcola la funzione data nei punti del vettore x
f1calc(x) Implementa la derivata della f(x) che calcola nei punti x
chebspace(a,b,n) Restituisce un vettore di n nodi distribuiti in [a,b] secondo Chebyschev
lpoly(x) Restituisce i polinomi di base di Lagrange, dati i nodi x
Lag=lfitn(L,y) Restituisce la matrice Lag dei coefficienti del polinomio interpolatore
di Lagrange, a partire dai polinomi di base di Lagrange L ed i valori y
assunti dalla funzione nei nodi.
V=lebesgue(L) Restituisce il valore della funzione di Lebesgue
Il computer utilizzato ha una precisione di 17 cifre, pertanto ciascun valore sarà
soggetto in primo luogo ad un errore di troncamento. In oltre la distanza minima tra due
-16
numeri dell’ordine dell’unità ottenuta con il comando eps, è pari a 2.2204·10 , per cui
l’errore per la rappresentazione di qualsiasi valore dell’ordine dell’unità è di circa
-16
1,1·10 .
Le ordinate dei nodi saranno perciò affette almeno da tale errore, se non sono
subentrati errore di ordine maggiore nel calcolo della funzione.
L’utilizzo di nodi approssimati comporta in primo luogo la presenza di un errore di pro-
pagazione, la cui entità è proporzionale alla funzione di Lebesgue Λ.
Poiché
n
Λ = ∑ L k ( x ) ,
k =0
è funzione esclusivamente dei nodi, è possibile minimizzare tale errore operando con no-
di distribuiti secondo Chebyshev.La funzione chebspace(a,b,n) implementa proprio la
formula per il calcolo delle ascisse dei nodi, le rispettive ordinate si ottengono si ottengo-
no con la funzione fcalc(x).
%% Nodi di Chebichev
nnodi=2;
X=chebspace(-2,1,nnodi);
Y=fcalc(X);
Fornisce i seguenti grafici al variare di nnodi:
Le interpolazioni con 3 e 4 punti si discostano fortemente dalla funzione, com’era
ovvio prevedere. Con 3 punti in particolare ho un polinomio interpolatore di grado 2, che
non può seguire la funzione nei suoi 3 cambi di direzione, presenti solamente per poli-
nomi di grado almeno pari a 4. Infatti anche con 4 nodi la curva interpolata, di grado 3,
cresce per x>1, mentre la funzione decresce per x>1. Con 6 nodi ho un polinomio di
Roberto Patrizi, 09114657 pag 2 di 8
Calcolo numerico Seconda tesina – Approssimazione di funzioni
grado 5 che riesce a seguire la funzione, mentre con 9 nodi si comincia ad avere una
buona riproduzione della funzione.
L’espressione analitica del polinomio interpolatore si può ottenere nei vari casi dai
due blocchi di istruzioni riportati nella pagina precedente, identificati con %%nodi di Che-
bichev e %%Polinomi interpolatori di Lagrange. Si ottiene una variabile identificata con Lag
,che rappresenta la matrice dei coefficienti del polinomio interpolatore, da intendersi co-
me:
p( x ) = Lag (1)x n + Lag ( 2)x n −1 + ... + Lag ( n − 1)x + Lag ( n )
%% Nodi di Chebichev
nnodi=2;
X=chebspace(-2,1,nnodi);
Y=fcalc(X);
f1a=f1calc(X(nnodi+1)); %I nodi sono in ordine inverso
f1b=f1calc(X(1));
%% Grafico funzione
plot(xx,yf);
plot(X,Y,'o');
plot(xx,yy);
Si ottengono i seguenti grafici
Si osserva una migliore accuratezza della riproduzione già con 4 nodi, grazie alla
presenza delle condizioni sulle derivate, che tuttavia non riescono comunque a riprodurre
la funzione con soli 3 nodi.
Anche la Spline con 3 nodi infatti non è altro che una parabola se non vengono
specificate le condizioni sulle derivate. I tre punti sono sufficienti a definire univocamente
i coefficienti dell’equazione di secondo grado che è identica sia per la spline che per i po-
linomi interpolatori di Lagrange.
a=f1calc(X(nnodi+1)); b=f1calc(X(1));
pp=spline(X,[a,Y,b]);
ysd=ppval(pp,xx);
ys=spline(X,Y,xx);
%% Errore
es=yf-ys;
esd=yf-ysd;
el=yf-yl;
Si ottengono i seguenti grafici:
Per la spline è stato graficato (la linea sottile continua indicata con Spline Der)
l’errore che si commette anche nel caso in cui si specificano le condizioni sulle derivate
agli estremi dell’intervallo, che, come si osserva, si mantiene generalmente inferiore ri-
spetto all’errore sia per l’approssimazione tramite polinomi di Lagrange che per le spline
senza condizioni sulle derivate.
Per 3 nodi, solo la condizione sulla derivata garantisce una migliore approssima-
zione della funzione con la spline rispetto ai polinomi con base di Lagrange. Per 4 nodi il
miglioramento è notevole, infine aumentando il numero di nodi, la presenza delle condi-
zioni sulle derivate agli estremi dell’intervallo provoca modifiche soltanto agli estremi
dell’intervallo, mentre all’interno le due spline sono identiche. Bastano 9 punti
-3
nell’intervallo considerato affinché l’errore si mantenga al di sotto dei 6 · 10 .
4. Funzioni Matlab
function Y=fcalc(X)
%
% function Y=fcalc(X)
% f(x) = (3x^2 + 2) / ( sqrt(1+x^2) * (1+2/3 x^2) )
function Y=f1calc(X)
%
% Y=f1calc(x)
%
%Tale funzione è la derivata della f implementata in fcalc
function X=chebspace(a,b,n)
%
% X=chebspace(a,b,n)
%
%Restituisce un vettore di punti distribuiti secondo Chebyshev.
%a,b sono gli estremi dell'intervallo, n è il numero di nodi -1.
function L=lpoly(X)
%
% L=lpoly(X)
%
%Funzione per il calcolo numerico dei polinomi interpolatori di Lagrange. In ingresso ho i nodi X.
%In uscita il vettore L contiene i coefficienti dei polinomi di Lagrange
% L(k)= [x-X(j)] / [X(k)-X(j)] per j=1..n+1, j diverso da k
%
n=length(X);
L=[];
for k=1:n %Ciclo del calcolo dei vari L (L1,L2,L3...)
temp=1;
for j=1:n %Ciclo per il calcolo della base k-esima Lk
if j~=k
temp=conv(temp,[1,-X(j)]/(X(k)-X(j)));
end
end
%temp contiene la base k-esima che voglio assegnare a L(k). Il polinomio è al
%massimo di grado n, =>temp contiene al massimo n+1elementi, L deve avere n righe
%ed n+1 colonne con i vettori temp
%allineati a destra.
L=accoda(L,temp);
end
function Lag=lfit(L,Y)
%
% Lag=lfit(L,Y)
%
%Restituisce il vettore Lag dei coefficienti del polinomio di Lagrange
%interpolante i punti X,Y
%In ingresso ho i polinomi di base di Lagrange L calcolati sui nodi X.
n=length(Y);
Lag=0;
for k=1:n
Lag=Lag+Y(k)*L(k,:);
end
function V=lebesgue(L,xx)
%
% V=lebesgue(L,xx)
%
%Calcola la funzione di Lebesgue a partire dal vettore dei coefficienti dei
%polinomi di base di Lagrange L, (ottenibili con la funzione L=lpolyn(nod)),
%e ne calcola il valore nei punti indicati dal vettore xx. Il risultato è
%un vettore V della stessa lunghezza di xx che contiene il valore assunto
%dalla funzione di lebesgue in ciascun punto di xx.
%
n=length(xx);
for i=1:n
V(i)=0;
for j=1:length(L)
V(i)=V(i)+abs(polyval(L(j,:),xx(i)));
end
end
function C=accoda(A,B)
%
% C=accoda(A,B)
%
%A e B sono matrici non necessariamente con lo stesso numero di colonne.
%La matrice C risultante è data dalla concatenazione di A,B, in modo tale
%che se le matrici siano allineate a destra, ed eventualmente gli spazi
%vuoti sulla sinistra sono colmati da zeri
%
[n,m]=size(A);
j=length(B);
if m==0
C=B;
elseif m==j
C=vertcat(A,B);
elseif m>j
B(:,j+1:m)=0;
B=circshift(B,[0,m-j]);
C=vertcat(A,B);
elseif m<j
A(:,m+1:j)=0;
A=circshift(A,[0,j-m]);
C=vertcat(A,B);
else
error('impossibile concatenare le matrici' );
end