Wprowadzenie do Matlaba
Transkrypt
Wprowadzenie do Matlaba
Wprowadzenie do Matlaba na przykładach Tomasz Twardowski [email protected] Kraków 2003 Słowo od Autora Opis powstał jako pomoc dla studentów pracujących na moich zajęciach, co nie wyklucza innego jego użycia. Nie ma być wyczerpującym przeglądem komend Matlaba, raczej ułatwieniem startu w nowym środowisku obliczeniowym. Uczy jak korzystać z systemu pomocy, przybliża podstawowe komendy i struktury języka. W założeniu miał być zwarty i „strawny” w ciągu godziny-dwóch pracy przy komputerze. Sugerowany sposób korzystania z dokumentu to jednoczesne czytanie komentarzy i wykonywanie w Matlabie podawanych przykładów. Dla oszczędności miejsca usunięto puste linie z zapisów sesji interaktywnych. Listingi programów i komunikaty Matlaba są wydrukowane czcionką Times i odmiennie justowane, a używane w tekście symbole Matlaba są podkreślone (jak np. nazwa funkcji disp). Z oszczędności miejsca konsekwentnie stosuję rodzaj męski pisząc o Czytelniku, płeć piękną proszę o wyrozumiałość. Opis ma dobrze służyć jego użytkownikowi, więc jeśli masz jakieś krytyczne i jednocześnie konstruktywne uwagi na temat tego dokumentu to prześlij je na mój adres e-mail. Dodać jeszcze muszę, że wyrażane w tekście opinie są moimi prywatnymi, a nie mojego pracodawcy. Spis treści Kilka pytań i odpowiedzi na początek ..................................................................................2 Taki lepszy kalkulator ............................................................................................................3 Programowanie obliczeń .......................................................................................................5 Prezentacja danych................................................................................................................7 Nowe możliwości....................................................................................................................9 Kilka pytań i odpowiedzi na początek Czym jest Matlab ? Matlab jest środowiskiem (edytor, debugger, okno poleceń, okna wykresów) obliczeniowym z interpreterem specyficznego języka zapisu zadań obliczeniowych. Może pracować w trybie interakcyjnym przez wykonywanie poszczególnych poleceń z linii komend jak i w trybie wsadowym przez wykonywanie instrukcji z pliku (skryptu Matlaba nazywanego m-plikiem). Czym nie jest Matlab ? Matlab nie jest językiem ogólnego przeznaczenia i z tego powodu generowane przez niego aplikacje nie będą konkurencyjne względem efektywnych czasowo języków C++ czy Fortran. Pisanie np. krytycznej czasowo aplikacji sterowania szybkiego obiektu w Matlabie (nawet w wersji skompilowanej) czy gry multimedialnej, chociaż możliwe, nie jest dobrym pomysłem. Którą wersję Matlaba opisuje ten dokument ? Opis dotyczy części wspólnej języka i funkcji dla wersji 4.x, 5.x i 6.x. Prezentowane przykłady były testowane na wersji 4.2. Elementy języka i funkcje wprowadzone w wersjach 5.x i 6.x są opisane w odrębnym rozdziale. Dlaczego Matlab jest taki popularny ? O sile i popularności tego środowiska obliczeniowego decydują zasobne biblioteki gotowych funkcji (toolbox’y) i łatwość poruszania się w środowisku obliczeniowym. Dostępne funkcje pokrywają podstawowe potrzeby obliczeniowe w wielu dziedzinach i mogą być modyfikowane na poziomie kodu źródłowego. Do czego można wykorzystać Matlaba ? Po pierwsze do obliczeń numerycznych na macierzach liczb zespolonych. Po drugie do przedstawiania informacji z obliczeń w postaci wykresów o różnej postaci z możliwością ich eksportowania do edytorów. Po trzecie do jeszcze kilku mniej popularnych, a czasem dziwnych, zastosowań. Czy wynikom obliczeń w Matlabie można ufać ? Biblioteki Matlaba zawierają funkcje pisane w większości przez specjalistów. Niektóre toolbox’y firmują nazwiska znane w dziedzinach specjalistycznych. Nie powinny więc zawierać błędów. Innym problemem jest możliwy w niektórych obliczeniach duży stopień kumulacji niedokładności reprezentacji numerycznej danych. W przypadku takich trudnych zadań obliczeniowych Matlab ostrzega o możliwej niedokładności wyniku. Ograniczone zaufanie do narzędzi i świadomość tego co się próbuje policzyć jest najlepszym wyjściem. Czy kod w Matlabie może współpracować z kodem kompilowanym ? Ze środowiska można wywoływać własne funkcje (w postaci wykonywalnej biblioteki DLL) kompilowane w innych środowiskach programowania (np. VC++). Matlab ma również możliwość kompilowania kodu i tworzenia samodzielnej aplikacji. Skąd wziąć Matlaba ? Jeśli chcesz mieć własną licencję to musisz zaoszczędzić odpowiednią kwotę pieniędzy (dość dużą jeśli wybieramy zestaw z kilkoma toolboxami) i wybrać się do sprzedawcy tego oprogramowania. Ponieważ ten dokument jest przeznaczony dla uczciwych ludzi, inne polecane wyjście to wybranie czegoś tańszego (patrz poniżej). Jeśli nie Matlab to co ? Istnieją inne środowiska obliczeń, jedne ukierunkowane na obliczenia numeryczne (Octave, Scilab, MathCAD), inne na obliczenia symboliczne (Mathematica, Maple). Podobno Octave pod Linuxa jest darmowy i ma składnię zbliżoną do Matlaba. Sam z żadnego z wymienionych nie korzystałem, bo nie mam potrzeby (zatrudnia mnie zamożna instytucja ;-)). Taki lepszy kalkulator Uruchomiłeś Matlaba i widzisz okienko Command Window z podpowiedzią pomocy i znakiem zachęty: To get started, select "MATLAB Help" from the Help menu. >> Bez dużej wiedzy na temat Matlaba możesz prowadzić obliczenia w stylu kalkulatorowym, z użyciem wartości zespolonych, stałych predefiniowanych (jak operator zespolony j i wartość pi) i funkcji (opis dostępny w systemie pomocy jak w przykładzie), np.: >> log10(sqrt(10))*3^4 + real(exp(j*pi/4))*3/4 - sin(pi/2) ans = 40.0303 >> help log10 LOG10 Common (base 10) logarithm. LOG10(X) is the base 10 logarithm of the elements of X. Complex results are produced if X is not positive. See also LOG, LOG2, EXP, LOGM. Jak można zobaczyć w powyższym przykładzie wynik wykonania polecenia jest domyślnie zapisywany do zmiennej ans. Jednak możemy go zapisać do dowolnie nazwanej (poza nazwami już użytymi w środowisku Matlaba) innej zmiennej, bez potrzeby jej deklarowania. Możemy również używać wyników zapamiętanych w zmiennych w dalszych obliczeniach. Zarówno dane do obliczeń jak i wyniki obliczeń mogą być macierzami o dowolnych (ograniczeniem jest rozmiar pamięci) wymiarach. Nazwy i wymiary zdefiniowanych zmiennych możesz odczytać komendą whos. >> T=[1 0 0; 0 0 1; 0 1 0] T= 1 0 0 0 0 1 0 1 0 >> x=[1;2;3] x= 1 2 3 >> x=T*x x= 1 3 2 >> y=x'*x % Komentarz: operator apostrof (’) oznacza transpozycję y= 14 >> whos Name Size Bytes Class T 3x3 72 double array x 3x1 24 double array y 1x1 8 double array Grand total is 13 elements using 104 bytes >> z=y*T; >> z z= 14 0 0 0 0 14 0 14 0 Jak można zauważyć w przedostatnim poleceniu dodanie średnika (;) na końcu wyrażenia powoduje „ciche” przypisanie do zmiennej, bez wypisywania jej wartości na ekranie. W dowolnym momencie możemy poznać zawartość zmiennej wpisując jej nazwę, oczywiście bez średnika, i naciskając Enter (jak w ostatnim poleceniu z przykładu). Średnik spełnia także ważną rolę przy wypełnianiu macierzy wartościami, jak w pierwszych dwóch poleceniach. Sygnalizuje on interpreterowi koniec wiersza macierzy (przejście do nowego wiersza), podczas gdy przecinek i spacja separują wartości w kolejnych kolumnach tego samego wiersza. Matlab sprawdza poprawność formalną wpisywanych poleceń obliczeniowych, w tym zgodność wymiarów macierzy. Macierze mogą być parametrami wywołania większości funkcji, które bądź realizują operacje macierzowe bądź wykonują operację dla każdego elementu macierzy. Rozróżnienie na te dwa typy operacji macierzowych istnieje również dla standardowych operatorów mnożenia, dzielenia i potęgowania, które wykonują operacje macierzowe w wersji standardowej (operatory *, / i ^) lub operacje element przez element w wersji specjalnej (operatory .*, ./ i .^). >> a=[1 2 3; 3 2 1]; >> max(a) ans = 3 2 3 >> b=[1 0 0; 0 1 0; 0 0 1]; >> c=[a; 2 3 1] c= 1 2 3 3 2 1 2 3 1 >> b*a ??? Error using ==> * Inner matrix dimensions must agree. >> c*b ans = 1 2 3 3 2 1 2 3 1 >> c.*b ans = 1 0 0 0 2 0 0 0 1 >> c^2 ans = 13 15 8 11 13 12 13 13 10 >> c.^2 ans = 1 4 9 9 4 1 4 9 1 >> b./c ans = 1.0000 0 0 0 0.5000 0 0 0 1.0000 >> b/c ans = -0.0833 0.5833 -0.3333 -0.0833 -0.4167 0.6667 0.4167 0.0833 -0.3333 Wyniki działania niektórych funkcji macierzowych mogą początkowo dziwić, jak w drugiej linii przykładu funkcja max(). Jednoznacznie działa ona dla wektorów, zwracając wartość maksymalną. Jej zdefiniowane dla macierzy działanie polega na wyznaczeniu wartości maksymalnej z każdej kolumny, i zwróceniu wektora wyznaczonych wartości. Wyznaczenie maksymalnej wartości w macierzy wymaga więc podwójnego wywołania max(max(a)). Programowanie obliczeń Jak już wspomniano, Matlab może interpretować instrukcje zapisane w pliku. Plik taki jest nazywany m-plikiem lub skryptem Matlaba i musi mieć rozszerzenie „.m”. Ponieważ programy więcej niż 3-linijkowe trudno jest obsługiwać w trybie interakcyjnym, m-pliki są często wykorzystywanym rozwiązaniem. Nawet proste obliczenia, które mają być wykonywane warunkowo lub wielokrotnie, wymagają użycia konstrukcji sterujących. Takie konstrukcje językowe to instrukcje warunku (if, switch) i pętli (for, while). Podstawowa instrukcja warunkowa w Matlabie ma postać ogólną: >> help if IF IF statement condition. The general form of the IF statement is IF expression statements ELSEIF expression statements ELSE statements END … Example if I == J A(I,J) = 2; elseif abs(I-J) == 1 A(I,J) = -1; else A(I,J) = 0; end a instrukcja podstawowej pętli: >> help for FOR Repeat statements a specific number of times. The general form of a FOR statement is: FOR variable = expr, statement, ..., statement END … Example FOR I = 1:N, FOR J = 1:N, A(I,J) = 1/(I+J-1); END END FOR S = 1.0: -0.1: 0.0, END steps S with increments of -0.1 FOR E = EYE(N), ... END sets E to the unit N-vectors. Na powyższych listingach pojawiły się dwa nie omawiane dotąd elementy. Pierwszy to indeksowanie elementów w macierzy przez podanie pozycji elementu: A(i,j)=0 oznacza wpisanie wartości 0 na przecięciu wiersza i i kolumny j. Elementy macierzy są w Matlabie indeksowane od 1. Drugi nowy element to wektorowe zadawanie wartości przez podanie wartości początkowej, przyrostu i wartości końcowej (granicznej). W ten sposób polecenie generowania np. wektora osi czasu dla sygnału sinusoidalnego, zamiast postaci rozwlekłej i wolno działającej, można zmieścić w jednej linijce. N=100; % Ilość podprzedziałów osi czasu dt=2*pi/N; % Wersja z pętlą for i=1:N +1 t(i)=(i-1)*dt; end % i = [ od 1 do N co 1 ] (1 to domyślny przyrost) % Wpis na pozycji (i) % Wersja wektorowa t=0:dt:2*pi; % Wersja funkcyjna t=linspace(0,2*pi,N+1); % generuje zadaną ilość równoodległych punktów Opisane dotąd możliwości języka nie pozwalają na pisanie rozbudowanych programów, z powodu niemożności lokalnego zastosowania zmiennych. Możliwość taką, jak w językach ogólnego przeznaczenia, dają funkcje, czyli części kodu operujące w wydzielonej przestrzeni zmiennych, komunikujące się z przestrzenią zewnętrzną przez parametry otrzymane i zwracane. Dzięki własnym funkcjom w Matlabie mamy możliwość rozwijania toolboxów o nowe operacje. Dość krępujące jest ograniczenie do jednej ilości funkcji w jednym pliku, ale wynika to z przyjętego w początkach życia Matlaba sposobu utrzymywania informacji o dostępnych funkcjach. Plik zawierający funkcję musi mieć rozszerzenie „.m” (jak skrypt) i specyficzny nagłówek, czyli pierwszą linię, informujący o parametrach zwracanych i otrzymywanych. Czas na przykład odrobinę bardziej rozbudowanego niż dotąd programu, z pętlami, warunkami, własnymi funkcjami i wywołaniami funkcji z toolboxów. Będzie to przykład obróbki sygnału temperatury dobowej z wyszukiwaniem maksimum, wyznaczaniem przejścia przez zero z aproksymacji wielomianowej, z prostą filtracją zakłóceń i z rysowaniem wykresu. Plik glowny.m lub bezpośrednio w Command Window: clear all; close all; load dane.dat % najpierw trzeba ten plik wygenerować (patrz niżej) czas=dane(:,1); temp=dane(:,2); N=length(czas); [mt,it]=max(temp); disp([‘Maksymalna zarejestrowana temperatura ‘, num2str(mt), ‘ o godzinie ‘, num2str(czas(it))]); % aproksymacja wielomianowa p=polyfit(czas, temp, 5); % Znajdź przejścia temperatury przez 0 r=roots(p); % Wybierz pierwiastki rzeczywiste i leżące wewnątrz przedziału czasu ir = imag(r)==0 & r>=czas(1) & r<=czas(N); if any(ir) disp([‘Temperatura przekroczyła zero w momentach: ‘]); for t=find(ir), disp(r(t)); end end % Przefiltruj sygnał temperatury własną funkcją odszumiającą tempo=odszum(temp); % własna funkcja (patrz niżej) % Przedstaw na wykresie wersję aproksymowaną i odszumioną plot(czas, tempo, ‘r’, czas, polyval(p,czas), ‘g’); % o tym w następnym rozdziale plik odszum.m : function y=odszum(x) N=length(x); % ile wartości w wektorze y(2:N-1)=(x(2:N-1)+x(1:N-2)+x(3:N))/3; % uśrednianie z sąsiadami y([1 N])=x([1 N]); % wartości graniczne bez zmiany plik dane.dat można wygenerować sztucznie zamiast mierzenia sekwencją: t=[0:0.25:24]'; % Od północy do północy % Pogoda w sam raz na marzec, temperatura „mierzona” z małym błędem losowym temp=-cos(2*pi*t/24)*5+0.1*randn(size(t)); ss=[t temp]; save dane.dat ss -ascii Plik z wywoływaną funkcją musi się znajdować na ścieżce znanej Matlabowi, tzn. albo na ścieżce z listy dostępnej przez polecenie path, albo w katalogu bieżącym. Bieżący katalog jest wyświetlany poleceniem pwd, a zmianę katalogu wykonuje polecenie cd nazwa_katalogu. Dobra praktyka to zmiana katalogu na własny katalog roboczy zaraz po rozpoczęciu sesji Matlaba. Listę plików w bieżącym katalogu wyświetla unixowo brzmiące polecenie ls lub dosowo-podobne dir. Prezentacja danych Tradycyjny sposób przedstawiania zależności między danymi to wykres. Ponieważ Matlab nie jest ukierunkowany symbolicznie, dane wejściowe do polecenia rysowania wykresu tworzą wektory wartości. Sprawą użytkownika jest odpowiednie przygotowanie danych. Przykładowe wykresy jednego okresu funkcji sinus w postaci zgrubnej i dużo dokładniejszej wraz z odpowiednimi poleceniami przedstawiono poniżej. x1=0:2*pi/10:2*pi; y1=sin(x1); x2=0:2*pi/100:2*pi; y2=sin(x2); plot(x1,y1,x2,y2); 1 0.5 0 -0.5 -1 0 2 4 6 8 Jak można zauważyć w wywołaniu funkcji rysującej plot, może ona przyjmować wiele zestawów opisujących wykresy. Każda para parametrów wywołania jest na wykresie rysowana innym kolorem. Użytkownik może również przejąć kontrolę nad wyglądem wykresu jak w poniższym bardziej rozbudowanym przykładzie. % przykład rysowania wykresu zadanego parametrycznie N=100; t=0:2*pi/N:2*pi; % generowanie N+1 punktów zmiennej parametrycznej x=sin(t); y1=sin(t+pi/4); y2=sin(t+pi/3); y3=sin(t+pi/2); y4=sin(t+pi); clf; % czyść okno graficzne plot(x,y1,'y'); % rysuj kolorem żółtym (yellow) hold on; % następne rysunki będą dodawane bez kasowania poprzednich plot(x,y2,'r'); % rysuj kolorem czerwonym (red) plot(x,y3,'g'); % rysuj kolorem zielonym (green) plot(x,y4,'bo-'); % rysuj kolorem niebieskim (blue) z kółkami w punktach danych grid on; % narysuj siatkę układu współrzędnych axis('equal'); % równa skala na osiach dla uzyskania poprawnego okręgu legend('f=pi/4', 'f=pi/3', 'f=pi/2', 'f=pi'); title('Elipsy'); xlabel('sin(t)'); ylabel('sin(t+f)'); hold off; % zwolnij rysunek Elipsy f=pi/4 f=pi/3 f=pi/2 f=pi 1 sin(t+f) 0.5 0 -0.5 -1 -1 -0.5 0 sin(t) 0.5 1 Poza podstawową komendą plot istnieje szereg innych specjalizowanych, jak hist, bar, stem, semilogy, loglog. Opis poleceń rysunków dwuwymiarowych podaje komenda help graph2d. Odrębnym zagadnieniem jest przedstawianie wykresów trójwymiarowych, czyli zależności danych od dwu zmiennych. Istnieje kilka sposobów reprezentacji informacji trójwymiarowej, np. poziomice (contour), mapa koloru (pcolor), siatka wartości (mesh) lub powierzchnia (surf). To zagadnienie omówię na przykładzie wykresów funkcji dwu zmiennych z= 1 , w różnych postaciach. (x − y 2 )2 + 1 2 [X,Y]=meshgrid([-3:0.1:3],[-3:0.1:3]); % generuj siatkę wartości dziedziny funkcji Z=1./((X.^2-Y.^2).^2+1); % oblicz wartości funkcji close all; % zamknij okna graficzne % będziemy rysować w pierwszym z czterech układów współrzędnych w jednym oknie subplot(2,2,1); surf(X,Y,Z); % najzwyklejsza powierzchnia z siatką subplot(2,2,2) % drugi układ współrzędnych contour(X,Y,Z); % układ poziomic axis('equal'); subplot(2,2,3); pcolor(X,Y,Z); % mapa koloru (wysokość funkcji oznaczana kolorem) shading('interp'); % włącz wygładzanie „łatek” koloru subplot(2,2,4); surfl(X,Y,Z); % powierzchnia bez siatki z modelem oświetlenia bocznego shading('interp'); view([10 70]); % ustaw kąt widzenia powierzchni: azymut=10, elewacja=70 colormap('hot'); % ustaw używaną mapę koloru (uwaga: ustawiana dla całego okna) Po wklejeniu tego kawałka kodu do Matlaba można podziwiać efekty. Nie zamieszczam ich tutaj, bo zajmują dużo bajtów. Listę innych poleceń związanych z grafiką w trzech wymiarach wypisuje help graph3d. Nowe możliwości Matlab w wersjach 5.x i 6.x został wzbogacony o nowe możliwości programowania. Ponieważ sam korzystam z nich tylko wtedy, kiedy muszę, to ograniczę opis do krótkiego wymienienia tych możliwości z odesłaniem do odpowiedniego hasła systemu pomocy. 1) macierze mogą mieć dowolną ilość wymiarów. Można je tworzyć przez łączenie np. macierzy dwuwymiarowych wzdłuż trzeciego wymiaru. Funkcja wykonująca łączenie to cat. 2) Możliwe jest definiowanie struktur polimorficznych, czyli struktur składających się z danych różnego typu. Przykładowa sekwencja tworząca strukturę: >> s = struct('strings',{{'hello','yes'}},'lengths',[5 3]) s= strings: {'hello' 'yes'} lengths: [5 3] 3) Możliwe jest programowanie obiektowe, tzn. struktury mogą zawierać funkcje, cechy klas obiektów mogą być dziedziczone, operatory i funkcje mogą być przeciążane. Przykład przeciążonej funkcji, tzn. funkcji z wieloma implementacjami wybieranymi do wykonania zależnie od typu danych w wywołaniu, to det. Podobnie rzecz ma się z innymi funkcjami zaimplementowanymi jednocześnie dla danych symbolicznych i numerycznych. 4) Interaktywna grafika z łatwym modyfikowaniem własności wykresów w okienku wykresu. 5) Środowisko programowania z licznymi narzędziami ułatwiającymi pracę, takimi jak Launch Pad, Command History, Workspace, Path Set. 6) Kompilator kodu do C/C++, a dalej w odpowiednim środowisku do EXE. Polecenie mcc. Spośród wymienionych, elementem z którym wcześniej lub później użytkownik będzie się musiał zapoznać są obiekty. Nowe toolboxy lub uaktualnienia dotychczasowych bazują właśnie na obiektach. Polecam do poczytania temat pomocy „Programming and Data Types: MATLAB Classes and Objects” wywoływany z Help Navigator.