如何在 Fortran 中初始化二维数组

Posted

技术标签:

【中文标题】如何在 Fortran 中初始化二维数组【英文标题】:How to initialize two-dimensional arrays in Fortran 【发布时间】:2022-01-18 10:03:24 【问题描述】:

如果我没记错的话,您可以在 C 中使用花括号语法轻松地初始化数组:

int* a = new int[]  1, 2, 3, 4 ;

当您出于数学目的希望使用特定测试值初始化矩阵时,如何在 Fortran 中对二维数组执行相同操作? (不必在单独的语句中对每个元素进行双重索引)

数组由以下任一方式定义

real, dimension(3, 3) :: a

real, dimension(:), allocatable :: a

【问题讨论】:

【参考方案1】:

对于多维 (rank>1) 数组,Fortran 的初始化方式与 C 解决方案不同,因为在 C 中,多维数组只是等数组的数组。

在 Fortran 中,每个等级对应于修改后数据类型的不同属性。但是对于 rank-1 数组,只有一个数组构造函数。由于这两个原因,通过数组构造函数初始化需要RESHAPE intrisic函数。

除了已经回答的问题之外,还有一种更直接的方法是按行而不是按列输入矩阵的值:reshape 有一个可选参数ORDER,可用于修改填充顺序多维数组的元素与数组构造函数的条目。

例如,对于第一个答案中的示例,可以这样写:

INTEGER, DIMENSION(3, 3) :: array=reshape( (/ 1, 2, 3, &
                                              4, 5, 6, &
                                              7, 8, 9 /), &
                                           shape(array), order=(/2,1/) )

完全按照代码行显示的顺序获取矩阵数组的填充。

数组(/2, 1/) 强制列索引(2) 优先于行索引(1),从而达到预期效果。

【讨论】:

【参考方案2】:

您可以使用 reshape 和 shape 内在函数来做到这一点。比如:

INTEGER, DIMENSION(3, 3) :: array
array = reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array))

但请记住列优先顺序。数组将是

1   4   7
2   5   8
3   6   9

整形后。

所以得到:

1   2   3
4   5   6
7   8   9

你还需要transpose内在:

array = transpose(reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array)))

对于更一般的示例(具有不同维度的可分配二维数组),需要sizeintrinsic:

PROGRAM main

  IMPLICIT NONE

  INTEGER, DIMENSION(:, :), ALLOCATABLE :: array

  ALLOCATE (array(2, 3))

  array = transpose(reshape((/ 1, 2, 3, 4, 5, 6 /),                            &
    (/ size(array, 2), size(array, 1) /)))

  DEALLOCATE (array)

END PROGRAM main

【讨论】:

1) 大多数编译器现在接受 Fortran 2003 表示法 [] 来初始化数组,而不是有些笨拙的 (/ /)。 2) 对于简单的情况,您可以通过按列主要顺序提供值来省略转置:array = reshape ( [1, 4, 7, 2, 5, 8, 3, 6, 9 ], shape (array) ) 我忘了说我们需要在 Fortran 90 中工作。【参考方案3】:

数组初始化可以在数组声明语句本身中完成,如下图:

program test
 real:: x(3) = (/1,2,3/)
 real:: y(3,3) = reshape((/1,2,3,4,5,6,7,8,9/), (/3,3/))
 integer:: i(3,2,2) = reshape((/1,2,3,4,5,6,7,8,9,10,11,12/), (/3,2,2/))

end program test

这让我很惊讶

 real:: y(3,3) = (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)

被编译器接受(尝试过 g95、gfortran)。原来shape(/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)9 而不是 3 3

【讨论】:

以上是关于如何在 Fortran 中初始化二维数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Fortran 中初始化二维数组

在 Fortran 90 中使用二维数组与派生类型数组

我是FORTRAN初学者,想得出一个二维数组中的最大值,说是可以用MAXVAL函数,具体在怎么用了,求解

使用 MPI_Gather 在 Fortran 中发送二维数组

在fortran中只为二维数组分配一维

试图将一个连续的动态二维数组从 C 传递到 Fortran