Programování v Matlabu Obsah: m-funkce a skripty; Krokování (ladění) funkcí/skriptů; Podmíněný příkaz; Cyklus s předem známým počtem opakování (iterační cyklus); Cyklus řízený podmínkou
Zoltán Szabó FBMI© 2007 http://webzam.fbmi.cvut.cz/szabo/matlab/
m-funkce a skripty • •
m-funkce a skripty jsou obyčejné textové soubory, a proto je lze psát i v libovolném textovém editoru. Z důvodu vyššího komfortu (zvýraznění syntaxe, možnost krokování) součást MATLABu také m-editor/Debugger (File → Open nebo File → New → M-file). >> edit
Skripty •
Skript je posloupnost příkazů uložených do souboru. Může vytvářet nové proměnné nebo mazat či měnit vybrané. Výsledky skriptu tedy zůstávají v pracovním prostředí i po jeho skončení. Skripty samozřejmě mohou volat jiné skripty nebo funkce, vytvářet grafická okna, vypisovat do Command Window,atd. average_script.m % a simple MATLAB m-file to calculate the % average of 5 numbers. % first define variables for the 5 numbers: a b c d e
= = = = =
5; 10; 15; 20; 25;
% now calculate the average of these and print it out: five_number_average = (a + b + c + d + e) / 5; five_number_average
Skripty •
•
Jméno skriptu musí splňovat stejná pravidla jako název proměnné - může obsahovat pouze písmena anglické abecedy, podtržítko a číslice (číslicí nesmí začínat). Skript můžeme spustit buď a) v Command Window - stačí zadat jméno souboru bez přípony (tj. skript priklad.m spustíme příkazem >> priklad), anebo b) v M-editoru/Debuggeru pomocí menu Debug → Run (klávesa F5).
m-funkce •
•
m-funkce má své vlastní pracovní prostředí, které je odděleno od pracovního prostředí Command Window. Všechny proměnné ve funkci jsou lokální (existují jen po dobu spuštění funkce). První řádek obsahuje definici funkce, po něm mohou následovat řádky s nápovědou k funkci (komentáře) a zbytek souboru tvoří příkazy (kód funkce, algoritmus).
název souboru se musí shodovat s názvem dané funkce
m-funkce
Příklady soucet.m function [s]=soucet(a,b) % SOUCET - soucet dvou cisel % s=soucet(a,b) % a,b ... scitance % s ... vysledek (soucet) % priklad volani: s=soucet(10,-2.5) s = a+b;
prepona.m function [prep]=prepona(odvesna1,odvesna2) % PREPONA - vypocet prepony pravouhleho trojuhelniku prep = (odvesna1^2 + odvesna2^2)^(1/2); % pouziti Pythagorovy vety
Poznámky Nápověda k funkci • není povinnou součástí funkce. Nápověda k funkci začíná druhým řádkem, pokud je tento řádek komentářem. Nápověda k funkci končí jakýmkoli řádkem, který již není komentářem (tj. i třeba prázdným řádkem). Pokud je v M-souboru funkce obsažena nápověda, zobrazíme ji příkazem >> help jméno_funkce. První řádek nápovědy by měl obsahovat jméno funkce a vystihovat její činnost, protože je vypisován příkazem >> lookfor slovo (slouží pro výpis všech funkcí obsahujících dané slovo). Další řádky nápovědy by měly obsahovat popis vstupů a výstupů funkce a také příklad jejího použití (volání). Kód funkce • (algoritmus; příkazy) začíná hned za nápovědou a obsahuje posloupnost příkazů, pomocí nichž funkce vypočítá své výstupy. Všechny výstupy funkce musí být jejím kódem vytvořeny, jinak je po spuštění funkce ohlášena chyba. Všechny přiřazovací příkazy unvitř funkce by měly být ukončeny středníkem (aby funkce neobtěžovala okolí výpisem pomocných proměnných).
Spuštění funkce •
Pokud jsme vytvořili vlastní funkci, můžeme ji spustit z Command Window (anebo z jiných funkcí či skriptů). Příkaz pro spuštění funkce vypadá obecně takto: >> [vystupy]=jmenofce(vstupy), pokud chceme uložit výsledky do nějakých proměnných nebo takto: >> jmenofce(vstupy), pokud nechceme výsledky ukládat do proměnných
Poznámky • • •
počet vstupních argumentů se musí shodovat s její definicí pořadí vstupních argumentů při volání je zavazující výstupy z funkce nejsme povinni odebírat (pokud nenapíšeme za voláním funkce středník, první z výstupů se vypíše pomocí ans)
Příklady: >> s=soucet(7,14); >> vysledek=soucet(7,14) >> x=7; y=14; soucet(x,y) >> soucet(3.1,8.14);
- s odebráním výstupu a bez jeho výpisu - s odebráním výstupu i jeho vypsáním - bez odebrání výstupu, ale vypsáním výsledku (pomocí ans) - bez odebrání výstupu, bez vypsání výsledku (v podstatě zbytečná akce)
Krokování (ladění) funkcí/skriptů Zobrazení kódu funkce • Kód funkce (tj. obsah M-souboru) vidíme v M-editoru/Debuggeru, ale můžeme jej zobrazit také v Command Window příkazem >> type jmenofce, kde jmenofce je název funkce (název M-souboru bez přípony). Krokování: 1. v M-editoru nastavíme breakpoint (F12) na nějakém řádku s příkazem 2. spustíme funkci s jejími parametry (z Command window) - v Command Window se objeví K>> a v M-editoru svítí zelená šipka před řádkem, který bude následně zpracován 3. pomocí F10 a F11 v M-editoru krokujeme (spouštíme jednotlivé příkazy) - výsledky kontrolujeme pomocí myši (pohyb nad názvem proměnné, jejíž obsah nás zajímá) nebo pomocí okna Workspace (kde by měl být nastaven Stack pro krokovanou funkci) 4. výsledkem celého snažení je nalezení chyby, její oprava a uložení opravené funkce
Krokování (ladění) funkcí/skriptů
Podmíněný příkaz (větvení) if podmínka příkazy end Poznámky: • V případě, že součástí podmínky je matice typu m × n, je podmínka pravdivá jen tehdy, pokud je pravdivá pro všechny prvky této matice. • V případě, že v nějaké podmínce použijeme binární logický operátor (& nebo |) a po vyhodnocení prvního argumentu je už zřejmý výsledek, tak se druhý argument nevyhodnocuje (zkrácené vyhodnocování). • Jednotlivé příkazy if se mohou vnořovat, tj. uvnitř ifu může být další příkaz if.
Podmíněný příkaz (2) if podmínka1 příkazy1 else příkazy2 end
Činnost příkazu if-else: nejprve se testuje podmínka - je-li pravdivá, provedou se příkazy1, je-li nepravdivá, provedou se příkazy2. Vždycky se tedy provede jedna skupina příkazů.
Podmíněný příkaz (3) if podmínka1 příkazy1 elseif podmínka2 příkazy2 else příkazy3 end Poznámky: • větev if musí být právě jedna • větev elseif nemusí být vůbec, případně jich může být více • větev else může být nanejvýš jedna
Cykly • cyklus s předem známým počtem opakování (iterační cyklus; realizovaný pomocí for) • cyklus řízený podmínkou (realizovaný pomocí while)
Cyklus s předem známým počtem opakování (iterační cyklus) for proměnná=výraz příkazy end
Poznámky: • Konec cyklu může nastat předčasně, pokud je v těle cyklu obsažen příkaz break nebo return • Cyklus for používáme vždy, když známe počet opakování určité činnosti. Iterační cyklus se často využívá pro tvorbu matic (jejichž prvky jsou generovány podle nějakého vzorce) a také je používán při zpracovávání matice prvek po prvku.
Cyklus řízený podmínkou while podmínka příkazy end
Poznámky: • Činnost cyklu lze vyjádřit větou: dokud platí podmínka, prováděj příkazy. • Konec cyklu může nastat i při prvním testu podmínky (je-li nulová), takže se může stát, že příkazy v těle cyklu se neprovedou ani jednou. • Řídicí podmínka cyklu by měla být ovlivňována prováděním příkazů v těle cyklu tak, aby jednou přestala platit. Jinak totiž cyklus nikdy neskončí (tzv. nekonečný cyklus) - poznáme to tím, že v Command Window se neobjeví >> a zpravidla se také neustále něco vypisuje. Pokud chceme ukončit provádění nekonečného cyklu, stiskneme CTRL+C.
Příklady Příklad cyklu ze života:
Příklad větvení uvnitř cyklu:
zalez_do_postele; while unaven zdrimni_si; end vylez_z_postele;
Příklad cyklu s počítadlem nesežraných sušenek: jdi_na_navstevu; pocet_susenek=29; while pocet_susenek>0 snez_susenku; pocet_susenek=pocet_susenek-1; end jdi_domu;
jdi_do_prace; while cas<16.00 if nekdo_jde_kolem predstirej_praci; else zdrimni_si; end end jdi_domu;
Příklady k řešení 1.
Sestavte funkci pro výpočet součtu prvních n přirozených čísel.
2.
Vytvořte funkci na výpočet faktoriálu zadaného čísla (na principu: n!=n*(n-1)*(n-2)*...*1, resp. n!=1*2*...*n)
3.
Diskrétní konvoluci lze vyjádřit dvěma rovnocennými vztahy (viz níže). Vytvořte funkci, pro výpočet konvoluce dvou vektorů h a x. n
y (n) = ∑ h(i ) x(n − i ) = h(0) x(n) + h(1) x(n − 1) + L + h(n) x(0) i =0 n
y (n) = ∑ x(i )h(n − i ) = x(0)h(n) + L + x(n − 1)h(1) + x(n)h(0) i =0