SEMESTRÁLNÍ PRÁCE Z PŘEDMĚTU
MODELOVÁNÍ MATLABEM
Jméno: Os. číslo: E-mail: Zadání: Datum vypracování:
Petr Thür A04236
[email protected] 8-D 7. 5. 2005
Zadání: Sestavte program (funkční M-soubor) pro vykreslení funkce jedné proměnné a výpočet jejího určitého integrálu na daném intervalu. Vstupem do programu je řetězec definující danou funkci a rozsah (definiční obor). Program vykreslí zadanou funkci jedné proměnné ve zvoleném rozsahu a vyplní integrovanou plochu. Číselným výstupem bude plocha pod křivkou na daném intervalu. Vytvořte grafické uživatelské prostředí, kde bude možno zadávat jednotlivé parametry úlohy a vykreslovat výstupy. Kontrola správnosti zadaných údajů je samozřejmostí. Při zadání prázdného vstupu zvolte a použijte implicitní hodnoty.
Postup řešení Nejprve bylo nutné vytvořit grafické uživatelské rozhraní (soubor gui.m) a umístit do něj všechny potřebné prvky (vstupní pole pro zadání funkce a hraničních bodů intervalu, spouštěcí tlačítko, oblast grafu, výstupní textové pole a další). Následně jsem začal vytvářet vlastní program. Na začátku je potřeba načíst hodnoty ze vstupních polí. Hodnoty zjišťuji pomocí funkce get a převedou na číslo funkcí str2num. Tato funkce vrací vektor, jehož druhá složka informuje o případné chybě při převodu, což jsem využitel při následné kontrole správnosti vstupu. Po zjištění krajních hodnot intervalu je možné vytvořit vektor vstupních hodnot (hodnoty osy x) a z nich pak vypočítat vektor funkčních hodnot (hodnoty osy y). Výpočet funkčních hodnot jsem vyřešil funkcí eval, která zároveň kontroluje správnost zadaného vstupu a při chybě vykoná řetězec zadaný jako druhý parametr. Protože plocha integrálu se vykresluje jako polygon, je nutné doplnit do vektorů ještě souřadnice posledního a prvního bodu osy x, aby mohl být útvar uzavřen a správně vykreslen. Poté se vykreslí integrovaná oblast jako barevná plocha a přes ní integrovaná funkce. Nyní zbývá vypočítat hodnotu integrálu. Výpočet jsem zajistil funkcí quad, pro její použití je však nutné vytvořit handle funkce. To se v programu provádí pomocí funkce eval a operátoru @. Handle společně s hranicemi intervalu se vládá do zmíněné funkce quad a ta vrací výslednou hodnotu určitého integrálu. Tato hodnota se následně vypíše do výstupního textového pole.
Uživatelský manuál Program spusťte příkazem gui (samozřejmě ve správné pracovní složku). Zobrazí se okno programu. Nahoře jsou umístěna pole pro zadání vstupů (levá a pravá hranice intervalu, na kterém se bude funkce integrovat, dále pole pro předpis funkce). Vpravo nahoře je tlačítko „Spustit“, kterým se provede vykreslení a výpočet integrálu. To samé způsobí kliknutí na položku „Spustit“ v menu okna. Při zadávání hodnot 2
pamatujte na to, že program pracuje s vektory, takže je nutné používat tečku před operátorem. Pokud je některá z hodnot špatně zadána, program zobrazí chybové hlášení a vyplní příslušné pole implicitní hodnotou. Po vykonání výpočtu se zobrazí graf funkce s vybarvenou plochou integrálu. Hranice intervalu jsou označeny svislými přerušovanými čárami. Pod grafem se zobrazí hodnota určitého integrálu funkce na zadaném intervalu a také hodnota integrálu absolutní hodnoty funkce, která charakterizuje obsah plochy vymezené grafem kolem osy x. Program ukončíte zavřením okna nebo kliknutím na položku „Zavřít“ v menu okna.
Ukázky výstupu
Ukázka implicitního zadání, je nutné přičíst malé číslo, aby se předešlo dělení nulou. Program jinak nedokáže funkci zintegrovat.
3
Stejná funkce, ale na intervalu od 0 do 5.
Funkce sin(x)+cos(x) na intervalu od –pi/4 do pi/4.
4
Funkce x3 na intervalu od -1 do 1.
Výpis kódu – soubor gui.m
clear all; hlavni=figure('NumberTitle','Off','MenuBar','None','Name','Určitý integrál'); menu_start=uimenu('Label','Spustit',... 'CallBack','funkce'); menu_konec=uimenu('Label','Konec',... 'CallBack','delete(hlavni)'); uicontrol('Units','Normalized',... 'Position',[0.05,0.925,0.2,0.025],... 'Style','Text',... 'HorizontalAlignment','left',... 'String','Interval:'); interval1=uicontrol('Units','Normalized',... 'Position',[0.05,0.85,0.1,0.05],... 'Style','Edit',... 'HorizontalAlignment','center',... 'String','-pi/4'); interval2=uicontrol('Units','Normalized',... 'Position',[0.15,0.85,0.1,0.05],... 'Style','Edit',... 'HorizontalAlignment','center',... 'String','pi/4'); uicontrol('Units','Normalized',... 'Position',[0.315,0.925,0.22,0.025],... 'Style','Text',... 'HorizontalAlignment','left',... 'String','Funkce:'); fce=uicontrol('Units','Normalized',... 'Position',[0.315,0.85,0.22,0.05],... 'Style','Edit',... 'HorizontalAlignment','center',... 'String','x.*sin(1./abs(x+0.001))'); tl_spustit=uicontrol('Units','Normalized',... 'Position',[0.6,0.85,0.35,0.1],... 'Style','PushButton',... 'FontSize',12,... 'String','Spustit',... 'CallBack','funkce');
5
osy=axes('Units','Normalized',... 'Position',[0.05,0.2,0.9,0.6]); vystup=uicontrol('Units','Normalized',... 'Position',[0.05,0.05,0.9,0.1],... 'Style','Text',... 'HorizontalAlignment','center',... 'FontSize',12,... 'String','');
Výpis kódu – soubor funkce.m
chyba=false; chyba_fce=false; [xmin,OK]=str2num(get(interval1,'String')); % pokud se vyskytla chyba pri prevodu cisla (pocatek intervalu), pak OK=0 if (OK==0) % zobrazi chybovy dialog a nastavi implicitni hodnotu na -pi/4 errordlg('Zadali jste špatně interval!','Chyba'); xmin=-pi/4; set(interval1,'String','-pi/4'); chyba=true; end [xmax,OK]=str2num(get(interval2,'String')); % pokud se vyskytla chyba pri prevodu cisla (konec intervalu), pak OK=0 if (OK==0) % jestlize chyba nastala uz pri prevadeni pocatku intervalu, % dialog se podruhe nezobrazi if (~chyba) errordlg('Zadali jste špatně interval!','Chyba'); end % nastavi implicitni hodnotu na pi/4 xmax=pi/4; set(interval2,'String','pi/4'); err=true; end % zkopiruje hranice intervalu pro pouziti v integralu xfcemin=xmin; xfcemax=xmax; % urci delku intervalu xint=xmax-xmin; % zvetsi interval pro vykresleni grafu o 10% na kazde strane % aby to lepe vypadalo :) xmin=xmin-0.1*xint; xmax=xmax+0.1*xint; % vytvori vektor vstupnich hodnot x=linspace(xmin,xmax,1200); % naplni vektor funkcnich hodnot podle zadane fuknce eval(strcat(['y=' get(fce,'String') ';']),'chyba_fce=true;'); % pokud neni funkce zadana spravne if (chyba_fce) % zobrazi chybovy dialog % nastavi implicitni funkci na x.*sin(1./abs(x+0.001)) errordlg('Zadali jste špatně funkci!','Chyba'); set(fce,'String','x.*sin(1./abs(x+0.001))'); chyba=true; end % vymaze graf cla(osy); % vymaze vystupni textove pole set(vystup,'String',''); % jestlize zatim nenastala zadna chyba if (~chyba) % zkopiruje potrebnou cast vstupniho vektoru xf=x(101:end-100); % prida na konec koncovy a pocatecni bod intervalu xf(length(xf)+1)=xfcemax; xf(length(xf)+1)=xfcemin;
6
% zkopiruje potrebnou cast funkcnich hodnot yf=y(101:end-100); % prida na konec dve nulove hodnoty pro uzavreni polygonu yf(length(yf)+1)=0; yf(length(yf)+1)=0; % zjisti minimum a maximum funkcnich hodnot a posunout o 5% % pokud jsou obe hodnoty stejnym smerem od nuly, pouzije se misto % nule blizsi hodnoty nula (aby byla videt cela plocha integralu) ymin=min([0 min(y)])-0.05; ymax=max([0 max(y)])+0.05; % zjisti rozsah funkcnich hodnot yint=ymax-ymin; % nastavi osy podle zjistenych rozmeru axis([xmin,xmax,ymin,ymax]); hold on; % vytvori vektory pro osu x axx=[xmin xmax]; axy=[0 0]; % vytvori vektory pro levou zarazku intervalu ay1x=[xfcemin xfcemin]; ay1y=[ymin ymax]; % vytvori vektory pro pravou zarazku intervalu ay2x=[xfcemax xfcemax]; ay2y=[ymin ymax]; % vykresli integral fill(xf,yf,'g','Line','none'); % vykresli osu x plot(axx,axy,'k'); % vykresli zarazky plot(ay1x,ay1y,':','Color',[0.5 0.5 0.5]); plot(ay2x,ay2y,':','Color',[0.5 0.5 0.5]); %vykresli funkci plot(x,y,'b','LineWidth',1.5); % vytvori handle pro funkci eval(strcat(['fx = @(x) ' get(fce,'String') ';'])); % spocita integral a zaokrouhli ho na 3 desetinna mista Q=quad(fx,xfcemin,xfcemax); Q=round(Q*1000)/1000; % vytvori handle pro absolutni hodnotu funkce eval(strcat(['fx = @(x) abs(' get(fce,'String') ');'])); % spocita integral z absolutni hodnoty a zaokrouhli ho Qabs=quad(fx,xfcemin,xfcemax); Qabs=round(Qabs*1000)/1000; % vypise vysledky set(vystup,'String',... sprintf('Integrál z této funkce (%s) v intervalu od %s do %s má hodnotu %s, obsah vybarvené plochy je %s.',... get(fce,'String'),... get(interval1,'String'),... get(interval2,'String'),... num2str(Q),... num2str(Qabs))); end
Použité zdroje -
fukce HELP příkazy a funkce probrané na cvičení Matlab Function Reference, The MathWorks Inc., 2001 Matlab a Simulink, Ing. František Dušek Csc., 2000 Matlab pro začátečníky, K. Zaplatílek a B. Doňar, 2003 rady jiných studentů na IRC
7
Závěr Ačkoliv se to tak původně nezdálo, po probrání většiny potřebných příkazů a funkcí na cvičení se řešení problému ukázalo býti relativně snadné, vše, co jsem neznal ze cvičení, jsem nastudoval z uvedených knih, detailní informace ke každému příkazu či funkci jsem pak získal použitím příkazu help. Díky práci na programu jsem si na cvičeních získané znalosti ještě více rozšířil, nicméně vzhledem ke studiu oboru informatika již asi nebudu mít mnoho příležitostí je využít.
8