Polja v Fortranu

Polja

Polja deklratiramo i atributom dimension. Pomnite, da so polja shranjena v spominu kot kolone, kar pri izpisu izgleda kot transponiran izpis. Tako bo pri definiciji

 real, dimension(3,2) :: a
write(*,*) a

izpisalo polja v naslednjem vrstnem redu: 1,3, 5, 2, 4, 6

Če želimo pravilen matematični izpis po vrsticah je potrebno izpisati v zanki

 do i = 1,3
  write(*,*) (a(i,j), j = 1,2) ) ! vgrajena zanka
end do

Podnaslavljanje

Za primer polja

 real, dimension(1:10) :: a

lahko dele polja naslovimo z

  • a(7:) ! a(7), a(8), a(9), a(10)
  • a(2:10:2) ! a(2), a(4), a(6), ...
  • a(:) ! whole array
  • a(10:2:-2) ! a(10), a(8), a(6),...

Tako lahko tudi cele range uporabljamo v artimetiki

  • a(1:10) = 0.0 ! priredi 0 vsem elementom
  • a(:) = a(:) + 1.0 ! dodaj 1 vsakemu elementu
  • a = 0.0 ! priredi polju ali skalarju?

Lahko tudi inicializiramo ob začetku programa s konstruktorjem (/.../)

  • real, dimension(2) :: s = (/ -1.0, 1.0 /)
  • a(1:5) = (/ 1.0, -1.0, 1.0, -1.0, 1.0 /)

ali z vsebovano zanko

  • real, dimension(10000) :: a = (/ (i, i = 1, 10000) /)

Skladna polja

Za medsebojno delo morajo biti polja skladna (konformna)

  • imeti morajo enako obliko
  • oz. isti rank (število dimenzij)
  • enak obseg v vsaki smeri

Pogojni operatorji

Za polja obstajajo tudi pogojni operatorji, ji se izvajajo na polju kot celota

  • Pogojni if
where (logical array-expression)
    array assignments
[else where] (logical array-expression)
   array assignments
end where

Forall

Namesto

 do i = 1, n
  a(i, i) = x(i)
end do

lahko uporabimo tudi

 forall(i = 1:n) a(i, i) = x(i)

ali celo bolj zahtevne izvedbe

 forall(i = 1:n)
  where (a(i, :) == 0) a(i, :) = i
  b(i, :) = i / a(i, :)
end forall

Vgrajene funkcije

lahko apliciramo tudi na polja kot celoto s tem da npr. a = sqrt(a) izračuna korene za vse elemente polja. Za polja imamo tudi vgrajene funkcije za poizvedovanje (size, lbound, ubound,shape) in pretvorbo:

  • Ustvarjanje polj: spread, pack, reshape, …
  • Množenje vektorjev in matrik: dot_product, matmul
  • Redukcijske funkcije: sum, product, any, maxval, minval…
  • Geometrijske funkcije: minloc, maxloc
  • Manipulacijske: transpose, cshift, …

Predpostavljena in avtomatska polja

Fortran omogoča prilagodljive velikosti polj

  • velikost je določena ob vstopu v podprogram
  • Se lahko uporablja le v podprogramu
  • Omogoča prilagodljivo ponovno izrabo v podprogramu
  • dimenzije teh polj so znane v času prevajanja
  • V fortranu 90 je znana kot privzeta-obllika ali avomatsko polje
  • Deklariramo z
 real, dimension(:) :: a! 1D polje
real, dimension(:,:) :: b! 2D polje
real, dimension(:,:,:) :: c ! 3D polje

Lokalne spremenljivke, ki so spremenljive velikosti so avtomatske. Velikost je lahko predpostavljana

 subroutine swap(a, b)
  real, dimension(:), intent(inout) :: a, b

Dinamična polja

  • Velikost se alocira pri izvajanju
  • zelo prilagodljiva, lahko pa upočasnijo računanje
  • Manjkajo meje za kontrolo pri prevajanj
  • V Fortranu so to alocirana (zasedena)  polja

Deklarira se jih z:

 real, dimension(:), allocatable:: names ! 1D polje
real, dimension(:,:), allocatable:: grid ! 2D polje

Spomin se alocira (priredi) in dealocira (sprosti) z ukazom

 allocate(work(n,2*n,3*n))
deallocate(work)

Primer dimaničih polj v modulu:

 module work_array
  implicit none
  integer :: n
  real, dimension(:,:,:), allocatable:: work
end module work_array

program main
  use work_array
  implicit none
  read(*,*) n
  allocate(work(n,2*n,3*n))
  . . .
  deallocate(work)
end program main