11. module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.module.pdf · a major...

21
11. Module 12/6/2016

Upload: others

Post on 10-Aug-2020

7 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

11. Module

12/6/2016

Page 2: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

A Major Feature of the Modern Fortran

• Module was introduced in Fortran 90.

• It is a container capable of sharing variables, subroutines, functions, interfaces and other among program units.

• Also, there are extra benefits for sharing them with modules, such as the global scope for variables and explicit interfaces for procedures.

• Two main capabilities a module can do:

1. Sharing data between program units

2. Creating explicit interfaces for procedures

module

integer ::

program subroutine function

module

subroutine ( , )

program

call subroutine ( , )

Pass Fail

Page 3: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

• Main program and subroutines/functions exchange data through argument list.

Sharing Data Using MODULE

subroutine fix(elev,dep,nx,ny) implicit none integer,intent(in) :: nx, ny real,intent(out) :: elev(nx,ny), dep(nx,ny) integer :: i, j do j = 1, ny do i = 1, nx elev(i,j)= elev(i,j) + 10.0 dep(i,j) = dep(i,j)/100.0 end do end do end subroutine

program main implicit none intger,parameter :: nx = 100, ny = 100 real :: elev(nx,ny), dep(nx,ny) integer :: i, j do i = 1, nx read(10,*) (elev(i,j), j=1,ny) read(11,*) (dep(i,j), j=1,ny) end do call fix(elev,dep,nx,ny) end program

subroutine fix use share implicit none integer :: i, j do j = 1, ny do i = 1, nx elev(i,j)= elev(i,j) + 10.0 dep(i,j) = dep(i,j)/100.0 end do end do end subroutine

program main use share implicit none integer :: i, j do i = 1, nx read(10,*) (elev(i,j), j=1,ny) read(11,*) (dep(i,j), j=1,ny) end do call fix end program

module share implicit none save integer,parameter :: nx=100, ny=100 real :: elev(nx,ny), dep(nx,ny) end module share

• They can also exchange data using modules.

Page 4: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

subroutine fix use share implicit none integer :: i, j do j = 1, ny do i = 1, nx elev(i,j)= elev(i,j) + 10.0 dep(i,j) = dep(i,j)/100.0 end do end do end subroutine

program main use share implicit none integer :: i, j do i = 1, nx read(10,*) (elev(i,j), j=1,ny) read(11,*) (dep(i,j), j=1,ny) end do call fix end program

module share implicit none save integer,parameter :: nx=100, ny=100 real :: elev(nx,ny), dep(nx,ny) end module share

• USE module_name: must be above any other statements except the program or subroutine statement

• SAVE: all data and variables declared preserved in all program units

• module codes must be positioned & compiled before other codes which use it.

Page 5: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

module share

program main

subroutine fix

share.mod

share.mod

old

new

• Module must be compiled before main program and subroutines/functions which use it.

> gfortran \ share.f90 main.f90 fix.f90

> gfortran \ main.f90 fix.f90 share.f90

share.mod and a.exe will be created.

module share

program main

subroutine fix

share.mod

new

If share.mod does not exist:

Fatal Error: Can't open module file 'share.mod' for reading at (1): No such file or directory

If share.mod already exists:

The old share.mod will be used in compiling, and a new share.mod will be created.

Page 6: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

PROGRAM t_random0 ! Test the random number generator random0 and use of MODULE ! USE ran001 IMPLICIT NONE REAL :: avg, ran, sum INTEGER :: i, iseq ! ! Print out 10 random numbers. WRITE (*,*) '10 random numbers: ' DO i=1,10 CALL random0(ran) WRITE (*,'(3X,F16.6,I12)') ran, iseed END DO ! ! Average 5 consecutive 10000-value sequences. WRITE (*,*) 'Averages of 5 consecutive 10000-sample sequences:' DO iseq=1,5 sum=0. DO i=1,10000 CALL random0(ran) sum=sum+ran END DO avg=sum/10000. WRITE (*,'(3X,F16.6)') avg END DO ! END PROGRAM

MODULE ran001 ! To declare data shared between subs random0 and seed. ! An initial value of iseed is given IMPLICIT NONE INTEGER, SAVE :: iseed = 9876 END MODULE ran001

