CALCOLO NUMERICO
a.a. 2014-2015
1
Esercizio 1: esame 24/01/2012
Si consideri la seguente tabella di dati approssimati alla quarta
cifra decimale:
f x exp( x ) x 2 2
si determini l’errore assoluto commesso in z e lo si confronti con
l’errore di troncamento teorico.
C- Si applichi la function polyfit di Matlab per ottenere il
polinomio interpolante dello stesso grado valutato su z e si calcoli
l’errore commesso nei due punti.
D- Si costruisca una tabella con 4 righe e 3 colonne, che riporti sulle
prime due righe i valori z(i), p(z(i)) e l’errore assoluto
abs(f(z(i))-p(z(i))) ottenuti con la function Neville
per i = 1,2; sulle rimanenti due righe riporti gli analoghi valori
ottenuti con polyfit. Si utilizzino opportuni formati di stampa.
E- Si commentino i risultati facendo un confronto tra le due
function.
Risoluzione
È noto che per costruire un polinomio interpolante di 4° grado, sono
necessari 5 dati (ascisse distinte ed i corrispondenti valori della
funzione). Tali punti saranno scelti dalla tabella data in modo
opportuno relativamente ai valori dei punti di valutazione. 3
Istruzioni Matlab
clear all; clc
% ascisse nodi
x = [1.0000 1.1667 1.3333 1.5000 1.6667 1.8333 2.0000]';
% ordinate nodi
y = [3.7183 4.5724 5.5714 6.7317 8.0723 9.6158 11.3891]';
z = [1.4 1.9]'; % punti di valutazione
ind = [3 4 5 6 7]; % indici dei nodi scelti per interpol.
n = 4; % grado del polinomio
[P,stimaerr] = Neville(x,y,z,ind,n); % chiamata Neville
v = polyfit(x(3:end),y(3:end),n); % chiamata polyfit
% in v sono presenti i coeff. del polinomio interpolante
Pv = polyval(v,z); % valutazione polinomio di polyfit in z
err = abs(exp(z)+z.^2-P(:,2)); % errore con Neville
errv = abs(exp(z)+z.^2-Pv); % errore con polyfit
tabella = [z P(:,2) err;z Pv errv]; % tabella richiesta
% Si ricordi che Neville in P riporta sia il valore di z
% (in prima colonna)che il valore, in esso, del polinomio
% interpolante (seconda colonna).
fprintf('z valori approssimati errore\n') % intestazione
fprintf('%4.1f %8.5f %10.2e\n',tabella') 4
Seguito risoluzione ed istruzioni Matlab
Procediamo al calcolo dell’errore teorico in base alla formula:
f
n 1
Et z n 1 z
n 1 !
Conosciamo la funzione e sappiamo che essa è di classe infinita di
regolarità.
Calcoliamo la derivata di ordine n+1 dove n=4 è il grado del
polinomio. Si ottiene, essendo nulla la derivata quinta di x^2,
f
5
x e x
Istruzioni Matlab
% Maggiorazione dell’errore teorico in z(1)
errTeorico_max1 = abs(exp(x(end))*prod(z(1)-
x(3:end))/factorial(n+1));
% Maggiorazione dell’errore teorico in z(2)
errTeorico_max2 = abs(exp(x(end))*prod(z(2)-
5
x(3:end))/factorial(n+1));
Risultati e commenti
z valori errore
1.4 6.01547 2.70e-004
1.9 10.29640 5.10e-004
1.4 6.01547 2.70e-004
1.9 10.29640 5.10e-004
errTeorico_max1 = 2.8477e-005
errTeorico_max2 = 2.1720e-005
7
b - Si costruisca per ogni valore di n,una figura in cui si riportino
le due funzioni spline (la spline naturale con linea continua e colore
verde, la spline di Matlab con punto-linea colore rosso); si riportino
anche i nodi di interpolazione con un pallino nero.
Si inseriscano label, titolo e legend.
end
Costruzione tabella e calcolo dell’errore per n = 21
Utilizzando una spline interpolante cubica, l’errore soddisfa la
disuguaglianza:
5
S f C 0 h4 f , C 0
4
.
384
2000
1500
1000
500
0
0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2
Valutazione dell’errore teorico: tenendo conto che h=2/20 ed
assumendo come da figura f max f x 2100,
4 4
x 0,2
possiamo scrivere:
S f 5/384*(2/20)^4*2100= 2.7344e-03
11
punti spline1 spline2 err1 err2
0.050 -1.1020068 -1.0889993 1.50e-002 2.02e-003
0.150 -0.6585369 -0.6620222 4.21e-003 7.21e-004
0.250 -0.3846197 -0.3836859 1.04e-003 1.10e-004
0.350 -0.1908766 -0.1911269 3.22e-004 7.19e-005
0.450 -0.0540561 -0.0539890 6.31e-005 3.92e-006
0.550 0.0464971 0.0464792 3.03e-005 1.23e-005
0.650 0.1215321 0.1215369 8.50e-009 4.81e-006
0.750 0.1785200 0.1785187 5.11e-006 3.82e-006
0.850 0.2223017 0.2223020 1.96e-006 2.31e-006
0.950 0.2562524 0.2562523 1.71e-006 1.61e-006
………………………………………………………………………………………………
1.450 0.3424770 0.3424769 3.53e-007 3.08e-007
1.550 0.3501658 0.3501660 5.48e-008 2.25e-007
1.650 0.3560324 0.3560318 8.31e-007 1.96e-007
1.750 0.3604111 0.3604135 2.31e-006 6.09e-008
1.850 0.3635902 0.3635814 9.24e-006 3.83e-007
-0.2
-0.4
-0.6
-0.8
-1
-1.2
-1.4
0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2
13
funzioni spline interpolanti, n=21
0.4
S
0.2 SM
-0.2
-0.4
-0.6
-0.8
-1
-1.2
-1.4
0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2
x y
0 0
1.2572 -1.7975
2.5133 -0.7675
3.7700 -0.2184
5.0265 -0.0414
6.2832 0
19
a) Polinomio Interpolante alle differenze divise
per approssimare la funzione in z1
Il polinomio da costruire è di quarto grado quindi ha 5 coefficienti
che vanno determinati; occorrono 5 punti di interpolazione
clear all
close all
clc
x=[0 1.2572 2.5133 3.770 5.0265 6.2832]'; % nodi
y=[0 -1.7975 -0.7675 -0.2184 -0.0414 0.0000]';
z=[0.8 4.5]'; % punti di valutazione;
% length(z)=r=2
np=4; % grado del polinomio interpolante
ind1=[1:5]'; % indice dei nodi di interpolazione
p41_int=Neville(x,y,z(1),ind1,np);
% p41_int contiene una matrice 1 x 2;
% nella riga presenta il valore di z(1) e la
% valutazione in esso del polinomio 20
a) Polinomio Interpolante alle differenze divise
per approssimare la funzione in z2
Anche in questo caso il polinomio da costruire è di quarto grado
quindi ha 5 coefficienti che si devono determinare; occorrono 5
punti di interpolazione
ind2=[2:6] ';% i nodi che si considerano sono
% diversi rispetto al caso precedente
% poiché z2=4.5 è situato tra x3 e x4
p42_int=Neville(x,y,z(2),ind2,np);
% Si riuniscono ora i due casi
pz=[p41_int(2);p42_int(2)];% pz è un vettore che
% contiene i valori dei polinomi in z1,z2
ppz =[p41_int;p42_int]; % ppz è invece,una
% matrice contenente z1 e di z2 nella prima
% colonna e i valori dei polinomi in z1 e z2 21
% nella seconda colonna.
b) Risultati dell’interpolazione e calcolo dell’errore
f=inline('x.*(x-2*pi).*exp(-x) ','x');
%costruisce una funzione inline di variabile 'x'
%(N.B. si può eliminare 'x' nella chiamata)
fz=feval(f,z); % valuta la funzione f in z
err_calc=abs(fz-pz); % errore in z
tab=[ppz fz err_calc];
fprintf('z P(z) f err_f \n')
fprintf('% 8.5f %12.8f %12.8f %12.2e \n',tab')
z P(z) f err_f
0.80000 -1.75164259 -1.97100318 2.19e-001
4.50000 -0.08256145 -0.08914230 6.58e-003
E m z m 1 z f x0 , x1 , , x m , x m 1
23
b) Ancora sulla Stima dell’Errore di Troncamento
Ricordiamo che i polinomi interpolanti di grado m e m+1 nella
scrittura di Newton alle differenze divise sono i seguenti:
Pm x f x0 x x0 f x0 , x1 x x0 x x m 1 f x 0 , , xm
Pm 1 x Pm x x x0 ... x x m 1 x x m f x0 , x1 , , x m 1
m 1 z f x0 , x1 , , xm , xm 1 Pm 1 z Pm z
Da quanto scritto nella slide precedente, risulta quindi:
Em z Pm 1 z Pm z , m lenght( ind1) 1
24
Istruzioni per il calcolo dell’Errore di troncamento
In questo caso, poiché si conosce la funzione, è possibile calcolare
correttamente l’errore di troncamento seguendo le istruzioni di
seguito riportate.
% calcolo dell'errore di troncamento
x1=[x', z(1)];% aggiunta del punto z1 tra i nodi
y1=feval(f,x1); % valutazione della funzione
A1 = dividif(x1,y1); % tabella delle diff. divise
E4(1)=abs(prod(z(1)-x)*A1(end,end));% errore
% di troncamento in z(1)
x2=[x', z(2)];% aggiunta del punto z2 tra i nodi
y2=feval(f,x2); % valutazione corrispondente
% della funzione
A2 = dividif(x2,y2);
E4(2)=abs(prod(z(2)-x)*A2(end,end));% errore
% di troncamento in z(2)
25
Function dividif: calcolo delle differenze
divise, costruzione della tabella corrispondente
function d=dividif(x,y)
[n,m]=size(y);
if n==1,n=m;end
n=n-1; d=zeros(n+1);d(:,1)=y';
for j=2:n+1
for i=j:n+1
d(i,j)=(d(i-1,j-1)-d(i,j-1))/(x(i-j+1)-
x(i));
end
end
26
Risultati del calcolo dell’errore di troncamento
Nella tabella che si costruisce, si riporta sia l’errore effettivamente
calcolato (comprensivo dell’errore di troncamento e dell’errore di
propagazioneindicato con errf) che l’errore di troncamento
definito da:
E m z m 1 z f z , x0 , x1 , , xm
31
Confronto polinomio - funzione
32
Istruzioni per il confronto polinomi - funzione
Si considerano i polinomi interpolanti di quarto e quinto grado e si
fa un confronto con la funzione.
figure()
P1=Neville(x,y,zz,ind1,length(x)-2); % grado 4
plot(zz,P1(:,2), '--b',zz,P(:,2),zz,feval(f,zz),'r',x,y,
'ko')
title('polinomi di Neville')
xlabel('x');grid
legend('n=4', 'n=5', 'funzione', 'nodi', 'Location',
'Best')
33
Confronto polinomi - funzione
34
c) Spline cubica naturale
Si utilizza la function Spline_interp per costruire la funzione
spline che è C ed ha due condizioni agli estremi dell’intervallo
2
36
Risultati confr. spline_interp - spline
zz S(zz) S_mat(zz) errS errS_mat
0.0000 0.00000000 0.00000000 0.00e+000 0.00e+000
0.1257 -0.25757013 -0.42708621 4.25e-001 2.55e-001
0.2513 -0.51042540 -0.78798156 6.69e-001 3.91e-001
.........
1.2566 -1.79774950 -1.79774950 0.00e+000 0.00e+000
1.3823 -1.79788921 -1.75248069 9.75e-002 5.21e-002
1.5080 -1.75748654 -1.68314404 1.64e-001 8.92e-002
1.6336 -1.68314770 -1.59395185 2.00e-001 1.11e-001
......... I valori in rosso sono relativi ai nodi di interpolazione!!!
5.0265 -0.04144552 -0.04144552 0.00e+000 0.00e+000
5.1522 -0.03176818 -0.03190436 1.95e-003 1.81e-003
5.2779 -0.02383803 -0.02367604 3.24e-003 3.40e-003
5.4035 -0.01746095 -0.01671796 3.93e-003 4.67e-003
5.5292 -0.01244280 -0.01098751 4.10e-003 5.56e-003
5.6549 -0.00858945 -0.00644212 3.85e-003 6.00e-003
5.7805 -0.00570676 -0.00303917 3.26e-003 5.93e-003
5.9062 -0.00360061 -0.00073608 2.46e-003 5.33e-003
37
figure()
plot(zz,ys,'k',zz,p_s(:,2),'b',zz,fzz,'r',x,y, 'ko')
title('Confronto tra Spline naturale e spline MATLAB')
legend('spl. MAT','spl. nat.','funzione','nodi',
'Location', 'Best') 38
grid on
d) polinomio approssimante ai minimi quadrati
fb=strvcat('1','t','t^2','t^3','t^4');
%funzioni di base
[vfz,coeff,A]=Min_quad(x,y,z,fb);
fz=feval(f,z);
errf_mq=abs(fz-vfz(:,2));%errore (f - Min_quad)
tab=[vfz fz errf_mq];
fprintf(' z P_mq f(z) errf \n')
fprintf('% 8.5f %12.8f %12.8f %12.2e\n',tab')
39
Confronto con function polyfit di MATLAB
utilizzata per approssimare ai minimi quadrati
vfz=Min_quad(xv,yv,zz,fb);
Coeff_P = polyfit(xv,yv,np); % determina i
% coefficienti del polinomio ai minimi quadrati
% np = 4 < (numero nodi –1)
% valutazione del polinomio in zz
P_mat=polyval(Coeff_P,zz);
%errore (f - Min_quad)
errf_mq=abs(fzz-vfz(:,2));
errf_fit=abs(fzz-P_mat); %errore (f – polyfit)
tab=[vfz P_mat errf_mq errf_fit];
fprintf('zz P_mq(zz) P_mat errf_mq …
errf_fit\n')
fprintf('% 8.5f %12.8f %12.8f %12.2e
%12.2e\n',tab')
40
Risultati confr. Min_quad - polyfit
zz vfz P_mat err_vfz err_P_mat
0.0000 -0.01305955 -0.01305955 1.31e-002 1.31e-002
0.1257 -0.41002007 -0.41002007 2.72e-001 2.72e-001
0.2513 -0.74454648 -0.74454648 4.35e-001 4.35e-001
......
1.2566 -1.73245178 -1.73245178 6.53e-002 6.53e-002
1.3823 -1.70750388 -1.70750388 7.10e-003 7.10e-003
1.5080 -1.66185665 -1.66185665 6.79e-002 6.79e-002
1.6336 -1.59870849 -1.59870849 1.16e-001 1.16e-001
......I valori in rosso sono relativi ai nodi assegnati; notare gli errori!!!
5.0265 -0.10674324 -0.10674324 6.53e-002 6.53e-002
5.1522 -0.13233196 -0.13233196 9.86e-002 9.86e-002
5.2779 -0.15605328 -0.15605328 1.29e-001 1.29e-001
5.4035 -0.17578698 -0.17578698 1.54e-001 1.54e-001
5.5292 -0.18923555 -0.18923555 1.73e-001 1.73e-001
5.6549 -0.19392420 -0.19392420 1.81e-001 1.81e-001
5.7805 -0.18720083 -0.18720083 1.78e-001 1.78e-001
5.9062 -0.16623607 -0.16623607 1.60e-001 1.60e-001
41
Esame dell’ordine con cui le due function restituiscono i
coefficienti del polinomio approssimante ai
minimi quadrati
Coeff_P = polyfit(x,y,np)% function MATLAB
>> Coeff_P =
0.02962287239868 -0.43986418884352 2.13939380034051
-3.42086839497736 -0.01305954566841
[vfz,coeff,A]=Min_quad(x,y,zz,fb);
>> coeff'
ans =
-0.01305954566842 -3.42086839497736 2.13939380034052
-0.43986418884352 0.02962287239868
coeff=[c0,c1,c2,c3,c4];
42
N. B. sono restituiti nell’ordine inverso!!
Le curve relative a
pol.MAT e pol. Min-quad
sono sovrapposte nella
figura!!
figure()
plot(zz,P_mat,'k',zz,vfz(:,2),'b',zz,fzz,'r',x,y, 'ko')
title('Confronto tra Min-quad e comando polyfit')
legend('pol. MAT','pol. Min-quad','funzione','nodi',
'Location', 'Best');grid on 43
Function Neville: prima parte
function [P,stimaerr]=Neville(x,y,z,ind,np)
lind=length(ind)-1;n=length(x)-1;m=length(z);
P=[];stimaerr=[];
if lind>n
disp('Il numero dei nodi scelti deve essere <= del numero
dei nodi totali')
return
elseif np>lind
disp('Il grado del polinomio deve essere minore del numero
dei nodi scelti')
return
end
for i=1:n
for j=i+1:n+1
if abs(x(i)-x(j))<=1.e-14
disp('I nodi devono essere distinti')
return % N.B. se return è in una function chiamata,si
end % torna al programma principale all’istruzione
end % successiva alla chiamata. Non porre mai tale
% istruzione nel programma principale se non si
end % vuole interrompere il programma. 44
Function Neville:seconda parte
xy=sortrows([x y]);x=xy(:,1);y=xy(:,2);
xy=sortrows([x(ind) y(ind)]);x=xy(:,1);y=xy(:,2);
if lind>np
xnp1=x(np+1);ynp1=y(np+1);
x(np+1)=x(end);y(np+1)=y(end);
x(end)=xnp1;y(end)=ynp1;
end
% Costruzione della tabella di Neville
p=y(1:lind+1)*ones(1,m);
for k=1:lind+1
for i=lind+1:-1:k+1
p(i,:)=p(i,:)+(z'-x(i)).*(p(i,:)-p(i-1,:))/(x(i)-x(i-k));
end
end
P=[z, p(np+1,:)'];
if lind>np
stimaerr=abs(p(np+1,:)-p(np+2,:))';
end
45
Function spline_interp: prima parte
function S=Spline_interp(x,y,z,p)
n=length(x)-1;m=length(z);h=diff(x);
% Matrice dei coefficienti e termini noti per calcolare M
d1(2:n)=2*(h(1:n-1)+h(2:n));d2=h;d3=h;
b(1)=(y(2)-y(1))/h(1);
b(2:n)=(y(3:n+1)-y(2:n))./h(2:n)-(y(2:n)-y(1:n-1))./h(1:n-1);
b(n+1)=(y(n+1)-y(n))/h(n);
switch p(1)
case(1)
d1(1)=2*h(1);d1(n+1)=2*h(n);
b(1)=b(1)-p(2);b(n+1)=p(3)-b(n+1);
case(2)
d1=d1(2:n);d2=d2(2:n-1);d3=d3(2:n-1);
b=b(2:n);b(1)=b(1)-h(1)/6*p(2);
b(n-1)=b(n-1)-h(n)/6*p(3);
Mf(1)=p(2);Mf(n+1)=p(3);
otherwise
S=[];disp('Scelta errata');return
end
46
Function spline_interp: seconda parte
A=diag(d1)+diag(d3,-1)+diag(d2,+1);
[L,U,P]=lu(A);yy=L\(P*(6*b)');M=U\yy;
if p(1)==2
Mf(2:n)=M; M=Mf';
End
47
Function spline_interp: terza parte
% Spline cubica interpolante e spline derivata
z=sort(z);S=[];
for j=1:m
xx=z(j);
for i=1:n
if xx>=x(i)&xx<=x(i+1)
s=(M(i+1)*(xx-x(i)).^3-M(i)*(xx-x(i+1)).^3)./(6*h(i))+c(i)*
(xx-x(i))+d(i);
s1=(M(i+1)*(xx-x(i)).^2-M(i)*(xx-x(i+1)).^2)./(2*h(i))+
c(i);
end
if xx<x(1)
disp('Un punto e'' esterno all''intervallo');return
end
if xx>x(n+1)
disp('Un punto e'' esterno all''intervallo');return
end
end
S=[S; s s1];
end
48
S=[z S];
Function min_quad:prima parte
function [vfz,coeff,A]=Min_quad(x,y,z,fb)
[k,l]=size(z);[m,l]=size(x);[n,s]=size(fb);
for i=1:m
t=x(i,:);
for j=1:n
A(i,j)=eval(fb(j,:));
end
end
if rank(A)==min(m,n)
% Decomposizione QR
[Q,R]=qr(A,0); coeff=R\(R'\(A'*y));% è equivalente
% a coeff= R\(Q'*y)
r=y-A*coeff;e=R\(R'\(A'*r)); coeff=coeff+e; %un
% passo di raffinamento
else
% Decomposizione SVD
[U,S,V]=svd(A,0);D=S'*S;
r=rank(D); d=1./diag(D(1:r,1:r));
Dr=diag([d;zeros(n-r,1)]); coeff=(V*Dr*V')*(A'*y);
49
end
Function min_quad:seconda parte
for i=1:k
t=z(i,:);
for j=1:n
Az(i,j)=eval(fb(j,:));
end
end
vfz=Az*coeff;
vfz=[z vfz];
50