Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
Stuff to know about arrays
Motivation: Arrays are an important part of FORTRAN as a scientific
computing language. In heat transfer, for example, we might wish to
represent a temperature field along a rod (e.g. T(x)). To do this numerically,
one might introduce a grid along the Cartesian axis (e.g. grid_x = {x_1 < x_2
< ...< x_N} ). The temperature field could be described approximately by
giving the values T(x_i).
Implementation: In ELF90 array status is bestowed by the dimension
attribute. Any of the data types is available as an array. While arrays have
long been part of the FORTRAN language, the way F90 deals with arrays is
one of the most significant changes from the F77 (and earlier) dialect(s).
real,
dimension(5)
integer , dimension(0:10)
:: x , z! x and z are real arrays of rank one
:: in ! in is an integer array of rank one
An array has rank - the number of dimension parameters; shape - the extent
in each dimension, and size - the total number of elements. Here we focus
initially on the rank-one case. In this case shape and size will have the
same value.
real, dimension (10) :: grid_x ! rank one, shape is 10, size is 10
real, dimension (0:10) :: grid_y ! rank one, shape and size are 11
integer, dimension (2:5) :: dum ! rank one, shape and size are 4
F90 ‘knows’ the rank, shape and size of an array, along with the numerical
values that fill it in. Note in the grid_y and dum examples, that array indices
do not have to start at 1.
Higher Rank: In some cases it is natural to imagine the array as a table with
rows and columns. Fortran 90 permits this structure as a rank - two array.
real, dimension (0:10,25)::temp ! rank two, shape is 11 by 25 , size is 275
Array storage: For some purposes it’s helpful to know that FORTRAN stores
rank two arrays in ‘column order’; thus our temp example above has the
elements stored in the order {temp(0,1), temp(1,1),...,temp(10,1),
temp(0,2), ... ,temp(10,25)}.
Array indexing: The individual array elements of any type can be used
exactly like scalar data of the same type. This is done via element subscripts.
Thus, based on our examples above, we can have grid_x(4) or grid_y(8) or
temp(i,j) (here i,j must be integer type). However, grid_x(0), or grid_y(i,j), or
temp(k) will cause a compiler error. This element subscripting can be used in
any legal scalar expression. To sum the elements in grid_x we can write:
ans = 0; do i=1,10; ans = ans + grid_x(i); end do
F90 also permits use of the entire array in expressions. The arrays must be
compatible (rank, shape, size) for this to be well-defined. From our first
example above, we can have z = x , meaning the entire arrays. We can also
read (7,*) dum to read the entire array (list-directed) in the order noted
above. F77 allows (only) this read/write reference to an entire array.
F90 has a number of powerful features for manipulating arrays. One of these
is a built-in utility called shape - when applied to an array this produces a
rank one integer array; the shape and size of the result are equal to the
rank of the original array. The values in this array are the extent of the array
in each dimension. Thus- shape(temp) = [ 11, 25]. A related utility is called
size yields the size of the array so that size(temp) = 275.
We can also manipulate array sections. This is similar to features in
Mathematica, Maple, Matlab and other modern languages.
grid_x(2:8:2] refers to the elements 2, 4, 6 & 8 in the grid_x array. This
section has rank - one, shape and size 4. This i:j:k notation is referred to as a
subscript triplet - i is the lower-bound, j is the upper-bound and k is the
stride. These must have integer value in the legal range for the array in
question. If not present k is assumed to be unity, if i is not present it’s
assumed to be the declared lower bound and j, if not present, is assumed to
be the declared upper-bound. Thus, temp(0,:) refers to the entire first row o f
the temp array; the array section has rank one, shape and size 25. On the
other hand, temp(1:1,1:5] has rank two, shape 1 by 5 and size 5. A shape
of 1 by 5 is not the same as a shape of 5. Indeed, a shape 1 array is not the
same as a scalar, that is grid_x(2) = grid_x(2:2) will also cause an error.
We can write arithmetic expressions using these array and array section
references. In this form scalar quantities are interpreted as arrays o f
compatible size. Thus, in z = 2*sin(x) + 5 the 2 (5) is interpreted as a rankone, shape 10 array filled with the value 2 (5). The asterisk means elementby-element multiplication, the plus sign means element-by-element addition
and sin(x) means apply the sin function to each element.
As a perhaps more useful example, the following statement forms the array
diff as the pair-wise difference quotient. This is an estimate for the partial
derivative of T(x,y) with respect to x at a particular y. diff needs an
appropriate type declarations statement. The array diff and the section o f
the array temp, which must be compatible, are rank-one and shape 9.
diff = ( temp(2:10,2) - temp(1:9,2) ) / ( grid_x(10) - grid_x(9))
Finally, F90 provides a vector subscript feature; where a rank-one integer
array can be used as a specification in an array segment. If, for example, iv
is a rank-one integer array of shape 5, then z(1:5) = x(iv) is legal and will
copy into the first five elements of the z array the values x(iv(1)), .. x(iv(5)).
While this will compile correctly, it may produce an execution error if the
values assigned to iv exceed the declared shape specification for x.