如何在FORTRAN的子程序中声明一个局部“矩阵”?

时间:2013-02-15 11:10:18

标签: fortran

我正在编写一个子程序来反转矩阵。 输入是矩阵A(n乘n),输出是矩阵invA。在子例程中,我想声明一个临时矩阵“temp”维度(n乘2n),但声明引起了奇怪的问题。在这一行之后(我在下面强调),我也声明整数i和j并初始化它们i = 0,j = 0。 但调试i和j的这些值,它显示i = 1572472!奇怪的!!!!!如果我删除代码行“real,dimension(m,m * 2):: temp”那么一切都很好。谁能解释一下为什么?

提前谢谢。 (我是.Net中的优秀程序员,现在正在学习Fortran - 但它让我发疯了!)

program weird

implicit none

Real, Dimension (2,2)::B
Real, Dimension (2,2) ::B_inversed


B(1,1) = 0.6
B(1,2) = 0.8  
B(2,1) = -0.8
B(2,2) = 0.6

Call InverseMatrix(B,B_inversed)

contains

subroutine InverseMatrix(A, invA)
implicit none
real, intent(in), dimension (:,:) :: A  
real, intent(out), dimension (size(a,1),size(a,2)) :: invA 

real, dimension (size(a,1),2*size(a,2)) :: temp  <------THIS LINE CAUSES PROBLEMS


integer:: i,j
i = 0 !<------- 
j = 0 !<-------DEBUG line stops here, showing i = 3734648 !VERY WEIRD!!!!!

invA(1,1) =0.0
invA(1,2) =0.0
invA(2,1) =0.0
invA(2,2) =0.0

end subroutine

end program

这是一个非常直接的FORTRAN代码,但为什么我没有得到'i'的正确值?

2 个答案:

答案 0 :(得分:3)

由于Fortran数组带有关于它们自己大小的信息,因此更好的方法是让你更像这样开始你的子程序:

subroutine inversematrix(a, inva)
    ! ALWAYS include the next line within any scoping unit
    implicit none
    real, intent(in), dimension (:,:) :: a  ! no need to tell the compilers what the dims are
    real, intent(out), dimension (size(a,1),size(a,2)) :: inva 

    real, dimension (size(a,1),2*size(a,2)) :: temp  

要回答您的问题,我无法立即了解您的代码无效的原因以及为什么变量i不会保留您为其分配的值。我想知道它是否连接到子程序的接口。在现代Fortran中,当技术上可行时,确保编译器生成必要的例程接口始终是一个好主意。实现这一目标的一种方法是将所有例程放入模块中,使用 - 关联它们,另一种方法是使用基本结构编写代码

program
! declarations
! executable statements
contains

subroutine ...
end subroutine

end program

而不是

subroutine ...
end subroutine

program
! declarations
! executable statements
end program

但我真的只是在猜测。

使用implicit none并确保编译器生成例程接口;这些可能无法治愈你的直接问题,但它们是很好的一般指导方针,将来会为你节省很多痛苦。

答案 1 :(得分:0)

英特尔编译器在优化期间会做一些可能影响调试器输出的事情:

  1. 它会重新排列语句的顺序,因此分配j = 0的行可能会在指定i = 0的行之前运行。

  2. 它“优化”变量,不仅可以删除未使用的变量,还可以将变量与其他未同时使用的变量相结合。

  3. 这两个看起来都是不可预测的(至少对我而言)。因此,如果您已修复程序以使其具有正确的行为,并且打印该值会产生正确的答案,则调试器可能仍会显示错误的值。您可以尝试关闭/关闭优化,看看会发生什么。