在C+中调用Fortran子例程时会产生错误的结果+;程序
我必须写一个Fortran例程返回逆矩阵。如果我在FORTRAN程序中运行下面的代码,逆矩阵是正确的,但是当我从C++代码运行子程序时,我的第一个值是错误的值。这似乎是数据类型或内存的问题 我做错了什么 下面是子程序:在C+中调用Fortran子例程时会产生错误的结果+;程序,fortran,inverse,Fortran,Inverse,我必须写一个Fortran例程返回逆矩阵。如果我在FORTRAN程序中运行下面的代码,逆矩阵是正确的,但是当我从C++代码运行子程序时,我的第一个值是错误的值。这似乎是数据类型或内存的问题 我做错了什么 下面是子程序: subroutine get_inverse_matrix( matrix, rows_matrix, cols_matrix, tmpMatrix, rows_tmpMatrix, cols_tmpMatrix) bind(c) use iso_c_bi
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
您正在使用kind
c\u double
将数组声明为typereal
,但您使用的是需要单精度输入的lapack例程(例如c\u float
)。要解决此问题,应将对sgetrf
和sgetri
的调用替换为dgetrf
和dgetri
正如Vladimir F在评论中指出的那样,如果您提供接口,这些问题可能更容易被发现。您使用kind
c\u double将数组声明为typereal
,但您使用的是需要单精度输入的lapack例程(例如c\u float
)。要解决此问题,应将对sgetrf
和sgetri
的调用替换为dgetrf
和dgetri
正如Vladimir F在评论中指出的那样,如果提供接口,这些问题会更容易被发现。如果将声明为typec\u double
的数组传递给期望单精度的lapack例程,这有时会导致问题。您能否尝试将sgetrf
和sgetri
替换为dgetrf
和dgetri
,这是否有帮助?在这种情况下,我也不会指望fortran能工作。注意,您也应该在C++代码中显示声明。我在C++代码中添加了声明。我还替换了你调用的矩阵,但结果是一个只有零的矩阵,不管我尝试了什么值。最好使用现代Fortran90+接口模块来LAPACK,或者至少有一个接口块来检查调用是否有错误。同样,在你的代码中,如果你传入矩阵,然后不使用它进行任何操作(打印除外)正如您已经注释掉了行tmpMatrix=matrix
。这是正确的还是仅仅是一个打字错误?代码< >代码>矩阵>代码>和/或<代码> TMPMatrix (即<代码> LHS < /C>和/或<代码> RES <代码>)在C++代码中初始化?谢谢注意。在试图修复时,我注释掉了该行。使用该线路时,dgetrf和dgetri调用该线路。谢谢!将声明为typec\u double
的数组传递给期望单精度的lapack例程,这有时会导致问题。您能否尝试将sgetrf
和sgetri
替换为dgetrf
和dgetri
,这是否有帮助?在这种情况下,我也不会指望fortran能工作。注意,您也应该在C++代码中显示声明。我在C++代码中添加了声明。我还替换了你调用的矩阵,但结果是一个只有零的矩阵,不管我尝试了什么值。最好使用现代Fortran90+接口模块来LAPACK,或者至少有一个接口块来检查调用是否有错误。同样,在你的代码中,如果你传入矩阵,然后不使用它进行任何操作(打印除外)正如您已经注释掉了行tmpMatrix=matrix
。这是正确的还是仅仅是一个打字错误?代码< >代码>矩阵>代码>和/或<代码> TMPMatrix (即<代码> LHS < /C>和/或<代码> RES <代码>)在C++代码中初始化?谢谢注意。在试图修复时,我注释掉了该行。使用该线路时,dgetrf和dgetri调用该线路。谢谢!