[předcházející kapitoly]

9. Maticové funkce

Obrovský potenciál MATLABu spočívá v jeho maticových funkcích. Nejpoužívanější z nich jsou

eigvlastní čísla a vlastní vektory
cholCholeskeho rozklad
svdrozklad podle singulárních hodnot
invinverze
luLU rozklad
qrQR rozklad
hessHessenbergův tvar
schurSchurova dekompozice
rrefViz manuál
expmmocnina matice
sqrtmodmocninová matice
polycharakteristický polynom
detdeterminant
sizerozměr
norm1-norma, 2-norma, F-norma, <infinity>-norma*
condViz manuál
rankhodnost
* Poznámka: <infinity> je symbol pro hodnotu nekonečno, v HTML pro ni zatím není patřičný zápis

Funkce mohou v MATLABu mít jeden nebo více výstupních argumentů, např.

y = eig(A), nebo jednoduše eig(A)

vytvoří sloupcový vektor obsahující vlastní čísla matice A, zatímco

[U,D] = eig(A)

vytvoří matici U, jejíž sloupce jsou vlastní vektory A, a diagonální matici D, která má na diagonále vlastní čísla A. Vyzkoušejte.

10. Příkazový řádek - úpravy a opětovné zadávání příkazů

Příkazový řádek lze v MATLABu editovat velice snadno. Šipkami umístíme kurzor na příslušné místo a použitím kláves Backspace a Delete smažeme nahrazované znaky. Na PC vyzkoušejte funkci kláves Home, End, Delete, jinde viz help cedit nebo type cedit.

Velice užitečná je funkce kláves šipka nahoru a šipka dolů. Umožňují pohyb po zásobníku předchozích příkazů. Lze tedy vyvolat předešlý příkazový řádek, upravit jej a odeslat jako nový příkaz. Tento postup je o mnoho pohodlnější než používání M-souborů, které vyžaduje přesouvání mezi MATLABem a editorem (viz kap. 12 a 14). Například počty operací (viz kap. 15) při počítání inverzních matic různých rozměrů mohou být porovnávány opakovaným voláním, úpravou a prováděním příkazu

a = rand(8); flops(0), inv(a); flops

Pokud bychom chtěli porovnat grafy funkcí y = sin mx a y = sin nx na intervalu [0,2\pi] pro různá m a n, bylo by to možné provést upravováním jednoho příkazového řádku:

m=2; n=3; x=0:.01:2*pi; y=sin(m*x); z=sin(n*x); plot(x,y,x,z)

11. Submatice a dvojtečkový zápis

Vektory a submatice se v MATLABu často používají k dosažení efektů komplexní manipulace s daty. Klíčem k účinné manipulaci s těmito objekty jsou "Dvojtečkový zápis" (který se používá jak pro generování vektorů tak i pro odkazování na submatice) a indexování pomocí vektorů. Jejich využívání dovoluje omezit používání cyklů, které MATLAB zpomalují, a zapsat kód jednoduše a čitelně. Pokuste se vynaložit na seznámení s nimi o něco více námahy.

Výraz 1:5 (již jsme se s ním setkali v příkazu for) je vlastně řádkový vektor [1 2 3 4 5]. Čísla nemusí být celá a posloupnost rostoucí, například

0.2:0.2:1.2

dává [0.2, 0.4, 0.6, 0.8, 1.0, 1.2], a

5:-1:1

dává [5 4 3 2 1]. Následující příkazy např. vytvoří tabulku hodnot funkce sinus. Vyzkoušejte.

x = [0.0:0.1:2.0]';
y = sin(x);
[x y]

Protože se funkce sin aplikuje po složkách, je výsledkem vektor y vytvořený z vektoru x.

Dvojtečkový zápis lze použít jako odkaz na submatici matice (indexování). Například

A(1:4,3)

je sloupcový vektor skládající se z prvních čtyř prvků třetího sloupce matice A. Samotná dvojtečka znamená celý řádek nebo sloupec:

A(:,3)

je třetí sloupec A a A(1:4,:) značí první čtyři řádky. Libovolný celočíselný vektor lze použít jako index:

A(:,[2 4])

