计算Fortran 90中两个向量的叉积

And*_*rew 7 fortran function cross-product

我想计算Fortran 90中两个向量的叉积.例如,在单词中,(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
Run Code Online (Sandbox Code Playgroud)

但是,我收到一条错误消息:

crosstest.f90:10.9:

  r=cross(m,n)
         1
Error: Rank mismatch in array reference at (1) (2/1)
Run Code Online (Sandbox Code Playgroud)

第10行是r=cross(m,n).似乎我必须错误地指定维度.以下是我的一些想法:

  1. 也许cross主程序中函数的声明应该只是一个整数变量,而不是1by3整数数组.所以我尝试删除主程序, DIMENSION(3)中的INTEGER, DIMENSION(3) :: cross行.但是我收到一条错误消息:

    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
    
    Run Code Online (Sandbox Code Playgroud)

    所以这可能更糟糕.

  2. Web上的一些(但不是全部)Fortran函数示例在EXTERNAL主程序中的函数声明之后放置一个语句.所以我尝试EXTERNAL cross在主程序中的声明块之后放置一行.我收到一条错误消息:

    crosstest.f90:8.16:
    
      EXTERNAL cross
                    1
    Error: EXTERNAL attribute conflicts with DIMENSION attribute at (1)
    
    Run Code Online (Sandbox Code Playgroud)

    所以这看起来也不正确.

  3. Web上的一些(但不是全部)Fortran函数示例在RETURN函数定义的倒数第二行上放置一个语句.我尝试过这个,但是我得到了原来的排名不匹配错误:

    crosstest.f90:10.9:
    
      r=cross(m,n)
             1
    Error: Rank mismatch in array reference at (1) (2/1)
    
    Run Code Online (Sandbox Code Playgroud)

    所以这不能解决问题.

你能帮我看看我的错误吗?

M. *_* B. 20

最好的做法是把你的程序(子程序和函数)的模块中,然后"使用"该模块由主程序或其他程序.您不需要从同一模块的其他过程"使用"该模块.这将使过程的接口显式化,以便调用程序或过程"知道"参数的特征...它允许编译器检查双方参数之间的一致性...调用者和被调用者...这消除了很多错误.

在语言标准之外,但在实践中是必要的:如果您使用一个文件,请将模块放在使用它的主程序之前.否则编译器将不会意识到它.所以:

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
Run Code Online (Sandbox Code Playgroud)

  • +1使用`[1,2,3]`而不是(更丑)`(\ 1,2,3 \)`. (3认同)

tos*_*ter 6

这是一个迟到的答案,但由于我偶然发现了这个并且对于你的错误发生的原因还没有真正的解释,我想我会为偶然发现这个问题的其他人添加一个解释:

在你的程序中,你定义一个名为crossrank 的数组,然后你调用cross你进一步定义的函数.由于该cross函数没有显式接口(请参阅MSB的答案),因此编译器此时不知道它.它所知道的是你声明的数组.如果编写r = cross(m, n),编译器认为您要访问数组位置(m,n)处的元素cross.由于此数组的等级为1,但您提供了两个参数,因此会出现错误

rank mismatch in array reference at (1) (2/1)
Run Code Online (Sandbox Code Playgroud)

这意味着当编译器期望一个时,你提供了两个坐标.