background image

Wprowadzenie do Matlaba 

na przykładach 

 
 

Tomasz Twardowski 

ttward@agh.edu.pl

 

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

 

background image

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 ;-)). 

background image

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; 

background image

>> 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 

background image

>> 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: 

background image

 
       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   

% i = [ od 1 do N co 1 ] (1 to domyślny przyrost) 

t(i)=(i-1)*dt;   

% Wpis na pozycji (i) 

end 
 
% 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); 

background image

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. 
 

0

2

4

6

8

-1

-0.5

0

0.5

1

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); 

 

background image

 
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 

-1

-0.5

0

0.5

1

-1

-0.5

0

0.5

1

Elipsy

sin(t)

si

n(

t+

f)

f=pi/4
f=pi/3
f=pi/2
f=pi

 

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 

1

)

(

1

2

2

2

+

=

y

x

z

, w różnych postaciach. 

 

[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  

background image

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.