0
逆行列を返すFortranルーチンを作成する必要があります。私がFortranプログラムで以下のコードを実行すると、逆行列は正しいですが、C++コードからサブルーチンを実行すると、最初の値が間違った値になります。これは、データ型やメモリの問題のようです。C++プログラムで呼び出すと、Fortranサブルーチンが間違った結果を返します
私は間違っていますか?ここで
はサブルーチンである:ここでは
subroutine get_inverse_matrix(matrix, rows_matrix, cols_matrix, tmpMatrix, rows_tmpMatrix, cols_tmpMatrix) bind(c)
use iso_c_binding
integer :: m, n, lda, lwork, info, size_m
integer(c_int) :: rows_matrix, cols_matrix, rows_tmpMatrix, cols_tmpMatrix
real(c_double) :: matrix(rows_matrix, cols_matrix), tmpMatrix(rows_tmpMatrix, cols_tmpMatrix)
integer, dimension(rows_matrix) :: ipiv
real, dimension(rows_matrix) :: work
size_m = rows_matrix
m = size_m
n = size_m
lda = size_m
lwork = size_m
write(*,*) "Matrix: ", matrix
!tmpMatrix = matrix
write(*,*) "Temp matrix: ", tmpMatrix
! LU-Faktorisierung (Dreieckszerlegung) der Matrix
call sgetrf(m, n, tmpMatrix, lda, ipiv, info)
write(*,*) info
! Inverse der LU-faktorisierten Matrix
call sgetri(n, tmpMatrix, lda, ipiv, work, lwork, info)
write(*,*) info
select case(info)
case(0)
write(*,*) "SUCCESS"
case(:-1)
write(*,*) "ILLEGAL VALUE"
case(1:)
write(*,*) "SINGULAR MATRIX"
end select
end subroutine get_inverse_matrix
は、C++コードでの宣言です:ここで
extern "C"
{
void get_inverse_matrix(double *matrix, int *rows_matrix, int *cols_matrix, double *tmpMatrix, int *rows_tmpMatrix, int *cols_tmpMatrix);}
は私のCからの呼び出しです++プログラム:
get_inverse_matrix(&lhs[0], &sz, &sz, &res[0], &sz, &sz);
マイプログラム3x3マトリックスのみを使用します。私は単位行列を渡すと結果は以下のようになります。
5.29981e-315 0 0
0 1 0
0 0 1
単精度を期待するlapackルーチンに 'c_double'型として宣言された配列を渡していますが、これは時には問題を引き起こすことがあります。あなたは 'sgetrf'と' sgetri'を 'dgetrf'と' dgetri'で置き換えることができますか?これは助けになりますか?私は、この場合にはどちらも働くことを期待していなかっただろう。おそらく、C++コードの宣言も表示する必要があります。 –
私はC++コードで宣言を追加しました。あなたが呼び出したときにも置き換えられましたが、結果はゼロだけの行列です。値を試しても問題ありません。 – fx88
LAPACKに現代のFortran90 +インターフェース・モジュールを使用するか、少なくともエラーの呼び出しを検査するインターフェース・ブロックを使用する方がはるかに優れています。 –