[[
✎ pl:dydaktyka:ml:lab1
]]
aiWiki
Pokaż stronę
Ostatnie zmiany
Indeks
Zaloguj
Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić.
====== Laboratorium 1 - Wprowadzenie do GNU Octave ====== Środowisko Octave jest wolnym odpowiednikiem pakietu MATLAB. [[http://www.gnu.org/software/octave/doc/interpreter/index.html|Dokumentacja]] ===== Instalacja i uruchamianie ===== W przypadku większości systemów Linux, pakiet Octave można zainstalować bezpośrednio z repozytorium: <code>$ sudo apt-get install octave</code> W przypadku systemu Windows i OS X, oprogramowanie Octave można ściągnąć ze strony projektu: [[http://www.gnu.org/software/octave/download.html|GNU Octave]]. W systemie Linux uruchamiamy środowisko za pomocą polecenia <code>$ octave</code> W konsoli Octave możemy wykonywać wszystkie podstawowe polecenia umożliwiające nawigację w systemie plików (cd, ls, etc). ===== Składnia ===== ==== Typy i zmienne ==== W języku Octave, nie prototypujemy zmiennych. Typy określane są automatycznie, tak jak w PHP, czy Bashu. <code octave>zmienna = 'moja zmienna'; zmienna = 12.34; zmienna = [2 3 4; 3 4 5];</code> Jednym z podstawowych //typów// danych w Octave są wektory i macierze. Definiujemy je za pomocą nawiasów kwadratowych. Wartości w **wierszach** oddzielamy spacjami lub przecinkami. Wiersze oddzielamy znakiem średnika. Załóżmy że chcemy zdefiniować następującą macierz i przypisać ją do zmiennej M: $$M = \begin{bmatrix} 5 & 6 & 0 \\ 6 & 0 & 1 \\ 0 & 6 & 1 \end{bmatrix}$$ W Octave zapiszemy ją jako:<code octave>M = [5 6 0; 6 0 1; 0 6 1] </code> Aby odwołać się do danego elementu macierzy, lub wektora używamy nawiasów okrągłych.\\ **Uwaga :!:** W Octave indeksowanie rozpoczyna się od 1 a nie jak w popularnych językach programowania od 0! Np. Aby pobrać/przypisać wartość elementu z pierwszego wiersza i drugiej kolumny macierzy M, piszemy: <code octave>M(1,2)=7 </code> Jako wynik otrzymujemy: $$M = \begin{bmatrix} 5 & 7 & 0 \\ 6 & 0 & 1 \\ 0 & 6 & 1 \end{bmatrix}$$ Octave umozliwia równiez odwoływanie się do całych kolumn i wierszy w danej macierzy: <code octave> M(:,3) % zwróci [0;1;1] M(2,:) % zwróci [6 0 1] </code> Sprawdź co jak zadziała poniższy kod: <code octave> M = [5 6 0; 6 0 1; 0 6 1]; M([2 3],[1 2]) </code> ==== Zakresy ==== Zakresy tworzy się za pomocą znaku dwukropka. Służą one do definiowania prostych zestawów danych, a także do odwoływania się do danych w wektorach i macierzach. Przetestuj działanie poniższych poleceń <code octave>zeros(1,10) zeros(2,10) ones(1,10) range = [1:10] range = [1:0.3:10] range(5:10) </code> ==== Operatory arytmetyczne==== Octave udostępnia podstawowe operatory arytmetyczne zarówno dla macierzy jak i skalarów. Pełny zbiór operatorów dostępny jest w [[http://www.gnu.org/software/octave/doc/interpreter/Arithmetic-Ops.html#Arithmetic-Ops|dokumentacji Octave]]. **Uwaga :!:** Zwróć uwagę na działanie operatorów połączonych z kropką! \\ Przetestuj działanie poniższego kodu. <code octave> A = [0.5 0.5; 1 1]; B = [2 2; 2 2]; A * B A .* B B ^ 2 B .^ D </code> ==== Instrukcje sterujące ==== Octave udostępnia powszechnie znane z innych języków programowania instrukcje sterujące. Pełny opis instrukcji sterujących można znaleźć w [[http://www.gnu.org/software/octave/doc/interpreter/Statements.html#Statements|dokumentacji Octave]] ==== Definiowanie funkcji ==== Szczegółowe dane na temat definiowania funkcji można znaleźć w [[http://www.gnu.org/software/octave/doc/interpreter/Functions-and-Scripts.html#Functions-and-Scripts|dokumentacji Octave]]. Poniżej kilka podstawowych infromacji: * Funkcje najczęściej definiujemy w osobnych plikach z rozszerzeniem **.m** * Nazwa funkcji musi zgadzać się z nazwą pliku! * Wywoływanie funkcji odbywa się poprzez podanie jej nazwy i listy argumentów. * Podczas wywoływania funkcji musimy znajdować się w katalogu w którym dana funkcja jest zapisana. * W Octave nie zwracamy wartości za pomocą **return**. Po prostu przypisujemy ją do zmiennej podanej jako element zwracany * Komentarze w kodzie wstawiamy za pomocą % Przykładowa definicja funkcji: <file octave srednia.m> function W = srednia(dane) % funkcja obliczająca średnią elementów w wektorze W = sum(dane)/length(dane); end </file> Aby wywołać funkcje z przykładu powyżej wykonujemy polecenie: <code octave>Wynik = srednia([2 3 4 5 6 7 8]); </code> Jeśli funkcja ma zwracać więcej niż jeden argument, zapisujemy to w ten sposób: <file octave myFind.m> function [IndexX,IndexY] = myFind(M,V) % Funkcja poszukująca wartości V w macierzy M % Funkcja zwraca indeksy znalezionej wartości, lub -1,-1 [rows,cols] = size(M); IndexX = IndexY =-1; for i=1:rows, for j=1:cols if M(i,j) == V IndexX = i; IndexY = j; return; endif end end end </file> Aby pobrać wartości zwracane przez funkcję powyżej wpisujemy np.: <code octave> [X,Y] = myFind(M,6); </code> ==== Rysowanie wykresów ==== Do rysowania wykresów używamy funkcji: * plot - rysowanie wykresów 2D * plot3d - rysowanie wykresów 3D * mesh - rysowanie płaszczyzn Porównaj działanie funkcji na poniższych przykładach. Jaka jest różnica pomiędzy plot3 a mesh? **Plot2** <code octave> x = [0:0.01:10]; y = sin(x); plot(x,y); </code> **Plot3** <code octave> t = 0:0.1:10*pi; r = linspace (0, 1, numel (t)); z = linspace (0, 1, numel (t)); plot3 (r.*sin(t), r.*cos(t), z); </code> **Mesh** <code octave> tx = ty = linspace (-8, 8, 41)'; [xx, yy] = meshgrid (tx, ty); r = sqrt (xx .^ 2 + yy .^ 2) + eps; tz = sin (r) ./ r; mesh (tx, ty, tz); </code> ===== Dobre praktyki ===== * Jeśli tylko jest to możliwe, używaj funkcji wbudowanych. Na przykład zamiast pisać swoją własną funkcję **srednia** lepiej było wykorzystać wbudowaną funkcję **mean**. * Jeśli to tylko możliwe, staraj się wykorzystywać operacje na macierzach, zamiast pętli. * Zawsze definiuj wcześniej wektor/macierz z która pracujesz (chyba że jest ona bezpośrednim wynikiem jakichś operacji). Np.:<code octave>M = zeros(3,3); [x,y] = size(M); for i=1:x for j=1:y M(i,j) = rand; end end</code> ===== Ćwiczenia ===== ==== Operacje podstawowe I==== Zakładając, że mamy następującą macierz $$A = \begin{bmatrix} 16 & 2 & 3 & 13 \\ 5 & 11& 10 & 8 \\ 9 & 7 & 6 & 12 \\ 4 & 14 & 15 & 1 \end{bmatrix}$$ Jakie indeksowanie macierzy A pozwoli na wyciągnięcie z niej następującej macierzy: $$B = \begin{bmatrix} 16 & 2 \\ 5 & 11 \\ 9 & 7 \\ 4 & 14 \end{bmatrix}$$ ==== Operacje podstawowe II==== Napisz funkcję znajdującą najmniejszy i największy element w macierzy i zwracającą te wartości. **Podpowiedź** użyj zbudowanych funkcji //min// i //max//. ==== Wartość wektora ==== Napisz funkcje wyznaczającą długość (normę) wektora podanego jako parametr, która określona jest wzorem: $$|A| = \sqrt{\sum\limits_{i=1}^n a_i^2} $$ ==== Odchylenie standardowe I==== Napisz funkcję wyznaczającą [[http://pl.wikipedia.org/wiki/Odchylenie_standardowe|odchylenie standardowe]] dla wartości wektora podanego jako parametr. Odchylenie standardowe dane jest wzorem: $$\sigma = \sqrt{\frac{\sum\limits_{i=1}^{N} \left(x_{i} - \mu)^{2}} {N-1}}$$ Gdzie $\mu$ to średnia, a N to liczba wszystkich elementów w probie. ==== Odchylenie standardowe II==== Przyjmij, że tym razem parametrem funkcji nie jest wektor, ale macierz. Funkcja powinna obliczyć odchylenia standardowe dla każdego wiersza macierzy osobno i zwrócić wektor odchylen standardowych. **Uwaga** Pamiętaj o zadaniu [[#Operacje_podstawowe_i|Operacje Podstawowe I i II]]! ==== Wydajność I==== Dla funkcji napisanych w poprzednich dwóch zadaniach ([[#dlugosc_wektora|Długość wektora]] oraz [[#odchylenie_standardowe_i|Odchylenie Standardowe I]]) dopisz ich odpowiedniki wektorowe (lub z użyciem pętli) i przetestuj ich działanie na wygenerowanym losowo zbiorze $10^6$ liczb. Aby wygenerować dane użyj:<code octave> data = rand(1,10^6); </code> Porównaj czasy wykonywania funkcji: <code octave> timestart = time(); %Wywolanie funkcji timestop = time(); printf('Czas wykonania to %d sekund.\n',(timestop-timestart)); </code> Jak zmienią się czasy gdy zmienimy ilość danych z $10^6$ na $10^8$? O ile wolniej (procentowo) wykonuje się algorytm wyznaczający odchylenie standardowe wykorzystujący wbudowaną funkcję obliczającą średnią od tego, który wykorzystuje funkcję //srednia// napisaną przez nas? ==== Wydajność II ==== Jak poprawic wydajnośc następujących fragmentów kodu: **Przykład I** <code octave>A = zeros(10,10) v = zeros(10, 1); x = zeros(10, 1); for i = 1:10 for j = 1:10 x(i) = v(i) + A(i, j) * v(j); end end </code> **Przykład II** <code octave> for i = 1:7 for j = 1:7 A(i, j) = log (X(i, j)); B(i, j) = X(i, j) ^ 2; C(i, j) = X(i, j) + 1; D(i, j) = X(i, j) / 4; end end </code> ==== Rysowanie wykresu funkcji ==== Napisz funkcję która będzie wyznaczała wartości funkcji z obrazka poniżej. Wyrysuj wartości tej funkcji na wykresie w przedziale od -10 do 10 z krokiem 0.5. {{:pl:dydaktyka:ml:absfun.png|Wartość bezwzględna}}
pl/dydaktyka/ml/lab1.txt
· ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
Pokaż stronę
Poprzednie wersje
Menadżer multimediów
Do góry