IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

5. diel - Cykly a maticový prístup v MATLAB

Podmienky a cykly sú základný stavebný prvok rozvetveného programu. Cykly majú v MATLAB miesto zľahka na okraji a možno trochu prekvapivou syntax i funkcionalitu. Koncepčne sa MATLAB celkom líši od C-like jazykov a zrovna prístup k cyklom zastáva peknú ukážkou.

Aj napriek tomu, že je tento článok o cykloch, všeobecné odporúčanie v MATLAB je snaha o maticové riešení. Povieme si prečo a na konci predstavíme zopár príkladov, ako to docieliť.

Maticový prístup vs. cykly

Ako bolo spomenuté v lekciách o maticiach a vektoroch, MATLAB je prispôsobený práve na prácu s nimi. Väčšina funkcií, ktorými prostredia disponuje, je prispôsobené tak, aby vstupným parametrom mohla byť práve matice alebo viacrozmerný vektor. S tým počítajú aj samotné operátormi, takže ak máme vektor (v iných jazykoch hovoríme o poli) v a chceme všetky jeho hodnoty deliť 3 a odpočítať dvojku, urobíme to jedným riadkom:

v = [1 2 3 4 5 6 7];
v2 = v/3-2;

For cyklus

For cyklus, ktorý robí ekvivalentný operáciu, bude vyzerať nasledovne:

for ii = length(v)
    v3(ii) = v(ii) / 3 - 2;
end

Takýto zápis je zbytočné zdĺhavý a vo finále je kód neefektívne. Avšak vidíme, ako sa for cyklus v MATLAB konštruuje.

Syntaxe for cyklu

Cyklus začína kľúčovým slovom for a uzatvára sa univerzálnym kľúčovým slovom end (to funguje aj u if, while a funkcií). To zaujímavé a trochu netradičné je spôsob, akým definujeme jednotlivé priechody cyklom. Prekvapenie - je to s pomocou vektora. Tým, čo je za kľúčovým slovom for, hovoríme: "vezmi vektor od jednotky do sedmičky (to je dĺžka vektora v) a každý jeho index pri jednotlivých priechodoch priraď do premennej ii ".

Prvky vektora, ktoré sú postupne priradené do ii, vôbec nemusíme definovať u kľúčového slova for. Ak by sme chceli upraviť pomocou for cyklu iba druhý, tretí a piaty prvok vektora v, mohli by sme to urobiť takto zápisom:

v4 = v; % nakopirovani hodnot
for ii = [2, 3, 5]
    v4(ii) = v4(ii) / 3 - 2;
end
% reseni bez cyklu
v4 = v;
v4([2, 3, 5]) = v4([2, 3, 5]) / 3 - 2;

Po cykle je uvedené aj riešenie bez neho. Ako už bolo povedané na začiatku, cyklom sa v takýchto prípadoch skôr snažíme vyhnúť, a preto je tu uvedené i správnejšie riešenie.

Ukážka definícií for cyklov

Pre ukážku si tu uvedieme niekoľko spôsobov, ako napísať definícii for cyklu. Ako už bolo spomenuté - ide predovšetkým o to, ako definovať vektor, čo je podrobne popísané v jednej z predchádzajúcich lekcií.

for ii = 9:-1:-9
end % od 9 sestupne k -9

for ii = linspace(2,23,101)
end %interval od 2 do 23 ve 101 prvcich

for ii = 0:1e-3:1
end % od 0 do 1 po 1 tisicine

for ii = randi(100,30)
end %30 nahodnych cisel od 1 do 100

Dvojité ii vs. i

Iteratívny premenná v cykle je pomenovaná ako dvojité ii namiesto obvyklého jedného. Dôvod je obsadenosť premenné i, ktoré je v MATLAB priradené komplexné číslo s reálnou časťou 0 a komplexné 1. Môžete to vyskúšať, ak do command window napíšete práve i:

i
ans = 0.0000 + 1.0000i

Použijete - ak v cykle i, nič závažné sa nestane, i sa iba predefinuje. Ak však v takomto cykle budete chcieť použiť komplexné číslo, tak týmto spôsobom nemôžete. Odporúčanie je nechodiť chybám naproti a radšej použiť iný názov premennej.

While cyklus

Cyklus while beží, keď je splnená podmienka v jeho definícii. Definícia sa uvádza za kľúčové slovo while a celý cyklus sa uzatvára pomocou end:

ii = 0;
while (ii < 5)
    disp(ii);
    ii = ii + 1;
end

Nekonečný cyklus, ktorý sa nás neustále bude pýtať na číslo, z ktorého vypočíta desatinu, vytvoríme takto:

while(true)
 s = input('desetina z: ');
 disp(['je ' num2str(s / 10)] );
end
% přerušit pomocí Ctrl + C

Ďalšie podrobnosti o tom, ako sa správa podmienka vo while cyklu, nájdete v článku o výrazoch a podmienkach. Podmienka za kľúčovým slovom while má rovnaké pravidlá ako za kľúčovým slovom if. Dozviete sa tam napríklad aj to, že nikdy nekončiaci while cyklus môžete rozbehnúť pomocou reťazca "nekonečno":