obsahuje (jako sloupce) druhý a čtvrtý sloupec A. Takovéto indexování je dovoleno na obou stranách přiřazovacího příkazu:

A(:,[2 4 5]) = B(:,1:3)

nahradí 2., 4. a 5. sloupec matice A prvními třemi sloupci matice B. Nezapomeňte, že přiřazena a zobrazena je celá pozměněná matice A Vyzkoušejte.

2. a 4. sloupec matice A lze zprava vynásobit maticí [1 2;3 4] (matice 2x2):

A(:,[2,4]) = A(:,[2,4])*[1 2;3 4]

Přiřazena (do A) a zobrazena je opět celá pozměněná matice.

Co se stane po zadání příkazu x = x(n:-1:1), je-li x n-složkový vektor? Vyzkoušejte.

Tyto funkce oceníte zejména pokud příkazy MATLABu porovnáte se zápisem stejné operace v Pascalu, Fortranu nebo C.

12. M-soubory

MATLAB umožňuje provést posloupnost příkazů uložených v souborech na disku. Tyto soubory se nazývají "M-soubory", protože musí být typu ".m". Podstatná část Vaší práce v MATLABu bude tvorba a ladění M-souborů.

Existují dva typy M-souborů: skriptové soubory a funkční soubory.

Skriptové soubory. Skriptový soubor se skládá z posloupnosti běžných MATLABovských příkazů. Má-li např. jméno rotate.m, pak příkaz rotate v MATLABu způsobí provedení příkazů obsažených v souboru. Proměnné ve skriptovém souboru jsou chápány jako globální a vždy změní hodnotu proměnných se stejným jménem, které byly definovány lokálně během práce v MATLABu.

Skriptové soubory se obvykle používají k zadávání dat do rozsáhlých matic. V souboru lze totiž chyby opravit lépe než při přímém zadávání. Je-li např. na disku soubor data.m obsahující

A = [
1 2 3 4
5 6 7 8
];

pak MATLABovský příkaz data provede přiřazení zadané v data.m.

M-soubor může obsahovat odkazy na jiné M-soubory včetně rekurzivního odkazu na sebe sama.

Funkční soubory. Funkční soubory vnášejí do MATLABu pružnost a přizpůsobivot. Můžete si vytvořit nové, vlastní funkce specielně pro Váš problém, které potom budou mít stejné postavení, jako běžné funkce v MATLABu. Proměnné jsou ve funkčních souborech standartně lokální, avšak od verze 4.0 je povoleno definovat proměnnou jako globální.

Pro ilustraci si uveďme krátký příklad funkčního souboru.

function a = randint(m,n)
%RANDINT Randomly generated integral matrix.
% randint(m,n) returns an m-by-n such matrix with entries
% between 0 and 9.
a = floor(10*rand(m,n));

Obecnější zápis této funkce by vypadal:

function a = randint(m,n,a,b)
%RANDINT Randomly generated integral matrix.
% randint(m,n) returns an m-by-n such matrix with entries
% between 0 and 9.
% rand(m,n,a,b) return entries between integers a and b.
if nargin < 3, a = 0, b = 9; end
a = floor((b-a+1)*rand(m,n)) + a;

Toto by na disku mělo být uloženo v souboru randint.m (aby jméno souboru odpovídalo jménu funkce). První řádek obsahuje deklaraci jména funkce a vstupních a výstupních argumentů. Bez této řádky by soubor byl pouze souborem skriptovým. Příkaz

z = randint(4,5),

potom například způsobí, že čísla 4 a 5 budou uložena do proměnných m a n ve funkčním souboru a výsledek se vloží do proměnné z. Jelikož proměnné ve funkčním souboru jsou lokální, jsou jejich názvy nezávislé na názvech proměnných definovaných z příkazové řádky při práci v MATLABu

Poznámka: Použití nargin ("number of input arguments (počet vstupních argumentů)") dovoluje předdefinovat hodnotu vstupního argumentu, který nebyl zadán -- stejně jako a a b v příkladu výše.

Funkce může také mít více výstupních argumentů, například:

