3. diel - Práca s maticami a vektormi
Spôsob práce s vektormi a maticami v MATLAB je natoľko zásadný tému, že je rozdelené do troch lekcií. Informácie v jednotlivých častiach sa prekrývajú a zakaždým sú podané trochu iným spôsobom. Umožní tak nahliadnuť do problematiky z rôznych uhlov.
V tejto časti si vysvetlíme indexovanie a prácu s bunkami. Druhá časť sa dopodrobna zaoberá tvorbou vektorov, prístupom k jednotlivým prvkom a ich filtrovaním. Podobné témy sú vysvetlené v tretej časti, len s pomocou matíc a na praktické ukážke úpravy fotografie.
Indexovanie v MATLAB
Pre začiatočníkov - index je jednoznačná pozícia hodnoty v poli, v našom prípade v matici, a je teda reprezentovaný pozíciou na riadku a v stĺpci.
Pre tých už pobozkané múzou programovacích jazykov je v MATLABe veľký rozdiel v zápise indexácie. V céčkových jazykoch sa pre zápis indexov používajú hranaté zátvorky, avšak v MATLAB sa na indexovanie používajú zátvorky guľaté a alebo tiež zložené. Rozdiel je popísaný nižšie.
Indexovanie v maticiach a vektoroch
Pre indexovanie v maticiach sa používajú okrúhle zátvorky. V prípade matíc sa uvádza do zátvoriek vždy čísla v poradí riadok, stĺpec, vrstva, rozměr4, ... Ak sa jedná o vektor, stačí do zátvoriek uviesť iba jedno číslo.
M = [1, 2, 3; 4, 5, 6; 7, 8, 9]; V = [10, 20, 30]; M(2,3) V(2)
Výstupom budú hodnota 6
pre maticu M
a
hodnota 20
pre vektor V
.
Bunky (cells)
Bunky sú špeciálnymi maticami, ktoré v sebe dokážu niesť hodnoty rôznych dátových typov. Ovšem najčastejšie sa s nimi v MATLABe človek stretne pri práci s vektormi textových reťazcov. Keďže je textový reťazec vektor znakov, nie je možné vytvoriť súvislú maticu reťazcov o pevne daných rozmeroch, pretože by inak museli všetky reťazce mať rovnakú dĺžku. Avšak keby dĺžka bola rovnaká, vytvorila by sa nám matica znakov, ale nie matice reťazcov.
Bunka sa definuje podobne ako matice s tým rozdielom, že sa namiesto zátvoriek používajú zátvorky zložené. Potom už pravidlá pre riadky a stĺpce platia rovnaké. Hodnoty v stĺpcoch sú oddelené medzerou alebo čiarkou a hodnoty na riadkoch sú oddelené bodkočiarkami.
M = ['abcd'; 'efgh']; % Matice znaků C = {'Ahoj'; 'Nazdar'}; % Buňka s textovými řetězci různých délek D = {'Ahoj', 2; .5, true}; % Buňka s různými datovými typy
Indexovanie v bunkách (cells)
Pri indexovanie buniek sa používajú ako zátvorky okrúhle, tak zátvorky zložené, avšak potom už je indexácia opäť rovnaká ako u matíc. Rozdielom je návratová hodnota po indexácii.
Ak budeme indexovať v okrúhlych zátvorkách, bude nám vrátená opäť bunka. Ak budeme indexovať v zložených zátvorkách, bude navrátená hodnota v dátovom typu uloženom v bunke na danom indexe.
A to je veľmi značný rozdiel, pretože ak by sme chceli napríklad
pracovať s hodnotou 2
, z bunky D
(uvedené vyššie),
tak pri indexácii pomocou okrúhlych zátvoriek dostaneme novú bunku
obsahujúcu len hodnotu 2
, ale nejedná sa o číslo
2
. Museli by sme znovu použiť indexáciu so zloženými
zátvorkami. V prípade buniek môžeme zapisovať aj vnorená indexovanie.
Napríklad, ak by sme chceli prvý znak textového reťazca v druhom riadku
bunky C
(pozri posledný riadok kódu nižšie):
M(2,3) % Výstupem bude znak 'g' C{1} % Výstupem bude řetězec (vektor) znaků 'Ahoj' D(1,2) % Výstupem bude nová buňka obsahující číslo 2 2 * D(1,2) % Řádek nám vyvolá chybu, protože nemůžeme násobit buňku 2 * D{1,2} % Tento řádek už nám ovšem navrátí číslo 4 C{2}(1) % Výstupem bude znak 'N'
Dynamické indexovanie
Dynamické indexovanie pravdepodobne nie je oficiálny termín pre to, čo hodláme popisovať, ale tento termín v spojení s nasledujúcimi vlastnosťami MATLABe osobne používam a myslím, že je najvýstižnejšie.
V systéme MATLAB totiž nemusíme indexovať len pre získanie jednej konkrétnej hodnoty, ale je možné nechať si navrátiť rozsah hodnôt podľa indexov, teda vektor alebo maticu. Tento princíp platí pre všetky polia v MATLAB, či už ide o vektory, matice či bunky.
Binárne (logická) matice
Než sa do toho pustíme, tak tu pre lepšie pochopenie ešte uvedieme
termín binárne matice, čiže matice obsahujúci iba logickej hodnoty
1
alebo 0
(platí alebo neplatí, aneb true alebo
false). Tieto matice je možné vytvoriť nespočetne spôsobmi. Niektoré z
nich si uvedieme.
- Pomocou funkcie
true()
alebo funkciafalse()
(ďalšie detaily parametrov v nápovede F1). Tieto funkcie navracia binárne matice buď plnej jednotiek (funkciatrue()
) alebo núl:
true(2,2) % Matice 2x2 plná logických jedniček false(5,3) % Matice 5x3 plná logických nul
- Pomocou cyklov
for
awhile
(cykly preberieme podrobne v ďalšej lekcii), kedy prechádzame jednotlivé indexy matice a nastavujeme ich hodnotu:
for a = 1 : 4 A(a) = false; end % Výstupem bude matice 1x4 (vektor) plný logických nul
- Výstupy podmienok. Toto je asi jeden z najväčších Meisterstück MATLABu. Pretože nemusíme prechádzať hodnotu po hodnote, ale jedným príkazom získame binárne maticu spĺňajúce danú podmienku. Navyše o tejto funkcii veľa užívateľov MATLABe väčšinou ani nevie:
V = [10, 20, 30]; A = V >= 20 % Ukládám výsledky podmínky do matice A
Matica A
bude o rovnakých rozmeroch, ako sú rozmery matice
V
s tým, že hodnota na danom indexe matice A
bude
výsledok dané podmienky pre hodnotu na indexu matice V
. V tomto
prípade bude výsledok vektor s hodnotami 0
, 1
,
1
.
Implementácia dynamického indexovanie
Dynamicky indexovať môžeme dvoma spôsobmi:
- Vektorom indexov (Vektor obsahujúci čísla indexov)
- Maskovaním indexov (Použitím binárne matice)
Pomocou vektora indexov môžeme získať novú maticu (napr. Pri spracovaní obrazu získame iba oblasť záujmu):
M = [1, 2, 3; 4, 5, 6; 7, 8, 9] N = M(1:2, 2:3) N = M([1, 2], [2, 3]) O = M(:, [1,3]) P = M(end, [1,3])
Pre maticu N
definujeme, že chceme 1. až 2. riadok a 2. až 3.
stĺpec. Sú tu pre lepšie pochopenie uvedené dva zápisy, ktoré sú úplne
rovnaké (Rozdiel je len v definícii vektora).
U definície matice O
sa nám objavuje "nový" znak a tým je
dvojbodka. Tá totiž pri indexácii znamená všetko.
Výsledkom teda budú všetky riadky pre 1. a 3. stĺpec matice
M
.
U definície matice P
sa nám objavuje pre zmenu nové slovo a
tým je end
, ktoré pri indexácii znamená
posledný. Výsledkom teda bude posledný riadok pre 1. a 3.
stĺpec matice M
.
výstup:
M = 1 2 3 4 5 6 7 8 9 N = 2 3 5 6 O = 1 3 4 6 7 9 P = 7 9
Pomocou maskovanie môžeme jednoducho prejsť a prípadne zmeniť všetky hodnoty v danej matici. Princíp je jednoduchý. Dosadíme do indexu logickú maticu o rovnakých rozmeroch ako je ovplyvňovaná matice a tam, kde je logická jednička, sa vykoná žiadaná zmena:
M = [1, 2, 3; 4, 5, 6; 7, 8, 9] B = mod(M, 2) == 0 M(B) = 0 % Rovnocenný zápis: M(mod(M, 2) == 0) = 0
V tomto prípade zisťujeme, či je zvyšok po delení (operácia modulo)
nulový, teda, či sa jedná o párne číslo. Ak áno, tak sa v binárnej
maticu B
zapíše na danej pozícii logická jednička. Potom túto
binárne maticu dosadíme ako index do matice M
a vykonáme
požadovanú operáciu. V kóde vyššie je to vynulovanie hodnoty. Toto sa dá
použiť napr. Pre prahovanie pri spracovaní obrazu:
výstup:
M = 1 2 3 4 5 6 7 8 9 B = 0 1 0 1 0 1 0 1 0 M = 1 0 3 0 5 0 7 0 9