while('nekonecno') %vyraz bude vyhodnocen jako true
    input('pokracovat?','s');
end

Výraz bude vyhodnotený ako true, pretože reťazec 'nekonecno' nie je 0. Treba podotknúť, že proti tomuto obskurnímu zápisu sa MATLAB bráni podčiarknutím a oranžovú hláškou.

Break a continue

Vykonávanie cyklu môžeme prerušiť kľúčovým slovom break. Predchádzajúci príklad nekonečného cyklu obohatíme o podmienku. Ak vstupom, ktorý užívateľ zadá, bude písmeno n, cyklus sa preruší:

while(true)
  inp = input('pokracovat?','s');
  if(inp == 'n')
    break;
  end
end

continue má podobnú funkciu ako break, však miesto prerušenie celého cyklu preruší iba aktuálny iterácii a prejde na ďalšie. Kód, ktorý nasleduje za continue, sa v aktuálnej iterácii nevykoná:

for ii=1:25
    if mod(ii, 3) == 0 % nasobek 3?
        continue % skoc na dalsi iteraci
    end
    disp(ii);
end

Tento kód by sa dal s kľudom uskutočniť pomocou inverzné konštrukcie podmienky if, či pomocou bloku else. Avšak v prípade, že by kód za continue (tu jeden riadok s funkciou disp()) bol rozsiahlejší, tak jeho umiestnenie do akéhokoľvek bloku znižuje prehľadnosť kódu.

Príklady cyklus vs. maticový prístup

Väčšina úloh, na ktoré by ste v iných programovacích jazykoch využili cyklus, ide v MATLAB spísať pomocou uplatnenie funkcií na vektory či matice. MATLAB je na to stavaný a maticové riešenie (ak nie je príliš krkolomné) je odporúčané. Jednak z dôvodu rýchlosti, ale aj prehľadnosti zdrojového kódu. Pár takých príkladov si tu ukážeme.

Suma prvkov

Sčítame všetky prvky vo vektora pomocou cyklu a potom pomocou funkcie:

v = rand(100,1); % nahodny vektor o 100 prvcich
suma = 0;
for ii = v
  suma = suma +ii;
end
% funkce
suma_m = sum(v);

Sčítaní prvkov dvoch matíc

Teraz sčítame 2 matice, opäť pomocou cyklov a potom maticovo:

A = rand(100); %nahodna matice 100x100
B = rand(100);
C = zeros(size(A));
for ii = 1:size(A,1)
    for yy = 1:size(A,2)
        C(ii,yy) = A(ii,yy) +B(ii,yy);
    end
end
% maticove
C_m = A+B;

Generovanie a vykreslenie sinusovek s rôznou frekvenciou

Nasledujúci kód vygeneruje grafy funkcie sínus s rôznou frekvenciou:

sinusivky s rôznou frekvenciou - Matlab

Opäť si ukážeme riešenie cyklom a maticou:

t = 0:0.01:1; % vektor casu
f = [1; 2; 3]; % frekvence 1 2 a 3 Hz

% reseni cyklem
figure;subplot 211; hold on;
for ii = f
v = sin(2 * pi * ii * t);
    plot(t, v, 'LineWidth', 3)
end

% reseni matici
subplot 212;
A = sin(2 * pi * f * t);
plot(t, A', 'LineWidth', 3)

Zníženie počtu farieb u šedotónové fotografie

A v poslednom príklade znížime počet farieb v čiernobielej fotografii:

Zníženie počtu farieb u fotografie v MATLAB - Matlab

Kód bude nasledujúci:

Fotka = imread('cameraman.tif');

Fotka2 = Fotka;
for ii = 1:size(Fotka, 1)
    for yy = 1:size(Fotka, 2)
        Fotka2(ii, yy) = uint8(round(Fotka2(ii, yy) / 255 * 3) * 128);
    end
end
subplot 121; imshow(Fotka);
subplot 122; imshow(Fotka2)

% maticove
M = uint8(round((Fotka / 255) * 3) * 128); % pouze 3 barvy (0, 128, 255)
figure; imshow(M)

Záver

V tejto lekcii sme predstavili dva cykly, ktorými MATLAB disponuje - for a while. Cyklus do-while v tomto programovacom jazyku nie je a výhody cyklu foreach prichádzajú so syntaxou cyklu for. Ďalej sme si ukázali kľúčové slová break a continue, ktorých fungovanie sa nelíši od iných jazykov.

Pre väčšinu operácií s maticami nie je vhodné cykly využívať. Prehľadný kód a väčšinou aj vyšší výkon získame pri využití maticového prístupu, na ktorý sú funkcie MATLAB pripravené. Pochopiteľne sú úlohy, kde sa cykly vyložene hodí. Odporúčam sa vždy pri písaní cykle zamyslieť nad tým, či by sa úloha nedala riešiť elegantnejšie.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 9x (2.18 kB)
Aplikácia je vrátane zdrojových kódov

 

Predchádzajúci článok
Porovnávanie hodnôt a podmienky v MATLAB
Všetky články v sekcii
Matlab
Preskočiť článok
(neodporúčame)
Zobrazenie grafov v MATLAB
Článok pre vás napísal tesař.tech
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje dýchání přibližně celý život
Aktivity