function [mean, stdev] = stat(x)
% STAT Mean and standard deviation
% For a vector x, stat(x) returns the
% mean and standard deviation of x.
% For a matrix x, stat(x) returns two row vectors containing,
% respectively, the mean and standard deviation of each column.
[m n] = size(x);
if m == 1
m = n; % handle case of a row vector
end
mean = sum(x)/m;
stdev = sqrt(sum(x.^2)/m - mean.^2);

Je-li toto umístěno v souboru stat.m, provede např. příkaz [xm, xd] = stat(x) přiřazení průměru a standartní odchylky vstupních dat (z vektoru x) do proměnných xm a xd. Lze také provést pouze jedno přiřazení i u funkce, která má více výstupních argumentů. Například xm = stat(x) (okolo xm nemusí být závorky) přiřadí průměr x do xm.

Symbol % znamená, že zbytek řádku je komentář. MATLAB zbytek řádku ignoruje. Několik prvních řádků s komentářem, které popisují M-soubor, bychom do funkčního souboru vždy měli napsat. Jsou přístupné např. pro on-line hlep a zobrazí se např zadáním help stat.

Tato funkce ilustruje některé z nástrojů MATLABu, které lze použít ke konstrukci efektivního kódu. Při zápisu pozor na technické problémy, např. že x.^2 je matice druhých mocnin prvků x, že sum je vektorová funkce (kap.8), že sqrt je skalární funkce (kap. 7) a že dělení v sum(x)/m je maticově-skalární operace.

Následující funkce, která počítá největší společný dělitel dvou celých čísel Eukleidovým algoritmem, je příkladem na použití chybových hlášení (viz příští kapitola).

function a = gcd(a,b)
% GCD Greatest common divisor
% gcd(a,b) is the greatest common divisor of
% the integers a and b, not both zero.
a = round(abs(a)); b = round(abs(b));
if a == 0 & b == 0
error('Nejv. spol. dělitel není definován, jsou-li obě čísla rovna nule.')
else
while b ~= 0
r = rem(a,b)
a = b; b = r;
end
end

Některé vyšší nástroje jsou předvedeny v následující funkci. Připomínáme, že některé ze vstupních argumentů funkce -- jako např. tol v ukázce, mohou být předdefinovány použitím nargin. Podobným způsobem může být použita proměnná nargout. Pozor na to, že relace je číslo (1 pro true, 0 pro false) a že příkazy while nebo if vyhodnotí relaci "nenula" znamená "true" a 0 znamená "false". Konečně MATLABovská funkce feval dovoluje použít jako vstupní proměnnou řetězec (string) odkazující na jinou funkci.

function [b, steps] = bisect(fun, x, tol)
%BISECT Zero of a function of one variable via the bisection method.
% bisect(fun,x) returns a zero of the function. fun is a string
% containing the name of a real-valued function of a single
% real variable; ordinarily functions are defined in M-files.
% x is a starting guess. The value returned is near a point
% where fun changes sign. For example,
% bisect('sin',3) is pi. Note the quotes around sin.
%
% An optional third input argument sets a tolerence for the
% relative accuracy of the result. The default is eps.
% An optional second output argument gives a matrix containing a
% trace of the steps; the rows are of form [c f(c)].
 
% Initialization
if nargin < 3, tol = eps; end
trace = (nargout == 2);
if x ~= 0, dx = x/20; else, dx = 1/20; end
a = x - dx; fa = feval(fun,a);
b = x + dx; fb = feval(fun,b);
 
% Find change of sign.
while (fa > 0) == (fb > 0)
dx = 2.0*dx;
a = x - dx; fa = feval(fun,a);
if (fa > 0) ~= (fb > 0), break, end
b = x + dx; fb = feval(fun,b);
end
if trace, steps = [a fa; b fb] end
 
% Main loop
while abs(b - a) > 2.0*tol*max(abs(b),1.0)
c = a + 0.5*(b - a); fc = feval(fun,c);
if trace, steps = [steps; [c fc]];
if (fb > 0) == (fc > 0)
b = c; fb = fc;
else
a = c; fa = fc;
end
end

Některé z MATLABovských funkcí jsou vestavěny, zatímco ostatní jsou distribuovány jako M-soubory. Kód jakéhokoli M-souboru (MATLABovského nebo Vašeho vlastního) lze prohlížet zadáním příkazu type jméno funkce. Vyzkoušejte zadat type eig, type vander a type rank.

