Fortran转置矩阵不适用于非2D阵列

时间:2011-12-16 05:05:17

标签: 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复制到具有所需顺序尺寸的虚拟阵列。我正在寻找简单的一线优雅方式。

谢谢。

2 个答案:

答案 0 :(得分:8)

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

  

情况(i):如果MATRIX A具有形状[n,m]且MATRIX B具有形状[m,k],   结果有形[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。来自Fortran 2008标准草案:

  

13.7.140 RESHAPE(来源,形状[,PAD,ORDER])

     

1说明。构造一个任意形状的数组。

     

2班。转型   功能。

     

3个论点。 SOURCE应该是任何类型的数组。如果PAD是   如果没有或大小为零,则SOURCE的大小应更大         大于或等于PRODUCT(SHAPE)。结果的大小是值的乘积        SHAPE的元素。 SHAPE应该是一级整数数组。 SIZE(x),其中x是对应的实际参数        SHAPE,应该是一个常量表达式,其值为正且小于16.它不应具有       值为负的元素。 PAD(可选)应为与SOURCE相同类型和类型参数的数组。订单(可选)   应为整数类型,其形状应与SHAPE相同   value应为(1,2,...,n)的排列,其中n是大小   SHAPE。如果不存在,就好像它存在价值(1,2,...   。 ,n)。

     

4结果特征。结果是一个形状的数组   SHAPE(即SHAPE(RESHAPE(SOURCE,SHAPE,PAD,ORDER))相等   SHAPE)与SOURCE具有相同的类型和类型参数。

     

5结果   值。结果的元素,采用置换下标顺序   订单(1),. 。 。 ,ORDER(n),是正常数组中SOURCE的那些   必要时,元素顺序由数组元素中的PAD跟随   顺序,如有必要,可以在阵列中添加PAD的其他副本   元素顺序。

答案 1 :(得分:2)

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