Map, Filter, Reduce in Fortran 2018

Milan Curcic
May 22, 2019 · 11 min read
Image for post
Image for post
Photo by Nik Shuliahin on Unsplash

Map

pure elemental real function square(x)
real, intent(in) :: x
square = x**2
end function square
pure recursive integer function fibonacci(n) result(fib)
integer, intent(in) :: n
if (n == 0) then
fib = 0
else if (n == 1) then
fib = 1
else
fib = fibonacci(n-1) + fibonacci(n-2)
end if
end function fibonacci
$ gfortran map.f90 
map.f90:7:27:
pure elemental recursive integer function fibonacci(n) result(fib)
1
Error: ELEMENTAL attribute conflicts with RECURSIVE attribute at (1)
pure function map(f, x)
procedure(f_int) :: f ! Mapping function
integer, intent(in) :: x(:) ! Input array
integer :: map(size(x)), i
map = [(f(x(i)), i = 1, size(x))]
end function map
interface
pure integer function f_int(x)
integer, intent(in) :: x
end function f_int
end interface

Filter

pure logical function even(n)
integer, intent(in) :: n
if (mod(n, 2) == 0) then
even = .true.
else
even = .false.
end if
end function even
result = pack(array, mask[, vector])
pure function filter(f, x)
procedure(f_int_logical) :: f ! An int -> logical function
integer, intent(in) :: x(:) ! Input array
integer, allocatable :: filter(:)
integer :: i
filter = pack(x, [(f(x(i)), i = 1, size(x))])
end function filter
interface
pure logical function f_int_logical(x)
integer, intent(in) :: x
end function f_int_logical
end interface
result = filter(even, map(fibonacci, [(n, n = 1, 30)]))

Reduce

The Fortran 2018 reduce

reduce(array, operation[, mask, identity, ordered])
reduce(array, operation, dim[, mask, identity, ordered])

Implementing your own reduce function

result = reduce(add, filter(even, map(fibonacci, x)), 0)
pure recursive integer function reduce(f, x, start) result(res)
procedure(f2_int) :: f
integer, intent(in) :: x(:), start
if (size(x) < 1) then
res = start
else
res = reduce(f, x(2:), f(start, x(1)))
end if
end function reduce
pure integer function f2_int(x, y)
integer, intent(in) :: x, y
end function f2_int
pure recursive integer function reduce_right(f, x, start) result(res)
procedure(f2_int) :: f
integer, intent(in) :: x(:), start
if (size(x) < 1) then
res = start
else
res = f(x(1), reduce_right(f, x(2:), start))
end if
end function reduce_right
integer, allocatable :: x(:)
x = [(n, n = 1, 30)]
print *, reduce(add, filter(even, map(fibonacci, x)), 0)

Summary

References

Modern Fortran

Modern Fortran: Building Efficient Parallel Applications

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store