Ich muss eine Fortran-Routine schreiben, die die inverse Matrix zurückgibt. Wenn ich den folgenden Code in einem Fortran-Programm ausführe, ist die inverse Matrix korrekt, aber wenn ich die Subroutine von C++ Code aus führe, ist mein erster Wert ein falscher Wert. Es scheint ein Problem mit den Datentypen oder dem Speicher zu sein.Fortran-Subroutine liefert falsches Ergebnis, wenn in C++ - Programm aufgerufen
Was mache ich falsch? Hier
ist das Unterprogramm:
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
Hier ist die Erklärung in der C++ Code:
extern "C"
{
void get_inverse_matrix(double *matrix, int *rows_matrix, int *cols_matrix, double *tmpMatrix, int *rows_tmpMatrix, int *cols_tmpMatrix);}
Hier ist der Anruf von meinem C++ Programm:
get_inverse_matrix(&lhs[0], &sz, &sz, &res[0], &sz, &sz);
Mein Programm verwendet nur eine 3x3-Matrix. Wenn ich die Identitätsmatrix passieren sieht das Ergebnis wie:
5.29981e-315 0 0
0 1 0
0 0 1
Sie übergeben ein Array, das als Typ 'c_double' deklariert ist, an lapack-Routinen, die eine einfache Genauigkeit erwarten, was manchmal Probleme verursachen kann. Können Sie versuchen, 'sgetrf' und' sgetri' durch 'dgetrf' und' dgetri' zu ersetzen und hilft das? Ich hätte nicht erwartet, dass der Fortran in diesem Fall funktionieren würde. Beachten Sie, dass Sie die Deklarationen wahrscheinlich auch im C++ - Code anzeigen sollten. –
Ich habe die Deklaration in C++ - Code hinzugefügt. Auch ich habe ersetzt, wie Sie angerufen haben, aber das Ergebnis ist eine Matrix mit nur Nullen, egal welche Werte ich versuchte. – fx88
Es ist viel besser, das moderne Fortran90 + Interfacemodul an LAPACK zu verwenden oder zumindest einen Schnittstellenblock zu haben, um den Aufruf auf Fehler zu überprüfen. –