SUBROUTINE random0 (ran) ! Generate a pseudorandom number with a uniform ! distribution in the range 0. <= ran < 1.0. ! USE ran001 ! Shared seed IMPLICIT NONE REAL, INTENT(OUT) :: ran ! iseed = MOD(8121*iseed+28411, 134456) ! Next number ran = REAL(iseed)/134456. END SUBROUTINE random0

Page 7: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

• In Fortran 77 programs, data sharing was implemented with common block.

Deprecated method to share data: common block

subroutine fix() implicit none integer,parameter :: n1 = 100, n2 = 100 real :: a(n1,n2), b(n1,n2) integer :: i, j common /hydro/ elev, dep do j = 1, n1 do i = 1, n2 elev(i,j)= elev(i,j) + 10.0 dep(i,j) = dep(i,j)/100.0 end do end do end subroutine

program main implicit none integer,parameter :: nx = 100, ny = 100 real :: elev(nx,ny), dep(nx,ny) integer :: i, j common /hydro/ elev, dep do i = 1, nx read(10,*) (elev(i,j), j=1,ny) read(11,*) (dep(i,j), j=1,ny) end do call fix() end program

Example:

Don't use it in your new program since it is not as flexible as sharing data through modules

Page 8: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

Variable Passing in Fortran: the Pass-by-Reference Scheme

What passed to the subroutine are the pointers to the memory addresses containing the calling arguments, not the actual values.

program test

subroutine sub1

program test real :: a, b(2) integer :: n call sub1(a,b,n) end program

The Fortran compiler will not recognize if the arguments between the main program and the subroutine are mismatched, e.g., real to integer, scalar to array.

Errors like this are extremely difficult to find and debug.

subroutine sub1(x,y,i) real, intent(out) :: x real, intent(in) :: y(2) integer :: i end subroutine sub1

a b(1) b(2) n

x y(1) y(2) i

Memory 1 byte

Only these addresses are passed

4 bytes = 32 bits integer = 24+8 bits real

Page 9: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

program bad_call ! To illustrate mismatch of calling argument implicit none real :: x=1. call bad_argument(x) end program bad_call

The Fortran compiler will not recognize if the arguments between the main program and the subroutine are mismatched, e.g., real to integer, scalar to array.

Errors like this are extremely difficult to find and debug.

Compile and execute using GNU Fortran:

> gfortran bad_call.f90

bad_call.f90:5.18: call bad_argument(x)1 Warning: Type mismatch in argument 'i' at (1); passed REAL(4) to INTEGER(4) > a.exe i= 2130567168

Compile and execute using Intel Fortran:

> ifort bad_call.f90 > a.out i= -1191408000

4 bytes = 32 bits integer = 24+8 bits real

subroutine bad_argument(i) implicit none integer :: i write(*,*) 'i=',i end subroutine bad_argument

Example:

Page 10: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

Using Modules to Create Explicit Interfaces

MODULE my_subs CONTAINS subroutine bad_argument(i) implicit none integer :: i write(*,*) 'i=',i end subroutine bad_argument END MODULE my_subs program bad_call2 ! Use MODULE to detect mismatch of arguments ! USE my_subs implicit none real :: x=1. call bad_argument(x) end program bad_call2

module procedure

• Procedures in modules (called module procedure) have explicit interfaces automatically.

Example:

Page 11: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

Compile and execute using Intel Fortran:

> ifort bad_call2.f90 bad_call2.f90(17): error #6633: The type of the actual argument differs from the type of the dummy argument. [X] call bad_argument(x) ------------------^ compilation aborted for bad_call2.f90 (code 1)

Compile and execute using GNU Fortran:

> gfortran bad_call2.f90 bad_call2.f90:17.18: call bad_argument(x) 1 Error: Type mismatch in argument 'i' at (1); passed REAL(4) to INTEGER(4)

Page 12: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

Implicit interface

subroutine fix (elev,dep,nx,ny) implicit none integer,intent(in) :: nx, ny real,intent(out) :: elev(nx,ny), dep(nx,ny) integer :: i, j do j = 1, ny do i = 1, nx elev(i,j)= elev(i,j) + 10.0 dep(i,j) = dep(i,j)/100.0 end do end do end subroutine

