Presentation is loading. Please wait.

Presentation is loading. Please wait.

Ch 13: ARRAY PROCESSING AND MATRIX MULTIPLICATION

Similar presentations


Presentation on theme: "Ch 13: ARRAY PROCESSING AND MATRIX MULTIPLICATION"— Presentation transcript:

1 Ch 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

2 In Chapter 7, we discussed rank = 1 arrays.
e.g. REAL, DIMENSION (11:60) :: a To solve problems in linear algebra we need many dimensions (i.e. rank >= 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 e.g A =

3 The 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)

4 and 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.0*a(3,4) ! Doubles a(3,4) and adds 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 : 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]) sum(array[,dim,mask])

6 From LINEAR ALGEBRA: MATMUL: e.g. A3x4 x B4x4 = C3x4 = where DOT_PRODUCT: e.g. Vectors X3x1 = , y3x1 = Dot_product computes

7 TRANSPOSE: 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 PROGRAM vectors_and_matrices IMPLICIT NONE
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 ! 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 [ ] [ ]

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

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

12 13.2 Basic concepts for dim => 1 arrays :
Recall: rank = No. of dim’s 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 = 4*2*100*8 = 6,400 Note : e.g. for b: DIMENSION(3 ,10 ,2) same as DIMENSION(1:3, 1:10 , 1:2) and the ‘extents’ are 3,10,2 Instead of the actual dim’s we can use ‘named constants’ e.g. INTEGER, PARAMETER :: s1=4, s2=2, s3=100, s4=s1*s2 . TYPE(point), DIMENSION(s1, s2, s3, s4) ::c

13 ‘shape’ of array : rank , extents of dim’s e.g.
shape of array ‘c’above : rank=4 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(11:18) :: a1 INTEGER, DIMENSION(5:7, -10:-1,2) :: b1 TYPE(Point), DIMENSION(5:8 , 0:1 , 100 , -3:4) :: 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.(array arr(0:49) ) 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 > 1 arrays e.g. array a (2,3) : a = RESHAPE((/1.0 ,2.0, 3.0, 4.0, 5.0,6.0/), (/2 , 3/) ) We could use nested implied ‘DO’ e.g. array a(2,2) : by the following declaration statement

16 INTEGER :: i, j REAL , DIMENSION(2,2) :: a = &
RESHAPE( (/ ((10*i+j , i = 1,2), j =1,2) / ) , (/ 2,2 /) ) Which the same as the following (explicit Do loop) : INTEGER :: i , j REAL, DIMENSION(2,2) :: a DO i = 1,2 DO j = 1,2 a( i,j) = 10*i+j 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 END PROGRAM vectors_and_matrices
! 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 [ ] ! [ ] vector_bc = MATMUL(matrix_b , vector_c) ! Vector_bc is now the vector : [ ] 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 col’s) 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
(I) explicit-shape: index bounds for each dim. given in the type-declaration e.g. (i) TYPE(person) , DIMENSION(101:110,20) :: company (ii) Procedure w/ expl-shape dummy arg’s SUBROUTINE explicit(a,b,m,n) IMPLICIT NONE INTEGER, INTENT(IN) :: m,n REAL, DIMENSION(m, n*n+1), INTENT(INOUT) ::a !rank=2 REAL,DIMENSION(-n:n,m,INT(m/n)), INTENT(OUT) ::b !rank=3 . END SUBROUTINE explicit

23 ((ii) cont’d) 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 (2:10,1:5) :: a REAL,DIMENSION(1:5,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 lower=5 and upper = unknown ! Note: : means lower=1 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) ! 1<= DIM <= 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 <= DIM <= 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 < θ <=180) between adjacent sides are always (positive) negative or equivalently (counter) clockwise : e.g. y y x x Non-Convex Convex

