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 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ů