program main implicit none intger,parameter :: nx = 100, ny = 100 real :: elev(nx,ny), dep(nx,ny) integer :: i, j do i = 1, nx read(10,*) (elev(i,j), j=1,ny) read(11,*) (dep(i,j), j=1,ny) end do call fix (elev,dep,nx,ny) end program

• Types of arguments are implicit between program units.

• Coders should check type mismatch themselves.

Example:

Page 13: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

module my_subs contains subroutine fix (elev,dep,nx,ny) implicit none integer,intent(in) :: nx, ny real,intent(out) :: elev(nx,ny), dep(nx,ny) integer :: i, j do j = 1, ny do i = 1, nx elev(i,j)= elev(i,j) + 10.0 dep(i,j) = dep(i,j)/100.0 end do end do end subroutine end module

program main use my_subs implicit none integer,parameter :: nx = 100, ny = 100 real :: elev(nx,ny), dep(nx,ny) integer :: i, j do i = 1, nx read(10,*) (elev(i,j), j=1,ny) read(11,*) (dep(i,j), j=1,ny) end do call fix (elev,dep,nx,ny) end program

• Types of arguments are explicit between program units.

• Compiler can check type mismatch automatically.

Explicit interface

Example:

Page 14: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

Keyword Arguments

• If a procedure's interface is explicit, then it is possible to use keyword arguments and optional arguments in the calling program to enhance flexibility.

module my_mod contains real function calc (first,second,third) implicit none real,intent(in) :: first, second, third calc = (third-first)/second end function end module

program t_keywords use my_mod implicit none write(*,*) calc(1.0,2.0,3.0) write(*,*) calc(first=1.0,second=2.0,third=3.0) write(*,*) calc(second=2.0,third=3.0,first=1.0) write(*,*) calc(1.0,third=3.0,second=2.0) end program

Example:

1.0000000 1.0000000 1.0000000 1.0000000

Execute:

Page 15: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

• An optional argument is a dummy procedure argument that are not always be present. It is only possible in procedures with explicit interface.

module my_mod contains subroutine calc(first,second,third,ans) implicit none real,intent(inout) :: third real,intent(in) :: first, second real,intent(out),optional :: ans if (present(ans)) then ans = (third-first)/second else third = (third-first)/second end if end subroutine end module

program t_optional use my_mod implicit none real :: answer, one=1.0, two=2.0, three=3.0 call calc(second=two,third=three,first=one,ans=answer) write(*,*) answer call calc(second=two,third=three,first=one) write(*,*) three end program

Optional Arguments

Example:

1.0000000 1.0000000

Execute:

Page 16: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

