Radosław Jarema
Paweł Piluk
Metody Numeryczne - sprawozdanie z laboratorium nr 3.
Ćwiczenie 1.
Szukamy funkcji postaci:
x |
0,955 |
1,380 |
1,854 |
2,093 |
2,674 |
3,006 |
3,255 |
3,940 |
4,060 |
y |
5,722 |
4,182 |
4,727 |
4,850 |
5,011 |
5,253 |
5,617 |
6,282 |
6,255 |
Która aproksymuje punkty z tabeli.
Wzór funkcji aproksymującej ma postać: f(x) =
.
Funkcja postaci
dobrze aproksymuje dane punkty.
Kod Matlab-a:
%% Aproksymacja (lab nr 3) - zadanie 1
close all; clc; clear all;
% zbior punktow, ktore aproksymujemy funkcją
xpoint = [0.955 1.380 1.854 2.093 2.674 3.006 3.255 3.940 4.060];
ypoint = [5.722 4.182 4.727 4.850 5.011 5.253 5.617 6.282 6.255];
%wzor funkcji, w ktorej Matlab bedzie optymalizowal wspolczynniki:
modelFun = @(c,x) (c(1)./x) + (c(2).*x);
%wartosci startowe wspolczynnikow do optymalizacji (Matlab od nich zacznie
%ale nie ma to wiekszego znaczenia
startingVals = [4 1];
%funkcja nlinfit optymalizuje wspolczynniki i wpisuje w wektor coefEsts
coefEsts = nlinfit(xpoint, ypoint, modelFun, startingVals);
%wektor x do rysowania wykresu funkcji, rysowanie wykresu
x_vec = linspace(0.5,5,100);
hold on; grid on;
plot(x_vec, modelFun(coefEsts, x_vec),'LineWidth',2); plot(xpoint,ypoint, 'ko');
xlabel('x'); ylabel('y'); title('Aproksymacja - zad.1');
disp(sprintf('\n--------------- APROKSYMACJA - zad.1 ---------------'))
disp('Funkcja postaci y = c1/x + c2*x');
disp(sprintf('c1 = %g',coefEsts(1)));
disp(sprintf('c2 = %g',coefEsts(2)));
disp(sprintf('\n'));
Ćwiczenie 2.
Szukamy linii prostej aproksymującej punkty (1,1), (2,2), (4,2), (5,3).
Wzór funkcji aproksymującej ma [postać: f(x) = 0,8 + 0,4x
Kod Matlab-a:
%% Aproksymacja (lab nr 3) - zadanie 2
close all; clc; clear all;
% zbior punktow, ktore aproksymujemy funkcją
x = [1 2 4 5];
y = [1 2 2 3];
%wzor funkcji, w ktorej Matlab bedzie optymalizowal wspolczynniki:
modelFun2 = @(a,x) a(1) + (a(2).*x);
%wartosci startowe wspolczynnikow
startingVals2 = [2 2];
%funkcja nlinfit optymalizuje wspolczynniki i wpisuje w wektor coefEsts
coefEsts = nlinfit(x, y, modelFun2, startingVals2);
%wektor x do rysowania wykresu funkcji, rysowanie wykresu
x_vec = linspace(0,6,100);
hold on; grid on;
plot(x,y,'ks'); plot(x_vec, modelFun2(coefEsts, x_vec),'LineWidth',2, 'Color','r');
xlabel('x'); ylabel('y'); title('Regresja liniowa');
disp(sprintf('\n--------------- APROKSYMACJA - zad.2 ---------------'))
disp('Funkcja postaci y = a0 + a1*x');
disp(sprintf('a0 = %g',coefEsts(1)));
disp(sprintf('a1 = %g',coefEsts(2)));
disp(sprintf('\n'));
Ćwiczenie 3.
Funkcja x = f(x) jest określona tablicą:
a) Znaleźć wielomian aproksymujący stopnia drugiego i określić średni błąd aproksymacji.
b) Znaleźć wielomian aproksymujący stopnia czwartego.
c) Zwiększyć liczbę punktów do 17 (równoodległych)
a następnie znaleźć dwa wielomiany aproksymujące stopnia drugiego na przedziałach:
x |
π/6 |
π/4 |
π/3 |
π/2 |
0 |
y |
|
|
|
1 |
0 |
a)
Wzór wielomianu aproksymującego ma postać: f(x) = -0,005 + 1,1685x - 0,3346x2
x |
π/6 |
π/4 |
π/3 |
π/2 |
0 |
- |
y |
|
|
|
1 |
0 |
- |
Błąd y |
0,005 |
0,0151 |
0,0007 |
0,0143 |
0,0049 |
S 2 = |
Kod Matlab-a:
%% Aproksymacja (lab nr 3) - zadanie 3a
close all; clc; clear all;
% zbior punktow, ktore aproksymujemy funkcją
x = [0 pi/6 pi/4 pi/3 pi/2];
y = [0 0.5 sqrt(2)/2 sqrt(3)/2 1 ];
%wzor funkcji, w ktorej Matlab bedzie optymalizowal wspolczynniki:
modelFun = @(c,x) c(1) + (c(2).*x) + (c(3).*(x.^2));
%wartosci startowe wspolczynnikow
startingVals = [2 2 2];
%funkcja nlinfit optymalizuje wspolczynniki i wpisuje w wektor coefEsts
coefEsts = nlinfit(x, y, modelFun, startingVals);
%wektor x do rysowania wykresu funkcji, rysowanie wykresu
xgrid = linspace(0,2,50);
hold on; grid on;
plot(xgrid, modelFun(coefEsts, xgrid),'LineWidth',2, 'Color','b'); plot(x,y, 'ko');
xlabel('x'); ylabel('y'); title('Aproksymacja funkcją kwadratową');
%obliczanie bledu sredniokwadratowego
for i=1:5
b(i) = abs( (coefEsts(1) + coefEsts(2)*x(i) + coefEsts(3)*(x(i)^2)) - y(i) );
end
disp(sprintf('\n--------------- APROKSYMACJA - zad.3a ---------------'))
disp('Funkcja postaci y = a0 + a1*x + a2*x^2');
disp(sprintf('a0 = %g',coefEsts(1)));
disp(sprintf('a1 = %g',coefEsts(2)));
disp(sprintf('a2 = %g',coefEsts(3)));
disp(sprintf('Bledy dla poszczegolnych punktów:'));
disp(sprintf('b(x1) = %g',b(1)));
disp(sprintf('b(x2) = %g',b(2)));
disp(sprintf('b(x3) = %g',b(3)));
disp(sprintf('b(x4) = %g',b(4)));
disp(sprintf('b(x5) = %g',b(5)));
disp(sprintf('Blad sredniokwadratowy = %g',mean(b.^2)));
disp(sprintf('\n'));
b)
Wzór wielomianu aproksymującego ma postać:
f(x) = 0 + 0,9956x + 0,0214x2 - 0,2043x3 + 0,0288x4
x |
π/6 |
π/4 |
π/3 |
π/2 |
0 |
- |
y |
|
|
|
1 |
0 |
- |
Błąd |
0 |
0,1504 |
0,1504 |
0,1504 |
0,1503 |
S 2 = 1,8098 * 10-26 |
Kod Matlab-a:
%% Aproksymacja (lab nr 3) - zadanie 3b
close all; clc; clear all;
% zbior punktow, ktore aproksymujemy funkcją
x = [0 pi/6 pi/4 pi/3 pi/2];
y = [0 0.5 sqrt(2)/2 sqrt(3)/2 1];
%wzor funkcji, w ktorej Matlab bedzie optymalizowal wspolczynniki:
modelFun = @(c,x) c(1) + (c(2).*x) + (c(3).*(x.^2)) + (c(4).*(x.^3)) + (c(5).*(x.^4));
%wartosci startowe wspolczynnikow
startingVals = [0 0 0 0 0];
%funkcja nlinfit optymalizuje wspolczynniki i wpisuje w wektor coefEsts
coefEsts = nlinfit(x, y, modelFun, startingVals);
%wektor x do rysowania wykresu funkcji, rysowanie wykresu
xgrid = linspace(-4,8,50);
hold on; grid on;
plot(xgrid, modelFun(coefEsts, xgrid),'LineWidth',2, 'Color','b'); plot(x,y, 'ko');
xlabel('x'); ylabel('y'); title('Aproksymacja wielomianem 4-ego stopnia');
%line(xgrid, modelFun(cf, xgrid), 'Color','r');
%obliczanie bledu sredniokwadratowego
for i=1:5
b(i) = abs( (coefEsts(1) + coefEsts(2)*x(i) + coefEsts(3)*(x(i)^2) + coefEsts(4)*(x(i)^3) + coefEsts(5)*(x(i)^4)) - y(i) );
end
disp(sprintf('\n--------------- APROKSYMACJA - zad.3b ---------------'))
disp('Funkcja postaci y = a0 + a1*x + a2*x^2 + a3*x^3 + a4*x^4');
disp(sprintf('a0 = %g',coefEsts(1)));
disp(sprintf('a1 = %g',coefEsts(2)));
disp(sprintf('a2 = %g',coefEsts(3)));
disp(sprintf('a3 = %g',coefEsts(4)));
disp(sprintf('a4 = %g',coefEsts(5)));
disp(sprintf('Bledy dla poszczegolnych punktów:'));
disp(sprintf('b(x1) = %g',b(1)));
disp(sprintf('b(x2) = %g',b(2)));
disp(sprintf('b(x3) = %g',b(3)));
disp(sprintf('b(x4) = %g',b(4)));
disp(sprintf('b(x5) = %g',b(5)));
disp(sprintf('Blad sredniokwadratowy = %g',mean(b.^2)));
disp(sprintf('\n'));
c)
Wzór wielomianu aproksymującego na przedziale
ma postać:
f(x) = -0,0036148 + 1,06869x - 0,21028x2
A na przedziale
: f(x) = -0,175813 + 1,4901x - 0,472188x2
Błąd średnio kwadratowy dla takiej aproksymacji wynosi: 2.90126 * 10 -6
Kod Matlab-a:
%% Aproksymacja (lab nr 3) - zadanie 3c
close all; clc; clear all;
% zbior punktow, ktore aproksymujemy funkcją - dwa przedziały
x_a = 0:(pi/32):(9*pi/32);
y_a = sin(x_a);
x_b = (9*pi/32):(pi/32):(17*pi/32);
y_b = sin(x_b);
%wzor funkcji, w ktorej Matlab bedzie optymalizowal wspolczynniki:
modelFun = @(c,x) c(1) + (c(2).*x) + (c(3).*(x.^2));
%wartosci startowe wspolczynnikow
startingVals = [2 2 2];
%funkcja nlinfit optymalizuje wspolczynniki i wpisuje w wektor coefEsts dla
%dwoch przedzialow
cf_a = nlinfit(x_a, y_a, modelFun, startingVals);
cf_b = nlinfit(x_b, y_b, modelFun, startingVals);
%wektor x do rysowania wykresu funkcji, rysowanie wykresu
xagrid = linspace(0,pi/4,50);
xbgrid = linspace(pi/4,17*pi/32,50);
hold on; grid on;
plot(xagrid, modelFun(cf_a, xagrid),'LineWidth',2, 'Color','r'); plot(x_a,y_a, 'go');
plot(xbgrid, modelFun(cf_b, xbgrid),'LineWidth',2, 'Color','b'); plot(x_b,y_b, 'ko');
xlabel('x'); ylabel('y'); title('Aproksymacja dwoma sklejanymi funkcjami kwadratowymi');
%obliczanie bledu sredniokwadratowego
for i=1:9
b_a(i) = abs( (cf_a(1) + cf_a(2)*x_a(i) + cf_a(3)*(x_a(i)^2)) - y_a(i) );
end
for i=1:9
b_b(i) = abs( (cf_b(1) + cf_b(2)*x_b(i) + cf_b(3)*(x_b(i)^2)) - y_b(i) );
end
disp(sprintf('\n--------------- APROKSYMACJA - zad.3c ---------------'))
disp('Dwie funkcje postaci y = ca0 + ca1*x + ca2*x^2');
disp(' y = cb0 + cb1*x + cb2*x^2');
disp(sprintf('ca0 = %g',cf_a(1)));
disp(sprintf('ca1 = %g',cf_a(2)));
disp(sprintf('ca2 = %g',cf_a(3)));
disp(sprintf('cb0 = %g',cf_b(1)));
disp(sprintf('cb1 = %g',cf_b(2)));
disp(sprintf('cb2 = %g',cf_b(3)));
disp(sprintf('\n'));
disp('Bledy dla poszczegolnych punktow:');
disp(sprintf('\n%g',b_a));
disp(sprintf('%g\n',b_b));
disp(sprintf('Blad sredniokwadratowy = %g', (mean(b_a.^2)+mean(b_b.^2))/2));
disp(sprintf('\n'));
Punkty łatwo było aproksymować funkcja 2 rzędu. Sinus na przedziale (0, π/2) dobrze aproksymuje się funkcja kwadratową. Jednak rozbicie funkcji na dwa przedziały daje jeszcze lepszą aproksymację, jeszcze mniejszy błąd średnio kwadratowy. Jak można się było spodziewać najlepszą aproksymacją okazała się aproksymacja wielomianem stopnia czwartego
Ćwiczenie 4.
Funkcję y = |x| aproksymować na przedziale <-1;1>
Wielomianem stopnia trzeciego
Wielomianem stopnia piątego
a)
Wzór wielomianu aproksymującego ma postać:
f(x) = 0,1942 + 1,4*10-16 x + 0,898987x2 - 3,5*10-16 x3
b)
Wzór wielomianu aproksymującego ma postać:
f(x) = 0,1187 - 4,9*10-76 x + 1,5917x2 + 4,1*10-16 x3 - 0,7403x4 + 3,6*10-16 x5
Lepszą aproksymację otrzymujemy przy wielomianie piątego stopnia.
Kod Matlab-a:
%% Aproksymacja (lab nr 3) - zadanie 4
close all; clc; clear all;
warning off;
% zbior punktow, ktore aproksymujemy funkcją
x = -1:0.1:1;
y = abs(x);
%wzory funkcji, w ktorych Matlab bedzie optymalizowal wspolczynniki
%oraz funkcje optymalizujace wspolczynniki
modelFun = @(c,x) c(1) + (c(2).*x) + (c(3).*(x.^2)) + (c(4).*(x.^3)) + (c(5).*(x.^4) + (c(6).*(x.^5)));
startingVals = [0 0 0 0 0 0];
cf = nlinfit(x, y, modelFun, startingVals);
modelFun3 = @(c,x) c(1) + (c(2).*x) + (c(3).*(x.^2)) + (c(4).*(x.^3));
startingVals3 = [0 0 0 0];
cf3 = nlinfit(x, y, modelFun3, startingVals3);
%rysowanie wykresu
xgrid = linspace(-1,1,100);
hold on; grid on;
plot(xgrid, modelFun(cf, xgrid),'LineWidth',2, 'Color','r'); plot(x,y, 'ko');
xlabel('x'); ylabel('y'); title('Aproksymacja wielomianem 5-ego stopnia');
figure;
hold on; grid on;
plot(xgrid, modelFun3(cf3, xgrid),'LineWidth',2, 'Color','r'); plot(x,y, 'ko');
xlabel('x'); ylabel('y'); title('Aproksymacja wielomianem 3-ego stopnia');
disp(sprintf('\n--------------- APROKSYMACJA - zad.4 ---------------'))
disp('Funkcja a postaci y = cb0 + cb1*x + cb2*x^2');
disp('Funkcja b postaci y = a0 + a1*x + a2*x^2 + a3*x^3 + a4*x^4');
disp(sprintf('\n'));
disp(sprintf('ca0 = %g',cf3(1)));
disp(sprintf('ca1 = %g',cf3(2)));
disp(sprintf('ca2 = %g',cf3(3)));
disp(sprintf('ca3 = %g',cf3(4)));
disp(sprintf('\n'));
disp(sprintf('cb0 = %g',cf(1)));
disp(sprintf('cb1 = %g',cf(2)));
disp(sprintf('cb2 = %g',cf(3)));
disp(sprintf('cb3 = %g',cf(4)));
disp(sprintf('cb4 = %g',cf(5)));
disp(sprintf('cb5 = %g',cf(6)));
Ćwiczenie 5.
Dla funkcji określonej tablicą znaleźć trygonometryczne przybliżenie średniokwadratowe.
x |
0 |
π/4 |
π/2 |
3π/4 |
π |
5π/4 |
3π/2 |
7π/4 |
y |
4 |
1,2929 |
-1 |
1,2929 |
4 |
2,7071 |
1 |
2,7071 |
Kod Matlab-a:
%% Aproksymacja (lab nr 3) - zadanie 5
clc; close all; clear all;
% zbior punktow, ktore aproksymujemy funkcją
xpoint = 0:(pi/4):(7*pi/4);
ypoint = [4 1.2929 -1 1.2929 4 2.7071 1 2.7071];
plot(xpoint,ypoint,'ko','linestyle','none')
% n-ilosc punktow aproksymacji, m-ilosc wspolczynnikow szeregu trygonom.
n = 8;
m = 3;
% wspolczynnik zerowy szeregu
a0 = mean(ypoint);
% na razie wspolczynniki wypelniamy zerami
a = zeros(1,m);
b = zeros(1,m);
%liczymy wspolczynniki
for i=1:m
for j=1:n
a(i) = a(i) + ypoint(j)*cos(2*pi*j*i/n);
b(i) = b(i) + ypoint(j)*sin(2*pi*j*i/n);
end
end
% wyswietlamy wspolczynniki
a = 2*a/n
b = 2*b/n
a0
% liczymy wektor y_app do narysowania funkcji
x_vec = 0:0.02:8;
y_app = zeros(1,length(x_vec));
for k=1:length(x_vec)
y_app(k) = a0;
for i=1:m
y_app(k) = y_app(k) + a(i)*cos(2*pi*i*x_vec(k)/n) + b(i)*sin(2*pi*i*x_vec(k)/n);
end
end
hold on; grid on;
plot(x_vec/1.2-1.0,y_app) %tutaj wspolczynnik K studenta :D bo nie wyszlo
xlabel('x'); ylabel('y'); title('Aproksymacja trygonometryczna');
Ćwiczenie 6.
Dopasować model ekspotencjalny postaci
do danej w tabeli. Następnie rozwiązać zadanie przez sprowadzenie do problemu regresji liniowej. Porównać rezultaty.
x |
0,4 |
0,8 |
1,2 |
1,6 |
2,0 |
2,3 |
y |
750 |
1000 |
1400 |
2000 |
2700 |
3750 |
Wzór wielomianu aproksymującego funkcją exp(x) ma postać:
f(x) = 489,512 exp(0,8763 x)
Wzór wielomianu aproksymującego funkcją liniową ma postać:
f(x) = -165,974 + 1517,57x
Dane punkty bardzo dobrze aproksymuje funkcja exp(x).
Kod Matlab-a:
%% Aproksymacja (lab nr 3) - zadanie 6
clc; close all; clear all;
% zbior punktow, ktore aproksymujemy funkcją
x = [0.4 0.8 1.2 1.6 2.0 2.3];
y = [750 1000 1400 2000 2700 3750];
% modele funkcji aproksymujacych
modelFun = @(a,x) a(1).*exp(a(2).*x);
modelFun2 = @(a,x) a(1) + (a(2).*x);
startingVals = [2 2];
startingVals2 = [2 2];
% optymalizacja wspolczynnikow
cf = nlinfit(x, y, modelFun, startingVals);
cf2 = nlinfit(x, y, modelFun2, startingVals2);
%rysowanie funkcji
xgrid = linspace(0,2.5,100);
hold on; grid on;
plot(xgrid, modelFun(cf, xgrid), 'Color','b'); plot(x,y, 'kd');
plot(xgrid, modelFun2(cf2, xgrid), 'Color','r');
xlabel('x'); ylabel('y'); title('Porównanie aproksymacji funkcją exp(x) do aproksymacji liniowej');
disp(sprintf('\n--------------- APROKSYMACJA - zad.6 ---------------'))
disp('Wspolczynniki funkcji aproksymujacej y = a0*exp(a1*x)');
disp(sprintf('a0 = %g',cf(1)));
disp(sprintf('a1 = %g',cf(2)));
disp(sprintf('\n'));
disp('Wspolczynniki funkcji aproksymujacej y = a0 + a1*x');
disp(sprintf('a0 = %g',cf2(1)));
disp(sprintf('a1 = %g',cf2(2)));
disp(sprintf('\n'));