【问题标题】:Fortran array rank for matmul intrinsicmatmul 内在函数的 Fortran 数组排名
【发布时间】:2017-06-02 14:56:33
【问题描述】:

以下链接https://gcc.gnu.org/onlinedocs/gcc-5.4.0/gfortran/MATMUL.html 明确指出,gfortran 期望输入到matmul 的矩阵排名为 1 或 2。但是以下 sn-p 无法编译:

Program scratch
  real(kind=8) :: A(10)=(/0,1,2,3,4,5,6,7,8,9/)
  real(kind=8) :: B(10)=(/0,1,2,3,4,5,6,7,8,9/)
  real(kind=8) :: C(10,10)
  print *,rank(A),rank(B)
  C=matmul(A,B)  
End Program scratch

gfortran 给出错误:

$gfortran scratch.f90 
scratch.f90:6:13:

   C=matmul(A,B)
         1
Error: ‘matrix_b’ argument of ‘matmul’ intrinsic at (1) must be of rank 2

我的 gfortran 是 5.4.0(与上面的链接兼容)。我做的事情真的很愚蠢吗?

【问题讨论】:

标签: fortran gfortran intrinsics


【解决方案1】:

您可以使用RESHAPE 将它们转换成MATMUL 喜欢的形式:

Program scratch
  real(kind=8) :: A(10)=(/0,1,2,3,4,5,6,7,8,9/)
  real(kind=8) :: B(10)=(/0,1,2,3,4,5,6,7,8,9/)
  real(kind=8) :: C(10,10)
  print *,rank(A),rank(B)
  C = matmul( RESHAPE(A,(/10,1/)), RESHAPE(B,(/1,10/)) )
  WRITE(*,"(10F7.2)") C
End Program scratch

【讨论】:

  • 谢谢,这很有帮助,我真的很想知道 gfortran 文档和编译器之间的脱节。
  • @ClintonWinant 重塑是一种将 (10) 数组视为 (1,10) 或 (10,1) 数组的方法。解释保持不变。
  • @ClintonWinant 你是对的——gfortran 文档不正确。这是 Fortran 标准中的相关行:“MATRIX A 和 MATRIX B 不应都具有等级一。” j3-fortran.org/doc/year/10/10-007.pdf
  • @Jack 谢谢,只是为了关闭循环,gfortran 只接受具有 2 级的数组,否则编译器返回:Error: Incompatible ranks 2 and 1 in assignment at (1),即使标准另有说明。我相信我们已经用尽了这个主题......
  • 其实,没有。对于A(10)B(10),gfortran 将同时采用C = matmul( reshape(A,(/1,10/)), B )C = matmul( A, reshape(B,(/10,1/)) )。但是,在这两种情况下,C 都必须是秩为 1 的单元素数组:C(1)
【解决方案2】:

您必须对两个向量的张量积执行此操作

Program scratch
  integer, parameter :: dp = kind(1.d0)
  real(dp) :: A(10,1)=reshape((/0,1,2,3,4,5,6,7,8,9/), (/ 10, 1 /))
  real(dp) :: B(1,10)=reshape((/0,1,2,3,4,5,6,7,8,9/), (/ 1, 10 /))
  real(dp) :: C(10,10)
  print *,rank(A),rank(B)
  C=matmul(A,B)
  print *, C
End Program scratch

如果你这样做

   A(1,10)
   B(10,1)

您将得到一个标量积。只有两个一维数组,不清楚您想要两种产品中的哪一种(尽管对于点产品,有一个特殊的功能可用)。

当您将矩阵乘以向量时,A 或 B 可以是一维数组。

【讨论】:

  • 所以关键是,尽管手册上说 1 阶矩阵输入是可接受的,但编译器更聪明,知道这是模棱两可的,并坚持 2 阶。因为 dot_product 内在存在,我以为 matmul 会默认为二元乘积,错了...谢谢
  • 排名 1 是允许的,但不是两个参数。
  • 这一行 real(dp) :: A(10,1)=(/0,1,2,3,4,5,6,7,8,9/) 给了我错误 Error: Incompatible rank 2 and 1 in assignment at (1) in gfortran 和 PGF90-S-0155-初始值设定项的形状与 pgfortran 中 (scratch.f90: 4) 的形状不匹配。我在这里做错了吗?
  • 不,我认为我有一个错误,但我的编译器出于某种原因允许这样做。我确实测试过。
  • 那是什么编译器?
猜你喜欢
  • 1970-01-01
  • 2019-11-11
  • 2018-11-04
  • 1970-01-01
  • 2021-04-24
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
  • 2013-11-14
相关资源
最近更新 更多