Matrix fortran函数MATMUL()的行为问题

Matrix fortran函数MATMUL()的行为问题,matrix,fortran,Matrix,Fortran,我是fortran的新手,我必须用MATMUL()乘以不同形状的矩阵,结果不是我所期望的 以下是我的fortran代码: integer, dimension(3,2) :: a integer, dimension(2,2) :: b integer :: i, j a = reshape((/ 1, 1, 1, 1, 1, 1 /), shape(a)) b = MATMUL(a,TRANSPOSE(a)) do j = 1, 2 do i = 1,

我是fortran的新手,我必须用MATMUL()乘以不同形状的矩阵,结果不是我所期望的

以下是我的fortran代码:

  integer, dimension(3,2) :: a
  integer, dimension(2,2) :: b
  integer :: i, j

  a = reshape((/ 1, 1, 1, 1, 1, 1 /), shape(a))

  b = MATMUL(a,TRANSPOSE(a))

  do j = 1, 2
     do i = 1, 2
        print*, b(i, j)
     end do
  end do
我期望这个矩阵作为结果:

b=
|3 |,一个2x2矩阵
|3 3|

相反,我收到了以下错误消息:

matmlt.f90(9):错误#6366:数组表达式的形状不一致。[乙] b=MATMUL(a,转置(a)) ------^

为了使这段代码正常工作,我必须像这样切换MATMUL参数:

b=MATMUL(转置(a),a)

这样,我就得到了一开始我所期待的。但这并不直观

纸面上,

a=
|1 |
|11|

转置(a)=
|1 |
|1 |
|11|

a x转置(a)=
|3 |
|3 3|

转置(a)xa=
|2|
|2|
|2 2|

我的代码有什么问题


谢谢。

您对变量的矩阵定义

     integer, dimension(3,2) :: a 
也就是说,你们有3行2列(和你们的假设不同)。随后

a=
|11 |
|11 |
|11 |

转置(a)=
111
111|

matmul(a,转置(a))=
|2|
|2|
|2|

所以变量b的定义应该是

 integer, dimension (3,3) :: b 
而不是

 integer, dimension (2,2) :: b  
这是什么原因

matmlt.f90(9):错误#6366:数组表达式的形状不一致。[B] B=MATMUL(a,转置(a))------^


错误

变量的矩阵定义

     integer, dimension(3,2) :: a 
也就是说,你们有3行2列(和你们的假设不同)。随后

a=
|11 |
|11 |
|11 |

转置(a)=
111
111|

matmul(a,转置(a))=
|2|
|2|
|2|

所以变量b的定义应该是

 integer, dimension (3,3) :: b 
而不是

 integer, dimension (2,2) :: b  
这是什么原因

matmlt.f90(9):错误#6366:数组表达式的形状不一致。[B] B=MATMUL(a,转置(a))------^


错误

A是一个3x2矩阵。因此转置(A)是一个2x3矩阵。因此A*转置(A)是一个3x3矩阵,它与B的2x2矩阵不兼容。我想把这作为一个答案,但我无法理解为什么你认为B应该是2x2,而不是正确的3x3。你能编辑一下你的问题,解释一下为什么你认为这更清楚一点吗?再看一遍,你似乎把所有的东西都转置了,a有3行2列,这就是(3,2)的意思。为什么你认为是相反的?一个(3列,2行)矩阵加上一个(2列,3行)矩阵将在乘法后给出一个(2列,2行)矩阵Fortran是列主数组,这是一个令人费解的问题-一个声明为
dimension(3,4)
的数组有3行和4列,就像在一行中一样,主要语言具有相似的语法。内存中数组的布局(这是主位所指的)不会影响向程序员公开的数组索引的语义。顺便说一下,要将矩阵
a
的每个元素设置为
1
,只需编写
a=1
,不需要对
重塑
进行任何修改。A是一个3x2矩阵。因此转置(A)是一个2x3矩阵。因此A*转置(A)是一个3x3矩阵,它与B的2x2矩阵不兼容。我想把这作为一个答案,但我无法理解为什么你认为B应该是2x2,而不是正确的3x3。你能编辑一下你的问题,解释一下为什么你认为这更清楚一点吗?再看一遍,你似乎把所有的东西都转置了,a有3行2列,这就是(3,2)的意思。为什么你认为是相反的?一个(3列,2行)矩阵加上一个(2列,3行)矩阵将在乘法后给出一个(2列,2行)矩阵Fortran是列主数组,这是一个令人费解的问题-一个声明为
dimension(3,4)
的数组有3行和4列,就像在一行中一样,主要语言具有相似的语法。内存中数组的布局(这是主位所指的)不会影响向程序员公开的数组索引的语义。顺便说一下,要将矩阵
a
的每个元素设置为
1
,只需编写
a=1
,我试图将C与fortran连接起来,因为C是行主键,fortran是列主键,我最初认为,要在fortran中声明矩阵,我们必须像这样切换行数和列数:C:a[3][2]fortran:a(2,3)从您的注释中,它应该声明为a(3,2)和我们通常做的一样。谢谢你的回答。你是对的,fortran是列主语言,但这个术语描述了数组元素在内存中是如何连续的。我知道用malloc(m x n x sizeof())在一维C中声明的2D数组指针,传递给fortran子例程将自动转换,因为它们存储在内存中的方式(行主(C)到列主(fortran))。因此,在fortran子例程中,在对矩阵进行任何操作之前,建议将其转换为(un)在进行任何处理之前,在将结果返回给调用c函数之前,需要进行另一次换位。我这样说对吗?嘿,从内存行为的角度来看,你是对的。为了进一步阅读,我可以建议。有趣的阅读。我可以修改我的c数组在内存中的存储方式(从row major到column major)来模拟fortran行为,但我认为这不是一个好办法。我更喜欢在fortran子例程中添加一个标志,指示它是否需要转置数组参数。通过这样做,如果c函数调用该fortran子例程,参数标志将切换为YES(用于转置)如果调用函数是fortran语言,则不会。我试图