• There is still other way to define interface (in case you don't want to use modules).

program interface_example implicit none ! Declare interface to subroutine "sort" interface subroutine sort(a,n) implicit none real,dimension(:),intent(inout) :: a integer,intent(in) :: n end subroutine sort end interface ! Declare local variables real,dimension(6) :: array = & (/1.,5.,3.,2.,6.,4./) Integer :: nvals = 6 ! Call "sort" to sort data call sort(n=nvals,a=array) write(*,*) array end program

subroutine sort(a,n) implicit none real,dimension(:),intent(inout) :: a integer,intent(in) :: n real :: tmp integer :: i, j, n_right n_right = 0 do j = 1, n-1 do i = 2, n-n_right if (a(i-1) > a(i)) then tmp = a(i) a(i) = a(i-1) a(i-1) = tmp end if end do n_right = n_right + 1 end do end subroutine sort

Interface Block

The interface block can be put after the declaration section as well

Example:

Page 17: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

Restricting Access of Module Data/Procedures

program restrict use my_mod, only: a, plus_two implicit none real :: b = 10.0 a = 100.0 call mult_two(a) write(*,*) a*b end program

module my_mod implicit none real :: a, b contains subroutine plus_two(x) implicit none real :: x x = x + 2.0 end subroutine subroutine mult_two(x) implicit none real :: x x = x * 2.0 end subroutine end module

> gfortran restrict.f90 restrict.f90: undefined reference to `mult_two_'

Compile:

• Variables, subroutines, and functions in modules can be partially invoked, using only in use statement.

• The purpose is to prevent naming conflicts

Example:

Page 18: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

• Variables, subroutines, and functions in modules can be invoked as other names, using => in use statement.

• The purpose is to prevent naming conflicts

Renaming Module Data/Procedures

program rename use my_mod, money=>a, m2=>mult_two implicit none real :: a = 30.255 money = 10000.0 call m2(money) write(*,*) money*a end program

local_name=>module_name module my_mod implicit none real :: a, b contains subroutine plus_two(x) implicit none real :: x x = x + 2.0 end subroutine !------------------------ subroutine mult_two(x) real :: x x = x * 2.0 end subroutine end module

605100.00

Execute:

Example:

Page 19: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

• Linear least-square approximation is a standard method to approximate over-determined systems.

• Consider time series of magnitude 𝑌𝑖 at time 𝑥𝑖, total 𝑁 data. If you want to approximate them with a linear curve 𝑦 = 𝑎𝑥 + 𝑏, the least-square approximation literally states that the summation of error 𝑌𝑖 − 𝑦𝑖

2 should be minimal:

Exercise : Linear Least-Square Approximation

𝑆 = 𝑌𝑖 − 𝑦𝑖2

𝑁

𝑖=1

= 𝑌𝑖 − 𝑎𝑥𝑖 − 𝑏2

𝑁

𝑖=1

𝑌𝑖

𝑦 = 𝑎𝑥 + 𝑏 𝑎 𝑥𝑖

2 + 𝑏 𝑥𝑖 = 𝑥𝑖𝑌𝑖

𝑎 𝑥𝑖 + 𝑏𝑁 = 𝑌𝑖

𝑐1𝑎 + 𝑐2𝑏 = 𝑐3

𝑐4𝑎 + 𝑐5𝑏 = 𝑐6

For the minimal 𝑆,

𝜕𝑆

𝜕𝑎= 0

𝜕𝑆

𝜕𝑏= 0

𝑎 =−𝑐3𝑐5 + 𝑐2𝑐6−𝑐1𝑐5 + 𝑐2𝑐4

𝑏 =𝑐3 − 𝑐1𝑎𝑐2

Page 20: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

1. Read the data 𝑥𝑖 (first column) and 𝑌𝑖 (second column) in the data file xy.dat shown below. The total number of data 𝑁 is given in the first line.

2. Develop a subroutine leastsq_linear1(N, x, Y, a, b) in a module sub_module to calculate 𝑎 and 𝑏 of the linear curve.

3. Develop a subroutine leastsq_linear2() without any dummy arguments to calculate 𝑎 and 𝑏. It should be outside a module. Use a module data_module to share variables between the subroutine and the main program.

4. Both programs should print out 𝑎 and 𝑏.

module sub_module leastsq_linear1(N, x, Y, a, b) end module program (Read data) call leastsq_linear1(N, x, Y, a, b) write(*,*) a, b end program

module data_module (Declare N, x, Y, a, b) end module subroutine leastsq_linear2() ... end subroutine program (Read data) call leastsq_linear2() write(*,*) a, b end program

leastsq_linear1 leastsq_linear2

Page 21: 11. Module - 國立臺灣大學homepage.ntu.edu.tw/~wttsai/fortran/ppt/11.Module.pdf · A Major Feature of the Modern Fortran •Module was introduced in Fortran 90. •It is a container

25 0.10000000 -1.3146429 0.20000000 -3.1990519 0.30000001 -0.10450792 0.40000001 -0.71243405 0.50000000 -2.2956548 0.60000002 -0.91617846 0.69999999 -2.6574748 0.80000001 -2.3678687 0.90000004 0.38248765 1.0000000 1.0534627 1.1000000 1.0077106 1.2000000 1.1989625 1.3000001 6.5031471 1.4000000 4.1205955 1.5000000 5.1728935 1.6000000 7.1715932 1.7000000 3.9966502 1.8000001 8.5051289 1.9000000 9.1784534 2.0000000 7.9379234 2.1000001 11.834155 2.2000000 9.8077221 2.3000000 9.3412457 2.4000001 14.611238 2.5000000 13.090397

xy.dat