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

Z GeoWikiCZ
Holesovsky (diskuse | příspěvky)
Holesovsky (diskuse | příspěvky)
 
(Není zobrazeno 18 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>
<!--
# grafy funkcí <code>plot(), subplot(), polar()</code>
# zobrazení zpráv, zadaní vstup
-->
# 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 ==
<!--
=== Interaktivní vstup ===


=== Grafické okno ===
<source lang=octave>
disp('Program vyzaduje vstup');
a = input('Zadejte cislo a: ')
</source>
-->
 
=== 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>
figure    # -> 1
all([1 1 1])
figure    # -> 2
all([0 0 1])
figure(4) # -> 4
all([0 0 0])
</source>
</source>
 
* funkce '''any()''' (uvažujme např. vícero výsledků relačních výrazů současně)
* Pro zavření všech grafických oken najednou funguje příkaz
<source lang=octave>
<source lang=octave>
close all
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) ===
 
<source lang=octave>
cislo = randi(10)


==== Popisky grafů ====
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 ''' - '''"a zároveň"''' - všechny podmínky musí platit současně


Vstupní data: [http://geo102.fsv.cvut.cz/vyuka/155GIT1/data/body.txt body.txt]
<source lang=octave>
% souvislý interval omezený z obou stran
a = rand(1,4)
relace1 = a > 0.2 & a < 0.7          % interval od 0.2 do 0.7
relace2 = all( a > 0.2 & a < 0.7 )  % relace platí ve všech složkách
                                      % relace1 a relace2 jsou totožné
                                      % (all je defaultní logická funkce)
</source>


<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, že 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 ''' - '''"nebo"''' - 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 [°]
% interval složený ze dvou částí
azi = [10 110 220 330]; % azimut satelitu [°]
a = rand(1,4)
azi = azi*pi/180;
relace3 = a < 0.2 | a > 0.7          % interval do 0.2 a od 0.7
figure(8)
relace4 = all( a < 0.2 | a > 0.7 )  % relace platí ve všech složkách
polar(pi/2-azi,90-ele,'*');
                                      % relace3 a relace4 jsou totožné
relace5 = any( a < 0.2 | a > 0.7 )  % relace platí alespoň v jedné složce
</source>
 
<source lang=octave>
% 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, že 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 / 9. cvičení / Příklady|9. cvičení - příklady]]
* [[155GIT1 / 6. cvičení / Příklady|6. cvičení - příklady]]
<!-- -->

Aktuální verze z 28. 3. 2025, 16:47

Algoritmizace, podmínky a cykly

Náplň

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

Ukázky

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 - "a zároveň" - všechny podmínky musí platit současně

% souvislý interval omezený z obou stran
 a = rand(1,4)
 relace1 = a > 0.2 & a < 0.7          % interval od 0.2 do 0.7
 relace2 = all( a > 0.2 & a < 0.7 )   % relace platí ve všech složkách
                                      % relace1 a relace2 jsou totožné
                                      % (all je defaultní logická funkce)
% 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, že 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 - "nebo" - musí platit alespoň jedna podmínka

% interval složený ze dvou částí
 a = rand(1,4)
 relace3 = a < 0.2 | a > 0.7          % interval do 0.2 a od 0.7
 relace4 = all( a < 0.2 | a > 0.7 )   % relace platí ve všech složkách
                                      % relace3 a relace4 jsou totožné
 relace5 = any( a < 0.2 | a > 0.7 )   % relace platí alespoň v jedné složce
% 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, že 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