155GIT1 / 5. cvičení: Porovnání verzí

Z GeoWikiCZ
mBez shrnutí editace
(Není zobrazeno 9 mezilehlých verzí od 2 dalších uživatelů.)
Řádek 1: Řádek 1:
{{Geoinformatika}}
{{Geoinformatika}}
{{Cvičení|155GIT1|5|Algoritmizace, podmínky a cykly}}
{{Cvičení|155GIT1|5|Matlab - Uživatelské funkce}}


== Náplň cvičení ==
== Náplň cvičení ==


# zobrazení zpráv, zadaní vstup
# uživatelské funkce
# podmínky (<tt>if, else, elseif, end, all, any</tt>)
# chybová hlášení, nápověda k funkci
# větvení (<tt>switch</tt>)
# drobné smíšené úlohy
# podmínky (<tt>for, while</tt>)
# příkazy <tt>break, continue</tt>


== Ukázky ==
== Ukázky ==


=== Interaktivní vstup ===
=== Uživatelské funkce ===
 
'''Syntax'''
function [vystup1,vystup2,...,vystupn] = nazev(vstup1,vstup2,...,vstupn)
end  % end neni povinne
 
Každá funkce musí být uložena ve vlastním souboru s příponou <tt>.m</tt>. Název souboru musí odpovídat názvu funkce! Klíčové slovo <tt>function</tt> musí být na prvním řádku souboru.
 
<source lang=octave>
function [min_x, max_x, mean_x] = stat(x)
 
    min_x = min(min(x));
    max_x = max(max(x));
    mean_x = mean(x(:));    % stejny vysledek jako mean_x = mean(mean(x))
 
end
</source>
 
'''Příklad volání'''


<source lang=octave>
<source lang=octave>
  disp('Program vyzaduje vstup');
  data = rand(5)
  a = input('Zadejte cislo a: ')
[mi, ma, mn] = stat(data);
  fprintf('min  = %.3f\nmax  = %.3f\nmean = %.3f\n', mi, ma, mn)
</source>
</source>


=== Vyhodnocování relačních výrazů, all, any ===
=== Chybová hlášení, nápověda ===


* pravdivá relace je vyhodnocena jako 1
* nepravdivá relace je vyhodnocena jako 0
* funkce '''all()''' (uvažujme např. vícero výsledků relačních výrazů současně)
<source lang=octave>
<source lang=octave>
  all([1 1 1])
  function [min_x, max_x, mean_x] = stat(x)
  all([0 0 1])
  % vypocet minimalni, maximalni a prumerne hodnoty matice
all([0 0 0])
 
    if any(any( imag(x)~=0 ))
        error('stat: Vstupni matice obsahuje komplexni cisla.')
    end
    min_x = min(min(x));
    max_x = max(max(x));
    mean_x = mean(x(:));
 
end
</source>
</source>
* funkce '''any()''' (uvažujme např. vícero výsledků relačních výrazů současně)
 
Vyvolání nápovědy k uživatelské funkci:
                         
<source lang=octave>
<source lang=octave>
  any([1 1 1])
  help stat
any([0 0 1])
any([0 0 0])
</source>
</source>


=== Větvení (if) ===
Volání funkce (chybná vstupní data):
<source lang=octave>
data1 = [data, 5+2i * ones(5,1)]
[mi, ma, mn] = stat(data1)
</source>
 
=== Příkaz return ===
* je-li v běhu funkce vykonán příkaz <tt>return</tt>, je okamžitě činnost funkce ukončena (bez vykonání evtl.dalších příkazů) a na pozici jejího volání jsou vráceny aktuálně vypočtené hodnoty výstupních parametrů funkce