13. Textové řetězce, chybová hlášení, input

Textové řetězce se v MATLABu zadávají obklopeny apostrofy. Například

s = 'This is a test'

přiřadí zadaný text do proměnné s.

Textové řetězce mohou být zobrazeny funkcí disp. Například:

disp('this message is hereby displayed')

Chybová hlášení je nejlepší zobrazovat pomocí funkce error,

error('Sorry, the matrix must be symmetric')

neboť je-li takto zapsáno v M-souboru, způsobí ukončení jeho činnosti.

Z M-souboru může být uživatel interaktivně požádán, aby zadal data, funkcí input. Když se například provádí příkaz

iter = input('Enter the number of iterations: ')
,

zobrazí se žádost o data (zde počet iterací) a do doby, než uživatel data zadá, je provádění výpočtu pozastaveno. Po stisku klávesy Enter (Return) jsou data přiřazena do proměnné iter a výpočet pokračuje.

14. Dočasná práce s M-soubory

Při práci s MATLABem je často třeba vytvořit nebo upravit nějaký M-soubor a pak se vrátit zpátky do MATLABu. Během editace M-souboru by však MATLAB měl zůstat spuštěný, protože jinak bychom při jeho ukončení ztratili všechny proměnné.

To lze jednoduše zařídit použitím znaku !. Jste-li v MATLABu a napíšete před jakýmkoli systémovým příkazem (editace, kopírování, tisk...) znak !, můžete tento příkaz provést, aniž byste ukončili MATLAB. Je-li např. příkaz ed příkazem pro spuštění editoru, pak v MATLABu zadaný příkaz

>> !ed rotate.m

umožní upravit soubor rotate.m ve Vašem textovém editoru. Po skončení práce v editoru se vrátíte do MATLABu do okamžiku, kdy jste jej opustili.

Jak již bylo poznamenáno v kapitole 1, v systémech s podporou více procesů (např. Unix) se vyplatí ponechat spuštěný MATLAB i editor. Zatímco v jednom procesu pracujeme, je druhý suspendován. Pokud mohou být tyto procesy otevřeny v různých oknech, ponechte v jednom otevřený MATLAB a ve druhém editor.

Pro podrobnější informace o Vašem systému a o lokální instalaci kontaktujte Vašeho správce.

Verze 4.0 obsahuje mnoho odlaďovacích nástrojů. Viz help dbtype a zde uvedené odkazy.

Jste-li v MATLABu, pak příkaz dir vypíše obsah aktuálního adresáře, zatímco příkaz what zobrazí pouze seznam M-souborů uložených v aktuálním adresáři. Příkazy delete a type lze použít ke smazání souboru z disku a k vypsání souboru na obrazovku, příkazem chdir lze změnit aktuální adresář. Tyto příkazy mohou nahradit systémové příkazy, ale nevyžadují použití !.

M-soubor musí být pro MATLAB dostupný. Soukromé M-soubory jsou většinou uloženy v podadresáři s názvem matlab v domovském adresáři uživatele a jsou tak pro MATLAB dostupné z jakéhokoli pracovního adresáře. Další informace viz manuál - kapitola MATLABPATH.

15. Porovnávání efektivity algoritmů, efektivní čas

Pro efektivitu algoritmu existují dvě kritéria. Počet vykonaných operací a čas, který uběhl od zahájení výpočtu.

MATLABovská funkce flops uchovává průběžně počet vykonaných operací. Příkaz flops(0) (ne flops = 0!) její hodnotu anuluje. Zadáme-li tedy flops(0) bezprostředně před zahájením běhu algoritmu a flops bezprostředně po jeho ukončení, udává hodnota počet vykonaných operací pro tento algoritmus.

MATLABovská funkce clock udává aktuální čas s přesností na setiny sekund (viz help clock). Máme-li dva časy, t1 a t2, pak etime(t2,t1) udává čas, který uběhl od t1 do t2. Dá se tedy např. změřit čas potřebný k vyřešení dané soustavy lineárních rovnic A x = b Gaussovou eliminací, a to následovně:

t = clock; x = A\b; time = etime(clock,t)

