Přeskočit na obsah

Pokročilá práce s poli

V částech podmínky a cykly jsem zmínil základní prvky jazyka fortran, které se dají použít obecně pro všechny struktury. Fortran ovšem poskytuje další funkce, které jsou speciálně navržené pro práci s poli.

příkaz where

Přikaz kombinuje cyklus s podminkou a slouží převážně k přiřazování hodnot prvkům pole. Podmínky musí být buď pole logical stejného tvaru jako pole v kódu nebo podmínka aplikovatelná na každý prvek pole v kódu.

    where (podmínka1) 
    
    	...kód...
    
    else where (podmínka2)
    
    	...další kód...
    
    end where
    					
    program stat_where
      implicit none
      
      real :: a(10),b(10),c(10)
      
      call random_number(a)
      call random_number(b)
      
      a = nint(a)*1.
      b = nint(10.*b)*1.
      
      write(*,'(10f7.1)') a
      write(*,'(10f7.1)') b
      
      where(a /= 0.)
        c = b/a
      else where
        c = 1.
      end where
      
      write(*,'(10f7.1)') c
      
    end program
    					

příkaz do concurrent

Příkaz je jako příkaz do až na to, že nemusí procházet pole postupně. Příkaz vznikl pro tzv. autoparelelizaci kompilérů. Oproti příkazů do by měl být rychlejší, ale jsou na něj kladena omezení. Např. uvnitř se smí používat jen pure funkce, aby se zabránilo vedlejším efektům, které by narušovali paralelní běh. Tento příkaz přišel s Fortranem 2008 a má nahradit příkaz forall, který je téměř stejný.

    do concurrent (i = L:U) 
    
    	...příkazy pracující s polem...
    
    end forall
    					

    program do_concurrent
      use iso_fortran_env
      implicit none
     
      integer,parameter :: n = 10000
      
      integer :: i,j
      real :: t1, t2
      real :: a(n),c(n,n)
      
      call random_number(a)
     
      call cpu_time(t1)
      do i=1,n
        do j=1,n
          c(i,j) = a(i) - a(j)
        end do
      end do
      call cpu_time(t2)
      write(*,*) "do            ", t2-t1
      
      call cpu_time(t1)
      do concurrent (i=1:n, j=1:n)
        c(i,j) = a(i) - a(j)
      end do 
      call cpu_time(t2)
      write(*,*) "do concurrent ", t2-t1
     
    end program
    					

další vnitřní funkce s poli

Zde následuje výčet dalších funkcí, které fortran podporuje. Tento seznam nemusí být úplný a některé funkce používájí další volitelné argumenty. V případě, že budete potřebovat podrobnější informace doporučuji se podívat do manuálu kompilátoru, který používáte. (V hranatých závorkách [] jsou vepoviné argumenty). Výraz mask je pole logických výrazů (např. pole A > pole B = ṕole logical apod.).

  • all(mask) - vrátí .true. pokud všechny prvky masky jsou .true.
  • any(mask) - vrátí .true. pokud některý prvek masky je .true.
  • count(mask) - vrátí počet (integer) prvků masky rovnající se .true.
  • merge(A, B, mask) - sloučí pole A a B podle masky. Pokud prvek masky je .true. je prvek výstupního pole prvek pole A jinak prvek pole B
  • pack(A, mask [,vector]) - vytvoří nám jednorozměrné pole skládající se z prvků pole A tam kde je maska .true.. Maska může být jen skalární .true., potom může převést vícerozměrné pole na jednorozměrné pole. Pokud zadáme vector, doplní se prvky z pole vector aby výsledné pole mělo stejný počet prvků jako pole A
  • unpack(vector, mask [, field]) - rozbalý vektor (1D pole) do tvaru a velikosti masky. Pokud zadáme field výsledné pole bude mít prvek z pole vector tam kde je maska .true. a tam kde je .false. prvek z pole field
  • reshape(A, tvar) - změní tvar pole A na zadaný tvar tvar