043. Comparing Fortran and NumPy syntax#
topic: Arrays
Used to NumPy? Many of the Fortran intrinsics to deal with arrays will already be familiar to you.
Fortran |
NumPy equivalent1 |
Value |
---|---|---|
integer :: a(2, 3)
|
np.empty(
(2, 3),
dtype=np.int32
)
|
|
a = 1
|
a[:] = 1
|
|
size(a)
|
a.size
|
6 |
shape(a)
|
a.shape
|
(2, 3) 7 |
a(1,1) = 100
|
a[0,0] = 100
|
Element in first row and first column set to 100 |
maxval(a)
|
a.max()
|
100 |
minval(a)
|
a.min()
|
1 |
sum(a)
|
a.sum()
|
105 |
sum(a, dim=1)
|
a.sum(axis=0)
|
(101, 2, 2) |
program cf_numpy
implicit none
integer, parameter :: m = 2, n = 3
integer :: a(m, n)
character(len=*), parameter :: fmt = "(x, a, ':', x, *(g0, x))"
print *, "Before setting:"
call print11(a)
a = 1 ! Set all elements
print *, "After setting:"
call print11(a)
print fmt, "size", size(a)
print fmt, "shape", shape(a)
a(1,1) = 100
print fmt, "maxval", maxval(a)
print fmt, "minval", minval(a)
print fmt, "sum", sum(a)
print fmt, "sum, dim=1", sum(a, dim=1)
print fmt, "sum, dim=2", sum(a, dim=2)
contains
subroutine print11(mat)
integer, intent(in) :: mat(:,:)
print "(3x, 'row 1:', x, *(i0, x))", mat(1, :)
print "(3x, 'col 1:', x, *(i0, x))", mat(:, 1)
end subroutine print11
end program cf_numpy
Before setting:
row 1: 0 2103326976 0
col 1: 0 0
After setting:
row 1: 1 1 1
col 1: 1 1
size: 6
shape: 2 3
maxval: 100
minval: 1
sum: 105
sum, dim=1: 101 2 2
sum, dim=2: 102 3
Note
NumPy also provides a functional API that makes it look more like Fortran. See such comparisons and more here: https://www.fortran90.org/src/rosetta.html
Used to NumPy? Lots of the Fortran intrinsics to deal with arrays will already be familiar to you. pic.twitter.com/GnKnbscsDX
— FortranTip (@fortrantip) December 23, 2021
- 1
The NumPy examples assume
import numpy as np
- 2
In Fortran, the “empty” array may get values set to zero, but this is not guaranteed (compiler and hardware(?) dependence). With NumPy, the uninitialized array elements will not (all) be zero.
- 3
In Fortran, remember that the array elements are stored in column-major order. In NumPy, row-major order is the default, though you can specify on creation or transform to column-major order.
- 4
With NumPy,
a = np.full((m, n), value, dtype=np.int32)
could be used to achieve the result of the first two steps.
- 5
Notes
Fortran supports the shorthand for setting all elements (
a = 1
above), but if you do that in Python,a
becomes a single Python integer (int
).Fortran also supports setting all elements with colon syntax, but you must specify a
:
for each dimension.In NumPy,
a[:]
anda[...]
both work as shorthand for the entire array regardless of the number of dimensions, whereas in Fortran we need to give a colon for each dimension:a(:,:)
.For Fortran allocatable arrays,
a = ...
might6 re-allocate the array, whereas explicita(:,:) = ...
would not.
- 6
If it has already been allocated and the RHS is an array with a different shape from the LHS.
a = 1
like in our example still just sets all elements to 1.