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

标签 multidimensional-array fortran matrix-multiplication

假设我有一个 3D 数组,A(1:3,1:4,1: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 函数就会变得困惑,例如:

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].

在你的情况下:

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:

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:

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 编译但产生运行时错误:

0: MATMUL: nonconforming array shapes

要在 Fortran 中 reshape 数组,您可以使用内部函数 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.

关于multidimensional-array - 矩阵的 Fortran 转置不适用于非二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8530022/

相关文章:

php - 如何从多维数组中删除一个数组?

c - Fortran 编译和 C 编译的 DLL 是否应该能够互换导入? (x86 目标)

fortran - 格式语句中重复计数的扩展(与隐含的 do 循环结合)

python - 定心矩阵

java - 使用 Jblas : Matrices need to have same length 的矩阵乘法

python - NumPy:对每个 ndarray 元素执行函数

php - 无法在多维数组中声明新数组

java - 在java中创建一个二维表

fortran - 使用 MPI IO 编写多个分布式数组

python - Numpy.点阵乘法: (n-by-m)*(m-by-k) and (m-by-k)*(k-by-n) have very different speeds