在C ++程序中调用时,Fortran子例程会提供错误的结果

时间:2016-07-22 12:49:00

标签: fortran inverse

我必须写一个返回逆矩阵的Fortran例程。如果我在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);

我的程序只使用3x3矩阵。如果我传递单位矩阵,结果如下:

5.29981e-315 0 0 
0 1 0 
0 0 1 

1 个答案:

答案 0 :(得分:4)

您正在将类型real声明为类型c_double,但您正在使用期望单精度输入的lapack例程(例如c_float)。要解决此问题,您应该使用sgetrfsgetri替换对dgetrfdgetri的来电。

正如Vladimir F在评论中所指出的,如果你提供接口,这些问题就更容易被抓住了。