Transcript Chapter 4

Chapter 7
Introduction to Procedures
Introduction to Procedures
•
•
•
•
•
So far, all programs written in such way that all subtasks are
integrated in one single large program.
There is no way to code, verify and test each subtask
independently before combining them to the final program.
Fortran has a special mechanism to do so.
Each subtask can be coded as a separate program unit called
external procedure which can be compiled and tested
independently.
FORTRAN External Procedures:
–
Subroutines
•
•
–
Functions
•
•
•
Can be invoked using CALL statement
They can return multiple results through calling arguments
Can be invoked by directly using them in expression
They return single value that is then used in the expression
Advantages of procedures:
1. Independent testing of subtasks
2. Reusable code
3. Isolation from unintended effects
Subroutines
•
Subroutine is a FORTRAN procedure that is invoked by naming it
in CALL statement and that retrieves its input values and return its
results through an argument list.
It is an independent program that starts with SUBROUTINE and
ends with END SUBROUTINE
•
•
The general form of subroutine (similar to program organization)
Standard FORTRAN name
Beginning
END
SUBROUTINE sub_name (argument_list)
…
( Declaration section)
…
(Execution section)
…
RETURN
END SUBROUTINE [sub_name]
Optional
Dummy arguments:
variables or arrays
passed from
program
Optional
If we need to return before END
similar to STOP, END Program
Subroutines
•
•
•
It is compiled independently away from the
program and any other subroutine.
When a program call the subroutine, the
execution of the program will suspend and the
procedure will execute till it reach RETURN or
END SUBROUTINE and the program then
resumes.
Any executable program can call a subroutine
including another subroutine.
Calling a subroutine
• Place a CALL statement in the calling
program’s code.
CALL sub_name (argument_list)
• The order and type of the actual
arguments match the order and type of
dummy arguments in the declared
subroutine.
z
Example-1
x
y
z
x
2
 y2
• Write a program that calculates the hypotenuse of right triangle.
The user should enter the first and second sides (x, y) and the
program calculates and print the hypotenuse (z)
PROGRAM mainProgram
IMPLICIT NONE
REAL :: x, y, z
WRITE (*,*) 'Enter first value: '
READ (*,*) x
WRITE (*,*) 'Enter second value: '
READ(*,*) y
z = SQRT(x**2 + y**2)
WRITE (*,*) 'Result: ', z
END PROGRAM
You can remove
RETURN
PROGRAM mainProgram
IMPLICIT NONE
REAL :: x, y, z
WRITE (*,*) 'Enter first value: '
READ (*,*) x
WRITE (*,*) 'Enter second value: '
READ(*,*) y
CALL calculate(x, y, z)
WRITE (*,*) 'Result: ', z
END PROGRAM
SUBROUTINE calculate ( first, second, output)
IMPLICIT NONE
REAL, INTENT(IN) :: first, second
REAL, INTENT(OUT) :: output
output = SQRT(first**2 + second**2)
RETURN
END SUBROUTINE

