Řízení toku programu

Příkazy se ve Fortranu provádějí postupně od začátku zdrojového textu do konce, není-li řečeno jinak.

Zápis podmínek

Rozvětvení řídícího toku programu lze realizovat třemi typy podmínek:

Tyto zápisy říkají počítači, že má vyhodnotit podmínku a je-li splněna pokračovat prvním příkazem. V opačném případě buď pokračuje druhým příkazem nebo neudělá nic.

Cykly

Opakované provádění příkazů zajišťují cykly.

První cyklus je nekonečný cyklus, opakuje se donekonečna pokud není přerušen například příkazem exit. který vyskočí z cyklu. Tato konstrukce umožňuje psát cykly s podmínkou na začatku, na konci i kdekoli jinde.

V dalších dvou případech cykly fungují tak, že říkají počítači aby vyhodnotit podmínku a je-li splněna vstoupit do cyklu, vykonat v něm příkazy, opět testovat podmínku, pokud je splněna vykonat příkazy, atd. While cykus má za podmínku logický výraz, prostřední aritmetický cyklus testuje hodnotu řídící proměnné kterou po každém vyhodnocení těla cyklu zvětší o hodnotu krok.

Ukončení programu

Normálně končí program v okamžiku, když už nemá na vykonání žádné příkazy. Jiná možnost bezpodmínečného ikončení programu je příkaz stop 'text' ktery ukončí program a na standardní výstup vypíše 'text'.

Skok a prázný příkaz

Příkaz skoku přenese další provádění programu na zvolený řádek. Příkaz goto 666 skočí na řádek označený návestím 666. Obyčejně je na řádku prázdný příkaz continue který nedělá nic. Dvojice těchto příkazů má především význam při ukončování komplikovaných vnořených cyklů s podmínkami a dále pak při ošetření havarie.

Řešení nelineárních rovnic

Dvě nejpoužívanější jednoduché metody řešení rovnic jsou robustní ale pomalé půlenní intervalu a rychlá ale méně stabilní Newtonova metoda. Na těchto jednoduchých metodách budeme demonstrovat základní použití podmínek a cyklů.

Půlení intervalu

Tahle metoda hledá řešení rovnice v předem zadaném intervalu na jednom jejímž okraji je funkce kladná na na druhém záporná. Program pak dělí zadanný interval na polovinu tak dlouho, dokud není jeho délka menší než předem zadaná hodnota. Jediným problémem je rozhodnout, ve kterém ze dvou vytvořených intervalů je skutečný kořen rovnice. Ten je ovšem opět v takovém intervalu, kde mají hodnoty opačná znaménka a tedy jejich součin je záporný.


program pulky
! program resi rovnici cos(x) = 0 metodou puleni intervalu
integer :: i,maxn
real :: a,b,x,fa,fb,fx,tol

! zadani intervalu
a = 1
b = 2

! maximalni pocet opakovani
maxn = 100

! hledana presnost vypoctu
tol = 1e-2

! vypocet funkce na krajich intervalu
fa = cos(a)
fb = cos(b)

i = 1
do 

   ! vypocet pulky intervalu a hodnoty v nem
   x = (a + b)/2.0
   fx = cos(x)

   ! vypis aktualniho korene
   write(*,*) "iterace = ",i," hodnota funkce = ",fx," odhad korene = ",x
    
   ! testy ukonceni
   if( fx == 0.0 ) exit
   if( abs(b - a)/2.0 < tol ) exit
   if( i >= maxn ) exit
   i = i + 1

   ! urceni intervalu ve kterem je koren
   if( fx*fb < 0 ) then     
     ! v intervalu x..b je koren
     a = x
     fa = fx
   else
     ! v intervalu a..x neni koren
     b = x
     fb = fx
   endif
enddo     

! vypis vysledku
write(*,*) "pocet iteraci = ",i
write(*,*) "hledany koren = ",x
write(*,*) "hodnota funkce = ",fx

end

Newtonova metoda

Tato metoda vychazí z myšlenky obráceneho Taylorova rozvoje funkce:

kterou lze do převést na tvar

Implementace je jednodušší než u metody půlení.


program Newton
! program resi rovnici cos(x) = 0 newtonovou metodou
integer :: i,maxn
real :: x,fx,f1,tol

! zadani pocatecniho odhadu minima, napr. z pulek
x = 1.5

! maximalni pocet opakovani
maxn = 100

! hledana presnost vypoctu
tol = 1e-5

! vypocet funkce 
f = cos(x)

do i = 1, maxn
  
   ! vypocet derivace
   f1 = -sin(x)

   ! vypocet noveho odhadu korene
   if( f1 /= 0.0 ) then
      x = x - f/f1
   else
      stop 'Nulova derivace'
   endif

   ! vypis aktualniho korene
   write(*,*) "iterace = ",i," funkce = ",fx," derivace = ", f1, &
              " odhad korene = ",x, 

   ! testy na ukonceni   
   if( abs(x) < tol ) exit

enddo     

! vypis vysledku
write(*,*) "pocet iteraci = ",i
write(*,*) "hledany koren = ",x
write(*,*) "hodnota funkce = ",fx

end

Tento poslední program obsahuje jednu nebo více chyb.