IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 5 - Cykly a maticový přístup v MATLAB

Podmínky a cykly jsou základní stavební prvek rozvětveného programu. Cykly mají v MATLAB místo lehce na okraji a možná trochu překvapivou syntaxi i funkcionalitu. Koncepčně se MATLAB celkem liší od C-like jazyků a zrovna přístup k cyklům je toho hezkou ukázkou.

I přesto, že je tento článek o cyklech, obecné doporučení v MATLAB je snaha o maticové řešení. Řekneme si proč a na konci představíme pár příkladů, jak toho docílit.

Maticový přístup vs. cykly

Jak bylo zmíněno v lekcích o maticích a vektorech, MATLAB je uzpůsoben právě na práci s nimi. Většina funkcí, kterými prostředí disponuje, je uzpůsobeno tak, aby vstupním parametrem mohla být právě matice nebo vícerozměrný vektor. S tím počítají i samotné operátory, takže pokud máme vektor (v jiných jazycích mluvíme o poli) v a chceme všechny jeho hodnoty dělit 3 a odečíst dvojku, uděláme to jedním řádkem:

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

For cyklus

For cyklus, který dělá ekvivalentní operaci, bude vypadat následovně:

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

Takovýto zápis je zbytečné zdlouhavý a ve finále je kód neefektivní. Nicméně vidíme, jak se for cyklus v MATLAB konstruuje.

Syntaxe for cyklu

Cyklus začíná klíčovým slovem for a uzavírá se univerzálním klíčovým slovem end (to funguje i u if, while a funkcí). To zajímavé a trochu netradiční je způsob, jakým definujeme jednotlivé průchody cyklem. Překvapení – je to s pomocí vektoru. Tím, co je za klíčovým slovem for, říkáme: "vezmi vektor od jedničky do sedmičky (to je délka vektoru v) a každý jeho index při jednotlivých průchodech přiřaď do proměnné ii".

Prvky vektoru, které jsou postupně přiřazeny do ii, vůbec nemusíme definovat u klíčového slova for. Pokud bychom chtěli upravit pomocí for cyklu pouze druhý, třetí a pátý prvek vektoru v, mohli bychom to udělat tímto zápisem:

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 cyklu je uvedeno i řešení bez něj. Jak již bylo řečeno na začátku, cyklům se v takovýchto případech spíše snažíme vyhnout, a proto je zde uvedeno i správnější řešení.

Ukázka definic for cyklů

Pro ukázku si zde uvedeme několik způsobů, jak napsat definici for cyklu. Jak již bylo zmíněno – jde především o to, jak definovat vektor, což je podrobně popsáno v jedné z předchozích lekcí.

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

Iterativní proměnná v cyklu je pojmenována jako dvojité ii místo obvyklého jednoho. Důvod je obsazenost proměnné i, které je v MATLAB přiřazeno komplexní číslo s reálnou částí 0 a komplexní 1. Můžete to vyzkoušet, pokud do command window napíšete právě i:

i
ans = 0.0000 + 1.0000i

Použijete – li v cyklu i, nic závažného se nestane, i se pouze předefinuje. Pokud však v takovém cyklu budete chtít použít komplexní číslo, tak tímto způsobem nemůžete. Doporučení je nechodit chybám naproti a raději použít jiný název proměnné.

While cyklus

Cyklus while běží, pokud je splněna podmínka v jeho definici. Definice se uvádí za klíčové slovo while a celý cyklus se uzavírá pomocí end:

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

Nekonečný cyklus, který se nás neustále bude dotazovat na číslo, ze kterého vypočítá desetinu, vytvoříme takto:

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

Další podrobnosti o tom, jak se chová podmínka ve while cyklu, naleznete v článku o výrazech a podmínkách. Podmínka za klíčovým slovem while má stejná pravidla jako za klíčovým slovem if. Dozvíte se tam například i to, že nikdy nekončící while cyklus můžete rozběhnout pomocí řetězce "nekonečno":

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

Výraz bude vyhodnocen jako true, jelikož řetězec 'nekonecno' není 0. Nutno podotknout, že proti tomuto obskurnímu zápisu se MATLAB brání podtržením a oranžovou hláškou.

Break a continue

Vykonávání cyklu můžeme přerušit klíčovým slovem break. Předchozí příklad nekonečného cyklu obohatíme o podmínku. Jestliže vstupem, který uživatel zadá, bude písmeno n, cyklus se přeruší:

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

continue má podobnou funkci jako break, nicméně místo přerušení celého cyklu přeruší pouze aktuální iteraci a přejde na další. Kód, který následuje za continue, se v aktuální iteraci neprovede:

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

Tento kód by se dal s klidem uskutečnit pomocí inverzní konstrukce podmínky if, či pomocí bloku else. Avšak v případě, že by kód za continue (zde jeden řádek s funkcí disp()) byl rozsáhlejší, tak jeho umístění do jakéhokoliv bloku snižuje přehlednost kódu.

Příklady cyklus vs. maticový přístup

Většina úloh, na které byste v jiných programovacích jazycích využili cyklus, jde v MATLAB sepsat pomocí uplatnění funkcí na vektory či matice. MATLAB je na to stavěný a maticové řešení (pokud není příliš krkolomné) je doporučené. Jednak z důvodu rychlosti, ale i přehlednosti zdrojového kódu. Pár takových příkladů si zde ukážeme.

Suma prvků

Sečtěme všechny prvky ve vektoru pomocí cyklu a pak pomocí funkce:

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

Sečtení prvků dvou matic

Nyní sečtěme 2 matice, opět pomocí cyklů a poté maticově:

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;

Generovaní a vykreslení sinusovek s různou frekvencí

Následující kód vygeneruje grafy funkce sinus s různou frekvencí:

sinusivky s různou frekvencí - Matlab

Opět si ukážeme řešení cyklem a maticí:

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)

Snížení počtu barev u šedotónové fotografie

A v posledním příkladu snížíme počet barev v černobílé fotografii:

Snížení počtu barev u fotografie v MATLAB - Matlab

Kód bude následující:

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ávěr

V této lekci jsme představili dva cykly, kterými MATLAB disponuje - for a while. Cyklus do-while v tomto programovacím jazyku není a výhody cyklu foreach přicházejí se syntaxí cyklu for. Dále jsme si ukázali klíčová slova break a continue, jejichž fungování se neliší od jiných jazyků.

Pro většinu operací s maticemi není vhodné cykly využívat. Přehledný kód a většinou i vyšší výkon získáme při využití maticového přístupu, na který jsou funkce MATLAB připravené. Pochopitelně jsou úlohy, kde se cykly vyloženě hodí. Doporučuji se vždy při psaní cyklu zamyslet nad tím, jestli by se úloha nedala řešit elegantněji.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 9x (2.18 kB)
Aplikace je včetně zdrojových kódů

 

Předchozí článek
Porovnávání hodnot a podmínky v MATLAB
Všechny články v sekci
Matlab
Přeskočit článek
(nedoporučujeme)
Zobrazení grafů v MATLABu
Článek pro vás napsal tesař.tech
Avatar
Uživatelské hodnocení:
6 hlasů
Autor se věnuje dýchání přibližně celý život
Aktivity