%% Funkcje - obrazy i przeciwobrazy zbiorów
%

 clear;
close all;

%
%% Funkcje jednej zmiennej
%
%% Przykład 1.
% Zajmiemy się funkcją f(x)=x-2\sin x. Narysujemy wykres tej funkcji w przedziale [-2\pi, 2\pi].
% Wyznaczymy obraz f([0,\pi]) oraz przeciwobraz f^{-1}([0,2]).
%
% Definiujemy funkcję f(x) i rysujemy jej wykres w zadanym przedziale.
% Dla lepszej czytelności dołożymy linie siatki.

syms x
f(x)=x-2*sin(x)
fplot(f(x), [-2*pi, 2*pi],'b')
grid on   % ta opcja powoduje, że widoczne będą linie siatki

%
% Na czerwono narysujemy fragment wykresu tej funkcji dla x\in \left\lbrack 0,\pi \right\rbrack i nałożymy na poprzedni wykres.

hold on  % to polecenie powoduje, że kolejny wykres będzie nałożony na poprzedni
fplot(f(x), [0, pi],'r-')
hold off

%
% Widzimy, że f([0,\pi]) jest przedziałem, gdyż f jest funkcją ciągłą, wystarczy wyznaczyć końce tego przedziału.
% Widzimy, że wartość najmniejsza jest osiągana w minimum blisko x=1,
% a największa wartość przyjmowana jest w prawym końcu przedziału i jest to fmax=f(\pi).
% Ekstema funkcji są w punktach, gdzie jej pochodna jest równa 0. Minimum, o które nam chodzi jest w punkcie bliskim 1.
% Podamy dokładne i numeryczne wartości fmin i fmax.

pochodna_f=diff(f)       % różniczkowanie funkcji wykonujemy przy pomocy polecenia diff()
solve(pochodna_f)         % rozwiązujemy równanie pochodna_f=0 i domyślnie dostajemy rozwiązania najbliższe zera
xmin=vpasolve(pochodna_f,x,1) % podaje rozwiązanie numeryczne równania pochodna(f)=0 najbliższe x=1
xmax=pi   % zauważyliśmy, że największa wartość będzie dla x=pi
fmin=f(sym(pi/3)) % dokładna wartość minimum
fmax=f(sym(pi)) % dokładna wartość największa
fmin_num=f(xmin)  % numeryczna wartość najmniejsza

% W wyniku przeprowadzonych obliczeń i obserwacji dostajemy f([0,\pi])=[\pi/3-\sqrt3, \pi].
%
% Teraz zajmiemy się wyznaczeniem przeciwobrazu f^{-1}([0,2]).
% Narysujemy wykres funkcji f oraz wykresy funkcji stałych y=0 i y=2 w przedziale [-3, 3].
% Przyjrzymy się części wykresu funkcji f pomiędzy otrzymanymi prostymi poziomymi.

fplot([f,0,2],[-3 3])      % trzy funkcje na jednym wykresie
grid on

%
% Widzimy, że część wykresu zawarta między tymi prostymi składa się z dwóch ciągłych fragmentów. Odpowiadają im przedziały argumentów [a,b] i [c,d], a<b<c<d,  gdzie f(a)=f(b)=f(c)=0, a f(d)=2. Ponadto b=0, a=-c, bo f jest funkcją nieparzystą. Znajdziemy rozwiązania numeryczne równań f(x)=0 w otoczeniu punktów -2 i 2 oraz równania f(x)=2 w otoczeniu punktu 3.
% Polecenie do rozwiązywania numerycznego równań:
% vpasolve(rownanie, niewiadoma, warunek poczatkowy x0 lub zakres [x1, x2])

a=vpasolve(f(x)==0,x,-2)  % dostaniemy rozwiazanie w poblizu x0=-2

c=vpasolve(f(x)==0,x,2)     % dostaniemy rozwiazanie w poblizu x0=2
d=vpasolve(f(x)==2,x,3)        % dostaniemy rozwiazanie w poblizu x0=3

