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

时间:2022-02-27 23:08:08

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

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

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)

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

The array is either defined by

该数组由。定义

real, dimension(3, 3) :: a

or

要么

real, dimension(:), allocatable :: a

3 个解决方案

#1


44  

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:

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

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

#2


14  

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.

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

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.

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

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.

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

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.

数组(/ 2,1 /)强制列索引(2)优先于行索引(1),从而产生所需的效果。

#3


5  

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!

编译器不接受(试过g95,gfortran)。事实证明,(/(/ 1,2,3 /),(/ 4,5,6 /),(/ 7,8,9 /)/)的形状是9而不是3 3!

#1


44  

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:

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

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

#2


14  

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.

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

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.

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

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.

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

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.

数组(/ 2,1 /)强制列索引(2)优先于行索引(1),从而产生所需的效果。

#3


5  

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!

编译器不接受(试过g95,gfortran)。事实证明,(/(/ 1,2,3 /),(/ 4,5,6 /),(/ 7,8,9 /)/)的形状是9而不是3 3!