Title: Ch 13: ARRAY PROCESSING AND MATRIX MULTIPLICATION
1Ch 13 ARRAY PROCESSING AND MATRIX MULTIPLICATION
- 13.1 Matrices and two-dimensional arrays
- 13.2 Basic array concepts for arrays having more
than one dimension - 13.3 Array constructors for rank-n arrays
- 13.4 Input and output with arrays
- 13.5 The five classes of arrays
- 13.6 Allocatable arrays
- 13.7 Whole array operations
- 13.8 Masked array assignment
- 13.9 Sub-arrays and array sections
2In Chapter 7, we discussed rank 1 arrays. e.g.
REAL, DIMENSION (1160) a To solve problems
in linear algebra we need many dimensions (i.e.
rank gt 2). 13.1 Matrices and two-dimensional
arrays A1,1 A1,2 A1,3 A1,4 A 3 x 4 matrix
A3x4 A A2,1 A2,2 A2,3 A2,4 A3,1 A3,2 A3
,3 A3,4 2 3 4 5 e.g A
3 4 5 6 4 5 6 7
3The matrix A can be defined in FORTRAN
90 REAL, DIMENSION (3,4) a Note in
DIMENSION (3,4) the no. of rows is 1st, then the
no. of columns. Other types of arrays are
possible e.g. LOGICAL, DIMENSION (10,4)
b,c,d e.g. b10x4 b(1,1) b(1,2) b(1,3)
b(1,4) . . b
(10,1) b(10,2) b(10,3) b(10,4)
4and the values b(i,j) .TRUE. Or .FALSE. for i
1,,10 j 1,,4. The array elements (being
scalars i.e. single elements) can be used in
expressions exactly as the simple type (e.g.
REAL, INTEGER, LOGICAL) variables or
constants. e.g a(3,4) 2.0a(3,4) 1.0 !
Doubles a(3,4) and adds 1 to it DO i
1,4 ! Replace row 1 of a by a(1,i)
a(3,i) row 3 of a. Row 3 is END DO
unaltered DO i 1,3 ! Replace column 2 of a
by a(i,2) a(i,1) column 1 of a. Column 1
END DO is unaltered
5- FORTRAN provides intrinsic functions for vectors
(1-dim arrays) and matrices (2-dim arrays) - Fig. 13.1
- matmul(array1, array2)dot_product(array1,
array2)transpose(array)maxval(array,dim,mask)
maxloc(array,dim) minval(array,dim,mask)
minloc(array,dim) product(array,dim,mask)su
m(array,dim,mask)
6From LINEAR ALGEBRA MATMUL e.g. A3x4 x B4x4
C3x4 where DOT_PRODUCT e.g. Vectors X3x1
, y3x1 Dot_product computes
7TRANSPOSE e.g. D4X3 AT3X4 MAXVAL
e.g. For array X Computes the
maximum of x(1) , x(2) , x(3) MINVAL computes
the minimum of x(1), x(2) , x(3) PRODUCT e.g.
for X computes x(1)x(2)x(3)
8- SUM computes x(1) x(2) x(3)
- Fig 13.2 An example of matrix and vector
multiplication - PROGRAM vectors_and_matrices
- IMPLICIT NONE
- INTEGER, DIMENSION(2,3) matrix_a
- INTEGER, DIMENSION(3,2) matrix_b
- INTEGER, DIMENSION(2,2) matrix_ab
- INTEGER, DIMENSION(2) vector_c (/ 1 , 2
/) - INTEGER, DIMENSION(3) vector_bc
- ! If all a(i,j) 1.0, write a 1.0
- ! Initialize matrix_a
- matrix_a(1,1) 1 ! Matrix_a is the matrix
- matrix_a(1,2) 2
9- matrix_a(1,3) 3 ! 1 2 3
- matrix_a(2,1) 2 ! 2 3 4
- matrix_a(2,2) 3
- matrix_a(2,3) 4
- ! Set matrix_b as the transpose of matrix_a
- matrix_b TRANSPOSE(matrix_a)
- !matrix_b is now the matrix 1 2
-
2 3 -
3 4 - ! Calculate matrix products
- matrix_ab MATMUL(matrix_a, matrix_b) !
matrix ab is now the matrix 14 20 -
20 29 -
10- vector_bc MATMUL(matrix_b, vector_c)
- !vector_bc is now the vector 5 8 11
- END PROGRAM vectors_and_matrices
- NOTE 1) The matrix/vectors intrinsic functions
help us program - very quickly the corresponding linear algebra
computations. - e.g. if in prog. of fig 13.2 we programmed with
DOloops - !matrix_b TRANSPOSE(matrix_a)
- DO i 1,3
- DO j 1,2
- matrix_b(i,j) matrix_a(j,i)
- ENDDO
- ENDDO
11- ! Matrix_ab MATMUL(matrix_a ,matrix_b)
- DO i 1,2
- DO j 1,2
- matrix_ab(i ,j) 0.0
- DO k 1 ,3
- matrix_ab(i,j) matrix_ab(i,j)
matrix_a(i,k) -
matrix_b(k,j) - ENDDO
- ENDDO
- ENDDO
12- 13.2 Basic concepts for dim gt 1 arrays
- Recall rank No. of dims and taken from
DIMENSION() - e.g. REAL, DIMENSION(8) a
!rank 1 - INTEGER, DIMENSION(3,10,2) b
!rank 3 - TYPE(point), DIMESION(4,2,100,8)
c !rank 4 - array size No. of array elements product of
extents 421008 6,400 -
- Note e.g. for b DIMENSION(3 ,10 ,2) same as
- DIMENSION(13, 110 , 12) and the extents
are 3,10,2 - Instead of the actual dims we can use named
constants - e.g. INTEGER, PARAMETER s14, s22, s3100,
s4s1s2 - .
- .
- TYPE(point), DIMENSION(s1, s2, s3, s4) c
13- shape of array rank , extents of dims e.g.
- shape of array cabove rank4 and extents
(/ 4,2,100,8/) - -e.g. arrays with different index bounds same
shape e.g. Arrays a1, b1, c1 below have the same
shape as arrays a, b, c above - REAL, DIMENSION(1118) a1
- INTEGER, DIMENSION(57, -10-1,2)
b1 - TYPE(Point), DIMENSION(58 , 01 ,
100 , -34) c1 - -Array element order (in FORTRAN) is by columns
e.g. - REAL , DIMENSION(4,3) arr
- PRINT , arr
- arr(1,1) , arr(2,1), arr(3,1), arr(4,1),
arr(1,2), arr(2,2) - arr(3,2) , arr(4,2), arr(1,3), arr(2,3),
arr(3,3), arr(4,3) -
14- arr(1,1) arr(1,2) arr(1,3)
- arr(4,1) arr(4,2) arr(4,3)
- 13.3 Array constructors
- e.g. arr (/-1, (0 , i 1,48),1 /)
- means
- arr(0) -1
- arr(1) 0
- .
- .
- arr(48) 0
- arr(49) 1
15- Since array constr. are 1-Dim we use RESHAPE to
apply to - Dim gt 1 arrays
- e.g. a RESHAPE((/1.0 ,2.0, 3.0, 4.0, 5.0,6.0/),
(/2 , 3/) -
-
- We could use nested implied DO e.g.
-
- by the following declaration statement
16- INTEGER i, j
- REAL , DIMENSION(2,2) a
- RESHAPE( (/ ((10ij , i 1,2),
j 1,2) / ) , (/ 2,2 /) ) - Which the same as the following
- INTEGER i , j
- REAL, DIMENSION(2,2) a
- DO i 1,2
- DO j 1,2
- a( i,j) 10ij
- ENDDO
- ENDDO
-
17- Fig.13.3 An improved example of matrix and vector
multiplication - PROGRAM vectors_and_matrices
- IMPLICIT NONE
- INTEGER , DIMENSION(2 , 3) matrix_a
- RESHAPE((/1,2,2,3,3,4/), (/
2,3 /)) - INTEGER, DIMENSION(3,2) matrix_b
- INTEGER, DIMENSION(2,2) matrix_ab
- INTEGER, DIMENSION(2) vector_c (/ 1,2 /)
- INTEGER, DIMENSION(3) vector_bc
- !Set matrix_b as the transpose of matrix_a
- matrix_b TRANSPOSE(matrix_a)
18- ! Matrix_b is now the matrix 1 2
- !
2 3 -
3 4 - !calculate matrix products
- matrix_ab MATMUL(matrix_a , matrix_b)
- !matrix_ab is now the matrix 14 20
- !
20 29 - vector_bc MATMUL(matrix_b , vector_c)
- ! Vector_bc is now the vector 5 8 11
- END PROGRAM vectors_and_matrices
19- 13.4 Input/output with arrays
- The ways for input/output with arrays
- . List of individual elements
- . List of individual elements under an implied
DO loop - . a complete array name (e.g a) with no
subscripts - e.g. REAL, DIMENSION(50 , 8) X
- (X has 50 rows, 8 cols)
-
- PRINT (8F8.2), x
-
20- will print out the data in the following way
- x(1,1) x(2,1) x(3,1) x(4,1) x(5,1)
x(6,1) x(7,1) x(8,1) - x(9,1) x(10,1) x(11,1) x(12,1) x(13,1)
x(14,1) x(15,1) x(16,1) - . . . .
. . . . - . . . .
. . . . - . . . .
. . .
. - x(49,1) x(50,1) x(1,2) x(2,2) x(3,2)
x(4,2) x(5,2) x(6,2) - X(7,2) x(8,2) x(9,2) x(10,2) x(11,2)
x(12,2) x(13,2) x(14,2) - . . . .
. . .
. - . . . .
. . .
. - which is not at all what was wanted!
- On the other hand, the statement
- PRINT (8F8.2) , ((x(i,j) , j 1,8 , i
1,50)
21- will cause the results to be printed in the
correct arrangement - x(1,1) x(1,2) x(1,3) x(1,4) x(1,5) x(1,6)
x(1,7) x(1,8) - x(2,1) x(2,2) x(2,3) x(2,4) x(2,5) x(2,6)
x(2,7) x(2,8) - . . . .
. . . . - . . . .
. . . . - . . . .
. . . . - 13.5 Five array classes
- (I) explicit-shape
- (II) assumed-shape
- (III) automatic
- (IV) assumed-size (old FORTRAN, skip)
- (V) deferred-shape or allocatable
22- (I) explicit-shape index bounds for each dim.
given in the type-declaration e.g. - (i) TYPE(person) , DIMENSION(101110,20)
company - (ii) Procedure w/ expl-shape dummy args
- SUBROUTINE explicit(a,b,m,n)
- IMPLICIT NONE
- INTEGER, INTENT(IN) m,n
- REAL, DIMENSION(m, nn1), INTENT(INOUT)
a - !rank2
- REAL,DIMENSION(-nn,m,INT(m/n)),
INTENT(OUT) b - !rank3
- .
- .
- END SUBROUTINE explicit
23- ((ii) contd) inside the calling program
- REAL, DIMENSION(15,50) p
- REAL, DIMENSION(15,15,2) q
- ..
- CALL explicit(p,q,15,7)
- (II) (assumed shape) DIMENSION(list of
assumed-shape specifiers). e.g. inside the
calling program - REAL,DIMENSION (210,15) a
- REAL,DIMENSION(15,10,20) b
- .
- CALL assumed_shape(a,b)
24- REAL FUNCTION assumed_shape(a,b)
- IMPLICIT NONE
- INTEGER, DIMENSION(,) a
!rank 2 - REAL, DIMENSION(5 ,,) b
!rank 3 - ! Note 5 means lower5 and upper
unknown - ! Note means lower1 and upper
unknown - ..
- DO i 1, SIZE(a,1)
- DO j 1 SIZE(a ,2)
- Intrinsic functions SIZE(a,) , LBOUND(a,),
UBOUND(a,) - SIZE(ARRAY , DIM) ! 1lt DIM lt rank
- If DIM is given then SIZE returns extent in
DIM else - it returns the size of the entire
array
25- LBOUND(ARRAY , DIM) ! 1 lt DIM lt rank
- returns the lower bound(s) of the indices.
- UBOUND similar for upper bounds
- If the array is rank 1 then LBOUND(ARRAY, 1)
- Example 13.1
- Problem Write a program to check if a polygon
is convex(?) - This is important in CAD (e.g. for virtual
reality applications) - e.g. POLYGONS
pn
p1
p2
Quadrilateral
Triangle
n-sided polygon
26- e.g (NON) convex shapes (enclosed by a curve)
- Any line segment between 2 pts must be inside the
shape. - CONVEXITY OF POLYGONS can be checked if all
angles - (-180 lt ? lt180) between adjacent sides are
always (positive) - negative or equivalently (counter) clockwise
e.g.
y
y
x
x
Non-Convex
Convex
27- All angles are clockwise Convex polygon
1 angle clockwise, others
- counter clockwise non-
- convex polygon
- It can be proved in vector math. (convexity
test) - For any 3 polygon vertex pts
- Pi (xi , yi)
- Pi1 (xi1 , yi1)
- Pi2 (xi2 , yi2)
- CHECK (xi1 xi)(yi2 yi1) (yi1-
yi)(xi2 xi1) has the - same sign i.e. gt0 OR lt0 going around the
polygon (counter) - clockwise
p4
p5
p6
p5
p3
p1 (x1,y1)
p4
p1
p3
A 5 sided polygon
p2
A 6 sided polygon
p2
28- NOTE e.g. For Fig. 13.6 The check called
orientation is done - at each vertex pt P. e.g
- P4 orientation (x5 x4)(y1 y5) (y5
y4)(x1 x5) gt 0 (?) -
lt 0(?) - P5 orientation (x1 x5)(y2 y1) (y1
y5)(x2 x1)gt0 (?) -
lt0 (?) - P1 orientation (x2 x1)(y3 y2) (y2
y1)(x3 x2) gt 0 (?) -
lt0(?) - i.e. at i
4 - we take
Pi2 P1 - AND at i
5 we take Pi1 P1, -
Pi2 P2
p4
p5
p1
p3
p2
29- INITIAL STRUCTURE PLAN
- 1 Obtain number of sides the polygon
- 2 Set convex flag true
- 3 Calculate the direction of rotation at the
first vertex - 4 Repeat for each remaining vertex
- 4.1.1 Set convex flag false
- 4.1.2 Exit from loop
- NOTE DIRECTION OF ROTATION is checked by
checking - at vertex orientation gt 0 (?)
- lt 0 (?)
30- Data design (SUBROUTINE CONVEX_POLYGON)
- Purpose
Type Name - A Arguments
- Array of points point
polygon - Convexity of the LOGICAL
convex - polygon
- B Local variables
- Orientation at first vertex REAL
anti - Number of vertices INTEGER
n_vertices - DO loop variable INTEGER
i
31- Structure plan
- Obtain number of slides of the polygon from
SIZE(polygon) - Set convex to true
- Calculate the direction of rotation at the first
vertex (anti) - using the function orientation
- Repeat for each remaining vertex
- 4.1 If antiorientation(this vertex)lt0
- 4.1.1 Set convex to false
- 4.1.2 Exit from loop
- Date design
- Purpose
Type Name - A Arguments
- Array of points
point p - Index of Vertex
INTEGER vertex - B Local variable
- Number of vertices
INTEGER n
32- Structure plan
- Obtain the number of vertices from SIZE(p)
- Calculate direction of rotation and return as the
value of the - function
- MODULE convexity
- IMPLICIT NONE
-
- !Derived type definition
- TYPE point
- REAL x,y
- END TYPE point
- CONTAINS
33- SUBROUTINE CONVEX_polygon(polygon, convex)
- IMPLICIT NONE
- !This subroutine determines whether a
polygon is convex - ! Dummy arguments
- TYPE(point), DIMENSION(), INTENT(IN)
polygon - LOGICAL, INTENT(OUT) convex
- !polygon is assumed-shape array
- !local variables
- REAL anti 0.0
- INTEGER i,n_vertices
- !Set initial value for convex and obtain
number of vertices - convex .TRUE.
- n_vertices SIZE(polygon , 1)
!n_vertices is the number of vertices
34- !Get direction of rotation at first vertex
- IF (orientation(polygon,1) gt 0.0 ) THEN
- anti 1.0
- ELSE
- anti - 1.0
- END IF
- !Check direction of rotation at remaining
vertices - DO i 2, n_vertices
- IF(antiorientation(polygon, i) lt 0.0)
THEN - !Return immediately a different
orientation occurs - convex .FALSE.
- EXIT
- END IF
- END DO
- END SUBROUTINE convex_polygon
35- REAL FUNCTION orientation (p , vertex)
- IMPLICIT NONE
- !This function returns the direction of
angular rotation - !at a specified vertex of polygon
- !positive if counter clockwise negative if
clockwise - ! Dummy arguments
- TYPE(point) , DIMENSION( ) , INTENT( IN
) p - INTEGER , INTENT(IN) vertex
- ! p is assumed-shape array
- !Local variable
- INTEGER n
- n SIZE(p , 1) ! N is the number of
vertices - !calculate orientation at this vertex
- IF (vertex n 1) THEN ! CASE Pn-1
, Pn , P1
36- orientation (p(n) x p(n
1) x) (p(1) y p(n) y) - - (p(n) y
p(n 1) y) (p(1) x p(n) x) - ELSE IF (vertex n) THEN ! CASE
Pn, P1, P2 - orientation (p(1) x p(n)
x) (p(2) y p(1) y) - - (p(1)
y p(n) y) (p(2) x p(1) x) - ELSE ! CASE Pvertex , Pvertex1 ,
Pvertex2 - orientation (p(vertex1) x
p(vertex) x) -
(p(vertex2) y p(vertex1) y) - -
(p(vertex1) y p(vertex) y) -
(p(vertex2) x p(vertex1) x) - END IF
- END FUNCTION orientation
- END MODULE convexity
37- PROGRAM polygon_test
- USE convexity
- IMPLICIT NONE
- !This program uses the module convexity to
establish - !whether a set of points make a convex
polygon - INTEGER, PARAMETER number_of_points 6
- TYPE(point) , DIMENSION(number_of_points)
polygon - INTEGER i
- LOGICAL convex
- !Ask for six points
- READ,number_of_point, number_of_points
- DO i 1, number_of_points
- PRINT (1x, Give vertex number ,
I2), i - READ , polygon(i) x , polygon(
i) y - END DO
38- ! Establish the polygons convexity
- CALL convex_polygon(polygon , convex)
- IF (convex) THEN
- PRINT , Polygon is convex
- ELSE
- PRINT , Polygon is not convex
- END IF
- END PROGRAM polygon_test
-
39- Fig. 13.8 Results produced be the program
polygon_test with 6 points - First program run Second
program run - Give vertex number 1 Give
vertex number 1 - 0,0
1,1 - Give vertex number 2 Give
vertex number 2 - 1,0
3,1 - Give vertex number 3 Give
vertex number 3 - 2,1
2,2 - Give vertex number 4 Give
vertex number 4 - 2,2
3,3 - Give vertex number 5 Give
vertex number 5 - 1,3
1,3 - Give vertex number 6 Give
vertex number 6 - - 1,1
0,2 - Polygon is convex
Polygon is not convex
40- Fig. 13.9 Results produced by the program
polygon_test with 5 points - (i.e. INTEGER, PARAMETER number_of_points 5
) - Give vertex number
1 - 1,1
- Give vertex number
2 - 3,1
- Give vertex number
3 - 3,3
- Give vertex number
4 - 1,3
- Give vertex number
5 - 0,2
- Polygon is convex
41- NOTE The arrays polygon (in subrout
convex_polygon) and - P (in function orientation) are assumed-shape
arrays. - (III) automatic arrays are a special case of
explicit-shape arrays - (only in sub-routines/functions not dummy args
but local arrays - with at least 1 index bound constant) e.g.
- SUBROUTINE abc(x, y, n)
- IMPLICIT NONE
- !Dummy arguments
- INTEGER, INTENT(IN) n
- REAL, DIMENSION(n), INTENT(INOUT) x !
Explicit shape, dummy argument - REAL, DIMENSION( ), INTENT(INOUT) y !
Assumed shape, dummy argument
42- ! Local variables
- REAL, DIMENSION(SIZE(y,1)) e !Automatic,
not dummy arg - REAL, DIMENSION(n,10) f !
Automatic, not dummy arg - REAL, DIMENSION(10) g ! Explicit-shape,
local array . !with constant bounds, not
. !automatic - .
- END SUBROUTINE abc
- Note SIZE(y,1) is determined by the shape of
dummy arg. y - Note 1) Automatic array is created on entry and
removed on exit to/from subroutine. - 2) Unlike automatic arrays, explicit-shape and
assumed-shape arrays can be dummy args and are
given fixed dimension in the calling program.
43- (V) allocatable arrays
- Beyond automatic arrays (which are local ) the
allocatable arrays allow user to control
allocation / de-allocation of memory for array
elements. - Steps
- Firstly, the allocatable array is specified in a
type declaration statement. - Secondly, space is dynamically allocated for its
elements in a separate allocation statement,
after which the array may be used in the normal
way. - Finally, after the array has been used and is no
longer required, the space for the elements is
deallocated by a deallocation statement.
44- -Declaration e.g.
- REAL,ALLOCATABLE arr_1( ) , arr_2( , ) ,
arr_3( , , ) - ALLOCATE(arr_1(20) , arr_2(1030 , -1010) ,
arr_3(20,30 50,5)) - NOTE
- -After ALLOCATE arrays can be used like
explicit-shape , assumed-shape, automatic-shape. - -Use STAT status_variable to check successful
allocation
45- e.g. Fig 13.10 An example of allocation of
allocatable arrays, with error checking - .
- m100, n80
- INTEGER error
- REAL , ALLOCATABLE , DIMENSION( ,)
p - INTEGER , ALLOCATABLE , DIMENSION(
,, ) q - TYPE(vector), ALLOCATABLE ,
DIMENSION( ) r - .
- .
- ALLOCATE(p(5,1000), q(10,m,n7) , r(
- 10 10) , STAT error) - IF(error / 0) THEN
- ! Space for p, q and r could not
be allocated - PRINT , Program could not
allocate space for p ,q and r - STOP
- END IF
- ! Space for p , q, and r successfully
allocated - .
- .
46- -DEALLOCATE (list of allocated arrays, STAT
st_var - releases the memory by removing allocated arrays.
- e.g. REAL, ALLOCATABLE, DIMENSION( )
varying_array - INTEGER i ,n, alloc_error ,
dealloc_error - .
- .
- READ , n
! Read maximum size needed - DO i 1 , n
- ALLOCATE(varying_array( - i
i ) , STAT alloc_error) - IF(alloc_error / 0) THEN
- PRINT ,
Insufficient space to allocate array -
when i , i - STOP
- END IF
- ! Calculate using varying_array
47- .
- .
- .
- DEALLOCATE(varying_array, STAT
dealloc_error) - IF(dealloc_error / 0) THEN
- PRINT , Unexpected
deallocation error - STOP
- END IF
- END DO
- .
- .
- - The allocated arrays can be kept in memory (on
exit from procedures) and used again later in the
program (e.g. calling the same procedure) by
using SAVE -
48- e.g.
- CHARACTER(LEN 50) , ALLOCATABLE , DIMENSION (
), - SAVE name
- NOTE This is not possible with other arrays
e.g. automatic. - Allocated arrays allow users to have control on
memory space use - e.g.
- SUBROUTINE space(n)
- IMPLICIT NONE
- INTEGER , INTENT(IN) n
- REAL , ALLOCATABLE , DIMENSION ( ,
) a , b - ALLOCATE(a(2n , 6n)) !
Allocate space for a - ! Calculate using a
! Uses 12n2 elem.s space - .
- .
- .
49- .
- DEALLOCATE(a)
!Free space used by a - ALLOCATE(b(3n , 4n)) !
Allocate space for b - ! Calculate using b
! Uses 12n2 elems space - .
- .
- .
- DEALLOCATE (b) !Free
space used by b - END SUBROUTINE space
- Total memory Space 12n2 elements space
50- The same subroutine with automatic arrays uses
24n2 elements space - e.g.
- SUBROUTINE space(n)
- IMPLICIT NONE
- INTEGER , INTENT(IN) n
- REAL , DIMENSION(2n , 6n) a
!12n2 elem.s space - REAL , DIMENSION(3n , 4n) b
!12n2 elem.s space - !Calculate using a
- .
- .
- !Calculate using b
- .
- .
- END SUBROUTINE space ! Total
24n2 elem. space
51- NOTE
- Allocatable arrays cannot be dummy arguments of
a procedure. - The result of a function cannot be allocatable
array. - Allocatable arrays cannot be used in a derived
type definition. - NOTE
- There are intrinsic functions which give
information on ALLOCATABLE - arrays e.g. ALLOCATED intrinsic function checks
if it was already allocated - e.g.
- .
- REAL , ALLOCATABLE , DIMENSION ()
work_array - .
- .
- IF ALLOCATED (work_array) DEALLOCATE
(work_array) - ALLOCATE (work_array (n m) , STAT
alloc_stat) - .
- .
52- Example 13.2 Program to find max, min in a set
of real no.s in a file and how many no.s are
less than the average-of-all no.s . - Analysis Use array (allocatable) to store the
nos because its size is not known. - Initial structure plan
- 1 . Allocate suitable work array
- 2. Do analysis on file
- Refine plan
- 1. Request maximum size of work array
required . - 2. Allocate a suitable work array
- 3. Carry out analysis of file
- 3.1 Get name of file
- 3.2 Find maximum and minimum
values, and their position in the file - ( or array)
- 3.3 Calculate mean , and count the
number of values less than the - mean
53- Final structure Plan
- 1 Call allocate_space to do the following
- 1.1 Request maximum size of file
- 1.2 Allocate a suitable work array
- 2 Call calculate to do the following
- 2.1 Get the name of the file and open it
- 2.2 Read all the numbers in the file
into the work array - 2.3 Call minmax to find minimum and
maximum values , and their - positions
- 2.4 Call num_less_than_mean to find the
number less than the mean
54- Solution
- MODULE work_space
- IMPLICIT NONE
- SAVE
- INTEGER work_size
- REAL , ALLOCATABLE , DIMENSION ()
work - END MODULE work_space
- PROGRAM flexible
- IMPLICIT NONE
- ! Allocate space for the array
work - CALL allocate_space
- ! Carry out calculations using the
array work - CALL calculate
- END PROGRAM flexible
-
55- SUBROUTINE allocate_space
- USE work_space
- IMPLICIT NONE
- ! This subroutine allocates the array
work at a size determined - ! by the user during execution
- !Local variable
- INTEGER error
- ! Ask for required size for array
- PRINT , Please give maximum size
of file or array - READ , work_size
- ! Allocate array
- ALLOCATE (work(work_size1) , STAT
error) - IF (error / 0) THEN
- ! Error during allocation terminate
processing - PRINT , Space requested
not possible - STOP
- END IF
- ! Work array successfully allocated
- END SUBROUTINE allocate_space
56- SUBROUTINE calculate
- USE work_space
- IMPLICIT NONE
- ! Local variables
- INTEGER i , n , min_p ,max_p,
open_error, io_stat - REAL min , max
- CHARACTER (LEN 20) file_name
- ! Get name of data file
- PRINT , Please give name of data
file ! Skip if READ is used - READ (A) , file_name ! Skip if
READ is used - !Open data file . Skip the following
OPEN if READ is used - OPEN ( UNIT 7 , FILE file_name ,
STATUS OLD , - ACTION READ , IOSTAT
open_error) - IF (open_error / 0) THEN
- PRINT , Error during file
opening - STOP
- END IF
57- ! Read data until end of file
- DO i 1, work_size
- ! READ, work(i) ! Skip the following
READ if READ is used - READ ( UNIT 7 , FMT , IOSTAT
io_stat ) work( i ) - ! Check for end of the file
- IF ( io_stat lt 0 ) EXIT
- END DO
- !Save number of numbers read
- n i 1
- ! Find maximum and minimum values
- CALL minmax ( n, min , max, min_p , max_p )
- ! Print details of minimum numbers and maximum
numbers - PRINT ( 1X , Minimum value is , F15 . 4 ,
- and occurs at position
, I10 / - 1X , Maximum value is ,
F15.4 , - and occurs at position
, I10), - min , min_p , max, max_p
58- ! Calculate number that are less than mean
- CALL num_less_than_mean(n)
- ! Deallocate work array
- DEALLOCATE ( work )
- END SUBROUTINE calculate
- SUBROUTINE minmax(n , minimum , maximum,
min_pos , max_pos) - USE work_space
- IMPLICIT NONE
- ! This subroutine calculates the largest
and smallest - ! Element values in work(1) to work(n)
- ! Dummy arguments
- INTEGER , INTENT(IN) n
- REAL, INTENT (OUT) minimum , maximum
- INTEGER , INTENT (OUT) min_pos ,
max_pos -
59- ! Local variable
- INTEGER i
- ! Establish initial values
- minimum work(1)
- maximum work(1)
- min_pos 1
- max_pos 1
- ! Loop to find maximum and minimum
values - DO i 2,n
- IF ( work(i) lt minimum) THEN
- minimum work(i)
- min_pos i
- ELSE IF (work(i) gt maximum)
THEN - maximum work(i)
- max_pos i
- END IF
- END DO
- END SUBROUTINE minmax
60- SUBROUTINE num_less_than_mean(n)
- USE work_space
- IMPLICIT NONE
- ! This subroutine calculates and prints
the number of elements - ! of work(1) to work(n) that are less
than the mean of all elements - ! Dummy argument
- INTEGER , INTENT (IN) n
- ! Local variables
- INTEGER i , less 0
- REAL sum 0.0 , mean
- ! Calculate mean
- DO i 1, n
- sum sum work(i)
- END DO
- mean sum / n
- ! Count number less than mean
-
-
61- DO i 1,n
- IF ( work(i) lt mean ) less
less1 - END DO
- ! Print number below the mean
- PRINT ( 1X, There are , I10,
numbers less than the mean -
of all numbers in the file ), less - END SUBROUTINE num_less_than_mean
62- Fig . 13.11 An alternative version of the
subroutine allocate_space - SUBROUTINE allocate_space ! It tries 3 times
to allocate the memory - USE work_space ! in
case the ALLOCATE fails - IMPLICIT NONE
- ! This subroutine allocates the array
work at a size - ! Determined by the user during
execution - ! Local variables
- INTEGER i, error
- ! Ask for required size for array
- DO i 1,3 ! three tries to allocate
the memory for the array work - PRINT , Please give
maximum size of file - READ , work_size
- ! Allocate array
- ALLOCATE (work(work_size) ,
STAT error) - IF (error 0) EXIT
- ! Error during allocation
try again ( max of 2 times)
63- PRINT , Space requested not
possible try again - END DO
- !Check to see if array was (finally)
allocated - IF (.NOT. ALLOCATED(work)) THEN
- ! No allocation even after three times
- PRINT , Three attempts to
allocate without success! - STOP
- END IF
- !Work array successfully allocated
- END SUBROUTINE allocate_space
64- 13.7 WHOLE ARRAY OPERATIONS
- Conformable arrays arrays of same shape
- e.g. (i)
- REAL , DIMENSION (10) p,q
- REAL , DIMENSION (10 19) r
- Operations with conform. arrays do not need loops
- e.g.
- DO i 1, 10
- p(i) q(i) r(i 9)
- END DO
- same as whole array operation p q
r -
65- (ii) e.g.
- REAL, DIMENSION(10, 10, 21, 21) x
- REAL, DIMENSION(09, 09, -1010, -1010)
y - REAL, DIMENSION(1120, -90, 020, -200)
z - shape of x rank 4, extents (10 , 10,
21, 21) - also shape of y and z
- rank 4, and extents (10 , 10, 21,
21) - Then the Fortran 90 statement
- x y z 10.0
- has exactly the same effect as the following
- DO loops
-
66- DO i 1, 10
- DO j 1, 10
- DO k 1, 21
- DO l 1, 21
- x(i,j,k,l)
y(i-1, j-1, k-11, l-11) -
z(i10, j-10, k-1, l-21) 10.0 - END DO
- END DO
- END DO
- END DO
67- Rules (from chapter 7) for working with whole
arrays - Two arrays are conformable if they have the same
shape - A scalar, including a constant, is conformable
with any array - All intrinsic operations are defined between
conformable objects - e.g. x yz 10.0 EXP(y)COS(z)
- Whole-array operations without loops also apply
to CHARACTER or LOGICAL ARRAYS. - (iii) e.g. CONCATENATION OF STRINGS
- CHARACTER (LEN7), DIMENSION (3,4)
string_1, string_2 - CHARACTER (LEN14), DIMENSION (3,4)
long_string - .
- .
- long_string string_1//string_2
- .
- print , ((long_string (i, j), j 1,4), i
1,3) -
-
68- Arrays of names
- e.g. string_1 RESHAPE(/ JOHN, GEORGE,
TOM, DAVID, , THOMAS /), (/ 3, 4 /) ! 12
first names - string_2 RESHAPE(/ smith, schmidt, , /),
(/ 3, 4 /) - ! 12 last names
- We can concatenate the two (first and last names)
by 2 do-loops - DO i 1, 3
- DO j 1, 4
- long_string(i,j) string_1(i,j)//string_2(i,j)
- END DO
- END DO
-
69- This is the same as the whole array operation
- long_string string_1//string_2
- (iv) We can place quotation marks around every
element of an array and store them in another
array - e.g. CHARACTER(LEN20), DIMENSION(4,50)
unquoted - CHARACTER(LEN22), DIMENSION(4,50) quoted
- .
- .
- quoted // unquoted //
- .
- .
70- is the same as
- DO i 1, 4
- DO j 1, 50
- quoted(i,j) // unquoted(i,j) //
- END DO
- END DO
- Logical operators ALL( ), ANY( ), are logical
intrinsic fun.s - (v) e.g. INTEGER , DIMENSION (3,4) a, b
- LOGICAL AllFlag .FALSE. , AnyFlag
.FALSE. - then IF (ALL (a gt 1.0))
- is the same as
71- DO i 1,3
- DO j 1,4
- IF( a(i,j) gt 1.0) THEN
- AllFlag .TRUE.
- ELSE
- EXIT
- END IFEND DO
- END DO
- IF ( AllFlag .TRUE. )
72- Also e.g.
- IF( ANY (a b)) is the same as
- DO i 1,3
- DO j 1,4
- IF ( a(i,j) b(i ,j))
THEN - AnyFlag
.TRUE. - EXIT
- END IF
- END DO
- END DO
- IF ( AnyFlag .TRUE.) ..
73- Array valued functions (CHAP . 7)
- RULES
- - An array-valued function must have an
explicit interface - (e.g. PLACE inside MODULE)
- - The type of the function , and an
appropriate dimension - attribute must appear within the body
of the function, not - as part of FUNCTION statement
- - The array that is the function result
must be an explicit-shape array, although it may
have variable extents in any of its - dimensions
-
74- e.g. outer product in linear algebra
-
- x3x1 , y4x1
- outer product of x, y is a matrix
- A x yT
- i.e. Ai j xi yj
75- e.g. Fig . 13.12 An array-valued function to
calculate the outer product of -
two vectors - FUNCTION outer(x , y)
- IMPLICIT NONE
- REAL , DIMENSION(), INTENT(IN) x, y
- REAL , DIMENSION(SIZE(x,1) , SIZE(y,1))
outer !type for funct - INTEGER i, j
- DO i 1 , SIZE(x , 1) !
intrinsic function size - DO j 1, SIZE(y,1) !
intrinsic function size - outer(i , j) x(i)
y(j) - END DO
- END DO
- END FUNCTION outer ! Result is
explicit-shape array - e.g. inside the main program that calls the
function outer - f outer(xactual,yactual)
-
76- The intrinsic functions or procedures can be
called in whole-array - operations.
- (vi) e.g. REAL, DIMENSION (10,10,21) a,b
- b sin(a) ! whole array operation
- ! is the same as
- DO i 1, 10
- DO j 1, 10
- DO k 1, 21
- b(i, j, k)
SIN(a(i , j, k)) - END DO
END DO - END DO