INTENT Attribute
• INTENT(IN)
Dummy argument is used to pass input data to subroutine only.
• INTENT(OUT)
Dummy argument is used to return result to the calling program only.
• INTENT(INOUT) or INTENT(IN OUT)
Dummy argument is used to both pass input data to subroutine and to
return result to the calling program.
• You need to specify INTENT type for each argument but not for local
variables of the subroutine.
• This will help the compiler to know what is expected for each
argument and easily discover errors.
REAL, INTENT(IN) :: in
in = 3
[ERROR]
Example-2
PROGRAM mainProgram
IMPLICIT NONE
INTEGER, PARAMETER:: max_Size =10
INTEGER :: i, j
REAL, DIMENSION (max_Size) :: dat
REAL :: temp
Write (*,*) 'Enter DATA set (', max_Size,' values) :'
WRITE (*,*)
DO i=1, max_Size
READ (*,*) dat(i)
END DO
DO i=max_Size, 1, -1
DO j=2, i
IF (dat(j-1) > dat(j)) THEN
Sort data
temp = dat(j-1)
in array
dat(j-1) = dat(j)
dat(j) = temp
ENDIF
END DO
END DO
WRITE (*,*) ' Sorted data: '
DO i=1, max_Size
WRITE (*,*) dat(i)
END DO
END PROGRAM
PROGRAM mainProgram
IMPLICIT NONE
INTEGER, PARAMETER:: max_Size =10
INTEGER :: i
REAL, DIMENSION (max_Size) :: dat
Write (*,*) 'Enter DATA set (', max_Size,' values) :'
WRITE (*,*)
DO i=1, max_Size
READ (*,*) dat(i)
END DO
CALL sortArray(dat, max_Size)
WRITE (*,*) ' Sorted data: '
DO i=1, max_Size
WRITE (*,*) dat(i)
END DO
END PROGRAM
SUBROUTINE sortArray (array, arrSize)
IMPLICIT NONE
INTEGER, INTENT (IN):: arrSize
REAL, DIMENSION(arrSize), INTENT(INOUT) :: array
INTEGER :: i, j
REAL :: temp
DO i=arrSize, 1, -1
DO j=2, i
IF (array(j-1) > array(j)) THEN
temp = array(j-1)
array(j-1) = array(j)
array(j) = temp
ENDIF
END DO
END DO
END SUBROUTINE
Variable passing in FORTRAN
• Pass-by-Reference
– The program passes a pointer to the memory location of actual arguments in
the list which are going to be used by the subroutine to get the values of the
dummy arguments.
– So, pointers are sent to the subroutine not values.
– Actual arguments should match the dummy arguments in number, type, and
order
PROGRAM test
REAL
SUBROUTINE adding
INTEGER
REAL
REAL
PROGRAM test
REAL :: a, b, sum
INTEGER :: c
...
CALL adding (a, b, c, sum)
...
END PROGRAM
SUBROUTINE adding (x1, x2, x3, x4)
REAL, INTENT(IN) :: x1, x2
INTEGER, INTENT(IN) :: x3
REAL, INTENT(OUT) :: x4
x4 = X1 + X2 + X3
END SUBROUTINE
Errors
PROGRAM test
REAL :: a, b, sum
REAL :: c
READ (*,*) a, b, c
CALL adding (a, b, c)
WRITE (*,*) 'sum : ', sum
END PROGRAM
PROGRAM test
REAL :: a, b, sum
REAL :: c
READ (*,*) a, b, c
CALL adding (a, b, c, sum)
WRITE (*,*) 'sum : ', sum
END PROGRAM
SUBROUTINE adding (x1, x2, x3, x4)
REAL, INTENT(IN) :: x1, x2
INTEGER, INTENT(IN) :: x3
REAL, INTENT(OUT) :: x4
WRITE (*,*) x1, ' ', x2,' ', x3
x4 = X1 + X2 + X3
END SUBROUTINE
SUBROUTINE adding (x1, x2, x3, x4)
REAL, INTENT(IN) :: x1, x2
INTEGER, INTENT(IN) :: x3
REAL, INTENT(OUT) :: x4
WRITE (*,*) x1, ' ', x2,' ', x3
x4 = X1 + X2 + X3
END SUBROUTINE
________________________________
Input :
12.6 16.5 14.9
Output:
12.6 16.5 1097754214
sum : 1.09775424E+09
___________________
Wrong:
Number of arguments
does not match
Exercise-1
Write a subroutine that takes three real values,
add them, and return the sum.
PROGRAM test
REAL :: a, b, c, sum
WRITE (*,*) ‘Enter three values: ’
READ (*,*) a, b, c
CALL adding (a, b, c, sum)
WRITE (*,*) 'sum : ', sum
END PROGRAM
SUBROUTINE adding (x1, x2, x3, x4)
REAL, INTENT(IN) :: x1, x2, x3
REAL, INTENT(OUT) :: x4
x4 = X1 + X2 + X3
END SUBROUTINE
Exercise-2
Write a subroutine that accepts three real values
and return the maximum value out of the three.
Don’t use the function MAX. PROGRAM test
REAL :: a, b, c, maxValue
WRITE (*,*) 'Enter three values: '
READ (*,*) a, b, c
CALL getMax (a, b, c, maxValue)
WRITE (*,*) '‘Largest Value : ', maxValue
END PROGRAM
SUBROUTINE getMax (x1, x2, x3, x4)
REAL, INTENT(IN) :: x1, x2, x3
REAL, INTENT(OUT) :: x4
x4=x1
IF(x2>x4) THEN
x4=x2
ENDIF
IF(x3>x4) THEN
x4=x3
ENDIF
END SUBROUTINE
Exercise-3
Write a subroutine that accepts three real values
and return the minimum value out of the three.
Don’t use the function MIN. PROGRAM test
REAL :: a, b, c, maxValue
WRITE (*,*) 'Enter three values: '
READ (*,*) a, b, c
CALL getMax (a, b, c, maxValue)
WRITE (*,*) '‘Largest Value : ', maxValue
END PROGRAM
SUBROUTINE getMax (x1, x2, x3, x4)
REAL, INTENT(IN) :: x1, x2, x3
REAL, INTENT(OUT) :: x4
x4=x1
IF(x2<x4) THEN
x4=x2
ENDIF
IF(x3<x4) THEN
x4=x3
ENDIF
END SUBROUTINE
Exercise-4
Write a subroutine that swap the values of two
variables.
PROGRAM test
REAL :: a, b
WRITE (*,*) 'Enter two values: '
READ (*,*) a, b
WRITE (*,*) ' a : ', a, ' b : ', b
CALL swap (a, b)
WRITE (*,*) ' a : ', a, ' b : ', b
END PROGRAM
SUBROUTINE swap (a,b)
REAL, INTENT(INOUT) :: a, b
REAL :: temp
temp = a
a=b
b = temp
END SUBROUTINE
Passing Arrays to subroutine
•
•
•
All what is needed is to send pointer to the memory
location of the first element of the array.
However, the subroutine also needs to know the size of
the array in order to perform operations and make sure
indexes stay within bounds.
There are three ways to do so:
1. Explicit-Shape dummy array
2. Assumed-Shape dummy array
3. Assumed-size dummy array
Explicit-Shape Dummy Array
• Pass the bounds and dimensions of the array as arguments to the
subroutine, then the array will be declared accordingly.
• This allow the bound checker in most of FORTRAN compiler to
detect out-of-bound errors.
• In this method, since the shape and bounds are known, whole
operations and array subsections can be used.
SUBROUTINE getNewData (dat1, dat2, n)
INTEGER, INTENT(IN) :: n
REAL, Dimension (n), INTENT(OUT) :: dat2
REAL, Dimension (n), INTENT(IN) :: dat1
SUBROUTINE getNewData (dat1, dat2, n)
INTEGER :: i
INTEGER, INTENT(IN) :: n
DO i=1,n
dat2(i)=dat1(i)+dat1(i)**2REAL, Dimension (n), INTENT(OUT) :: dat2
REAL, Dimension (n), INTENT(IN) :: dat1
END DO
SUBROUTINE getNewData (dat1, dat2, n)
INTEGER :: i
END SUBROUTINE
INTEGER, INTENT(IN) :: n
dat2=dat1+dat1**2
REAL, Dimension (n), INTENT(OUT) :: dat2
END SUBROUTINE
REAL, Dimension (n), INTENT(IN) :: dat1
INTEGER :: i
dat2(1:n)=dat1(1:n)+dat1(1:n)**2
END SUBROUTINE
Assumed-Shape Dummy Array
• Shape is known rather than bounds.
• Declared using colon as placeholder for subscripts of the arrays
• The subroutine should have an explicit interface and no need to
pass the array size or bounds to it. (uses modules)
• Whole array operations and subsection can be used in this type
MODULE test
CONTAINS
SUBROUTINE getNewData (dat1, dat2)
REAL, Dimension (:), INTENT(OUT) :: dat2
REAL, Dimension (:), INTENT(IN) :: dat1
dat2=dat1+dat1**2
END SUBROUTINE
END MODULE
Assumed-Size Dummy Array
• Declare the size of the array as (*) assumed size
• Actual length not known by the compiler
• Bounds checking, whole array operations and array sections does
not work here.
• This was in old FORTRAN, it should never be used in new programs
SUBROUTINE getNewData (dat1, dat2, n)
INTEGER, INTENT(IN) :: n
REAL, Dimension (*), INTENT(OUT) :: dat2
REAL, Dimension (*), INTENT(IN) :: dat1
DO i=1,n
dat2(i)=dat1(i)+dat1(i)**2
END DO
END SUBROUTINE
n is not the array size. It represent how
many elements should be involved in
the operation
Exercise-5
Write a subroutine that accept array and
return the sum of all its elements.
PROGRAM test
IMPLICIT NONE
INTEGER, Parameter :: maxSize=5
REAL :: sum
REAL, DIMENSION(maxSize) :: arr=(/2., -1., 5., 10., 0./)
CALL sumAll (arr, maxSize, sum)
WRITE(*,*) ' sum of all values: ', sum
END PROGRAM
SUBROUTINE sumAll (dat, n, total)
INTEGER, INTENT(IN) :: n
REAL, Dimension (n), INTENT(IN) :: dat
REAL, INTENT(OUT) :: total
INTEGER :: i
total=0
DO i=1,n
total=total+dat(i)
END DO
END SUBROUTINE
Exercise-6
Write a subroutine that find the maximum
value in an array (don’t use MAX function).
PROGRAM test
IMPLICIT NONE
INTEGER, Parameter :: maxSize=5
REAL :: maxValue
REAL, DIMENSION(maxSize) :: arr=(/2., -1., 5., 10., 0./)
CALL getMax (arr, maxSize, maxValue)
WRITE(*,*) ' maximum values: ', maxValue
END PROGRAM
SUBROUTINE getMax (dat, n, num)
INTEGER, INTENT(IN) :: n
REAL, Dimension (n), INTENT(IN) :: dat
REAL, INTENT(OUT) :: num
INTEGER :: i
num=dat(1)
DO i=2,n
IF (dat(i)>num) THEN
num = dat(i)
END IF
END DO
END SUBROUTINE
Exercise-7
Write a subroutine that find the minimum
value in an array (don’t use MIN function).
PROGRAM test
IMPLICIT NONE
INTEGER, Parameter :: maxSize=5
REAL :: maxValue
REAL, DIMENSION(maxSize) :: arr=(/2., -1., 5., 10., 0./)
CALL getMax (arr, maxSize, maxValue)
WRITE(*,*) ' maximum values: ', maxValue
END PROGRAM
SUBROUTINE getMax (dat, n, num)
INTEGER, INTENT(IN) :: n
REAL, Dimension (n), INTENT(IN) :: dat
REAL, INTENT(OUT) :: num
INTEGER :: i
num=dat(1)
DO i=2,n
IF (dat(i)<num) THEN
num = dat(i)
END IF
END DO
END SUBROUTINE
Passing Character Variables to Subroutine
• The length of the character variable is declared with (*).
• It is not necessary to know the length in subroutine.
• When the subroutine is called the length of the dummy argument will
be the length of the actual argument in the program.
• However, you can tell the size of the character at run time using the
function LEN.
SUBROUTINE sampleSUB (name)
CHARACTER(len=*), INTENT(IN) :: name
WRITE(*,*) ‘The length of the received name is: ’, LEN(name)
END SUBROUTINE
Error Handling in Subroutine
SUBROUTINE getRES (a, b, res)
IMPLICIT NONE
REAL, INTENT(IN) :: a, b
REAL, INTENT(OUT) :: res
REAL :: temp
temp = a -b
res = SQRT(temp)
END SUBROUTINE
What does this subroutine do?
What is the output if a = 1, b = 2 ?
Run time error:
res = -NaN
Rewrite it to avoid this problem.
SUBROUTINE getRES (a, b, res,
res) error)
IMPLICIT NONE
First solution:
Never
use STOP
when
in any
square
subroutine.
root of negative
Add an error
values
flagisthat
requested
indicates
REAL, INTENT(IN) :: a, b
printsituation
the
an errorwhen
and stop
the subroutine
the program
return
before
wrong
returning
values
form
and pass it
REAL, INTENT(OUT) :: res
subroutine.
the main program.
The main After
program
returning
loosesfrom
all data
the subroutine,
that are processed
the
REAL :: temp
INTEGER,
INTENT(OUT) :: error to
before calling
program
should
thecheck
subroutine.
the flagIsand
there
display
a better
error
way?
message for the
temp =::a-b
REAL
temp
user.
IF (temp>=0)
temp
= a-b THEN
res(temp>=0)
IF
= SQRT(temp)
THEN
ELSE
res
= SQRT(temp)
WRITE(*,*)
error
= 0 'Square root of negative value in subroutine getRes'
STOP
ELSE
ENDIF
res
=0
END SUBROUTINE
error
=1
ENDIF
END SUBROUTINE
Program Design
•
Write a program that accepts real values from the user and store
them in 1-D array. The user first should be asked to enter the size of
the data set he needs to enter. Then, he will be asked to enter the
values. Your program should make statistics on the data that are
stored in the array. The statistics will include:
1.
2.
3.
4.
5.
•
Find the max value and its location in the array
Find the min value and its location in the array
Calculate the average of all values
Find the median
Calculate the standard deviation
For each one of the above subtasks write a subroutine. The main
program will just accept the user inputs, store them in an array and
call these five subroutines to get the results and print them to the
user.
Sharing Data Using Modules
• Programs, Subroutine and Functions can exchange data
through modules in addition to argument list.
• Module is a separately compiled program unit that
contains the definitions and initial values of the data we
wish to share between program units.
• It provides a way to share data between program units.
• Modules are especially useful for sharing large volumes
of data among many program and procedure units.
Module Construct
Beginning
Declaration of
the data to be
shared
END
MODULE module_name
IMPLICIT NONE
SAVE
INTEGER, PARAMETER :: num_Vals = 5
REAL, DIMENSION(num_Vals) :: values
END MODULE
Using Modules
• Any program unit can make use of that
share data it contains the command
USE module_name
• The USE command must be the first
command after the program name or
subroutine name.
• USE association is the process of
accessing information in a module using
the USE statement
Example - 3
PROGRAM test
USE module_name
IMPLICIT NONE
values=(/1, 2, 3, 4, 5/)
WRITE (*,*) values
END PROGRAM
SUBROUTINE display
USE module_name
IMPLICIT NONE
WRITE (*,*) values
END SUBROUTINE
MODULE module_name
IMPLICIT NONE
SAVE
INTEGER, PARAMETER :: num_Vals = 5
REAL, DIMENSION(num_Vals) :: values
END MODULE
Example - 4
PROGRAM test
IMPLICIT NONE
CALL display
END PROGRAM
SUBROUTINE display
USE module_name
IMPLICIT NONE
WRITE (*,*) values
END SUBROUTINE
MODULE module_name
IMPLICIT NONE
SAVE
INTEGER, PARAMETER :: num_Vals = 5
REAL, DIMENSION(num_Vals) :: values=(/1,2,3,4,5/)
END MODULE
Random Number Generator
• Random number generator is a procedure that return different
numbers that seem to be random.
• One simple random number generator uses the following equation
Ni+1 = MOD( 8121 ni + 28411, 134456)
• The random number rani = ni / 134456
• n0 is call the seed of the sequence which should be entered by the
user so the sequence vary from run to another.
• Write a subroutine randomNum that generates and return a single
number ran based on the above equations. Another subroutine
(seed) should be called to get the seed value n0.
Random Number Generator
PROGRAM randomGenerator
IMPLICIT NONE
INTEGER :: n0
REAL :: num
WRITE (*,*) 'Enter the seed value: '
READ (*,*) n0
CALL seed(n0)
CALL randomNum(num)
WRITE (*,*) num
END PROGRAM
SUBROUTINE randomNum(ran)
USE ranValue
IMPLICIT NONE
REAL, INTENT(OUT):: ran
n = MOD(8121*n+28411, 134456)
ran = REAL(n)/134456
END SUBROUTINE
SUBROUTINE seed(inSeed)
USE ranValue
IMPLICIT NONE
INTEGER, INTENT(IN):: inSeed
n = ABS(inSeed)
END SUBROUTINE
MODULE ranValue
IMPLICIT NONE
SAVE
INTEGER :: n
END MODULE
PROGRAM randomGenerator
IMPLICIT NONE
INTEGER :: n0
REAL :: num
WRITE (*,*) 'Enter the seed value: '
READ (*,*) n0
CALL seed(n0)
CALL randomNum(num)
WRITE (*,*) num
END PROGRAM
SUBROUTINE randomNum(ran)
USE ranValue
IMPLICIT NONE
REAL, INTENT(OUT):: ran
n = MOD(8121*n+28411, 134456)
ran = REAL(n)/134456
END SUBROUTINE
SUBROUTINE seed(inSeed)
USE ranValue
IMPLICIT NONE
INTEGER, INTENT(IN):: inSeed
n = ABS(inSeed)
END SUBROUTINE
MODULE ranValue
IMPLICIT NONE
SAVE
INTEGER :: n
END MODULE
Full Program
•
Now, modify the main program so
that it prints 10 random numbers.
•
Then, make it generates 1000
numbers and calculate their
average.
PROGRAM randomGenerator
IMPLICIT NONE
INTEGER :: n0, i
REAL :: num, sum=0, Avg
WRITE (*,*) 'Enter the seed value: '
READ (*,*) n0
CALL seed(n0)
WRITE (*,*) ' 10 random numbers : '
DO i=1, 10
CALL randomNum(num)
WRITE (*,*) num
END DO
DO i=1, 1000
CALL randomNum(num)
sum = sum +num
END DO
Avg = sum / 1000
WRITE (*,*) ' The average of 1000 random numbers
is: ', Avg
END PROGRAM
FORTRAN FUNCTION
• FORTRAN Function is a procedure that returns single
output which can be, number, logical value, character
string or an array.
• In contrast to routines, functions can be used and
combined with expressions.
• Function types:
– Intrinsic functions
Built into the FORTRAN language (e.g. SIN(x), MAX(a,b))
– User-defined functions (function subprograms)
Defined by a programmer to meet specific needs not addressed by
intrinsic functions and they are used in expressions like intrinsic
function.
Function Construct
Standard FORTRAN name
Beginning
END
Dummy arguments:
variables or arrays
passed from program.
Can be blank but with
parenthesis
FUNCTION functionName (argument_List)
…
(Declaration Section must declare type of functionName)
…
The return value
(Execution section)
functionName = expr
Optional
RETURN
If we need to return before END
END FUNCTION [ functionName ]
Optional
FUNCTION myMax (a , b)
IMPLICIT NONE
REAL :: myMax
REAL, INTENT(IN) :: a, b
IF(a>=b) THEN
myMax = a
ELSE
myMax=b
END IF
END FUNCTION
Declaring Function Type
FUNCTION myMax(a,b)
REAL :: myMax
OR
REAL FUNCTION myMax(a,b)
FUNCTION myMax (a , b)
IMPLICIT NONE
REAL :: myMax
REAL, INTENT(IN) :: a, b
IF(a>=b) THEN
myMax = a
ELSE
myMax=b
END IF
END FUNCTION
REAL FUNCTION myMax (a , b)
IMPLICIT NONE
REAL, INTENT(IN) :: a, b
IF(a>=b) THEN
myMax = a
ELSE
myMax=b
END IF
END FUNCTION
Exercise-8
Write a program that call the function quadf that calculates and returns
the value of the quadratic equation. In the main program the user
will be asked to enter the three coefficients a, b, c and the evaluation
value x. All of these four values will be sent as arguments to the
function quadf. Finally, the program will print the result returned by
the function.
quadf(a, b, c, x)  ax2  bx  c
PROGRAM quadraticFunction
IMPLICIT NONE
REAL :: quadf
REAL :: a, b, c, x, f
WRITE (*,*) 'Enter the three coefficients
a,b,c : '
READ (*,*) a,b,c
WRITE (*,*) 'Enter the evaluation value x: '
READ (*,*) x
f = quadf(x, a, b, c)
WRITE (*,*) 'The quadratic result: ', f
END PROGRAM
FUNCTION quadf(x,a,b,c)
IMPLICIT NONE
REAL :: quadf
REAL, INTENT(IN) :: x,a,b,c
quadf=a*x**2+b*x+c
END FUNCTION
REAL FUNCTION quadf(x,a,b,c)
IMPLICIT NONE
REAL, INTENT(IN) :: x,a,b,c
quadf=a*x**2+b*x+c
END FUNCTION
Unintended Side Effects in Functions
• Side effect happen when the function change
the values of the input arguments in the
program.
• The function should produce single output and it
should have no side effects.
• It should never modify its input arguments.
• If you need a function that produce more than
one result then, use subroutine instead.
• Always declare input arguments with
INTENT(IN) to avoid side effects.
Exercise-9
• The sinc function is defined by the equation:
sinc(x)=sin(x)/x
• It is easy to implement but consider x equal or very close
to zero.
• Modify the equation to be:
IF |x|> Epsilon sinc(x)=sin(x)/x
Else
sinc=1
• Epsilon is very small real number that is chosen to
ensure that the division does not cause divide by zero. A
good value of Epsilon is 1.0E-30
PROGRAM getSINC
IMPLICIT NONE
REAL :: sinc
REAL :: x
WRITE (*,*) 'Enter a number to evaluate with SINC : '
READ (*,*) x
WRITE(*,*) 'THe value is: ', sinc(x)
END PROGRAM
REAL FUNCTION sinc(x)
IMPLICIT NONE
REAL, PARAMETER :: eps=1.0E-30
REAL, INTENT(IN) :: x
IF (ABS(x)>eps) THEN
sinc=SIN(x)/x
ELSE
sinc=1
END IF
END FUNCTION
Tutorial
Write a subroutine to compute the average of all the
elements in a matrix. Use a SUBROUTINE AND A
MODULE within a program to ask the user for a
matrix, and compute its average. Add one more subroutine to
PROGRAM tutorial_on_subroutines
USE tut
IMPLICIT NONE
INTEGER :: i, j
WRITE(*,*) 'Enter the elements of the matrix A (3x3)'
READ (*,*) A
CALL find_mean
WRITE (*,*) 'The mean of your matrix = ', A_mean
END PROGRAM
MODULE tut
IMPLICIT NONE
REAL, DIMENSION (3,3) :: A
REAL:: A_mean
END MODULE
find the maximum value in
the matrix and its location
SUBROUTINE find_mean
USE tut
IMPLICIT NONE
INTEGER :: i, j
REAL :: total=0.0
DO i=1,3
DO j=1,3
total = total + A(i,j)
END DO
END DO
A_mean = total / 9.0
END SUBROUTINE