What Is An Array?
What Is An Array?
What is an Array?
• An array is a collection of data of the same type.
Array elements are indexed or subscripted like x1, x2,
. . .. xn in mathematics.
1
1-D Arrays
• By now, I’m sure you have run across cases or
examples where you could have seen a use for
indexed variable names
• We do this with Fortran arrays
• Here is an example of the simplest type of array is a
1-D array: y(i+1) = 2.0*y(i)
Example
How x is stored
implicit none in computer
memory
integer x(10)
INTEGER i
.
do i=1,10 .
.
x(i) = i
end do
WRITE(*,*) x x(1)
end x(2)
x(3)
.
Program output: .
.
x(10)
1 2 3 4 5 6 7 8 9 10
.
.
.
2
Example
An obvious example of the usefulness of arrays is when you need to read in a lot of
related variables, such as temperature measurements taken at regular intervals
over time.
read(*,*) temp1
read(*,*) temp2
read(*,*) temp3
.
.
.
read(*,*) temp49
read(*,*) temp50
With arrays, the same thing can be accomplished much more easily:
real temp(50)
do i=1,50
read(*,*) temp(i)
end do
Declaration of Arrays
There are several ways to declare arrays:
real temp(50) or
real :: temp(50)
real, dimension temp(50) or
real, dimension :: temp(50)
real temp
dimension temp(50)
3
The DIMENSION Attribute
• A Fortran 90 program uses the DIMENSION attribute
to declare arrays.
• The DIMENSION attribute requires three components
in order to complete an array specification,
– rank,
– shape, and
– extent.
• The rank of an array is the number of “indices” or
“subscripts.” The maximum rank is 7 (i.e., seven-
dimensional).
• The shape of an array indicates the number of
elements in each “dimension.”
7
4
The DIMENSION Attribute
• The extent is written as m:n, where m and n (m ≤ n)
are Integers. We saw this in the SELECT CASE,
substring, etc.
• Each dimension has its own extent.
• An extent of a dimension is the range of its index. If
m: is omitted, the default is 1.
• A(-3:2) means possible indices are A(-3),A(-2) ,A(-1),
A(0),A(1),A(2)
• A(5:8) means possible indices are 5,6,7,8
• A(7) means possible indices are 1,2,3,4,5,6,7
Dimensions of Arrays
Examples: real temp(50)
which creates an array in which the first subscript is 1, and the last is 50, giving a
total of 50 values in the array.
However, arrays are not limited to a value of 1 as the lower subscript.
The general form is:
real temp(L:U)
10
10
5
Example
11
11
2-D Arrays
2-D arrays are a simple extension of the 1-D array concept:
real x(5,5)
12
12
6
Use of Array
• Fortran 90 has, in general, three different ways to use
arrays: referring to
– individual array element,
write(*,*) x(3), write(*,*) x(3,5)
• The first one is very easy. One just starts with the array
name, followed by () between which are the indices
separated by ,.
• Note that each index must be an INTEGER or an
expression evaluated to an INTEGER, and the value of
an index must be in the range of the corresponding 13
extent. But, Fortran 90 won’t check it for you
13
14
14
7
Example Use of Array
Suppose we have the following declarations:
INTEGER, PARAMETER :: L_BOUND = 3, U_BOUND = 10
INTEGER, DIMENSION(L_BOUND:U_BOUND, &
L_BOUND:U_BOUND) :: a
DO i = L_BOUND, U_BOUND DO i = L_BOUND, U_BOUND
DO j = L_BOUND, U_BOUND DO j = i+1, U_BOUND
A(i,j) = 0 t = a(i,j)
END DO a(i,j) = a(j,i)
a(i,i) = 1 a(j,i) = t
END DO END DO
END DO
15
Allocatable Arrays
• The default array type is compile-time
– array size is set in program
– if the program doesn’t need as much storage as
what is declared, then the program is wasting
memory storage
– if the program needs more storage than what is
declared, it may fail
• Fortran 90 introduces allocatable arrays
– allocatable arrays are run-time
– array size is set during the running of the program,
not at compile time
– allows arrays to be sized just right for the
particular application
16
16
8
Allocatable Arrays
• Allocatable arrays are distinguished from compile-time
arrays in two ways:
– a special declaration statement
– an allocate statement, in which the array size is
actually set
– a deallocate statement is also available, to return
memory to the pool
17
17
Form:
type, DIMENSION(:), ALLOCATABLE :: list
or
where
Purpose:
Declares that each of the identifiers in the list is an array whose size will
be specified during execution.
18
18
9
ALLOCATE Statement
where
list is a list of array specifications of the form:
array-name(l:u)
where the pair l:u is a pair of integer expressions, and
status-variable is an integer variable.
Purpose:
Allocates space for each array listed. The range of subscripts is given by
l:u. If l is one, only u need be specified (without the :). In the second
form, status-variable will be set to zero if allocation is successful, but will be
assigned some system-dependant error value if there is insufficient
memory, or if the array has already been allocated.
19
19
DEALLOCATE Statement
where
list is a list of names of currently allocated arrays
status-variable is an integer variable
Purpose:
Releases the memory allocated to the arrays listed. In the second form, the
integer variable status-variable will be set to zero if deallocation is
successful, but it will be assigned some system-dependent error value if it is
not successful, for example, if no memory was previously allocated to an
array.
20
20
10
Example
implicit none
INTEGER, DIMENSION(:), ALLOCATABLE :: x
INTEGER n, errstat, i
WRITE(*,*) "enter size for array x: "
READ(*,*) n
ALLOCATE(x(n))
do i=1,n
x(i) = i
end do enter size for array x: 10
do i=1,n
WRITE(*,*) x(i) 1
end do 2
DEALLOCATE(x) 3
end 4
5
Output: 6
7
8
9
10
Program Completed
Press Enter to Continue. 21
21
Array Constructors
• Rather than assign array values one by one, it is
convenient to give an array a set of values using an
array constructor.
22
22
11
Array Constructors
• There are three possible forms for the array
constructor values:
1. A scalar expression as in
X (1:4) = (/ 1.2, 3.5, 1.1, 1.5 /)
2. An array expression as in
X (1:4) = (/ A (I, 1:2), A (I+1, 2:3) /)
X(1)= A(I,1)
X(2)= A(I,2)
X(3)= A(I+1,2)
X(4)= A(I+1,3)
3. An implied do loop as in
x (1:4) = (/ (sqrt (real (i)), i = 1, 4) /) 23
x (1:4) = (/sqrt(y(i)),i=5,8)/)
23
Y(5:8)= (/4,9,16,25/)
Do i=5,8
x (1:4) = sqrt(y(i))
enddo
24
24
12
Array Constants
An array constant may be constructed of a list of values enclosed between (/ and /):
(/1,2,3,4,5,6,7,8,9,10/)
This method can be tedious if you have very many constants to assign to an array,
so there is a method that automates this, called the implied-do:
(/(i,i=1,10)/)
does exactly the same as above, but automates the process with the implied-do.
25
25
Examples
integer :: a(10)
a = (/1,2,3,4,5,6,7,8,9,10/)
integer :: a(10)
do i=1,10
a(i) = i
end do
26
26
13
There is a simple way to assign a constant value to an entire array:
integer :: a(100)
a = 0
assigns the value zero to EACH MEMBER of the array a. This is typically used to
initialize the values of array variables.
It is always a good idea to initialize all the values of all your array variables
(usually to zero for integer or real arrays, and to “ “ (a blank) for character
arrays).
This is because initial values of arrays are undefined, and if you perform logical
tests on array values that are undefined, results may be unpredictable.
27
27
Array Expressions
Operators and functions normally applied to simple expressions may also be applied
to arrays having the same number of elements and to arrays and simple expressions.
The operations to an array are carried out elementwise.
Output: 7 9 11 13 15 6 14 24 36 50
28
28
14
Array Sections and Subarrays
Sometimes it is necessary to construct arrays by selecting elements from another
array, called a parent array. These new arrays, called array sections or
subarrays, are constructed by using expressions of the form:
array-name(subscript-triplet)
or
array-name(vector-subscript)
29
29
Example
implicit none
INTEGER a(10), b(10), i
a = (/(i,i=1,10)/) assigns integer values 1-10 to a
b = a(10:1:-1)
has the effect of reversing the values
WRITE(*,*) a
WRITE(*,*) b
end
1 2 3 4 5 6 7 8 9 10
output
10 9 8 7 6 5 4 3 2 1
30
30
15
for array-name(vector-subscript)
31
31
As an aside, note that the same thing (in this case) can be accomplished with the
Fortran intrinsic function cshift:
implicit none
INTEGER i
CHARACTER a(10)
a = (/'A','B','C','D','E','F','G','H','I','J'/)
WRITE(*,*) a
DO i=1,10
a = CSHIFT(a,1)
WRITE(*,*) a
cshift(a,n) shifts the members
END DO of the array a by n places. If n is
end positive, the shift is to the left; if n is
negative, the shift is to the right.
Output: ABCDEFGHIJ
Array elements “pushed” to the left
BCDEFGHIJA
CDEFGHIJAB of the first member are re-inserted
DEFGHIJABC at the end of the array for n > 0.
EFGHIJABCD
FGHIJABCDE Array elements “pushed” to the right
GHIJABCDEF of the last member are re-inserted at
HIJABCDEFG the beginning of the array for n < 0.
IJABCDEFGH
JABCDEFGHI
ABCDEFGHIJ
32
32
16
Input/Output with Arrays
I/O with arrays is greatly facilitated by the implied do-loop.
implicit none 1
INTEGER i, a(50) 2
do i=1,50 which produces 3
.
.
a(i) = i the output: .
48
end do
49
do i=1,50 50
WRITE(*,*) a(i)
end do
33
33
implicit none
INTEGER i, a(50)
do i=1,50
a(i) = i
end do
WRITE(*,*) (a(i),i=1,50)
end
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
Note that there is not a line break after the number 30, the line just wrapped
because of the size of the window that it was originally written to.
In the previous case, the write statement was encountered 50 times, and so there
were 50 new lines. But with the implied-do, the effect is that the write statement is
only encountered once, thus all the values that are written are written without line
breaks, unless you put them in with a format statement.
34
34
17
This makes it easy to create nice looking output:
implicit none
INTEGER i, a(50) Notice that the first 1x in the
do i=1,50 format statement must go inside
a(i) = i the repeat parenthesis, because
end do there must be a blank at the
WRITE(*,10) (a(i),i=1,50) beginning of each line to control
10 FORMAT(10(1x,i2,1x)) line spacing properly.
end
Output: 1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
35
35
In this example, assume that the output on the previous page is saved in a file
called “inputa.txt”. This program reads the values in, and prints them out in the
same form:
implicit none
INTEGER i,j, a(5,10)
OPEN(UNIT=10,FILE="inputa.txt")
READ(10,*) ((a(i,j),i=1,5),j=1,10)
WRITE(*,10) ((a(i,j),i=1,5),j=1,10)
10 FORMAT(10(1x,i2,1x))
end
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
Output: 21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
36
36
18
WHERE Statement
Form:
WHERE (logical-array-expr) array-var1 = array-expr1
or
WHERE (logical-array-expr)
array-var1 = array-expr1
.
.
.
array-varm = array-exprm
ELSEWHERE
array-varm+1 = array-exprm+1
.
.
.
array-varn = array-exprn
END WHERE
Where:
logical-array-expr is a logical-valued array expression and each array-vari has
the same size as the value of logical-array-expr; in the second form, the
ELSEWHERE part is optional.
Purpose:
Evaluates logical-arry-expr element by element. Whenever the expression is true,
assigns the value of the corresponding element of each array-expri to the corresponding
element of array-vari. All other elements are left unchanged in the first form.
38
38
Example
Now let’s use the where construct to re-write the random number program:
Program Output
implicit none 0.43 0
REAL x(10)
0.45 0
INTEGER jump(10),i
!You have(x) with random numbers
0.91 1
where (x > 0.5) 0.48 0
jump = 1 0.72 1
elsewhere 0.73 1
jump = 0 0.90 1
end where 0.47 0
do i=1,10
0.10 0
WRITE(*,10) x(i), jump(i)
10 FORMAT(1x,f5.2,1x,i1)
0.33 0
end do
end
39
39
19
Let’s examine this program more carefully:
40
40
41
41
20
Fortran 90 Intrinsic Array-Processing
Subprograms
MAXVAL
• Returns the maximum value of all elements in an array, a
set of elements in an array, or elements in a specified
dimension of an array.
• Syntax
• result = MAXVAL (array [, dim] [, mask])
• array (Input) Must be an array of type integer or real.
• dim (Optional; input) Must be a scalar integer expression
with a value in the range 1 to n, where n is the rank of
array.
• mask (Optional; input) Must be a logical array that is
conformable with array.
42
42
43
43
21
Fortran 90 Intrinsic Array-Processing
Subprograms
• Examples
1. The value of MAXVAL ((/2, 3, 4/)) is 4 because that is the
maximum value in the rank-one array.
44
45
45
22
Fortran 90 Intrinsic Array-Processing
Subprograms
• Results:
• The result is an array of type default integer.
• The following rules apply if dim is omitted:
• The array result has rank one and a size equal to the rank of
array.
• If MINLOC(array) is specified, the elements in the array result
form the subscript of the location of the element with the
minimum value in array. The ith subscript returned lies in the
range 1 to ei, where ei is the extent of the ith dimension of array.
• If MINLOC(array, MASK=mask) is specified, the elements in the
array result form the subscript of the location of the element with
the minimum value corresponding to the condition specified by
mask.
46
46
47
23
Assignment
1) Write a program to read values from an input data
file and to sort them into ascending order.
48
48
24