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

Z GeoWikiCZ
mBez shrnutí editace
 
(Není zobrazeno 10 mezilehlých verzí od 2 dalších uživatelů.)
Řádek 1: Řádek 1:
{{Geoinformatika}}
{{Geoinformatika}}
{{Cvičení|155GIT1|6|Grafy funkcí}}
{{Cvičení|155GIT1|6|Algoritmizace, podmínky a cykly}}


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


# grafické okno <code>figure</code>
# zobrazení zpráv, zadaní vstup
# grafy funkcí <code>plot(), subplot(), polar()</code>
# podmínky (<tt>if, else, elseif, end, all, any</tt>)
# větvení (<tt>switch</tt>)
# cykly (<tt>for, while</tt>)
# příkazy <tt>break, continue</tt>
# složené podmínky


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


=== Grafické okno ===
=== Interaktivní vstup ===


<source lang=octave>
<source lang=octave>
figure    # -> 1
disp('Program vyzaduje vstup');
figure    # -> 2
a = input('Zadejte cislo a: ')
figure(4) # -> 4
</source>
</source>


* Pro zavření všech grafických oken najednou funguje příkaz
=== Vyhodnocování relačních výrazů, all, any ===
 
* 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>
close all
all([1 1 1])
all([0 0 1])
all([0 0 0])
</source>
* funkce '''any()''' (uvažujme např. vícero výsledků relačních výrazů současně)
<source lang=octave>
any([1 1 1])
any([0 0 1])
any([0 0 0])
</source>
</source>


=== Grafy funkcí ===
=== Větvení (if) ===