27 counter clockwise: non- convex polygon
All angles are clockwise: Convex polygon 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) Pi+1 = (xi+1 , yi+1) Pi+2 = (xi+2 , yi+2) CHECK: (xi+1 – xi)*(yi+2 – yi+1) – (yi+1- yi)*(xi+2 – xi+1) has the same sign i.e. ‘>0’ OR ‘<0’ going around the polygon (counter) clockwise p4 p5 p6 p5 p3 p1 (x1,y1) p4 p1 p3 A 5 sided polygon p2 p2 A 6 sided polygon

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) > 0 (?) < 0(?) P5 : orientation = (x1 – x5)*(y2 – y1) – (y1 – y5)*(x2 – x1)>0 (?) <0 (?) P1 : orientation = (x2 – x1)*(y3 – y2) – (y2 – y1)*(x3 – x2) > 0 (?) <0(?) i.e. at i = 4: we take Pi+2 = P1 AND at i = 5: we take Pi+1 = P1, Pi+2 = P2 p4 p5 p3 p1 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 Set convex flag false Exit from loop NOTE : DIRECTION OF ROTATION is checked by checking at vertex : orientation > 0 (?) < 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 If anti*orientation(this vertex)<0 Set convex to false 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 Obtain the number of vertices from SIZE(p)
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) > 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(anti*orientation(polygon, i) < 0.0) THEN !Return immediately a different orientation occurs convex = .FALSE. EXIT 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 , Pvertex+1 , Pvertex+2 orientation = (p(vertex+1) % x – p(vertex) % x) *(p(vertex+2) % y – p(vertex+1) % y) - (p(vertex+1) % y – p(vertex) % y) *(p(vertex+2) % x – p(vertex+1) % 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_points, 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 polygon’s 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 Give vertex number 1 0, ,1 Give vertex number Give vertex number 2 1, ,1 Give vertex number Give vertex number 3 2, ,2 Give vertex number Give vertex number 4 2, ,3 Give vertex number Give vertex number 5 1, ,3 Give vertex number Give vertex number 6 - 1, ,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 arg’s 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 Note: SIZE(y,1) is determined by the shape of dummy arg. ‘y’
! 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 arg’s 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(10:30 , -10:10) , 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 REAL , ALLOCATABLE , DIMENSION(: ,:) :: p
e.g. Fig An example of allocation of allocatable arrays, with error checking . … m=100, n=80 INTEGER :: error REAL , ALLOCATABLE , DIMENSION(: ,:) :: p INTEGER , ALLOCATABLE , DIMENSION( : ,:, :) :: q TYPE(vector), ALLOCATABLE , DIMENSION( : ) :: r . ALLOCATE(p(5,1000), q(10,m,n+7) , 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 SUBROUTINE space(n) IMPLICIT NONE INTEGER , INTENT(IN) :: n REAL , ALLOCATABLE , DIMENSION ( : , :) :: a , b ALLOCATE(a(2*n , 6*n)) ! Allocate space for a ! Calculate using a ! Uses 12n2 elem.’s space .

49 . DEALLOCATE(a) !Free space used by a ALLOCATE(b(3*n , 4*n)) ! Allocate space for b ! Calculate using b ! Uses 12n2 elem’s 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(2*n , 6*n) :: a !12n2 elem.’s space REAL , DIMENSION(3*n , 4*n) :: 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
Example 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 no’s 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 ! 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_size+1) , 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 INTEGER :: i , n , min_p ,max_p, open_error, io_stat REAL :: min , max
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 < 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 ”, F , “ 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 ! Establish initial values minimum = work(1) maximum = work(1)
! 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) < minimum) THEN minimum = work(i) min_pos = i ELSE IF (work(i) > maximum) THEN maximum = work(i) max_pos = i END IF END DO END SUBROUTINE minmax

60 ! This subroutine calculates and prints the number of elements
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) < mean ) less = less+1 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 +1) , STAT = error) IF (error = = 0) EXIT ! Error during allocation – try again ( max of 3 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(0:9, 0:9, -10:10, -10:10) :: y REAL, DIMENSION(11:20, -9:0, 0:20, -20:0) :: 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(i+10, j-10, k-1, l-21) 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= y+z EXP(y)+COS(z) Whole-array operations without loops also apply to CHARACTER or LOGICAL ARRAYS. (iii) e.g. CONCATENATION OF STRINGS: CHARACTER (LEN=7), DIMENSION (3,4) : : string_1, string_2 CHARACTER (LEN=14), 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

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(LEN=20), DIMENSION(4,50) : : unquoted CHARACTER(LEN=22), 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 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 > 1.0)) …

71 DO i = 1,3 DO j = 1,4 IF( a(i,j) > 1.0) THEN AllFlag = .TRUE. ELSE
EXIT END IF END 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 IF ( AnyFlag == .TRUE.) ..

73 Array valued functions (CHAP . 7)
RULES : - An array-valued function must have an explicit interface (e.g. put it inside MODULE by using CONTAINS) - 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 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


Download ppt "Ch 13: ARRAY PROCESSING AND MATRIX MULTIPLICATION"

Similar presentations


Ads by Google