matmul内在函数的Fortran数组秩
下面的链接明确指出,gfortran希望输入到matmul内在函数的Fortran数组秩,fortran,gfortran,intrinsics,Fortran,Gfortran,Intrinsics,下面的链接明确指出,gfortran希望输入到matmul的矩阵为秩1或秩2。但是,以下代码段无法编译: 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 sc
matmul
的矩阵为秩1或秩2。但是,以下代码段无法编译:
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(与上面的链接兼容)。我真的在做傻事吗 对于两个向量的张量积,必须这样做
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)
你会得到一个标量积。由于只有两个1D阵列,不清楚您想要两个产品中的哪一个(尽管对于dot产品,有一个特殊的功能可用)
当将矩阵乘以向量时,A或B可以是一维数组。必须对两个向量的张量积执行此操作
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)
你会得到一个标量积。由于只有两个1D阵列,不清楚您想要两个产品中的哪一个(尽管对于dot产品,有一个特殊的功能可用)
当您将矩阵乘以向量时,A或B可以是一维数组。您可以使用
重塑
将它们转换为一种形式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
您可以使用
重塑
将它们转换为一种形式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
是的,您使用的是
kind=8
@VladimirF谢谢,不幸的是,我将声明更改为real(kind=4)
,gfortran报告了相同的错误。这不是重点,请参阅和我的回答。这与报告的错误无关。非常密切相关,但不是完全重复的。是的,您使用的是kind=8
@VladimirF谢谢,不幸的是,我将声明更改为real(kind=4)
,gfortran报告了相同的错误。这不是重点,请参阅和我的答案。它与报告的错误无关。非常密切相关,但不是完全重复的,所以重点是,尽管手册中说秩1的矩阵输入是可接受的,编译器更聪明,知道这是不明确的,并坚持秩2。因为dot_积的内在存在,我认为matmul会默认为并矢积,错了。。。谢谢你,1是单独的,但不是两个参数。这一行real(dp)::A(10,1)=(/0,1,2,3,4,5,6,7,8,9/)
给出了一个错误:gfortran中(1)处赋值中的秩2和1不兼容,并且PGF90-S-0155-初始值设定项的形状与pgfortran中A(scratch.f90:4)的形状不匹配。我在这里做错了什么吗?不,我想我在那里有个错误,但我的编译器出于某种原因允许这样做。我做了测试。那是什么编译器?所以重点是,尽管手册上说秩1的矩阵输入是可接受的,但编译器更聪明,知道这是不明确的,并且坚持秩2。因为dot_积的内在存在,我认为matmul会默认为并矢积,错了。。。谢谢你,1是单独的,但不是两个参数。这一行real(dp)::A(10,1)=(/0,1,2,3,4,5,6,7,8,9/)
给出了一个错误:gfortran中(1)处赋值中的秩2和1不兼容,并且PGF90-S-0155-初始值设定项的形状与pgfortran中A(scratch.f90:4)的形状不匹配。我在这里做错了什么吗?不,我想我在那里有个错误,但我的编译器出于某种原因允许这样做。我做了测试。那是什么编译器?谢谢,这很有帮助,我真的很想知道gfortran文档和编译器之间的脱节。@ClintonWinant重塑是一种将(10)数组视为(1,10)或(10,1)数组的方法。解释保持不变。@ClintonWinant您是正确的——gfortran文档不正确。下面是Fortran标准中的相关行:“矩阵A和矩阵B不应都有秩1”。@Jack谢谢,为了结束循环,gfortran只接受秩2的两个数组,否则编译器返回:Error:assignment at(1)
中不兼容的秩2和1,即使标准另有规定。我相信我们已经讲完了这个主题……事实上,没有。有了A(10)
和B(10)
,gfortran将同时接受C=matmul(重塑(A,(/1,10/)),B)
和C=matmul(A,重塑(B,(/10,1/)
)。但是,在这两种情况下,C都必须是秩1的单元素数组:C(1)
谢谢,这很有帮助,我真的很想知道gfortran文档和编译器之间的脱节。@ClintonWinant重塑是一种将(10)数组视为(1,10)或(10,1)数组的方法。解释保持不变。@ClintonWinant您是正确的——gfortran文档不正确。下面是Fortran标准中的相关行:“矩阵A和矩阵B不应都有秩1”。@Jack谢谢,为了结束循环,gfortran只接受秩2的两个数组,否则编译器返回:Error:assignment at(1)
中不兼容的秩2和1,即使标准另有规定。我相信我们已经讲完了这个主题……事实上,没有。有了A(10)
和B(10)
,gfortran将同时接受C=matmul(重塑(A,(/1,10/)),B)
和C=matmul(A,重塑(B,(/10,1/)
)。然而,在这两种情况下,C必须是秩1的单元素数组:C(1)