Fortran - Fortran Examples - Wikibooks, Open Books For An Open World
Fortran - Fortran Examples - Wikibooks, Open Books For An Open World
examples
< Fort ran
Fortran
C AREA OF A TRIANGLE -
HERON'S FORMULA
C OUTPUT -
READ(5,501) IA,IB,IC
501 FORMAT(3I5)
IF (IA) 701, 777, 701
701 IF (IB) 702, 777, 702
702 IF (IC) 703, 777, 703
777 STOP 1
703 S = (IA + IB + IC) /
2.0
AREA = SQRT( S * (S -
IA) * (S - IB) * (S - IC) )
WRITE(6,801)
IA,IB,IC,AREA
801 FORMAT(4H A= ,I5,5H
B= ,I5,5H C= ,I5,8H AREA=
,F10.2,
$13H SQUARE UNITS)
STOP
END
501 FORMAT(3I5)
601 FORMAT(4H A= ,I5,5H
B= ,I5,5H C= ,I5,8H AREA=
,F10.2,
$13H SQUARE UNITS)
602 FORMAT(10HNORMAL END)
603 FORMAT(23HINPUT
ERROR, ZERO VALUE)
INTEGER A,B,C
10 READ(5,501) A,B,C
IF(A.EQ.0 .AND.
B.EQ.0 .AND. C.EQ.0) GO TO
50
IF(A.EQ.0 .OR.
B.EQ.0 .OR. C.EQ.0) GO TO
90
S = (A + B + C) / 2.0
AREA = SQRT( S * (S -
A) * (S - B) * (S - C) )
WRITE(6,601)
A,B,C,AREA
GO TO 10
50 WRITE(6,602)
STOP
90 WRITE(6,603)
STOP
END
501 FORMAT(3I5)
601 FORMAT(" A= ",I5,"
B= ",I5," C= ",I5," AREA=
",F10.2,
$"SQUARE UNITS")
602 FORMAT("NORMAL END")
603 FORMAT("INPUT ERROR
OR ZERO VALUE ERROR")
INTEGER A,B,C
10
READ(5,501,END=50,ERR=90)
A,B,C
IF(A=0 .OR. B=0 .OR.
C=0) GO TO 90
S = (A + B + C) / 2.0
AREA = SQRT( S * (S -
A) * (S - B) * (S - C) )
WRITE(6,601)
A,B,C,AREA
GO TO 10
50 WRITE(6,602)
STOP
90 WRITE(6,603)
STOP
END
"Retro" FORTRAN IV
A retro example of a FORTRAN IV (later
evolved into FORTRAN 66) program deck
is available on the IBM 1130 page,
including the IBM 1130 DM2 JCL required
for compilation and execution. An IBM
1130 emulator is available at IBM 1130.org
(http://ibm1130.org/) that will allow the
FORTRAN IV program to be compiled and
run on a PC.
Hello, World program
FORTRAN 77
As of FORTRAN 77, single quotes are used
to delimit character literals, and inline
character strings may be used instead of
references to FORMAT statements.
Comment lines may be indicated with
either a C or an asterisk ( * ) in column
1.
PROGRAM HELLO
* The PRINT statement
is like WRITE,
PRINT '(A)',
'Hello, world'
STOP
END
Fortran 90
program HelloWorld
write (*,*) 'Hello,
world!' ! This is an
inline comment
Fortran 77 examples
PROGRAM EUCLID
PRINT *, 'A?'
READ *, NA
IF (NA.LE.0) THEN
PRINT *, 'A must
be a positive integer.'
STOP
END IF
PRINT *, 'B?'
READ *, NB
IF (NB.LE.0) THEN
PRINT *, 'B must
be a positive integer.'
STOP
END IF
PRINT *, 'The GCD
of', NA, ' and', NB, ' is',
NGCD(NA, NB), '.'
STOP
END
Complex numbers
* Demonstration of
COMPLEX numbers
* where j is the
imaginary number sqrt(-1)
PROGRAM CMPLXD
IMPLICIT COMPLEX(X)
PARAMETER (PI =
3.141592653589793, XJ = (0,
1))
DO 1, I = 0, 7
X = EXP(XJ * I *
PI / 4)
IF
(AIMAG(X).LT.0) THEN
PRINT 2, 'e**
(j*', I, '*pi/4) = ',
REAL(X), ' - j',-AIMAG(X)
ELSE
PRINT 2, 'e**
(j*', I, '*pi/4) = ',
REAL(X), ' + j', AIMAG(X)
END IF
2 FORMAT (A, I1, A,
F10.7, A, F9.7)
1 CONTINUE
STOP
END
$ cmplxd
e**(j*0*pi/4) = 1.0000000
+ j0.0000000
e**(j*1*pi/4) = 0.7071068
+ j0.7071068
e**(j*2*pi/4) = 0.0000000
+ j1.0000000
e**(j*3*pi/4) = -0.7071068
+ j0.7071068
e**(j*4*pi/4) = -1.0000000
- j0.0000001
e**(j*5*pi/4) = -0.7071066
- j0.7071069
e**(j*6*pi/4) = 0.0000000
- j1.0000000
e**(j*7*pi/4) = 0.7071070
- j0.7071065
program area
implicit none
real :: A, B, C, S
! area of a triangle
read *, A, B, C
S = (A + B + C)/2
A = sqrt(S*(S-A)*(S-B)*
(S-C))
print *,"area =",A
stop
end program area
! sum.f90
program summation
implicit none
integer :: sum, a
print *, "This program
performs summations. Enter
0 to stop."
open (unit=10,
file="SumData.DAT")
sum = 0
do
print *, "Add:"
read *, a
if (a == 0) then
exit
else
sum = sum + a
end if
write (10,*) a
end do
print *, "Summation =",
sum
write (10,*) "Summation
=", sum
close(10)
end
1
2
3
Summation = 6
Calculating cylinder area
program cylinder
! constants=pi
! variables=radius squared
and height
implicit none !
Require all variables to be
explicitly declared
integer :: ierr
character(1) :: yn
real :: radius, height,
area
real, parameter :: pi =
3.141592653589793
interactive_loop: do
if (ierr /= 0) then
write(*,*) 'Error,
invalid input.'
cycle
interactive_loop
end if
area = 2*pi *
(radius**2 + radius*height)
write
(*,'(1x,a7,f6.2,5x,a7,f6.2,
5x,a5,f6.2)') &
'radius=',radius,'height=',
height,'area=',area
yn = ' '
yn_loop: do
write(*,*) 'Perform
another calculation? y[n]'
read(*,'(a1)') yn
if (yn=='y' .or.
yn=='Y') exit yn_loop
if (yn=='n' .or.
yn=='N' .or. yn==' ') exit
interactive_loop
end do yn_loop
end do interactive_loop
program average
implicit none
integer ::
number_of_points
real, dimension(:),
allocatable :: points
real ::
average_points=0.,
positive_average=0.,
negative_average=0.
allocate
(points(number_of_points))
if (number_of_points > 0)
average_points =
sum(points)/number_of_point
s
deallocate (points)
! Print result to terminal
write (*,'(''Average =
'', 1g12.4)')
average_points
write (*,'(''Average of
positive points = '',
1g12.4)') positive_average
write (*,'(''Average of
negative points = '',
1g12.4)') negative_average
Writing functions
Modern Fortran features available for use
with procedures, including deferred-shape,
protected, and optional arguments, are
illustrated in the following example, a
function to solve a system of linear
equations.
function
gauss_sparse(num_iter, tol,
b, A, x, actual_iter)
result(tol_max)
implicit none
real :: tol_max
integer, intent(in) ::
num_iter
real, intent(in) :: tol
real, intent(in),
dimension(:) :: b, A(:,:)
real, intent(inout) ::
x(:)
integer, optional,
intent(out) :: actual_iter
! Locals
integer :: i, n, iter
real :: xk
! Initialize values
n = size(b) ! Size of
array, obtained using size
intrinsic function
tol_max = 2. * tol
iter = 0
convergence_loop: do
while (tol_max >= tol .and.
iter < num_iter); iter =
iter + 1
tol_max = -1. !
Reset the tolerance value
iteration_loop: do i
= 1, n
! Compute the
current x-value
xk = (b(i) -
dot_product(A(i,:i-1),x(:i-
1)) -
dot_product(A(i,i+1:n),x(i+
1:n))) / A(i, i)
!
dot_product(a,v)=a'b
tol_max =
max((abs(x(i) - xk)/(1. +
abs(xk))) ** 2, abs(A(i, i)
* (x(i) - xk)), tol_max)
x(i) = xk
enddo iteration_loop
enddo convergence_loop
if
(present(actual_iter))
actual_iter = iter
program test_gauss_sparse
implicit none
! explicit interface to
the gauss_sparse function
interface
function
gauss_sparse(num_iter, tol,
b, A, x, actual_iter)
result(tol_max)
real :: tol_max
integer,
intent(in) :: num_iter
real, intent(in)
:: tol
real,
intent(in), dimension(:) ::
b, A(:,:)
real,
intent(inout) :: x(:)
integer,
optional, intent(out) ::
actual_iter
end function
end interface
! declare variables
integer :: i, N = 3,
actual_iter
real :: residue
real, allocatable ::
A(:,:), x(:), b(:)
! allocate arrays
A = reshape([(real(i),
i = 1, size(A))], shape(A))
do i = 1, size(A, 1)
A(i,i) =
sum(A(i,:)) + 1
enddo
! Initialize b
b = [(i, i = 1,
size(b))]
! Initial (guess)
solution
x = b
residue =
gauss_sparse(num_iter =
100, &
b = b, &
A = a, &
x = x, &
actual_iter = actual_iter)
! Output
end program
test_gauss_sparse
Writing subroutines
implicit none
! Input/Output
real, intent(inout) ::
a1(:), a2(:)
! Locals
integer :: i
real :: a
! Swap
do i = 1, min(size(a1),
size(a2))
a = a1(i)
a1(i) = a2(i)
a2(i) = a
enddo
subroutine swap_real(a1,
a2)
implicit none
! Input/Output
real, intent(inout) ::
a1(:), a2(:)
! Locals
integer :: N
N = min(size(a1),
size(a2))
call swap_e(a1(:N),
a2(:N))
contains
elemental subroutine
swap_e(a1, a2)
real, intent(inout)
:: a1, a2
real :: a
a = a1
a1 = a2
a2 = a
end subroutine swap_e
end subroutine swap_real
program test_swap_real
implicit none
! explicit interface to
the swap_real subroutine
interface
subroutine
swap_real(a1, a2)
real,
intent(inout) :: a1(:),
a2(:)
end subroutine
swap_real
end interface
! Declare variables
integer :: i
real :: a(10), b(10)
! Initialize a, b
a = [(real(i), i = 1,
20, 2)]
b = a + 1
print '(/"before
swap:")'
print '("a = [",
10f6.1, "]")', a
print '("b = [",
10f6.1, "]")', b
call swap_real(a, b)
module SomeModule
implicit none
contains
elemental function A(x)
result(res)
integer :: res
integer, intent(IN)
:: x
res = x + 1
end function
end module SomeModule
program Test
use SomeModule,
DoSomething => A
implicit none
!Declare variables
integer, parameter :: m
= 3, n = 3
integer, pointer ::
p(:)=>null(),
q(:,:)=>null()
integer, allocatable,
target :: A(:,:)
integer :: istat = 0, i,
j
character(80) :: fmt
! Matrix A is:
! A = [[ 1 4 7 ]
! [ 2 5 8 ]
! [ 3 6 9 ]
! ]
A = reshape([(i, i = 1,
size(A))], shape(A))
q = A
! p will be associated
with the first column of A
p => A(:, 1)
p = p ** 2
nullify(p)
! Matrix A becomes:
! A = [[ 1 4 7 ]
! [ 4 5 8 ]
! [ 9 6 9 ]
! ]
q = q + A
! Matrix q becomes:
! q = [[ 2 8 14 ]
! [ 6 10 16 ]
! [12 12 18 ]
! ]
! Use p as an ordinary
array
p =
reshape(DoSomething(A + A
** 2), shape(p))
! Array operation:
! p(1) = 3
! p(2) = 21
! p(3) = 91
! p(4) = 21
! p(5) = 31
! p(6) = 43
! p(7) = 57
! p(8) = 73
! p(9) = 91
write(*, '("Array
operation:" /
(4x,"p(",i0,") = ",i0))')
(i, p(i), i = 1, size(p))
deallocate(A, p, q, stat
= istat)
if (istat /= 0) stop
'Error during deallocation'
Module programming
A module is a program unit which contains
data definitions, global data, and
CONTAIN ed procedures. Unlike a simple
INCLUDE file, a module is an
independent program unit that can be
compiled separately and linked in its
binary form. Once compiled, a module's
public contents can be made visible to a
calling routine via the USE statement.
module GlobalModule
! Reference to a pair of
procedures included in a
previously compiled
! module named
PortabilityLibrary
use PortabilityLibrary,
only: GetLastError, & !
Generic procedure
Date ! Specific
procedure
! Constants
integer, parameter ::
dp_k = kind (1.0d0) !
Double precision kind
! Variables
integer :: n, m, retint
logical :: status,
retlog
character(50) :: AppName
! Arrays
real, allocatable,
dimension(:,:,:) :: a, b,
c, d
complex(dp_k),
allocatable, dimension(:)
:: z
type ijk
integer :: i
integer :: j
integer :: k
end type ijk
type matrix
integer m, n
real, allocatable ::
a(:,:) ! Fortran 2003
feature. For Fortran 95,
use the pointer attribute
instead
public
private :: AppName
interface swap
module procedure
swap_integer, swap_real
end interface swap
interface GetLastError
! This adds a new,
additional procedure to the
! generic procedure
GetLastError
module procedure
GetLastError_GlobalModule
end interface
GetLastError
! Operator overloading
interface operator(+)
module procedure
add_ijk
end interface
interface
function
gauss_sparse(num_iter, tol,
b, A, x, actual_iter)
result(tol_max)
real :: tol_max
integer,
intent(in) :: num_iter
real, intent(in)
:: tol
real, intent(in),
dimension(:) :: b, A(:,:)
real,
intent(inout) :: x(:)
integer, optional,
intent(out) :: actual_iter
end function
gauss_sparse
end interface
! Procedures included in
the module
contains
! Internal function
function add_ijk(ijk_1,
ijk_2)
type(ijk) add_ijk,
ijk_1, ijk_2
intent(in) :: ijk_1,
ijk_2
add_ijk = ijk(ijk_1%i
+ ijk_2%i, ijk_1%j +
ijk_2%j, ijk_1%k + ijk_2%k)
end function add_ijk
! Include external files
include
'swap_integer.f90' !
Comments SHOULDN'T be added
on include lines
include 'swap_real.f90'
end module GlobalModule
Retrieved from
"https://en.wikibooks.org/w/index.php?
title=Fortran/Fortran_examples&oldid=4287160"