Sprawozdanie Metody Numeryczne
Ćw nr 3
Interpolacja i aproksymacja
Adam Tondel 153019
Bartłomiej Łaszek 152133
Cel ćwiczenia:
celem ćwiczenia było zbadanie oraz wykorzystanie działania interpolacji wielomianowej z wykorzystaniem możliwości programu MatLab oraz porównanie wyników aproksymacji znanej nam wcześniej funkcji z wynikami otrzymanymi dzięki obliczeniom.
Przebieg ćwiczenia:
Funkcją, jaką pierwotnie badaliśmy, była . pierwszym etapem naszej pracy było wyznaczenie punktów wykresu dla pierwotnej funkcji, a następnie za pomocą możliwości MatLab'a i wbudowanej funkcji polyfit oraz polyval funkcja była aproksymowana na przedziale 1-4
m-file jaki został przez nas napisany do obliczenia tej funkcji miał następującą postać:
for n=1:4
x=1:0.25:4;
y=1.2*x.^2+x.*2.3-3.1;
p=polyfit(x,y,n);
plot(x,y,'red+')
hold on;
xw=1:0.1:4;
yw=polyval(p,xw);
plot(xw,yw,'blue')
end
Wykres jaki otrzymaliśmy przedstawiał się natomiast w sposób pokazany poniżej:
Pierwsza niebieska linia na wykresie, która jest prostoliniowa, przedstawia aproksymacje funkcji za pomocą wielomianu pierwszego stopnia, natomiast druga za pomocą wielomianu drugiego stopnia. Wielomian stopnia 3 pokrywa się na wykresie z wielomianem stopnia 2 ponieważ współczynnik będący przy najwyższej potędze ma wartość 0. To samo ma miejsce przy wielomianie 4 stopnia – 2 najwyższe współczynniki mają zerowe wartości.
Następną funkcją, jaka była poddana analizie była funkcja . Zielona linia przedstawia funkcję, która jest przybliżona wielomianami kolejnych stopni, a czerwona linia przedstawia błąd jaki popełnialiśmy dla kolejnych przybliżeń. Wielomiany przybliżające funkcje są stopnia od 1 do 20
M-plik
wygląda następująco:
for n=1:20
x=-5:0.3:5;
y=abs(sqrt(x.*1));
p=polyfit(x,y,n);
plot(x,y,'*')
hold on;
xw=-5:0.3:5;
yw=polyval(p,xw);
plot(xw,yw,'green')
hold on
b=yw-y;
plot(x,b,'red')
end
Dla wielomianów stopni od 21 do 33 wykres przedstawia się tak:
Następny
wykres będzie przedstawiał wielomiany stopni od 34 do 40. zauważyć
na nich można wyraźny efekt Rungego – przybliżenie zatem jakie
otrzymaliśmy nie jest poprawne.
Kolejnym naszym zadaniem było napisanie funkcji aproksymującej dla zbioru wartości elementów i kolejno napisanie dla niej skryptu aproksymującego.
Pierwszą funkcją była . Plik wykonawczy wygląda jak poniżej:
f0=[1 1 1 1 ];
f1=[0 1 2 3];
f2=[0 1 4 9];
x=[0 1 2 3];
y=[1 2 4 8];
fi=[ones(size(x));x;x.*x];
X=fi*fi'
c=fi*y'
d=inv(X)*c
x1=polyfit(c,d,2)
x2=[x1(1,3)*x.*x+x1(1,2)*x+x1(1,1)]
plot(x,y,'blue');
hold on;
plot(x2, 'green*');
blad=x2-y;
plot(x,blad,'red');
wykres otrzymany wygląda tak:
Niebieska linia na wykresie przedstawia wykres podstawowej funkcji. Linie zielona przerywana jest jej przybliżeniem a ostatnie czerwona linia jest błędem pomiędzy poprzednimi dwoma funkcjami. Na podstawie wyżej pokazanych wykresów można stwierdzić, że przybliżenie jest obarczone dużym błędem na końcu przedziału.
Następnym w kolejności zadaniem jest uzyskanie funkcji opisującej w sposób jak najdokładniejszy na podstawie podanych wartości zjawisko zmiany poziomu wody na morzu. Funkcja opisująca to zjawisko w postaci pierwotnej wyglądała następująco:
Plik MatLab'a realizujący powyższe zadanie ma postać:
t=[0 2 4 6 8 10];
h=[1.0 1.6 1.4 0.6 0.2 0.8];
Mi=[ones(size(t)); sin((2*pi*t)/12); cos((2*pi*t)/12)]
X=Mi *Mi'
b=Mi * h'
c=inv(A) * b
figure;
wys=polyfit(t,h,2)
wys1=[wys(1,1)+wys(1,2)*sin((2*pi*t)/12)+wys(1,3)*cos((2*pi*t)/12)];
err=wys1-h
plot(t,h,'green'),xlabel('t[h]'),ylabel('h [m]')
hold on
plot(t,err,'red')
plot(t,wys1,'blue--')
Linia zielona na wykresie przedstawia wykres funkcji bazowej, linia przerywana określa wykres otrzymany za pomocą obliczeń z MatLab'a, a linia czerwona przedstawia wykres błędu.
Wykres
przedstawia się tak:
Przedostatnim zadaniem w tym ćwiczeniu było aproksymowanie funkcji kwadratowej dla 2 wartości bazowych. Warunkiem było osiąganie przez tą funkcję ekstremum w punkcie 1, oraz 2 warunek – funkcja nie może przecinać osi x. Funkcja jaka będzie przeze mnie badana będzie miała następującą postać czyli po przekształceniu będzie ona wyglądała tak . Otrzymujemy zatem m-plik który przedstawia się tak:
format long e;
x=[-2 -1 0 1 2 3 4];
y=[19 9 3 1 3 9 19];
F=[ones(size(x)); x.*x - 2*x];
X=F *F';
b=F * y';
c=inv(X) * b;
f=polyfit(x,y,1);
f2=[f(1,1)+f(1,2)*(x.*x - x*2)];
err=f2 - y;
figure;
plot(x,y,'green')
hold on
plot(x,f2,'blue--')
plot(x,err,'red')
Wykres przedstawiony poniżej jest wynikiem działania tego pliku, gdzie następujące linie oznaczają kolejno: linia zielona to linia przedstawiająca wykres funkcji uzyskanej wprost ze wzoru, linia przerywana niebieska oznacza wartość przybliżoną funkcji obliczonej na podstawie MatLab'a a linia czerwona to linia przedstawiająca błąd pomiędzy tymi dwoma wykresami.
Naszym
ostatnim zadaniem w tym ćwiczeniu było przybliżenie funkcji
kwadratowej posiadającej miejsce zerowe dokładnie w punkcie (1;0) ,
oraz dodatkowy warunek jest taki, że aproksymacja przeprowadzona ma
być dla 3 funkcji bazowych. Jako funkcję pierwotną przyjmijmy
.
Plik z MatLab'a przedstawiony poniżej:
x=[ -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5];
y=[x.*x + 2*x - 3];
F=[ones(size(x)); x; x.^x];
X=F *F';
b=F * y';
c=inv(X) * b;
f=polyfit(x,y,2);
f2=[f(1,3)+f(1,2)*x + f(1,1)*(x.*x)];
err=f2 - y;
figure;
plot(x,y,'green');
hold on
plot(x,f2,'blue--')
plot(-3,0,'black*',1,0,'black*')
plot(x,err,'red')
Wykres przedstawia się następująco:
Linia
niebieska i zielona pokrywają się ze sobą, co za tym idzie
przybliżenie dobrze odwzorowuje nam funkcię właściwą. Linia
czerwona pokazuje nam błąd, który jest w tym wypadku zerowy na
całym przedziale aproksymacji. Jest to jednak przybliżenie,
ponieważ błąd jaki uzyskaliśmy możemy sprawdzić wpisując do
MatLaba polecenie format
long wtedy
okazuje się, że błąd jest na poziomie 10-13
czyli
jak widać jest na bardzo niskim poziomie.
Wnioski:
Podsumowując wyniki naszej pracy można powiedzieć, że do uzyskania dobrej dokładności przybliżenia funkcji należy spełnić kilka warunków. Jednym z nich jest stosowanie do aproksymacji kilku funkcji bazowych – w przedostatnim punkcie widać wyraźnie, że błąd jest niepomiernie duży w stosunku do funkcji prawdziwej, w punkcie ostatnim widzimy, że błąd jest minimalny i bez konsekwencji możemy go pominąć. Można zatem powiedzieć, że liczba funkcji bazowych powinna być dostatecznie duża. W pierwszych 2 zadaniach możemy powiedzieć, że wielkie znaczenie ma także stopień wielomianu interpolacyjnego oraz krok z jakim dokonujemy obliczeń jak także rodzaj funkcji jaką chcemy przybliżać. W 2 punkcie widać wyraźne problemy z przybliżeniem funkcji która w punkcie równym 0 nie ma pochodnej, czyli funkcja w punkcie równym 0 jest nieróżniczkowalna co za tym idzie błąd jest duży w okolicy tego punktu. Widać również na podstawie punktu 1, że podczas przybliżania funkcji kwadratowej błąd dla wielomianów drugiego, trzeciego oraz czwartego stopnia jest również pomijalnie mały – mimo tego że chcieliśmy przybliżyć tą funkcję wielomianem wyższego stopnia, okazało się, że współczynniki są zerowe przy potędze 3 i 4 tak więc rozwiązania nałożyły się na siebie. Kolejnym nasuwającym się wnioskiem jest to, że wielomiany należy aproksymować dla n liczby węzłów – nie mniejszej od stopnia wielomianu. Jest jednak pewne ograniczenie – przy zbyt wysokiej liczbie węzłów dochodzą jeszcze inne aspekty na które należy zwrócić uwagę, a mianowicie nie można podnosić dowolnie ilości węzłów gdyż prowadzi to do powstawania efektu Rungego, co doprowadza do dużych błędów. Jeżeli chodzi o porównanie metod jakimi posługiwaliśmy się na zajęciach można stwierdzić, że najlepsze wyniki aproksymacji daje nam funkcja oparta o aproksymację średniokwadratową, natomiast wbudowane funkcje polifit i polival obarczone są dużą niedokładnością.