目录
Modern Fortran 数组操作
Fortran 2008 提供了丰富的数组操作功能,包括数组声明、初始化、切片、逐元素操作、标量与数组操作、数组函数、动态数组、数组构造器、比较、排序和广播等。这些功能使得数组处理更加简洁和高效。通过合理使用这些功能,可以大大简化代码并提高程序的性能。以下是一些常见的数组操作:
数组声明和初始化
声明数组
real, dimension(5) :: x
integer, dimension(3, 3) :: matrix初始化数组
- 使用数组构造器:
reshape和spread
real, dimension(3, 4) :: matrix
matrix = reshape([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [3, 4])
print *, "Matrix:"
print *, matrixreal, dimension(5) :: x
real, dimension(5, 3) :: y
x = [1.0, 2.0, 3.0, 4.0, 5.0]
y = spread(x, 2, 3)
print *, "Spread array y:"
print *, y- 使用
data语句:data x /1.0, 2.0, 3.0, 4.0, 5.0/ data matrix /1, 2, 3, 4, 5, 6, 7, 8, 9/
数组切片
数组切片允许你访问数组的子集。
real, dimension(10) :: x
x = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
! 访问第 2 到第 5 个元素
print *, x(2:5) ! 输出: 2.0 3.0 4.0 5.0
! 访问第 1 到第 10 个元素,步长为 2
print *, x(1:10:2) ! 输出: 1.0 3.0 5.0 7.0 9.0数组操作
逐元素操作
Fortran 支持对数组的逐元素操作,包括加法、减法、乘法和除法。
real, dimension(5) :: a, b, c
a = [1.0, 2.0, 3.0, 4.0, 5.0]
b = [6.0, 7.0, 8.0, 9.0, 10.0]
c = a + b ! 逐元素加法
c = a - b ! 逐元素减法
c = a * b ! 逐元素乘法
c = a / b ! 逐元素除法标量与数组操作
标量可以与数组进行逐元素操作。
real, dimension(5) :: x, y
real :: scalar = 2.0
x = [1.0, 2.0, 3.0, 4.0, 5.0]
y = scalar * x ! 标量乘法
y = x / scalar ! 标量除法数组函数
Fortran 提供了许多内置的数组函数,用于执行常见的数组操作。
数组大小
real, dimension(3, 4) :: matrix
integer :: size1, size2
size1 = size(matrix, 1) ! 第一维的大小
size2 = size(matrix, 2) ! 第二维的大小
print *, "Size of first dimension:", size1
print *, "Size of second dimension:", size2数组形状
real, dimension(3, 4) :: matrix
integer, dimension(:), allocatable :: shape
shape = shape(matrix)
print *, "Shape of matrix:", shape数组转置
real, dimension(3, 4) :: matrix
real, dimension(4, 3) :: transposed
matrix = reshape([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [3, 4])
transposed = transpose(matrix)
print *, "Transposed matrix:"
print *, transposed数组求和
real, dimension(5) :: x
x = [1.0, 2.0, 3.0, 4.0, 5.0]
print *, "Sum of x:", sum(x)数组最大值和最小值
real, dimension(5) :: x
x = [1.0, 2.0, 3.0, 4.0, 5.0]
print *, "Maximum value in x:", maxval(x)
print *, "Minimum value in x:", minval(x)数组分配和释放
动态数组
real, allocatable :: x(:)
integer :: n
n = 10
allocate(x(n))
x = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
print *, "Dynamic array x:", x
deallocate(x)可选参数
real, allocatable :: x(:)
integer :: n
n = 10
allocate(x(n), stat=ierr)
if (ierr /= 0) then
print *, "Allocation failed"
else
x = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
print *, "Dynamic array x:", x
end if
deallocate(x)7. 数组比较
元素比较
real, dimension(5) :: a, b
logical, dimension(5) :: comparison
a = [1.0, 2.0, 3.0, 4.0, 5.0]
b = [1.0, 2.0, 3.0, 4.0, 6.0]
comparison = a == b
print *, "Comparison result:", comparison8. 数组排序
Fortran 2008 提供了 sort 函数,用于对数组进行排序。
real, dimension(5) :: x
x = [5.0, 3.0, 1.0, 4.0, 2.0]
call sort(x)
print *, "Sorted array x:", x9. 数组广播
Fortran 支持数组广播,允许对不同形状的数组进行操作。
real, dimension(3, 3) :: matrix
real, dimension(3) :: vector
real, dimension(3, 3) :: result
matrix = reshape([1, 2, 3, 4, 5, 6, 7, 8, 9], [3, 3])
vector = [1.0, 2.0, 3.0]
result = matrix + vector
print *, "Broadcasted result:"
print *, resultModern Fortran 矩阵乘法
Fortran 2008 中,矩阵和数组的乘法可以通过内置的数组操作和函数来实现。Fortran 提供了多种方式来执行矩阵乘法,包括逐元素乘法和矩阵-矩阵乘法。以下是一些常见的操作:
逐元素乘法
逐元素乘法是指两个矩阵或数组的对应元素相乘。这在 Fortran 中非常直观,可以直接使用 * 运算符。
program elementwise_multiply
implicit none
real, dimension(2, 3) :: A, B, C
! 初始化矩阵 A 和 B
A = reshape([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], [2, 3])
B = reshape([7.0, 8.0, 9.0, 10.0, 11.0, 12.0], [2, 3])
! 逐元素乘法
C = A * B
! 输出结果矩阵 C
print *, "Elementwise multiplication result:"
print *, C
end program elementwise_multiply矩阵-矩阵乘法
矩阵-矩阵乘法是指两个矩阵的线性代数乘法。Fortran 2008 提供了 matmul 内置函数来执行矩阵乘法。
program matrix_multiply
implicit none
real, dimension(2, 3) :: A
real, dimension(3, 2) :: B
real, dimension(2, 2) :: C
! 初始化矩阵 A 和 B
A = reshape([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], [2, 3])
B = reshape([7.0, 8.0, 9.0, 10.0, 11.0, 12.0], [3, 2])
! 矩阵乘法
C = matmul(A, B)
! 输出结果矩阵 C
print *, "Matrix multiplication result:"
print *, C
end program matrix_multiply矩阵-向量乘法
矩阵-向量乘法是指一个矩阵与一个向量的线性代数乘法。Fortran 2008 也支持这种操作。
program matrix_vector_multiply
implicit none
real, dimension(2, 3) :: A
real, dimension(3) :: x
real, dimension(2) :: y
! 初始化矩阵 A 和向量 x
A = reshape([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], [2, 3])
x = [7.0, 8.0, 9.0]
! 矩阵-向量乘法
y = matmul(A, x)
! 输出结果向量 y
print *, "Matrix-vector multiplication result:"
print *, y
end program matrix_vector_multiply使用 BLAS 进行矩阵乘法
虽然 Fortran 2008 提供了 matmul 函数,但在某些情况下,使用 BLAS 库可以提供更高的性能。BLAS 提供了 sgemm 函数用于矩阵乘法。
program blas_matrix_multiply
implicit none
integer, parameter :: m = 2, n = 3, k = 2
real, dimension(m, k) :: A
real, dimension(k, n) :: B
real, dimension(m, n) :: C
! 初始化矩阵 A 和 B
A = reshape([1.0, 2.0, 3.0, 4.0], [m, k])
B = reshape([5.0, 6.0, 7.0, 8.0, 9.0, 10.0], [k, n])
! 调用 BLAS 的 sgemm 函数
call sgemm('N', 'N', m, n, k, 1.0, A, m, B, k, 0.0, C, m)
! 输出结果矩阵 C
print *, "Matrix multiplication result using BLAS:"
print *, C
end program blas_matrix_multiply编译和运行
将上述代码保存为 .f90 文件,然后使用以下命令编译和运行:
gfortran -o example example.f90
./example如果使用 BLAS,需要链接 BLAS 库:
gfortran -o example example.f90 $(pkg-config --libs blas)
./example总结
Fortran 2008 提供了多种方式来执行矩阵和数组的乘法:
- 逐元素乘法:直接使用
*运算符。 - 矩阵-矩阵乘法:使用
matmul函数。 - 矩阵-向量乘法:使用
matmul函数。 - 高性能矩阵乘法:使用 BLAS 库的
sgemm函数。