0

行列を逆にするサブルーチンを書いています。入力は行列A(n x n)、出力は行列invAです。サブルーチン内で、一時行列の「一時」次元(n x 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」の正しい値を取得できなかったのですか?

4

2 に答える 2

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では、技術的に可能な場合は、コンパイラーが必要なルーチン・インターフェースを生成することを確認することをお勧めします。これを実現する1つの方法は、すべてのルーチンをモジュールに入れて使用-関連付け、もう1つは、基本構造を使用してコードを作成することです。

program
! declarations
! executable statements
contains

subroutine ...
end subroutine

end program

それよりも

subroutine ...
end subroutine

program
! declarations
! executable statements
end program

しかし、私は本当に推測しているだけです。

implicit noneコンパイラがルーチンインターフェイスを生成することを使用して確認します。これらはあなたの当面の問題を解決しないかもしれませんが、それらは良い一般的なガイドラインであり、将来あなたに多くの苦痛を救うでしょう。

于 2013-02-15T11:41:06.623 に答える
0

インテル®コンパイラーは、最適化中にデバッガーの出力に影響を与える可能性のあるいくつかのことを行います。

  1. ステートメントの順序を再配置するため、j = 0を割り当てる行は、i=0を割り当てる行の前に実行される可能性があります。

  2. 未使用の変数を削除するだけでなく、同時に使用されていない他の変数と変数を組み合わせることにより、変数を「最適化」します。

これらは両方とも(少なくとも私には)予測できないように見えることがあります。したがって、プログラムが正しい動作をするように修正し、値を出力すると正しい答えが得られる場合でも、デバッガーは間違った値を表示する可能性があります。最適化をオフ/オフにして、何が起こるかを確認できます。

于 2013-08-18T21:48:48.980 に答える