FORTRAN
Source code for the example FORTRAN library.
fortran_lib.f90
! fortran_lib.f90
!
! Basic examples of passing different data types to a FORTRAN function and subroutine.
!
! Compiled in Windows using:
! gfortran -fno-underscoring -fPIC fortran_lib.f90 -static -shared -o fortran_lib64.dll
!
! return the sum of two 8-bit signed integers
function sum_8bit(a, b) result(value)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'sum_8bit' :: sum_8bit
implicit none
integer(1) :: a, b, value
value = a + b
end function sum_8bit
! return the sum of two 16-bit signed integers
function sum_16bit(a, b) result(value)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'sum_16bit' :: sum_16bit
implicit none
integer(2) :: a, b, value
value = a + b
end function sum_16bit
! return the sum of two 32-bit signed integers
function sum_32bit(a, b) result(value)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'sum_32bit' :: sum_32bit
implicit none
integer(4) :: a, b, value
value = a + b
end function sum_32bit
! return the sum of two 64-bit signed integers
function sum_64bit(a, b) result(value)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'sum_64bit' :: sum_64bit
implicit none
integer(8) :: a, b, value
value = a + b
end function sum_64bit
! return the product of two 32-bit floating point numbers
function multiply_float32(a, b) result(value)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'multiply_float32' :: multiply_float32
implicit none
real(4) :: a, b, value
value = a * b
end function multiply_float32
! return the product of two 64-bit floating point numbers
function multiply_float64(a, b) result(value)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'multiply_float64' :: multiply_float64
implicit none
real(8) :: a, b, value
value = a * b
end function multiply_float64
! return True if 'a' > 0 else False
function is_positive(a) result(value)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'is_positive' :: is_positive
implicit none
logical :: value
real(8) :: a
value = a > 0.d0
end function is_positive
! if do_addition is True return a+b otherwise return a-b
function add_or_subtract(a, b, do_addition) result(value)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'add_or_subtract' :: add_or_subtract
implicit none
logical :: do_addition
integer(4) :: a, b, value
if (do_addition) then
value = a + b
else
value = a - b
endif
end function add_or_subtract
! compute the n'th factorial of a 8-bit signed integer, return a double-precision number
function factorial(n) result(value)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'factorial' :: factorial
implicit none
integer(1) :: n
integer(4) :: i
double precision value
if (n < 0) then
value = 0.d0
print *, "Cannot compute the factorial of a negative number", n
else
value = 1.d0
do i = 2, n
value = value * i
enddo
endif
end function factorial
! calculate the standard deviation of an array.
function standard_deviation(a, n) result(var)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'standard_deviation' :: standard_deviation
integer :: n ! the length of the array
double precision :: var, a(n)
var = SUM(a)/SIZE(a) ! SUM is a built-in fortran function
var = SQRT(SUM((a-var)**2)/(SIZE(a)-1.0))
end function standard_deviation
! compute the Bessel function of the first kind of order 0 of x
function besselj0(x) result(val)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'besselj0' :: besselj0
double precision :: x, val
val = BESSEL_J0(x)
end function besselJ0
! reverse a string, 'n' is the length of the original string
subroutine reverse_string(original, n, reversed)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'reverse_string' :: reverse_string
!DEC$ ATTRIBUTES REFERENCE :: original, reversed
implicit none
integer :: i, n
character(len=n) :: original, reversed
do i = 1, n
reversed(i:i) = original(n-i+1:n-i+1)
end do
end subroutine reverse_string
! element-wise addition of two 1D double-precision arrays
subroutine add_1d_arrays(a, in1, in2, n)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'add_1d_arrays' :: add_1d_arrays
implicit none
integer(4) :: n ! the length of the input arrays
double precision :: in1(n), in2(n) ! the arrays to add (element-wise)
double precision :: a(n) ! the array that will contain the element-wise sum
a(:) = in1(:) + in2(:)
end subroutine add_1d_arrays
! multiply two 2D, double-precision arrays.
! NOTE: multi-dimensional arrays are column-major order in FORTRAN,
! whereas C (Python) is row-major order.
subroutine matrix_multiply(a, a1, r1, c1, a2, r2, c2)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'matrix_multiply' :: matrix_multiply
implicit none
integer(4) :: r1, c1, r2, c2 ! the dimensions of the input arrays
double precision :: a1(r1,c1), a2(r2,c2) ! the arrays to multiply
double precision :: a(r1,c2) ! resultant array
a = MATMUL(a1, a2)
end subroutine matrix_multiply