计算Fortran 90中两个向量的叉积 [英] Computing the cross product of two vectors in Fortran 90

查看:1360
本文介绍了计算Fortran 90中两个向量的叉积的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想计算Fortran 90中两个向量的叉积。例如,用(1,2,3)和(4,5,6)的叉积结果是(-3 ,6,-3)以笛卡尔坐标表示。我写了下面的代码(主程序接着是函数定义):

 程序交叉测试
隐式无

INTEGER,DIMENSION(3):: m,n
INTEGER,DIMENSION(3):: cross
INTEGER,DIMENSION(3):: r

m = (/ 1,2,3 /)
n =(/ 4,5,6)
r =交叉(m,n)

结束程序交叉测试

函数cross(a,b)
INTEGER,DIMENSION(3):: cross
INTEGER,DIMENSION(3),INTENT(IN):: a,b
$ b $ (1)= a(2)* b(3)-a(3)* b(2)
cross(2)= a(3)* b (3)
cross(3)= a(1)* b(2) - a(2)* b(1)
结束功能cross

但是,我收到错误消息:

 交叉测试(1)(2/1)








$错误: / code>

其中第10行是 r = cross(m,n)。看来我必须错误地指定尺寸。以下是我的一些想法:


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

      crosstest.f90:10.4:

    r = cross(m, n)
    1
    错误:在(1)中对函数'cross'的引用要么需要
    显式的INTERFACE,要么等级不正确

    所以这可能更糟糕。

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

      crosstest.f90:8.16:

    EXTERNAL cross
    1
    错误:EXTERNAL属性在(1)处与DIMENSION属性冲突

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

      crosstest.f90:10.9:
    $ b $ (1)(2/1)


    所以这并不能解决问题。

帮我看看我的错误?

解决方案

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



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

  module my_subs 

隐式无

包含

函数cross(a,b)
INTEGER,DIMENSION(3):: cross
INTEGER,DIMENSION(3),INTENT(IN):: a,b
$ (1)= a(2)* b(3)-a(3)* b(2)
cross(2)= a(3)* b(1) * b(3)
交叉(3)= a(1)* b(2) - a(2)* b(1)
结束功能cross

end module my_subs


程序交叉测试
使用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交叉测试


I would like to compute the cross product of two vectors in Fortran 90. For example, in words, the cross product of (1, 2, 3) and (4, 5, 6) turns out to be (-3, 6, -3) in Cartesian coordinates. I wrote the following code (main program followed by function definition):

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

But, I get an error message:

crosstest.f90:10.9:

  r=cross(m,n)
         1
Error: Rank mismatch in array reference at (1) (2/1)

where line 10 is r=cross(m,n). It seems that I must be specifying a dimension incorrectly. Here are a few ideas I have:

  1. Perhaps the declaration of the function cross in the main program should be simply an integer variable, rather than a 1by3 integer array. So I tried deleting the , DIMENSION(3) in the INTEGER, DIMENSION(3) :: cross line in the main program. But I get an error message:

    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
    

    so this is even worse, probably.

  2. Some (but not all) Fortran function examples on the web place an EXTERNAL statement after the function declaration in the main program. So I tried placing a line EXTERNAL cross after the declaration block in the main program. I get an error message:

    crosstest.f90:8.16:
    
      EXTERNAL cross
                    1
    Error: EXTERNAL attribute conflicts with DIMENSION attribute at (1)
    

    So this seems incorrect also.

  3. Some (but not all) Fortran function examples on the web place a RETURN statement on the second-to-last line of the function definition. I tried this, but I get the original rank mismatch error:

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

    So this does not fix the problem.

Can you please help me see my error?

解决方案

The best practice is to place your procedures (subroutines and functions) in a module and then "use" that module from your main program or other procedures. You don't need to "use" the module from other procedures of the same module. This will make the interface of the procedure explicit so that the calling program or procedure "knows" the characteristics of the arguments ... it allows the compiler to check for consistency between the arguments on both sides ... caller and callee .. this eliminates a lot of bugs.

Outside of the language standard, but in practice necessary: if you use one file, place the module before the main program that uses it. Otherwise the compiler will be unaware of it. so:

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

这篇关于计算Fortran 90中两个向量的叉积的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