Základy programování v Matlabu - část 4
Ing. Petr Pokorný, Ph.D.
Funkce
Funkce jsou samostatné obecně napsané skripty nebo jejich části, pomocí kterých můžeme rozčleňovat, zpřehledňovat a řídit komplexně psaný kód programu.
Uživatelsky definované funkce
- definice začíná klíčovým slovem slovem function
- seznam volitelného počtu parametrů ohraničený [ ], jeden parametr nemusí být v závorkách
- výstižné jméno funkce
- vstupní parametry za jménem v kulatých závorkách
- funkce ukládáme do samostatného souboru s příponou .m pod stejným jménem, jako název funkce
function [vystupy] = jmeno(vstupy)
% popis funkce pro help a doc
Příklad: Funkce pro výpočet lichoběžníkového pravidla
function I = intlich(x,y)
% vypocte numericky integral lichobeznikovym pravidlem
I = (b - a)/N*((fa + fb)/2 + sum(y(2:end-1)));
Funkce s volitelným počtem vstupních parametrů
Matlab umožňuje vytvářet funkce s předem neznámým počtem a typem vstupních parametrů. Pro vhodnou organizaci skriptu slouží dvě funkce:
- nargin - vrátí počet vstupních parametrů,
- varargin - vrátí pole buněk vstupních parametrů (podrobnosti k datovému typu pole buněk viz doc cell).
function N = myfcn(varargin)
% demonstracni funkce pro volitelny pocet vstupnich parametru
N = nargin; % vrati pocet vstupnich parametru
disp( varargin{in} ); % postupne zobrazi bunku na pozici in
In-line a lokálně definované funkce
Další z možností tvorby funkcí jsou:
- In-line funkce - definované v řádku
- Lokálně definované funkce (vnořené) - proměnné, které nejsou na vstupu, hledá v nadřazené funkci
function out = localFcn(in)
% lokalne definovana funkce
out = in + a; % a je dedena promenna
Hierarchie hledání zdrojového kódu funkce
Při volání funkce Matlab postupně provádí následující kroky:
- Je-li funkce volána ve skriptu, nejprve prohledává tento aktivní skript a při výskytu inline nebo vnořené funkce volá její zdrojový kód.
- Není-li funkce in-line nebo vnořená, prohledává současný aktivní adresář (Current Folder). Je-li přítomný m-file se jménem totožným s názvem volané funkce, volá jeho zdrojový kód.
- Není-li funkce nalezena v bodech 1. a 2., prohledává zadané cesty vyhledávání (způsob prohlížení nebo zadávání vyhledávacích cest viz doc path).
Příklady
Příklad 1 (upravený příklad 3 z části 3)
Napište funkci, pomocí které budete iterativně počítat odmocninu z reálného čísla x s přesností 1e−15. Využijte rekurentní vztah pro
daný jako: Funkci vhodně nazvěte, vstupní parametry volte x - číslo, ze kterého je počítána odmocnina, T - tolerance výpočtu.
K výpočtu odmocniny využijte cyklus while nebo jiný vhodný způsob.
Nápověda k řešení cylku:
- Definujte proměnnou TEST rovnou např. 1. Dále definujte proměnnou Y rovnu vstupní hodnotě X.
- Využijte while cyklus, který bude probíhat tak dlouho, dokud TEST nesplní podmínku přesnosti (TEST > 1e−15).
- Ve while cyklu definujte proměnnou Y0 rovnu hodnotě Y.
- Dále přepočítejte hodnotu proměnné Y dle rekurzivního vztahu.
- Hodnotu TEST přepočítejte jako absolutní hodnotu rozdílu hodnot Y a Y0.
Příklad 2 (upravený příklad 4 z části 3)
Vytvořte soubor vyhlazeni.m a vyčistěte prostředí (clc, close all, clear all).
Vytvořte vektor X = [1, 1.4, 2, 2.9, 3.5, 4, 5.1, 7, 8.2, 9.1, 9.3, 9.5, 10]. Dále vytvořte vektor Y s hodnotami √(X) + "náhodně generované číslo" s normálním rozdělením s nulovou střední hodnotou a směrodatnou odchylkou 0.1.
Napište funkci, která bude vyhlazovat 2D data Y pomocí průměrování na okolí ±W/2 okolo daného bodu X, kde W je libovolná šířka průměrujícího intervalu (reálné číslo). Vstupní parametry funkce budou data X a Y a šířka okna W.
Volejte funkci pro různé šířky okna a filtrovaná data zobrazte do vhodného grafu.
Příklad 3 (upravený příklad 3 a 4 z části 3 - pokračování)
Vytvořte funkci pro výpočet numerické integrace lichoběžníkovým pravidlem nad daty X a Y a to takovým způsobem, že funkce rozliší, zda byly zadány dva vektory nebo jeden:
- Jestliže je na vstupu zadán jeden vektor, předpokládejte, že je to vektor Y s rovnoměrným dělením s rozestupem 1.
- Jestliže jsou na vstupu zadány dva vektory, poté předpokládejte, že se jedná o vektory X a Y, ale uvažujte, že dělení X není rovnoměrné a spusťte algoritmus pro adaptivní dělení vektoru X (viz příklad 4 z části 3 - pokračování) s tolerancí
.
Příklad 4
Pepík chce vytvořit pomůcku pro svého tatínka, vášnivého turistu, a napsat funkci, pomocí které dokáže určit vesnici nejblíže zadanému bodu. Z mapy odměřil souřadnice pěti vesnic (viz kód níže). Předpokládejme, že se tatínek ke každé vesnici z každého bodu může dostat po přímé čáře.
% tabulka_vesnice = [ id_vesnice X Y ]
tabulka_vesnice = [ 1 125.25 479.52
Napište samostatnou funkci najdi_vesnici, kde vstupními parametry budou:
- matice XY_vesnice kartézských souřadnic, kde první sloupec budou X-ové souřadnice a druhý Y-ové,
- vektor XY_bod, kde první položka bude X-ová souřadnice bodu a druhá Y-ová.
Výstupem poté bude index (číslo řádku matice) vesnice, která je nejblíže danému bodu. Pokud bude více vesnic stejně vzdáleno od daného bodu a blíže než ostatní, vypište indexy všech. Využijte např. funkce sqrt, min, find, apod.
Vytvořte poté nový skript a vyčistěte prostředí (clc, close all, clear all). Ve skriptu vytvořte matici se souřadnicemi vesnic (souřadnice můžete volit sami) a zkoušejte volat vytvořenou funkci pro hledání vesnic. Můžete vytvořit přehledný graf vyhledávání.
Příklad 5
Doplňte funkci najdi_vesnici z příkladu 4 ošetřením vstupních dat:
- Zajistěte, aby byly zadány oba dva vstupní parametry funkce (if, nargin). Pokud tomu tak není, vypište chybové hlášení (error).
- Dále ošetřete, zda-li má matice XY_vesnice dva sloupce (size) a není-li prázdná (isempty) a zda-li vektor XY_bod má dva prvky. Nebude-li tomu tak, opět vypište chybové hlášení (error).
Napadnou-li vás další podmínky, funkci doplňte.
Příklad 6
Napište funkci, která vyhladí průměrujícím filtrem 3D data. Data k vyhlazení nasimulujte jako matici DATA pomocí funkce peaks na gridu {−3:0.1:3}x{−2:0.1:2} s přidáním náhodného šumu s normálním rozdělením se střední hodnotou 0 a směrodatnou odchylkou 0.5 (randn).
Vytvořte funkci filtrace, jejíž vstupní parametry budou matice dat k filtraci (DATA) a rozměr průměrujícího čtvercového okna N. Nejdříve ošetřete, aby N bylo liché číslo. Pokud není, vypište varovnou hlášku (warning), přičtěte +1 a pokračujte ve vyhodnocení.
Filtraci proveďte takovým způsobem, že hodnota (i, j) ve filtrovaném obraze bude odpovídat průměru z hodnot DATA(i – M:i + M, j – M:j + M), kde M = (N– 1)/2. Ošetřete také okrajové oblasti, kde okno „přesahuje“ mimo obraz. Zde průměrujte z dostupných hodnot, které budou splňovat podmínku oblasti.
Pro filtraci využijte funkce mean ve for-cyklu (mean, for). Můžete také vyzkoušet konvoluci (conv).
Příklad 7
Napište funkci pro výpočet faktoriálu. Porovnejte časy výpočtů vaší funkce s implementovanou funkcí Matlabu factorial pro rostoucí hodnoty argumentů od 5 do 100. Porovnání opakujte 100krát a určete průměrnou dobu výpočtu pro jednotlivé argumenty. Výsledky zobrazte v přehledném grafu. K záznamu času vyzkoušejte různé funkce tic, toc, timeit nebo cputime.