Chtěli byste porovnat toto číslo a počet vykonaných operací při řešení stejné soustavy vzorcem x = inv(A)*b;? Vyzkoušejte. Verze 4.0 obsahuje výhodnější tic a toc.

Je nutno poznamenat, že etime nemusí být objektivní kritérium na počítačích, které umožňují sdílení času. Zde totiž čas potřebný k provedení algoritmu závisí na momentální celkové vytíženosti počítače.

16. Formát výstupu

Formát zobrazovaných výsledků lze v MATLABu ovlivnit následujícími příkazy:

format shortzobrazení na 4 desetinná místa (default)
format longzobrazení na 14 desetinných míst
format short escient. zápis na 4 des. místa
format long escient. zápis na 15 des. mist

Vybraný formát je pro výstupy uplatňován až do té doby, kdy je změněn na jiný.

Příkaz format compact zabraňuje zobrazování zbytečných prázdných řádků a tím dovoluje zahustit zápis informací na obrazovce. Jeho použití nezávisí na žádném jiném příkazu format.

17. Hardcopy

Hardcopy nejsnáze vyvoláme příkazem diary. Příkazem

diary jméno souboru

se zahájí zápis do diskového souboru daného jména, pokud jméno není uvedeno, vytvoří se automaticky soubor s názvem diary). Zapisováno je vše, co se objeví na obrazovce (kromě grafiky), a to zž do té doby, kdy zadáme příkaz diary off; příkaz diary on vyvolá pokračování přerušeného zápisu. Po ukončení práce lze tento soubor upravovat, tisknout atd. dle libosti buď ze systému nebo přímo z MATLABu použitím znaku ! (viz kap. 14).

18. Grafika

V MATLABu je možné zobrazovat jak rovinné, tak i 3-D (síťové) grafy. Příkazem plotdemo si můžete prohlédnout ukázky některých grafických funkcí.

Rovinné grafy. Příkaz plot vytváří grafy závislosti x a y; jsou-li x a y vektory o stejné délce, pak plot(x,y) otevře grafické okno a vykreslí x-y graf (jako prvky x versus prvky y). Například graf funkce sinus na intervalu od -4 do 4 lze získat pomocí příkazů:

x = -4:.01:4; y = sin(x); plot(x,y)

Vyzkoušejte. Vektor x je chápán jako část definičního oboru, 0.1 je zvolený krok a y je vektor udávající hodnoty funkce sinus ve zvolených bodech (krok 0,1), protože funkce sin aplikovaná na vektor působí po složkách.

Jste-li v grafickém modu, můžete se stiskem libovolné klávesy vrátit zpět na příkazový řádek MATLABu. Naopak příkaz shg (show graph = zobraz graf) vrátí aktuální grafickou obrazovku. Pokud Váš počítač podporuje víceokenní umisťování procesů se zvláštním grafickým oknem, je výhodné ponechat grafické okno otevřené někde po straně obrazovky.

Jako druhý příklad si můžete nakreslit graf funkce y = e^(-x^2) na intervalu od -1.5 do 1.5 :

x = -1.5:.01:1.5; y = exp(-x.^2); plot(x,y)

Poznámka: Raději před znak ^ připište tečku. Budete mít jistotu, že umocnění skutečně proběhne po složkách (viz kap. 3).

Lze vykreslit i grafy parametrizovaných křivek, vyzkoušejte např.

t=0:.001:2*pi; x=cos(3*t); y=sin(2*t); plot(x,y)

Příkaz grid přikreslí do grafu čtvercovou síť.

Ke grafům lze samozřejmě připojit titulky, popisky os a je možné přidat i text přímo do grafu. Slouží k tomu následující příkazy (všechny mají jako argument řetězec (string)).

titletitulek grafu
xlabelpopis osy x
ylabelpopis osy y
gtextinteraktivně vkládaný text
textumístění textu na zadané souřadnice

Například příkaz

title('Best Least Squares Fit')

vyrobí ke grafu titulek, příkaz gtext('The Spot') umožní vybrat (myší, šipkami) místo, kam se daný text umístí po stisku nějaké jiné klávesy.