* <code>plot()</code> {{bullet}} [http://geo.fsv.cvut.cz/user/gin/git1/matlab.pdf#page=95 argumenty]
* [http://geo.fsv.cvut.cz/vyuka/155git1/matlab/matlab.pdf#page=71 syntaxe]


<source lang=octave>
<source lang=octave>
x = [0:3:360];
% skalární podmínka
y = sin(x*pi/180);
a = randi(10)    % randi(n) generuje náhodné přirozené číslo z intervalu od 1 do n
plot(x, y);
b = randi(10)
%
 
% nove okno
if a < b  % je-li podmínka pravdivá, proveď následující příkazy
figure(2)
    disp('a je mensi nez b');
plot(x, y, 'r+')
else      % není-li shora uvedená podmínka pravdivá, proveď následující příkazy
%
    disp('a je vetsi nebo rovno b');
% vice grafu najednou
end
figure(3)
 
z = cos(x*pi/180);
% vektorová podmínka
plot(x, y, '--b', x, z, ':k');
a = [1 2];
b = [0 3];
 
if a < b  % vyhodnotí se jako:  if all(a < b)
    disp('a je po prvcich vzdy mensi nez b');
else
    disp('a je po prvcich alespon jednou vetsi nez b');
end
 
% test na (ne)nulové prvky proměnné (proměnné a,b jsou typicky logické proměnné, obsahují tedy výsledky relačních výrazů, tj. 0 či 1)
if b      % totéž jako:  if all(b)
    disp('b neobsahuje zadne nulove cleny');
elseif a  % totéž jako:  if all(a)
    disp('b obsahuje nulovy clen, a neobsahuje zadne nulove cleny');
else
    disp('a i b obsahuji nulovy clen');
end
   
if any(b)
    disp('b obsahuje alespon jeden nenulovy clen');
end
</source>
</source>


{{fig|octave-graf-1|<code>plot(x, y, '--b', x, z, ':k')</code>}}
=== Větvení (switch) ===


==== Popisky grafů ====
<source lang=octave>
cislo = randi(10)
 
switch cislo    % pro následné vyjmenované hodonoty (v položkách case) proměnné cislo proveď uvedený příkaz
                % v závislosti na konkrétní hodnotě proměnné cislo
  case 1
    disp('cislo je 1')
  case {2,3}    % výčet více přípustných hodnot je proveden ve složených závorkách
    disp('cislo je 2 nebo 3')
  case {4,6,7}
    disp('cislo je 4, 6 nebo 7')
  otherwise    % pro výše neuvedené hodnoty proměnné cislo
    disp('cislo je 5 nebo vetsi nez 7')
end
</source>
 
=== Cyklus for ===


<source lang=octave>
<source lang=octave>
figure(4)
% tvorba vektoru
hold on % zapne kresleni grafu do aktivniho okna bez vymazani predchoziho obsahu
n = 4
plot(x,y,'m');
  for i = 1:n      % cyklus for poběží pro předem známý počet opakování (tj. pro předem vyjmenované hodnoty proměnné i)
plot(x,z,'b');
    a(i) = i^2    % vzniklý vektor obsahuje druhé mocniny indexu prvku
title('Funkce sinus a cosinus')
end
xlabel('argument ve stupnich')
 
ylabel('funkcni hodnota')
% tvorba matice
xlim([0 360])
m = 4  % pocet radku
ylim([-1.2 1.2])
n = 3  % pocet sloupcu
box on
for i = 1:m            % řádkový index
%
    for j = 1:n       % sloupcový index
% legenda
        A(i,j) = i+j  % vzniklá matice obsahuje součet řádkového a sloupcového indexu prvku
legend('sinus','cosinus','Location','SouthWest')
    end
       % prvni argumenty ('sinus','cosinus') jsou polozky legendy
end
      % 'Location' je jedna z vlastnosti objektu legend a bezprostredne po ni nasleduje nastaveni pripustne hodnoty teto vlastnosti ('SouthWest')
 
% V Matlabu lze pouzit i vhodnejsi umisteni legendy (nejmensi kolize s grafem)
% příklad - v matici vyhledat sudé řádky, v těchto řádcích změnit znaménko všech prvků (jedna z možných variant zápisu)
legend('sinus','cosinus','Location','Best')
A = rand(5,4)
% popr. zapis, ktery umisti legendu mimo plochu grafu
for i=1:size(A,1)
legend('sinus','cosinus',-1)
    if rem(i,2) == 0  % rem(a,b) ... zbytek po dělení čísla a číslem b; podle řádkového indexu i testujeme, zda jde o lichý či sudý řádek
%
        A(i,:) = -1 * A(i,:)
grid on
    end
plot([0 360],[0 0],'k')   % vykresleni osy x plnou cernou carou
end
hold off
</source>
</source>


{{fig|octave-graf-4|Graf s popisky}}
=== Cyklus while ===
 
==== Více grafů v jednom okně ====


<source lang=octave>
<source lang=octave>
x = 1:100;
a = 1;
figure(5)
b = 5;
% prvni graf
while a < b  % výpočet probíhá, dokud platí podmínka (tj. dokud je podmínka pravdivá)
subplot(2, 2, 1)
    a
plot(x, x)
    a = a + 1;
% druhy graf
end
subplot(2, 2, 2)
plot(x, sqrt(x))
% treti graf
subplot(2, 2, 3)
plot(x, log(x))
% ctvrty graf
subplot(2, 2, 4)
plot(x, x.^2)
</source>
</source>


{{fig|octave-graf-2|<code>subplot()</code>}}
=== Příkazy break, continue ===
 
==== Omezení oblasti grafu ====


<source lang=octave>
<source lang=octave>
x = 0:0.1:5;
for i = 1:5
y = exp(x);
    if i == 2
figure(6)
        continue;  % od tohoto místa cyklus for pokračuje dále, ovšem již pro další hodnotu proměnné i (tj. pro i=3);
% cely graf
                    % zbytek příkazů v těle cyklu for pro původní hodnotu proměnné (i=2) se již nevykoná
subplot(2, 1, 1)
    end
plot(x, y)
    if i == 4
% vysek grafu pro oblast x <1, 2>; y <0, 10>
        break;    % na tomto místě se cyklus for okamžitě ukončí
subplot(2, 1, 2)
    end
plot(x, y)
    fprintf('i = %d\n', i);
axis([1,2,0,10])
end
</source>
</source>


{{fig|octave-graf-3|<code>axis()</code>}}
=== Složené podmínky ===


==== Graf s orientaci os v S-JTSK ====
''' logické AND ''' - všechny podmínky musí platit současně
 
Vstupní data: [ftp://athena.fsv.cvut.cz/ZFG/GIT1/body.txt body.txt] <!--[http://geo102.fsv.cvut.cz/vyuka/155GIT1/data/body.txt body.txt]-->


<source lang=octave>
<source lang=octave>
% nacteni dat
% iterativní proces skončí již při splnění jedné z požadovaných přesností
vstup = fopen('body.txt','r');
dx = 10;   % přesnost v souřadnici x - apriorní hodnota
P = fscanf(vstup,'%f',[3 inf]);
dy = 10;  % přesnost v souřadnici y - apriorní hodnota
BYX = P';
i = 0;     % čítač iterací
fclose(vstup);
while dx > 0.1 & dy > 0.1  % požadovaná přesnost pro obě souřadnice - 0.1 (např. mm)
    i = i+1
    dx = dx/2
    dy = dy/5
end


% vypocet smerniku
% výsledkem složené podmínky AND je, ze cyklus while skončí, jakmile již jedna z podmínek přestane platit; přesnost se tedy nedosáhne v obou souřadnicích, ale jen v jedné z nich !!
stan = [4001 730288.89 1054582.63]; % cb Y X (stanovisko)
DY = BYX(:,2) - stan(2);
DX = BYX(:,3) - stan(3);
sig = atan2(DY,DX);    % v radianech
sig = sig*200/pi;
% prevod smerniku do intervalu <0,400>
for i=1:length(sig)
    if sig(i)<0
        sig(i)=sig(i)+400;
    end
end
sig  % kontrolni zobrazeni vypoctenych hodnot smerniku


% kontrolni graf v JTSK
% totéž
figure(7)
dx = 10;   % přesnost v souřadnici x - apriorní hodnota
x = BYX(:,3);
dy = 10;   % přesnost v souřadnici y - apriorní hodnota
y = BYX(:,2);
i = 0;     % čítač iterací
cb = BYX(:,1);
while all([dx > 0.1, dy > 0.1])   % totéžwhile [dx > 0.1, dy > 0.1]
plot(-y,-x,'.r',-1*stan(2),-1*stan(3),'.b');
    i = i+1
for i=1:size(BYX,1)
    dx = dx/2
     cislab = num2str(cb(i));      % prevod numericke hodnoty na format string
    dy = dy/5
    text(-y(i)+0.4,-x(i),cislab);
end
end
cislos = stan(1);
text(-1*stan(2),-1*stan(3),num2str(cislos));
title('body v JTSK');
xlabel('Y'); ylabel('X');
%
% v Matlabu je mozne i dalsi siroke ovladani vzhledu grafu, napr.:
% ----------------------------------------------------------------
% nastaveni pozice popisu os pro aktivni osy
set(gca,'XAxisLocation','top','YAxisLocation','right');  % gca - vrati identifikator pro objekt aktivnich os
%
% zapis spravnych numerickych hodnot poradnic na (matlabovske) ose x
krokx = 10;  % rozestup poradnic
poradnicex = (-1*ceil(max(y)/10)*10) : krokx : (-1*floor(min(y)/10)*10) % definice okrouhlych hodnot poradnic
xlim([poradnicex(1) poradnicex(end)]);
set(gca,'XTick',poradnicex);                        % definice rysek poradnic
set(gca,'XTickLabel',sprintf('%.0f|',-poradnicex)); % definice popisu rysek poradnic spolu s nastavenim jejich formatu
%
% zapis spravnych numerickych hodnot poradnic na (matlabovske) ose y
kroky = 10;
poradnicey = (-1*ceil(max(x)/10)*10) : kroky : (-1*floor(min(x)/10)*10)
ylim([poradnicey(1) poradnicey(end)]);
set(gca,'YTick',poradnicey);
set(gca,'YTickLabel',sprintf('%.0f|',-poradnicey));
</source>
</source>


==== Polární graf ====
''' logické OR ''' - musí platit alespoň jedna podmínka
* např. zobrazení polohy satelitu (tzv. Skyplot)


<source lang=octave>
<source lang=octave>
ele = [80 30 10 50];   % elevacni uhel satelitu [°]
% iterativní proces skončí až po splnění všech požadovaných přesností
azi = [10 110 220 330]; % azimut satelitu [°]
dx = 10;   % přesnost v souřadnici x - apriorní hodnota
azi = azi*pi/180;
dy = 10;   % přesnost v souřadnici y - apriorní hodnota
figure(8)
i = 0;     % čítač iterací
polar(pi/2-azi,90-ele,'*');
while dx > 0.1 | dy > 0.1  % požadovaná přesnost pro obě souřadnice - 0.1 (např. mm)
    i = i+1
    dx = dx/2
    dy = dy/5
end
 
% výsledkem složené podmínky OR je, ze cyklus while skončí, až všechny z podmínek přestanou platit; přesnost se tedy dosáhne ve všech souřadnicích !!
 
% totěž
dx = 10;  % přesnost v souřadnici x - apriorní hodnota
dy = 10;  % přesnost v souřadnici y - apriorní hodnota
i = 0;    % čítač iterací
while any([dx > 0.1, dy > 0.1])
    i = i+1
    dx = dx/2
    dy = dy/5
end
</source>
</source>


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

Aktuální verze z 13. 4. 2023, 03:54

Algoritmizace, podmínky a cykly

Náplň

  1. zobrazení zpráv, zadaní vstup
  2. podmínky (if, else, elseif, end, all, any)
  3. větvení (switch)
  4. cykly (for, while)
  5. příkazy break, continue
  6. složené podmínky

Ukázky

Interaktivní vstup

 disp('Program vyzaduje vstup');
 a = input('Zadejte cislo a: ')

Vyhodnocování relačních výrazů, all, any

  • 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ě)
 all([1 1 1])
 all([0 0 1])
 all([0 0 0])
  • funkce any() (uvažujme např. vícero výsledků relačních výrazů současně)
 any([1 1 1])
 any([0 0 1])
 any([0 0 0])

Větvení (if)

% skalární podmínka
 a = randi(10)    % randi(n) generuje náhodné přirozené číslo z intervalu od 1 do n
 b = randi(10)

 if a < b   % je-li podmínka pravdivá, proveď následující příkazy
     disp('a je mensi nez b');
 else       % není-li shora uvedená podmínka pravdivá, proveď následující příkazy
     disp('a je vetsi nebo rovno b');
 end

% vektorová podmínka
 a = [1 2];
 b = [0 3];

 if a < b  % vyhodnotí se jako:  if all(a < b)
     disp('a je po prvcich vzdy mensi nez b');
 else
     disp('a je po prvcich alespon jednou vetsi nez b');
 end

% test na (ne)nulové prvky proměnné (proměnné a,b jsou typicky logické proměnné, obsahují tedy výsledky relačních výrazů, tj. 0 či 1)
 if b      % totéž jako:  if all(b)
     disp('b neobsahuje zadne nulove cleny');
 elseif a  % totéž jako:  if all(a)
     disp('b obsahuje nulovy clen, a neobsahuje zadne nulove cleny');
 else
     disp('a i b obsahuji nulovy clen');
 end
    
 if any(b)
     disp('b obsahuje alespon jeden nenulovy clen');
 end

Větvení (switch)

 cislo = randi(10)

 switch cislo    % pro následné vyjmenované hodonoty (v položkách case) proměnné cislo proveď uvedený příkaz
                 % v závislosti na konkrétní hodnotě proměnné cislo 
   case 1
     disp('cislo je 1')
   case {2,3}    % výčet více přípustných hodnot je proveden ve složených závorkách 
     disp('cislo je 2 nebo 3')
   case {4,6,7}
     disp('cislo je 4, 6 nebo 7')
   otherwise     % pro výše neuvedené hodnoty proměnné cislo
     disp('cislo je 5 nebo vetsi nez 7')
 end

Cyklus for

% tvorba vektoru
 n = 4
 for i = 1:n       % cyklus for poběží pro předem známý počet opakování (tj. pro předem vyjmenované hodnoty proměnné i)
     a(i) = i^2    % vzniklý vektor obsahuje druhé mocniny indexu prvku
 end

% tvorba matice
 m = 4  % pocet radku
 n = 3  % pocet sloupcu
 for i = 1:m            % řádkový index
     for j = 1:n        % sloupcový index
         A(i,j) = i+j   % vzniklá matice obsahuje součet řádkového a sloupcového indexu prvku
     end
 end

% příklad - v matici vyhledat sudé řádky, v těchto řádcích změnit znaménko všech prvků (jedna z možných variant zápisu)
 A = rand(5,4)
 for i=1:size(A,1)
     if rem(i,2) == 0   % rem(a,b) ... zbytek po dělení čísla a číslem b; podle řádkového indexu i testujeme, zda jde o lichý či sudý řádek
         A(i,:) = -1 * A(i,:)
     end
 end

Cyklus while

 a = 1;
 b = 5;
 while a < b   % výpočet probíhá, dokud platí podmínka (tj. dokud je podmínka pravdivá)
     a
     a = a + 1;
 end

Příkazy break, continue

 for i = 1:5
     if i == 2
         continue;  % od tohoto místa cyklus for pokračuje dále, ovšem již pro další hodnotu proměnné i (tj. pro i=3);
                    % zbytek příkazů v těle cyklu for pro původní hodnotu proměnné (i=2) se již nevykoná
     end
     if i == 4
         break;     % na tomto místě se cyklus for okamžitě ukončí
     end
     fprintf('i = %d\n', i);
 end

Složené podmínky

logické AND - všechny podmínky musí platit současně

% iterativní proces skončí již při splnění jedné z požadovaných přesností
 dx = 10;   % přesnost v souřadnici x - apriorní hodnota
 dy = 10;   % přesnost v souřadnici y - apriorní hodnota
 i = 0;     % čítač iterací
 while dx > 0.1 & dy > 0.1   % požadovaná přesnost pro obě souřadnice - 0.1 (např. mm)
     i = i+1
     dx = dx/2
     dy = dy/5
 end

% výsledkem složené podmínky AND je, ze cyklus while skončí, jakmile již jedna z podmínek přestane platit; přesnost se tedy nedosáhne v obou souřadnicích, ale jen v jedné z nich !!

% totéž
 dx = 10;   % přesnost v souřadnici x - apriorní hodnota
 dy = 10;   % přesnost v souřadnici y - apriorní hodnota
 i = 0;     % čítač iterací
 while all([dx > 0.1, dy > 0.1])   % totéž:  while [dx > 0.1, dy > 0.1]
     i = i+1
     dx = dx/2
     dy = dy/5
 end

logické OR - musí platit alespoň jedna podmínka

% iterativní proces skončí až po splnění všech požadovaných přesností
 dx = 10;   % přesnost v souřadnici x - apriorní hodnota
 dy = 10;   % přesnost v souřadnici y - apriorní hodnota
 i = 0;     % čítač iterací
 while dx > 0.1 | dy > 0.1   % požadovaná přesnost pro obě souřadnice - 0.1 (např. mm)
     i = i+1
     dx = dx/2
     dy = dy/5
 end

% výsledkem složené podmínky OR je, ze cyklus while skončí, až všechny z podmínek přestanou platit; přesnost se tedy dosáhne ve všech souřadnicích !!

% totěž
 dx = 10;   % přesnost v souřadnici x - apriorní hodnota
 dy = 10;   % přesnost v souřadnici y - apriorní hodnota
 i = 0;     % čítač iterací
 while any([dx > 0.1, dy > 0.1])
     i = i+1
     dx = dx/2
     dy = dy/5
 end

Úlohy