Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
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 4 - Porovnávání hodnot a podmínky v MATLAB

V této lekci se zaměříme na podmínku if, příkaz switch a porovnávání hodnot. Vysvětlíme si syntaxi a některé speciální prvky v jazyku MATLAB.

Podmínka if

Potřebujeme-li ve skriptu podmínit vykonání bloku kódu, slouží k tomu klíčové slovo if. Za tímto slovem má místo samotná podmínka, jejíž výsledkem je hodnota true nebo false (tedy pravda nebo nepravda). Závorka netřeba a blok kódu se uzavírá klíčovým slovem end.

Ukažme si příklad:

a = 10;
if a == 10
  disp('Acko je deset')
end

Kód výše vypíše text 'Acko je deset' pokud je v proměnné a hodnota 10, což v tomto programu platí. Můžete si zkusit hodnotu a na začátku programu změnit tak, aby se daný blok neprovedl.

Operátory porovnání

Při zapisování podmínek můžeme používat porovnávací operátory a negaci.

Dvojité rovnítko (==) značí rovnost, což je běžně využívaný operátor ve spoustě jiných jazycích. Stejně tak je tomu u operátorů pro větší (>), větší nebo rovno(>=) a nebo menší (<) a menší nebo rovno (<=).

Negace v MATLAB

Trochu nezvyklý je operátor nerovnosti – rovnítko negované tildou (~=). Tilda je v MATLAB operátorem negace, podobně jako například v C# vykřičník (!).

Na české klávesnici napíšete vlnovku (~) klávesovou zkratkou AltGr + ~ (obvykle to tlačítko pod Esc nebo může být i na klávese 1) Pokud se vám nechce lovit vlnovku na klávesnicích, alternativou jednoznakového operátoru je funkce not(), která zneguje jakýkoliv vstup, který jí předhodíme:

if not(a==10)
end
%stejné jako
if a~=10
end

Tilda místo výstupního parametru

Tilda má ještě jedno užití, se kterým se setkáme poměrně často. Je jím zamezení návratové hodnoty z funkce.

Vezměme si jako příklad funkci min(), která může být využita pro návrat minima z vektoru:

mi = min([2 3 5 1])
%výsledkem bude mi s hodnotou 1

Též může být využita pro získání jak tohoto minima, tak indexu, na kterém se hodnota nachází:

[index_mi, mi] = min([2 3 5 1])

V případě, že nás zajímá pouze index, nemůžeme využít jen jeden návratový parametr (vrátilo by se minimum). Možnost je vytvořit proměnnou mi a pak ji nepoužít, což je vzdálené od dobrých mravů, jelikož to činí kód nepřehledným (editor si to myslí také, proto vám mi oranžově podtrhne). Druhou možností je místo mi dát tildu, čímž říkáme, že nás hodnota nezajímá:

[index_mi, ~] = min([2 3 5 1])

Operátory OR a AND

Máme-li více podmínek, podle kterých se chceme rozhodovat o větvení programu, můžeme využít logické operátory OR (|) a AND (&) a nebo jejich ekvivalenty ve formě funkcí or() a and(). Chovají se přesně tak, jak známe z jakéhokoliv jiného jazyka. Výsledkem porovnávání operátorem OR bude 1 (true), pokud je alespoň jedna z porovnávaných stran true. Výsledkem porovnání operátorem AND bude true pouze v případě, že jsou obě strany true.

Uveďme si zde pár příkladů pro hlubší pochopení:

a = 1;
b = 2;
a == 1 & b == 2  %true
a < 1 | b > 2  %false
a <= 1 & b > 0  %true
a > 2 | b~=6 & a+b <= 3 %true

Dvojité operátory && a ||

Narazíte-li na zdvojený operátor OR nebo AND, znamená to jednoduše skutečnost, že výraz na pravé straně se vyhodnocuje pouze v případě, že to má smysl. Ukažme si příklad:

a = 1;
b = 2;
a > 2 && b ==2

Zde se vyhodnotí jen výraz a > 2. Jeho výsledkem je false, tedy je jasné, že celý výraz bude false a není nutné hodnotit výraz na pravé straně, tak jako to bude v případě, že první podmínka je true (a > 2 & b == 2).

Důvodem této zkratky je jednak šetření výkonem (na pravé straně může být funkce s výstupním parametrem typu bool, jejíž výpočetní čas je nezanedbatelný) a také prevence před zastavením programu:

a = 0;
a~=0 && Nedefinovany_Nesmysl() %vysledkem je false
a~=0 & Nedefinovany_Nesmysl() %vysledkem je chyba

Nutno podotknout, že toto zkratkovité porovnání, které přináší dvojité operátory, je automatické u if a while cyklu (ne for) i v případě, že je operátor pouze jeden:

if a~=0 & Nedefinovany_Nesmysl() %nenastane chyba
end

Použití dvojitých operátorů je však doporučeno, protože použití jednoduchého operátoru při porovnávání něčeho jiného, než je logický skalár, může vyústit v neočekávaný výsledek (zdroj) :-S . S tím souvisí následující podkapitola.

Vektory v podmínce if

Obecně se MATLAB brání pomocí oranžových hlášek ("vykonám to, ale dávej pozor"), abyste v if porovnávali něco jiného než skaláry (hodnoty obsahující pouze jeden prvek).

Při použití zdvojeného operátoru (&& a ||) u něčeho jiného, než jsou skaláry, MATLAB vypíše chybu. Nicméně bez vypsání chyby schroustá podmínka if všechno co je skalár nebo vícerozměrný vektor... A pokud se v tomto vektoru (kdekoliv) nachází 0, zhodnotí výsledek jako false, pokud nikoliv, zhodnotí výsledek jako true:

if [1 1 1]
     disp('true pro 1 1 1')
end

if [2.5 3 1e9]
     disp('true pro 2.5 3 1e91')
end

if [5 6 9 0 2]
     disp('true pro 5 6 9 0 2')%sem nevleze
end

if [0 0 0]==[0 0 0]
    disp('true pro[0 0 0]==[0 0 0]')
end

if [1 1]&[1 1]
    disp('true pro[1 1]&[1 1]')
end

if [1 1]&&[1 1]
    disp('true pro[1 1]&[1 1]')%nevleze, vypise chybu
end

Mé doporučení je jednoduché – netrapte MATLAB i když si to nechá líbit, respektujte oranžové hlášky, v if porovnávejte pouze skaláry a buďte si vědomi těchto skutečností.

Porovnávání vektorů a matic

Porovnávání vektorů a matic o stejném rozměru je možné pomocí standardních operátorů. Výsledkem porovnání je binární vektor o totožných rozměrech:

m = [1 2 3];
n = [1 2 4];
m==n % [1 1 0]
m<=n % [1 1 1]
m~=n % [0 0 1]

Porovnáváme-li skalár s vektorem, MATLAB porovná každý prvek vektoru právě se skalárem a výsledkem je binární vektor o stejném rozměru jako vektor z porovnání:

m == 2 % [0 1 0]

Jsou – li rozměry vektorů různé a ani jeden z nich není skalár, MATLAB zahlásí chybu:

m == [1 2] % chyba - Matrix dimensions must agree.

Je-li jeden vektor v porovnání řádkový a druhý sloupcový (mají rozměry m x 1 a 1 x n), je výsledkem binární matice o rozměrech z obou vektorů (m x n):

[1;2;3] == [1 2 3 4]

%  1   0   0   0
%  0   1   0   0
%  0   0   1   0

Porovnávání řetězců

V MATLABu je řetězec chápán jako vektor znaků, snažíme-li se ho porovnávat, bude porovnávat jednotlivé znaky. Je to zcela totožné jako u vektorů. Výsledkem je binární vektor a v případě, že řetězce jsou jinak dlouhé, je výsledkem chyba:

'ahoj' == 'ahoj'  % [1 1 1 1]
'ahoj' == 'cau'   % chyba - Matrix dimensions must agree.

Pro porovnání řetězců slouží funkce strcmp():

strcmp('ahoj','cau')  %false

Další větvení – else, elseif

Chceme-li vykonat zcela jiný kód při neplatnosti podmínky, slouží k tomu klíčové slovo else. Blok else se vykoná vždy, když podmínka bude vyhodnocena jako false, tedy vždy, když se nevykoná část kódu následovaná za if:

a = 11;
if a==10
  disp('Acko je deset')
else
  disp('Acko je jine nez deset') %sem vleze
end

Klíčové slovo end je zde jen jednou a ohraničuje celý blok.

elseif

Podmínek může být vícero, k tomu slouží klíčové slovo elseif následované další podmínkou:

a = 11;
if a==10
    disp('Acko je deset')
elseif a == 11
    disp('Acko je jedenact')
else
    disp('Acko je jiné nez deset a jedenact')
end

Switch – Zjednodušení konstrukce elseif

Kdybychom chtěli do předešlé ukázky kódu přidat bloky pro vypsání dvanáctky, třináctky, atd..., jednotlivá porovnání za klíčovým slovem elseif se budou neustále opakovat (a == 12 apod.). Tomuto opakování zamezí přepínač, tedy switch.

Následující ukázka dělá zcela stejné porovnání s tím, že přidává blok pro dvanáctku:

a = 11;

switch a
    case 10
        disp('Acko je deset')
    case 11
        disp('Acko je jedenact')
    case 12
        disp('Acko je dvanact')
    otherwise
        disp('Acko je jine nez 10,11,12')
end

Závěr a úloha

V této lekci jsme si vysvětlili jak funguje porovnávání hodnot a některé binární operátory, podmínka if a příkaz switch.

Následující úloha spočívá v odhadnutí výsledku daných příkladů. Řešení naleznete tím, že výrazy pustíte v MATALABu nebo se podíváte do přiloženého souboru, které obsahuje též veškerý kód z této lekce. Nespouštějte je tedy všechny najednou, ale zkuste se prvně zamyslet nad tím, co který udělá :)

u1 = [1 2 3]<[1 2 3]
u2 = 'haf'<='buu'
u3 = 0&&true
u4 = true||16
u5 = 1|-8
u6 = NaN==NaN
u7 = Inf==Inf
u8 = 0e-17 == -0.0
u9 = Inf-1==Inf+6
u10= 1e-150==1e-149
u11 = 1e-1500==1e-15001
u12 = [4;3;3] == [4 3 3]

Přiznávám, že některé z úloh jsou trochu zákeřné. Nebudete-li vědět proč má příklad zrovna takový výsledek, dejte vědět v komentářích!


 

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 13x (2.33 kB)
Aplikace je včetně zdrojových kódů

 

Předchozí článek
Práce s maticemi a vektory
Všechny články v sekci
Matlab
Přeskočit článek
(nedoporučujeme)
Cykly a maticový přístup v MATLAB
Článek pro vás napsal tesař.tech
Avatar
Uživatelské hodnocení:
8 hlasů
Autor se věnuje dýchání přibližně celý život
Aktivity