数组操作

由于其计算目标,数组上的数学运算在 Fortran 中是直截了当的。

加减

对相同形状和大小的阵列的操作与矩阵代数非常相似。可以编写加法(和减法)来代替用循环遍历所有索引:

real, dimension(2,3) :: A, B, C
real, dimension(5,6,3) :: D
A    = 3.    ! Assigning single value to the whole array
B    = 5.    ! Equivalent writing for assignment
C    = A + B ! All elements of C now have value 8.
D    = A + B ! Compiler will raise an error. The shapes and dimensions are not the same

切片中的数组也是有效的:

integer::i, j
real, dimension(3,2) :: Mat = 0.
real, dimension(3)   :: Vec1 = 0., Vec2 = 0., Vec3 = 0.
i = 0
j = 0
do i = 1,3
  do j = 1,2
    Mat(i,j) = i+j
  enddo
enddo
Vec1 = Mat(:,1)
Vec2 = Mat(:,2)
Vec3 = Mat(1:2,1) + Mat(2:3,2)

功能

以同样的方式,假设组件操作(尽管这不是系统的),大多数内部函数可以隐式使用:

real, dimension(2) :: A, B
A(1) = 6
A(2) = 44 ! Random values
B    = sin(A) ! Identical to B(1) = sin(6), B(2) = sin(44).

乘法和除法

必须注意产品和分工:使用*/符号的内在操作是逐个元素的:

real, dimension(2) :: A, B, C
A(1) = 2
A(2) = 4
B(1) = 1
B(2) = 3
C = A*B ! Returns C(1) = 2*1 and C(2) = 4*3

这绝不能与矩阵运算相混淆(见下文)。

矩阵运算

矩阵运算是内在程序。例如,上一节数组的矩阵乘积如下:

real, dimension(2,1) :: A, B
real, dimension(1,1) :: C
A(1) = 2
A(2) = 4
B(1) = 1
B(2) = 3
C = matmul(transpose(A),B) ! Returns the scalar product of vectors A and B

复杂操作允许通过创建临时数组来封装函数。虽然有些编译器和编译选项允许,但不建议这样做。例如,可以编写包含矩阵转置的产品:

real, dimension(3,3) :: A, B, C
A(:) = 4
B(:) = 5
C = matmul(transpose(A),matmul(B,matmul(A,transpose(B)))) ! Equivalent to A^t.B.A.B^T