矩阵的 Fortran 转置不适用于非二维数组

Fortran transpose of matrix doesn't work on non-2D arrays

假设我有一个 3D 数组,A(1:3,1:4,1:5),我只想处理它的一部分,例如:

1
2
3
4
5
real :: A(1:3,1:4,1:5), B(1:5,1:2)
real, allocatable :: C(:,:)

allocate(C(size(A,1),size(B,2)))
C = matmul(A(1:3,1,1:5),B)

Fortran 似乎很好。但是,如果我需要处理转置,那么 Fortran 中的 transpose 函数就会混淆,例如:

1
2
3
4
5
real :: A(1:3,1:4,1:5), B(1:3,1:2)
real, allocatable :: C(:,:)

allocate(C(size(A,3),size(B,2)))
C = matmul(transpose(A(1:3,1,1:5)),B)

如何使用 Fortran 交换数组中的维度?例如,我有 A(3,4,5);有没有一个函数/命令可以接受这个并给我 A(5,4,3) 或 A(4,3,5) 或任何我想要的安排?当然,无需执行诸如将 A 复制到具有所需顺序的维度的虚拟数组之类的操作。我正在寻找一种简单的单行优雅方式。

谢谢。


TRANSPOSE 没有问题。对于您提供的示例代码,它工作得很好。问题是您的数组与矩阵乘法不兼容。来自 Fortran 2008 标准草案:

Case (i): If MATRIX A has shape [n, m] and MATRIX B has shape [m, k],
the result has shape [n, k].

在你的情况下:

1
C = matmul(transpose(A(1:3,1,1:5)),B)

这里,transpose(A(1:3,1,1:5))是一个5x3的矩阵,B是2x5。因此,这两个矩阵对于 MATMUL 是不可合的。我想知道您是如何没有注意到这一点的,因为编译器会给出明确的错误消息:

gfortran 4.1.2:

1
2
3
4
5
In file matrix.f90:13

C = matmul(transpose(A(:,1,:)),B)
          1
Error: different shape on dimension 2 for argument 'matrix_a' and dimension 1 for argument 'matrix_b' at (1) for intrinsic matmul

ifort 12.0.2.137:

1
2
3
4
matrix.f90(13): error #6241: The shapes of the arguments are inconsistent or nonconformable.   [MATMUL]
C = matmul(transpose(A(:,1,:)),B)
----^
compilation aborted for matrix.f90 (code 1)

pgf90 10.6-0 编译但产生运行时错误:

1
0: MATMUL: nonconforming array shapes

为了在 Fortran 中重塑数组,您可以使用内部函数 RESHAPE。来自 Fortran 2008 标准草案:

13.7.140 RESHAPE (SOURCE, SHAPE [, PAD, ORDER])

1 Description. Construct an array of an arbitrary shape.

2 Class. Transformational
function.

3 Arguments. SOURCE shall be an array of any type. If PAD is
absent or of size zero, the size of SOURCE shall be greater
than or equal to PRODUCT (SHAPE). The size of the result is the product of the values of the
elements of SHAPE. SHAPE shall be a rank-one integer array. SIZE (x), where x is the actual argument corresponding to
SHAPE, shall be a constant expression whose value is positive and less than 16. It shall not have
an element whose value is negative. PAD (optional) shall be an array of the same type and type parameters as SOURCE. ORDER (optional)
shall be of type integer, shall have the same shape as SHAPE, and its
value shall be a permutation of (1, 2, . . . , n), where n is the size
of SHAPE. If absent, it is as if it were present with value (1, 2, . .
. , n).

4 Result Characteristics. The result is an array of shape
SHAPE (that is, SHAPE (RESHAPE (SOURCE, SHAPE, PAD, ORDER)) is equal
to SHAPE) with the same type and type parameters as SOURCE.

5 Result
Value. The elements of the result, taken in permuted subscript order
ORDER (1), . . . , ORDER (n), are those of SOURCE in normal array
element order followed if necessary by those of PAD in array element
order, followed if necessary by additional copies of PAD in array
element order.


A(1:3,1,1:5) 是大小为 3 x 5 的二阶数组。通过为三阶数组 "A" 的第二个索引指定特定值 (1)而不是你降低了维度的范围。 A(1:3,1,1:5) 的转置应该是大小为 5 x 3 的二阶数组。

如果您想对数组的维度进行任意更改,请使用 "reshape" 内在函数。它是否会将元素放置在您想要的位置是另一个问题。用法示例:A = reshape (A, [5,4,3]).