* [http://geo.fsv.cvut.cz/user/gin/git1/matlab.pdf#page=66 přednášky]
=== Drobné úlohy ===


<source lang=octave>
'''Funkce pro výpočet nekonečné řady do zadané přesnosti (příklad iterativního výpočtu)'''
% skalarni podminka
a = randi(10)
b = randi(10)


if a < b
např. výpočet funkce arctg(), viz {{wikipedia|Taylorova řada}}:
    disp('a je mensi nez b');
else
    disp('a je vetsi nebo rovno b');
end


% vektorova podminka
<source lang=octave>
  a = [1 2];
  function [arctgx] = arctg(x,mez)
  b = [0 3];
  % vypocet funkce arctg rozvojem v radu do zadane presnosti
% IN:  x      ... vektor argumentu funkce
%      mez    ... zadana presnost vypoctu
% OUT: arctgx ... vektor vypoctenych uhlu z intervalu <-pi/2,pi/2>


  if a < b  % vyhodnoti se jako:  if all(a < b)
  if any(x > 1) | any(x < -1)
    disp('a je po prvcich vzdy mensi nez b');
     error('arctg: Vstupni hodnoty musi byt z intervalu <-1,1>.')
else
     disp('a je po prvcich alespon jednou vetsi nez b');
  end
  end


% test na (ne)nulove prvky promenne (promenna obvykle obsahuje vysledky relacnich vyrazu, tj. 0 ci 1)
% vypocet pro kazdy prvek daneho vektoru samostatne
if b     % totez jako:  if all(b)
for i=1:length(x)
     disp('b neobsahuje zadne nulove cleny');
    % start iterace pro i-ty vstupni prvek
  elseif a  % totez jako:  if all(a)
    y0 = 100; % vkladam fiktivni hodnotu, kterou x na vstupu nikdy nemuze nabyt
    disp('b obsahuje nulovy clen, a neobsahuje zadne nulove cleny');
    % 1.iterace
  else
    n = 1;
    disp('a i b obsahuji nulovy clen');
     y = x(i);
end
     while  abs( y-y0 ) > mez
   
        % n-ta iterace
if any(b)
        n = n+1;
     disp('b obsahuje alespon jeden nenulovy clen');
        y0 = y;
        y = y0 + (-1)^(n+1) * x(i)^(2*n-1/ (2*n-1);
    end
    % ulozeni vypoctene hodnoty do vystupni promenne
    arctgx(i) = y;
     fprintf('Pocet iteraci vypoctu: %d\n',n)
  end
  end
</source>
</source>


=== Větvení (switch) ===
'''Funkce pro načtení neformátovaných dat po řádcích'''
 
např. záměna čárky za tečku:


<source lang=octave>
<source lang=octave>
  cislo = randi(10)
  function teckazacarku(file)
% vyhleda vsechny carky v souboru a zameni je za tecku
% IN: file ... jmeno vstupniho souboru (textovy retezec)


  switch cislo
  if ischar(file) == 0
  case 1
     error('Jmeno vstupniho souboru musi byt textovy retezec.');
    disp('cislo je 1')
  case {2,3}
    disp('cislo je 2 nebo 3')
  case {4,6,7}
    disp('cislo je 4, 6 nebo 7')
  otherwise
     disp('cislo je 5 nebo vetsi nez 7')
  end
  end
</source>


=== Cyklus for ===
vstup = fopen(file,'r');


<source lang=octave>
  filenew = [file(1:end-4), '_upr', file(end-3:end)];  % jmeno noveho souboru
% tvorba vektoru
  vystup = fopen(filenew,'w');
  n = 4
  for i = 1:n
    a(i) = i^2
end


% tvorba matice
  konec = 0; % indentifikator konce souboru
  m = 4 % pocet radku
  while konec==0
  n = 3 % pocet sloupcu
    radek = fgets(vstup); % fgets() nacte 1 radek souboru (se znakem \n)
for i = 1:m
     for i=1:length(radek)
     for j = 1:n
         if radek(i) == ','
         A(i,j) = i+j
            radek(i) = '.';
        end
     end
     end
    fprintf(vystup,'%s',radek);
    konec = feof(vstup);  % feof() vrati pro konec souboru hodnotu 1, jinak vraci hodnotu 0
  end
  end


% priklad - v matici vyhledat sude radky (jedna z moznych variant zapisu)
  fclose all;
  A = rand(5,4)
  fprintf('Data ulozena do souboru %s\n',filenew);
  for i=1:size(A,1)
    if rem(i,2) == 0        % rem(a,b) ... zbytek po deleni cisla a cislem b
        A(i,:) = -1 * A(i,:)
    end
end
</source>
</source>


=== Cyklus while ===
datový soubor [http://geo102.fsv.cvut.cz/vyuka/155GIT1/data/carky.txt carky.txt] <!--[ftp://athena.fsv.cvut.cz/ZFG/GIT1/carky.txt carky.txt]--> ke stažení


<source lang=octave>
Volání funkce:
a = 1;
b = 5;
while a < b
    a
    a = a + 1;
end
</source>
 
=== Příkazy break, continue ===


<source lang=octave>
<source lang=octave>
  for i = 1:5
  teckazacarku('carky.txt')
    if i == 2
        continue;
    end
    if i == 4
        break;
    end
    fprintf('i = %d\n', i);
end
</source>
</source>


== Úlohy ==
== Úlohy ==
* [[155GIT1 / 5. cvičení / Příklady|5. cvičení - příklady]]
* [[155GIT1 / 5. cvičení / Příklady|5. cvičení - příklady]]

Verze z 22. 3. 2021, 22:30

Matlab - Uživatelské funkce

Náplň cvičení

  1. uživatelské funkce
  2. chybová hlášení, nápověda k funkci
  3. drobné smíšené úlohy

Ukázky

Uživatelské funkce

Syntax

function [vystup1,vystup2,...,vystupn] = nazev(vstup1,vstup2,...,vstupn)

end  % end neni povinne

Každá funkce musí být uložena ve vlastním souboru s příponou .m. Název souboru musí odpovídat názvu funkce! Klíčové slovo function musí být na prvním řádku souboru.

 function [min_x, max_x, mean_x] = stat(x)

    min_x = min(min(x));
    max_x = max(max(x));
    mean_x = mean(x(:));    % stejny vysledek jako mean_x = mean(mean(x))

 end

Příklad volání

 data = rand(5)
 [mi, ma, mn] = stat(data);
 fprintf('min  = %.3f\nmax  = %.3f\nmean = %.3f\n', mi, ma, mn)

Chybová hlášení, nápověda

 function [min_x, max_x, mean_x] = stat(x)
 % vypocet minimalni, maximalni a prumerne hodnoty matice

     if any(any( imag(x)~=0 ))
         error('stat: Vstupni matice obsahuje komplexni cisla.')
     end
     min_x = min(min(x));
     max_x = max(max(x));
     mean_x = mean(x(:));

 end

Vyvolání nápovědy k uživatelské funkci:

 help stat

Volání funkce (chybná vstupní data):

 data1 = [data, 5+2i * ones(5,1)]
 [mi, ma, mn] = stat(data1)

Příkaz return

  • je-li v běhu funkce vykonán příkaz return, je okamžitě činnost funkce ukončena (bez vykonání evtl.dalších příkazů) a na pozici jejího volání jsou vráceny aktuálně vypočtené hodnoty výstupních parametrů funkce

Drobné úlohy

Funkce pro výpočet nekonečné řady do zadané přesnosti (příklad iterativního výpočtu)

např. výpočet funkce arctg(), viz Taylorova řada:

 function [arctgx] = arctg(x,mez)
 % vypocet funkce arctg rozvojem v radu do zadane presnosti
 % IN:  x      ... vektor argumentu funkce
 %      mez    ... zadana presnost vypoctu
 % OUT: arctgx ... vektor vypoctenych uhlu z intervalu <-pi/2,pi/2>

 if any(x > 1) | any(x < -1)
     error('arctg: Vstupni hodnoty musi byt z intervalu <-1,1>.')
 end

 % vypocet pro kazdy prvek daneho vektoru samostatne
 for i=1:length(x)
     % start iterace pro i-ty vstupni prvek
     y0 = 100; % vkladam fiktivni hodnotu, kterou x na vstupu nikdy nemuze nabyt
     % 1.iterace
     n = 1;
     y = x(i);
     while  abs( y-y0 ) > mez
         % n-ta iterace
         n = n+1;
         y0 = y;
         y = y0 + (-1)^(n+1) *  x(i)^(2*n-1)  / (2*n-1);
     end
     % ulozeni vypoctene hodnoty do vystupni promenne
     arctgx(i) = y;
     fprintf('Pocet iteraci vypoctu: %d\n',n)
 end

Funkce pro načtení neformátovaných dat po řádcích

např. záměna čárky za tečku:

 function teckazacarku(file)
 % vyhleda vsechny carky v souboru a zameni je za tecku
 % IN: file ... jmeno vstupniho souboru (textovy retezec)

 if ischar(file) == 0
     error('Jmeno vstupniho souboru musi byt textovy retezec.');
 end

 vstup = fopen(file,'r');

 filenew = [file(1:end-4), '_upr', file(end-3:end)];  % jmeno noveho souboru
 vystup = fopen(filenew,'w');

 konec = 0;  % indentifikator konce souboru
 while konec==0
     radek = fgets(vstup);  % fgets() nacte 1 radek souboru (se znakem \n)
     for i=1:length(radek)
         if radek(i) == ','
             radek(i) = '.';
         end
     end
     fprintf(vystup,'%s',radek);
     konec = feof(vstup);   % feof() vrati pro konec souboru hodnotu 1, jinak vraci hodnotu 0 
 end

 fclose all;
 fprintf('Data ulozena do souboru %s\n',filenew);

datový soubor carky.txt ke stažení

Volání funkce:

 teckazacarku('carky.txt')

Úlohy