November Black Friday C# týden
BlackFriday je tu! Využij jedinečnou příležitost a získej až 80 % znalostí navíc zdarma! Více zde
Pouze tento týden sleva až 80 % na e-learning týkající se C#

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

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

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

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

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í

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

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.


 

Stáhnout

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

 

 

Článek pro vás napsal tesař.tech
Avatar
Jak se ti líbí článek?
1 hlasů
Autor se věnuje dýchání přibližně celý život
Předchozí článek
Porovnávání hodnot a podmínky v MATLAB
Všechny články v sekci
Matlab
Miniatura
Následující článek
Zobrazení grafů v MATLABu
Aktivity (4)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!