Předdefinované nastavení pro osy je takové, že se měřitko volí automaticky. To lze změnit příkazem axis. Je-li c = [xmin,xmax,ymin,ymax] čtyřprvkový vektor, pak axis(c) nastaví měřítko tak, jak je předepsáno v c. Samotné axis zmrazí aktuální nastavení pro všechny další grafy do odvolání, zadáme-li axis ještě jednou potom, vrátí původní nastavení na automatické měřítko. Příkaz axis('square') zajistí, že na obou osách bude použito stejné měřítko. Ve verzi 4.0 byl význam axis zásadně pozměněn, viz help axis.

Dvě možnosti, jak vykreslit dva grafy do jednoho obrázku si ukážeme na příkladě

x=0:.01:2*pi;y1=sin(x);y2=sin(2*x);y3=sin(4*x);plot(x,y1,x,y2,x,y3)

a při sestavování matice Y, která jako sloupce obsahuje funkční hodnoty.

x=0:.01:2*pi; Y=[sin(x)', sin(2*x)', sin(4*x)']; plot(x,Y)

Jiný způsob je hold. Příkaz hold zmrazí aktuální grafickou obrazovku a všechny následující grafické výstupy do ní přikresluje. Opětovné zadání příkazu hold ruší příkaz "hold" původní. Ve verzi 4.0 lze použít i příkazy hold on a hold off. Je možné měnit i předdefinované nastavení typů čar a způsob vykreslování bodů, např.

x=0:.01:2*pi; y1=sin(x); y2=sin(2*x); y3=sin(4*x); plot(x,y1,'--',x,y2,':',x,y3,'+')

vrátí na výstupu první graf čárkovaně, druhý tečkovaně a třetí jen jako bodový - na každém bodě zobrazí +. Druhy čar a znaků pro grafiku jsou:

Čáry: plná (-), čárkovaná (--) tečkovaná (:) a čerchovaná (-.)
Znaky: bod (.), plus (+), hvězdička (*), kroužek (o) a křížek ( písmeno x) (x)

Pro nastavení barev viz help plot.

Pro zobrazení grafu jen do části graf. obrazovky lze použít příkaz subplot a prohlížet tak až 4 grafy najednou. Viz help subplot.

Uložení - kopie grafiky

Pozn. překladatele: V originále následuje složitý popis ukládání a tisku grafického výstupu. V novějších verzích MATLABu však stačí zvolit vhodné uložení grafiky v menu a uložený soubor potom upravit nebo odeslat na tiskárnu.

3-D grafika. Trojdimenzionální síťové grafy jsou kresleny funkcí mesh. Příkaz mesh(z) vykreslí trojdimenzoinální perspektivní zobrazení prvků matice z. Potah sítě je definován pomocí z-souřadnic bodů nad pravoúhlou rovinou x-y. Vyzkoušejte mesh(eye(10)).

Chceme-li vykreslit graf funkce z = f(x,y) na obdélníku, musíme nejprve definovat vektory xx a yy, které budou udávat dělení stran obdélníka. Funkcí meshdom (mesh domain; ve verzi 4.0 meshgrid) se potom vytvoří matice x, Každý její řádek je roven xx a délka jejího sloupce je rovna yy. Podobně se vytvoří matice y, jejíž každý sloupec je roven yy. Příkaz:

[x,y] = meshdom(xx,yy);

Dále se spočítá matice z, tu získáme vypočtením hodnot funkce f po složkách přes matice x a y. Na tuto matici z již lze aplikovat funkci mesh.

Například graf funkce z = e^(-x^2-y^2) nad čtvercem [-2,2] x [-2,2] můžete nakreslit takto (vyzkoušejte):

xx = -2:.1:2;
yy = xx;
[x,y] = meshdom(xx,yy);
z = exp(-x.^2 - y.^2);
mesh(z)

První tři řádky kódu lze samozřejmě nahradit zápisem

[x,y] = meshdom(-2:.1:2, -2:.1:2);

Další informace týkající se mesh viz manuál.

Ve verzi 4.0 se možnosti MATLABu pro 3-D grafiku výrazně rozšířily, viz on-line help k příkazům plot3, mesh a surf.

[pokračovat další kapitolou]
[návrat na obsah]