%
%% Wizualizacja funkcji dwóch zmiennych
%% Przykład 2.
%% Zajmiemy się funkcją  f_1(x,y)=2-\sqrt{x^2+y^2}.
%% Narysujemy powierzchnię będącą wykresem tej funkcji dla x\in [-3,3] i y\in [-3,3]  oraz kilka jej poziomic, a także jej wykres konturowy (poziomicowy).
%% Następnie narysujemy przeciwobraz f_1^{-1} \left(\left\lbrace -1,0,1\right\rbrace \right)i  wyznaczymy f_1^{-1} \left(\left\lbrack 0,1\right\rbrack \right).
%% Na podstawie wykresu konturowego wyznaczymy obraz  f_1 \left(\left\lbrack -1,3\right\rbrack \times \left\lbrack -2,1\right\rbrack \right).
%
% Polecenie    fsurf(f(x,y), opcje) tworzy wykres funkcji dwóch zmiennych (powierzchnia).
% Pod wykresem zostaną narysowane poziomice - opcja 'ShowContours','on', osie oznaczymy: x,y,z.

clear; 
close all;
syms x y
f1(x,y)=2-(x^2+y^2)^(1/2);
wykres_f1=fsurf(f1,[-3,3],'ShowContours','on');
axis image
xlabel('x')
ylabel('y')
zlabel('z')
colorbar   % wyswietlenie skali kolorów

%
% Możemy określić kolor powierzchni za pomocą opcji   'FaceColor'.
% Możemy ustalić przezroczystość wykresu za pomocą opcji   'FaceAlpha'

fsurf(f1,[-3,3],'FaceColor','m','FaceAlpha', 0.6 );   % m - kolor magenta

%
%% Rysowanie poziomic funkcji
% Gdy mamy zdefiniowaną funkcję, możemy rysować jej poziomice, czyli przeciwobrazy zbiorów jednoelementowych.
% Wykorzystamy polecenie   fimplicit(rownanie, opcje),    które rysuje zbiór rozwiązań równania.
% Wykres dla poziomicy f1(x,y)=1 narysujemy ciągłą linią czerwoną.
% Wykres dla poziomicy f1(x,y) = -1 narysujemy przerywaną linią niebieską.
% Wykres poziomicy f1(x,y) = 0 narysujemy ciągłą linią zieloną.
% Na obrazku umieścimy legendę.

fimplicit(f1==1,'-r')
grid on
hold on

fimplicit(f1==-1,'--b')

fimplicit(f1==0,'-g')
axis equal

legend('show','Location','eastoutside')
hold off

% Na powyższym rysunku trzy okręgi tworzą zbiór  f_1^{-1} \left(\left\lbrace -1,0,1\right\rbrace \right)
% Znając kształt powierzchni, która jest wykresem funkcji f1, możemy stwierdzić, że np. funkcja f1 będzie przyjmowała wartości z przedziału [0,1] w obszarze ograniczonym poziomicami f1=0 i f1=1 łącznie z tymi poziomicami. Tak więc zbiór f_1^{-1} \left(\left\lbrack 0,1\right\rbrack \right) to w pierścień ograniczony okręgami: czerwonym i zielonym.
%
% W celu wyznacznia zbioru f_1 \left(\left\lbrack -1,3\right\rbrack \times \left\lbrack -2,1\right\rbrack \right)  narysujemy wykres konturowy funkcji f1 w prostokącie \left\lbrack -1,3\right\rbrack \times \left\lbrack -2,1\right\rbrack

fcontour(f1,[-1 3 -2 1],'Fill','on','LevelStep',0.25);
axis equal
colorbar
grid on
fcontour(f1,[-1 3 -2 1],'Fill','off','LevelStep',0.2); % zmiana parametrów wykresu
axis equal
colormap('jet');  % można ustalić inny sposób doboru kolorów
colorbar
grid on

