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

发布于 2024-09-18 22:08:41 字数 322 浏览 6 评论 0原文

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

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

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

数组由

real, dimension(3, 3) :: a

或定义

real, dimension(:), allocatable :: a

In C you can easily initialize an array using the curly braces syntax, if I remember correctly:

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

How can you do the same in Fortran for two-dimensional arrays when you wish to initialize a matrix with specific test values for mathematical purposes? (Without having to doubly index every element on separate statements)

The array is either defined by

real, dimension(3, 3) :: a

or

real, dimension(:), allocatable :: a

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小耗子 2024-09-25 22:08:42

您可以使用 reshape形状 内在函数。类似于:

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)))

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

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

You can do that using reshape and shape intrinsics. Something like:

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

But remember the column-major order. The array will be

1   4   7
2   5   8
3   6   9

after reshaping.

So to get:

1   2   3
4   5   6
7   8   9

you also need transpose intrinsic:

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

For more general example (allocatable 2D array with different dimensions), one needs size intrinsic:

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
梦屿孤独相伴 2024-09-25 22:08:42

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

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

除了已经回答的内容之外,还有一种更直接的方法按行而不是按列输入矩阵的值: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),给出期望的效果。

For multidimensional (rank>1) arrays, the Fortran way for initialization differs from the C solution because in C multidimensional arrays are just arrays of arrays of etc.

In Fortran, each rank corresponds to a different attribute of the modified data type. But there is only one array constructor, for rank-1 arrays. From these two reasons, initialization through array constructor requires the RESHAPE intrisic function.

In addition to what has already been answered, there is a more direct way of entering the value of a matrix by row instead as by column: reshape has an optional argument ORDER which can be used to modify the order of filling the element of the multidimensional array with the entries of the array constructor.

For instance, in the case of the example in the first answer, one could write:

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

obtaining the filling of the matrix array exactly in the order shown by the lines of code.

The array (/2, 1/) forces the column index (2) to have precedence on the row index (1), giving the desired effect.

み零 2024-09-25 22:08:42

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

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)。事实证明,形状
(/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)9 并且不是3 3

Array initialization can be done in the array declaration statement itself, as shown below:

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

It surprises me that

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

is not accepted by the compiler (tried g95, gfortran). It turns out that the shape of
(/(/1,2,3/),(/4,5,6/),(/7,8,9/)/) is 9 and not 3 3!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文