在Fortran 90中计算两个向量的叉积
我想计算Fortran 90中两个vector的叉积。例如,用(1,2,3)和(4,5,6)的叉积结果是(-3,6, -3)以笛卡尔坐标表示。 我写了下面的代码(主程序后跟函数定义):
PROGRAM crosstest IMPLICIT NONE INTEGER, DIMENSION(3) :: m, n INTEGER, DIMENSION(3) :: cross INTEGER, DIMENSION(3) :: r m=(/1, 2, 3/) n=(/4, 5, 6/) r=cross(m,n) END PROGRAM crosstest FUNCTION cross(a, b) INTEGER, DIMENSION(3) :: cross INTEGER, DIMENSION(3), INTENT(IN) :: a, b cross(1) = a(2) * b(3) - a(3) * b(2) cross(2) = a(3) * b(1) - a(1) * b(3) cross(3) = a(1) * b(2) - a(2) * b(1) END FUNCTION cross
但是,我收到一条错误消息:
crosstest.f90:10.9: r=cross(m,n) 1 Error: Rank mismatch in array reference at (1) (2/1)
第10行是r = cross(m,n) 。 看来我必须指定一个尺寸不正确。 以下是我的一些想法:
(1)也许在主程序中交叉函数的声明应该只是一个整数variables,而不是一个1by3的整数数组。 所以我试着在主程序的INTEGER,DIMENSION(3):: cross行中删除“,DIMENSION(3)”。 但是我收到一条错误消息:
crosstest.f90:10.4: r=cross(m,n) 1 Error: The reference to function 'cross' at (1) either needs an explicit INTERFACE or the rank is incorrect
所以这可能更糟。
(2)Web上的一些(但不是全部)Fortran函数示例在主程序中的函数声明之后放置EXTERNAL语句。 所以我试图在主程序的声明块之后放置一行EXTERNAL十字 。 我收到一条错误消息:
crosstest.f90:8.16: EXTERNAL cross 1 Error: EXTERNAL attribute conflicts with DIMENSION attribute at (1)
所以这似乎也是不正确的。
(3)Web上的一些(但不是全部)Fortran函数示例在函数定义的倒数第二行上放置了一个RETURN语句。 我试过这个,但我得到原来的排名不匹配错误:
crosstest.f90:10.9: r=cross(m,n) 1 Error: Rank mismatch in array reference at (1) (2/1)
所以这不能解决问题。
你能帮我看看我的错误吗?
非常感谢您的时间。
最好的做法是将你的程序(子程序和函数)放在一个模块中,然后从主程序或其他程序中“使用”这个模块。 您不需要从同一个模块的其他程序“使用”模块。 这将使过程的接口显式化,以便调用程序或过程“知道”参数的特征…它允许编译器检查两边参数之间的一致性…调用者和被调用者… this消除了很多的错误。
在语言标准之外,但在实践中是必要的:如果您使用一个文件,请将模块放在使用它的主程序之前。 否则编译器将不知道它。 所以:
module my_subs implicit none contains FUNCTION cross(a, b) INTEGER, DIMENSION(3) :: cross INTEGER, DIMENSION(3), INTENT(IN) :: a, b cross(1) = a(2) * b(3) - a(3) * b(2) cross(2) = a(3) * b(1) - a(1) * b(3) cross(3) = a(1) * b(2) - a(2) * b(1) END FUNCTION cross end module my_subs PROGRAM crosstest use my_subs IMPLICIT NONE INTEGER, DIMENSION(3) :: m, n INTEGER, DIMENSION(3) :: r m= [ 1, 2, 3 ] n= [ 4, 5, 6 ] r=cross(m,n) write (*, *) r END PROGRAM crosstest
这是一个迟到的答案,但是由于我偶然发现了这个问题,而且还没有真正的解释为什么你的错误发生了,所以我想给所有其他的人解释这个问题:
在你的程序中,你定义了一个名为cross
的数组,这个数组的名字是1.然后你调用你定义的cross
函数。 由于cross
函数没有明确的接口(请参阅MSB的答案),编译器此时不知道它。 它所知道的是你声明的数组。 如果你写r = cross(m, n)
,编译器认为你想访问数组cross
位置(m,n)处的元素。 由于这个数组的排名是1,但是你提供了两个参数,你会得到这个错误
rank mismatch in array reference at (1) (2/1)
这意味着当编译器期待的时候你提供了两个坐标。