! 17. Array Operations.					File: arrayops17.f90
!------------------------------------------------------------------------------!

MODULE section
	IMPLICIT NONE
CONTAINS
	SUBROUTINE item(number)

		! to interrupt program until you are ready for next section

		! declarations
		CHARACTER(LEN=1) :: yes
		INTEGER, INTENT(IN) :: number

		! item  
		PRINT *
		PRINT *, 'Are you ready the next item?'
		PRINT *, 'If yes, type y'
		READ *, yes
		IF (yes /= 'y') THEN
			PRINT *,'...exiting the program.'
		ELSE
			PRINT *
			PRINT *, 'Item ',number
			PRINT *
		END IF

	END SUBROUTINE item
END MODULE section


PROGRAM arrayops
	USE section
	IMPLICIT NONE

	! This program illustrates how arrays may be treated as SINGLE objects.
	! Work through items carefully relating the output with the program 
	! section. First read the definition of CONFORMABLE objects in $1 of 
	! the notes below.

	! declarations
	INTEGER :: i,j
	REAL, PARAMETER :: pi = 3.1415926, piby3=pi/3.0
	REAL, DIMENSION(3,4) :: arr1=0.0
	REAL, DIMENSION(0:2) ::arr2=(/1.0,2.0,3.0/), arr3=(/4.0,5.0,6.0/),arr4
	INTEGER, DIMENSION(2,3) :: arr5=RESHAPE( (/1,2,3,4,5,6/),(/2,3/) )
	INTEGER, DIMENSION(2,3) :: arr6=RESHAPE( (/7,8,9,0,1,2/),(/2,3/) ), arr7
	REAL, DIMENSION(2,3) :: arr8=RESHAPE( (/ ((i*piby3),i=0,5) /),(/2,3/) )
	REAL, DIMENSION(2,3) :: arr9

	! Item 1
	! Initializing whole arrays. See above how this is done for the 2D 
	! array, arr1. Note that the scalar 0.0 is conformable with arr1. 
	! Print it out row by row.

	DO i=1,3
		PRINT *, (arr1(i,j),j=1,4)
	END DO

	! Item 2
	! Intrinsic operations (+-*/**) may be carried out on conformable 
	! objects.
	CALL item(2)

	arr4 = 2.0*arr2/arr3
	arr7 = 3*arr6**arr5

	PRINT *
	PRINT *, 'arr4 = '
	PRINT *
	PRINT *, arr4
	PRINT *
	PRINT *, 'arr7 = '
	PRINT *
	DO i=1,2
		PRINT *, (arr7(i,j),j=1,3)
	END DO

	! Item 3
	! Arrays may be used as arguments in Fortran intrinsic functions. 
	CALL item(3)

	arr9 = COS(arr8)

	PRINT *
	PRINT *, 'arr8 = '
	PRINT *
	DO i=1,2
		PRINT *, (arr8(i,j),j=1,3)
	END DO
	PRINT *
	PRINT *, 'arr9 = '
	PRINT *
	DO i=1,2
		PRINT *, (arr9(i,j),j=1,3)
	END DO


END PROGRAM arrayops

!! 1.	Operations with WHOLE arrays.
!!
!!	Array elements are scalar variables and hence may be used in any way 
!!	that a scalar variable is used.
!!
!!	Fortran90 has the facility to treat an array as a SINGLE object upon 
!!	which we can perform various operations. Naturally, there are certain 
!!	rules which must be adhered to (mostly obvious):
!!
!!		(i) Two arrays are said to be CONFORMABLE if they have the 
!!		same shape.
!!		(ii) A scalar is conformable with any array.
!!		(iii) All the usual intrinsic functions are defined between 
!!		two conformable objects.

!! 2.	All the usual operations (+-*/**) can be carried out between 
!!	conformable objects; this is done on an element-by-element basis. 
!!	For example, the following multiplies a given element of the matrix 
!!	a by 21 [cf (ii)], then multiplies this by the corresponding element 
!!	of b, and finally assigns the value to the corresponding element of c. 
!!	This is performed for each element.
!!
!!		INTEGER, DIMENSION(3,4) :: a,b,c
!!
!!		c = 21*a*b

!! 3.	Arrays may be used as arguments for all the Fortran90 intrinsic 
!!	functions (SIN, COS,ABS, etc). They are examples of elemental intrinsic 
!!	procedures in which the function reference is carried out for each 
!!	element of the array. The result must be an array with the same shape 
!!	as the argument. For example,
!!
!!		arr_1 = SQRT(arr_2)
!!		arr_3 = COS(arr_4) 
!!		arr_5 = MIN(0.0,arr_1,arr_2)	[note that the scalar 0.0 
!!						is conformable with  any array]
!!		etc.
!!
 
!!	END OF FILE: arrayops17.f90
