Подпрограмма Fortran дает неправильный результат при вызове в программе C++
Я должен написать процедуру Fortran, возвращающую обратную матрицу. Если я запускаю приведенный ниже код в программе на Фортране, обратная матрица верна, но когда я запускаю подпрограмму из кода C++, мое первое значение является неправильным. Это похоже на проблему с типами данных или памятью.
Что я делаю неправильно?
Вот подпрограмма:
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);
Моя программа использует только матрицу 3х3. Если я передам матрицу тождеств, результат будет выглядеть так:
5.29981e-315 0 0
0 1 0
0 0 1
1 ответ
Вы объявляете свои массивы как type real
с добрым c_double
но вы используете процедуры lapack, которые ожидают ввода с одинарной точностью (например, c_float
). Чтобы это исправить, вы должны заменить звонки на sgetrf
а также sgetri
с dgetrf
а также dgetri
,
Как отметил Владимир Федорович в комментариях, эти проблемы могут быть легко обнаружены, если вы предоставите интерфейсы.