160 likes | 268 Views
AME 150 L. More Subroutine & Functions (& hints on HW 8). Writing Functions. We will define a function "Noisy_Sine" that add some white noise to the sine White Noise is a heterogeneous mixture of signals extending over an infinite frequency range (acoustic definition)
E N D
AME 150 L More Subroutine & Functions (& hints on HW 8) AME 150 L
Writing Functions • We will define a function "Noisy_Sine" that add some white noise to the sine • White Noise is a heterogeneous mixture of signals extending over an infinite frequency range (acoustic definition) • Fortran has a function that will generate a pseudo-random noise: random_number(x) AME 150 L
FUNCTION noisy_sine (x,amp) IMPLICIT NONE REAL, INTENT(IN):: x,amp REAL :: noisy_sine, noise LOGICAL :: First_Entry=.TRUE. IF( First_Entry ) THEN First_Entry = .FALSE. !Initialize r-n generator CALL Random_Seed () END IF CALL Random_number(noise) !r-n uniform in 0-1 noisy_sine = SIN(x) + amp * ( noise - .5 ) return END FUNCTION noisy_sine AME 150 L
Compiling a Subroutine or Function f90 Noisy_sine.f90 Undefined first referenced symbol in file main /usr/spac/sparcompilers/5.1/... ld: fatal: Symbol referencing errors. No output written to a.out ------------ • One problem is: message wraps on screen! • Why do they do the two column display? • Meaning - No MAIN program! (why didn't they say that?) AME 150 L
"Calling" Program • Any Subroutine or Function is used only when invoked (Called) • Test program (driver) is designed to exercise program (check inputs and outputs) AME 150 L
PROGRAM testdrive IMPLICIT NONE REAL :: x, Noisy_sine DO write (*,*)"Enter x=" read (*,*)x WRITE (*,*)x, sin(x), Noisy_sine(x,0.1) END DO END PROGRAM testdrive AME 150 L
Types of Errors 1) Missing symbol: (MAIN) or Subroutine 2) Incorrect calling sequence (arguments) Omit argument. Does Fortran take 0? No, It actually took some garbage (GIGO again) 3) Try incorrect type of arguments (Integer or character instead of REAL) Does it look like Fortran used 0? AME 150 L
Forcing an Interface INTERFACE FUNCTION noisy_sine (x,amp) IMPLICIT NONE REAL, INTENT(IN):: x, amp REAL :: noisy_sine END FUNCTION noisy_sine END INTERFACE AME 150 L
Interface Description • Does not contain any executable statements • Protects against interface errors at COMPILE TIME (not run time) • Use of INCLUDE (Not recommended) • Older extension (not a Fortran statement) INCLUDE "filename" • (better to use module facility) AME 150 L
Common Errors • Compiler Errors - Wrong Fortran Syntax • Logic Errors - Fortran statements don't do what you intended (they do what you say) • Linker Errors - Missing Symbol Names • Interface Errors - Mismatch in order, type, or usage of arguments to subroutines and/or functions AME 150 L
Arrays • Collections of data referenced by same symbol (with an index or subscript) • Must always describe Type, dimension [and shape] • Modern systems allow dynamic allocation • Older Fortran only referred to elements of an array, Fortran 90/95 can overload operators (+, -, *) to simplify coding AME 150 L
Arrays - Examples • Declaration: REAL, Dimension(10):: a, b, c ! indices go from 1 to 10 REAL :: a(10), b(0:20), c(-10:10) INTEGER, parameter:: Size=20 REAL , dimension(size,size) :: X INTEGER,allocatable,dimension(:,:)::k (we will not use allocatable arrays in AME 150) AME 150 L
Calling Program: PROGRAM test IMPLICIT none REAL, dimension(10,20)::a . . . CALL SUB1 ( a , 10 ) . . . END PROGRAM test Subprogram Subroutine SUB1 (x, nd) IMPLICIT none INTEGER,INTENT (IN)::nd REAL,dimension(nd,*),& &INTENT(IN OUT):: x . . . RETURN . . . END Subroutine SUB1 Arrays in Subprograms AME 150 L
Storage of Arrays • An array is stored ONCE in memory • It exists in the Highest Order (towards main program) routine that references it • Subroutines refer to a Pointer, and do not create a copy of an array • On the USC computers, arrays are stored linearly in memory AME 150 L
Storage of Arrays -2 AME 150 L
Storage of Arrays -3 • A subroutine only needs to know that a one dimensional array is an array • For 2 and 3 dimensional arrays, the subroutine MUST know size of all but the last dimension • Don't count on Fortran to check the dimensions for you AME 150 L