Introduction to Arrays
The arrays is one of the most important types in Fortran. It can represent many mathematical entities such as grids, matrices, vectors, and so forth. The members of an array are frequently called elements. From the computational point of view, an array is a data structure that contains data of the same type with each scalar element addressed by indexing into the array. Indices must be integers. An array has one or more dimensions . The bounds are the lowest and highest indexes. The rank is the number of dimensions. The size of an array is the number of elements. The shape is a tuple giving the size in each individual dimension.
Arrays must be declared by type and either by size or by some indication of the number of dimensions. The simplest case is static arrays, which are declared to be of a fixed size and shape.
REAL, DIMENSION(100) :: A INTEGER, DIMENSION(50,50) :: INDS CHARACTER(LEN=3), DIMENSION(12) :: MONTHS
By default the index starts at 1. However, it can start at any integer less than the upper bound:
REAL, DIMENSION(-1:101,0:3) :: A0
Arrays may have zero size. The maximum (standard) dimensions up to the F2003 standard is 7. This increases to 15 in F2008. Fortran arrays carry metadata (shape, size, bounds, some other data) about themselves and these data can be extracted by intrinsic functions.
Each element can be addressed by its index or indices, which must be enclosed in parentheses.
Remember that the bounds start at 1 by default.
Compiler Bounds Checking
One of the most common errors in programming, in all languages that support an array or something like it, is attempting to access an element with values for the indices that are outside the declared bounds. This frequently happens with loops such as
! Average nearest neighbors do j=1,m do i=1,n A(i,j)=0.25*(B(i+1,j)+B(i,j+1)+B(i-1,j)+B(i,j-1)) !OOPS enddo enddo
Most usually this results in an error such as “Segmentation fault.”
In Fortran, compilers know the size and shape of each array, once allocated, so they are able to check each operation to make sure it is within the bounds. However, since this can greatly slow down your executable, it must be invoked at compile time. The name of the option may vary from one compiler to another.
For gfortran and Intel they are:
gfortran -g -fbounds-check mycode.f90 ifort -g -CB mycode.f90 ifort -g -check bounds mycode.f90
Be sure to remove the options
-g -<array check> and replace with
-O once your program is debugged.
Fortran supports array operations in which an action is applied across an entire array, elementwise. All arithmetic operators and most of the mathematical functions are overloaded to accept array arguments, for arrays of numerical type.
T=3.0 A=3.14159*I B=sin(A) C=A/B !Watch out for elements that are zero
Array elements are adjacent in memory and are arranged linearly no matter how many dimensions you declare. If you declare a 3x2 array the order in memory is
(1,1), (2,1), (3,1), (1,2), (2,2), (3,2)
“Orientation” refers to how the array is stored in memory , not to any mathematical properties. Fortran is column-major oriented. Most other languages are row-major oriented. Loop indices should reflect this whenever possible (when you need loops). Fortran: outermost first. Go right to left.
do k=1,nz-1 do j=1,ny-1 do i=1,nx A(i,j,k) = C(i,j,k) !loop order is do k/do j/do i enddo enddo enddo
Array operations can be used to avoid loops in many cases, and the compiler will be able to optimize them automatically.
Obtaining Size and Shape Information
SIZE(ARRAY [,DIM]) function returns the number of elements in the array if
DIM is absent. If it is present, it returns the number of elements in that dimension, e.g. number of rows or columns.
SHAPE(ARRAY) function returns a one-dimensional array whose elements are the dimensions of the array.
RANK(ARRAY) function returns the rank (number of dimensions).
Where functions like a “vectorized”loop+conditional. The clauses must be array assignments.
where ( A>=0.0 ) B=sqrt(A) elsewhere B=0. end where
- Open a new file (you can call it arrays.f90) and type
program arrays ! Array demo ```fortran implicit none real, dimension(10) :: A integer :: i, j A=[(0.2*real(i),i=1,10)] end program
- In arrays.f90 1 Print the size and shape of the array A 2 Declare a new real array W of shape 10x10. Set all values to 1.0 using an array operation. 3 Declare another 10x10 array Z. Use a nested loop to set each element of W(i,j) to the sum of its row and column indices. Remember that Fortran loops should run over indices from right to left, e.g.
do j=1,N do i=1,M A(i,j)=something enddo enddo
4 Change the fourth column of the second row of Z to 1.1
- In arrays.f90
- Add a WHERE to set elements to W equal to the corresponding elements of Z if the element of Z is less than 7. Print W(2,4).
program arrays implicit none real, dimension(10,10) :: A integer :: i, j real, dimension(10,10) :: W, Z do j=1,10 do i=1,10 A(i,j)=0.1*i+0.2*j enddo enddo print *, size(A) print *, shape(A) W=1.0 do j=1,10 do i=1,10 Z(i,j)=i+j enddo enddo Z(2,4)=1.1 where (Z<7) W=Z endwhere print *,W(2,4) end program