%
% Na podstawie uzyskanych wykresów stwierdzamy, że na wybranym obszarze funkcja osiąga wartości z przedziału [fmin, fmax], gdzie fmax =f1(0,0), a fmin=f(3,-2) - wartość w punkcie najbardziej oddalonym od (0,0).

fmax=f1(0,0)
fmin=f1(3,-2)

%% Ostatecznie zbiór  f_1 \left(\left\lbrack -1,3\right\rbrack \times \left\lbrack -2,1\right\rbrack \right)=\left\lbrack 2-\sqrt{13},2\right\rbrack.
%
%% Przykład 3.
%% Zajmiemy się funkcją   f_2(x,y)=|y|-x.
%% Narysujemy wykres tej funkcji dla argumentów z prostokąta [-3,3]\times[-3,3].
%% Następnie wyznaczymy obraz prostokąta [-1, 2]\times[-1,2] dla tej funkcji oraz obraz koła  x^2 +y^2 \le 2\ldotp
%% Przypomnienie: obraz zbioru A wyznaczony przez funkcję f, to zbiór wartości funkcji f otrzymanych dla argumentów należących do A.

clear; 
close all;
syms x y
f2(x,y)= abs(y)-x;

wykres_f2=fsurf(f2,[-3,3,-3,3],'ShowContours','on');
axis tight
xlabel('x')
ylabel('y')
zlabel('z')
colormap('jet');
colorbar

%
% Gdy chcemy wiedzieć, jak zmieniają się wartości funkcji  w prostokącie [-1, 2]\times[-1,2] możemy narysować wykres poziomicowy w obszarze zawierającym ten prostokąt. W tym celu wykorzystamy operację
%    fcontour(funkcja, zakres, opcje).
%  Dorysujemy prostokąt (operacja plot dla listy wierzchołków).

f_2c=fcontour(f2,[-2 3 -2 3],'Fill','on','MeshDensity',150,'LevelStep',0.25);
axis equal
colormap('gray');  % można ustalić inny sposób doboru kolorów
colorbar
grid on
hold on
plot([-1 2 2 -1 -1], [-1 -1 2 2 -1],'k-o')  % rysunek obwodu prostokąta
hold off

% Na podstawie tego rysunku możemy stwierdzić, że w podanym prostokącie funkcja przyjmie wartości z przedziału [fmin, fmax], gdzie fmin = f2(2,0), a fmax=f2(-1,2).

f2min=f2(2,0)
f2max=f2(-1,2)

%% Szukany obraz prostokąta wyznaczony przez funkcję f2  to   f_2 \left(\left\lbrack -1,2\right\rbrack \times \left\lbrack -1,2\right\rbrack \right)=\left\lbrack -2,3\right\rbrack.
%
% Jeśli chcemy wiedzieć, jakie będą wartości funkcji  w obszarze ograniczonym okręgiem x^2+y^2=2 możemy dołożyć wykres tego okręgu.

f2c=fcontour(f2,[-2 2 -2 2],'MeshDensity',51, 'LevelStep',0.25); 
% fc2 - wykres poziomic funkcji f2 w obszarze zawierającym okrąg
hold on
colormap('jet');
fimplicit(x^2+y^2==2,'-k') % rysunek okręgu określonego równaniem
grid on
legend('show','Location','best')
axis equal
colorbar
hold off

%
% Na podstawie rysunku możemy stwierdzić, że funkcja przyjmie najmniejszą wartość w punkcie okręgu o największej współrzędnej x, czyli fmin=f(\sqrt{2},0). Wartość największa będzie osiągana w punktach, gdzie poziomice są styczne do okręgu, czyli fmax=f(-1,1)=f(-1,-1).

f2max=f2(-1,1)
f2min=f2(sqrt(2),0)

%% Szukany obraz koła wyznaczony przez funkcję f2 to  f_2 \left(\left\lbrace \left(x,y\right):x^2 +y^2 \le 2\right\rbrace \right)=\left\lbrack -\sqrt{2},2\right\rbrack.
%%