目录

返回 主页

Modern Fortran 数组操作

Fortran 2008 提供了丰富的数组操作功能,包括数组声明、初始化、切片、逐元素操作、标量与数组操作、数组函数、动态数组、数组构造器、比较、排序和广播等。这些功能使得数组处理更加简洁和高效。通过合理使用这些功能,可以大大简化代码并提高程序的性能。以下是一些常见的数组操作:

数组声明和初始化

声明数组

real, dimension(5) :: x
integer, dimension(3, 3) :: matrix

初始化数组

real, dimension(3, 4) :: matrix
matrix = reshape([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [3, 4])
print *, "Matrix:"
print *, matrix
real, 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

数组切片

数组切片允许你访问数组的子集。

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:", comparison

8. 数组排序

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:", x

9. 数组广播

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 *, result

Modern 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 提供了多种方式来执行矩阵和数组的乘法:

返回 主页