Inverse matrix in fortran mexFunction - matlab lapack library
Show older comments
I am trying to use LAPACK to invert a matrix in Fortran through mex. Depending on the matrix dimension Matlab crashes. E.g. for Hin=diag(1:3);[T1]=TestInvMex(int32(1),Hin) gives correct answer. Hin=diag(1:6);[T1]=TestInvMex(int32(1),Hin) crashes. Matlab version 2012b on linux. My code TestInvMex.F90:
#include "fintrf.h"
!======================================================================
! mex -v -largeArrayDims TestInvMex.F90 -output TestInvMex FOPTIMFLAGS='-O3' -lmwlapack -lmwblas
!======================================================================
! Gateway routine
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
! Declarations
implicit none
! mexFunction arguments:
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
! Function declarations:
mwPointer mxCreateDoubleMatrix, mxGetPr, mxGetPi
integer mxIsNumeric
! mwPointer mxGetM, mxGetN, mxIsInt8, mxIsInt32
mwSignedIndex mxGetM, mxGetN, mxIsInt8, mxIsInt32
! Pointers to input/output mxArrays:
mwPointer mode_pr, H_RE_pr, H_IM_pr, Hinv_RE_pr, Hinv_IM_pr
! Array information:
! mwsize m, n
mwSignedIndex m, n
! Define variables - Arguments for computational routine:
integer, parameter :: dp=SELECTED_REAL_KIND(15) ! dp=15 digits, sp->6 instead.
integer, parameter :: I32=SELECTED_INT_KIND(15) ! INT64=15, INT32=6.
mwSignedIndex,parameter :: myOne=1,myTwo=2,myFour=4
INTEGER(I32) :: mode
COMPLEX(dp), DIMENSION(:,:), ALLOCATABLE :: H
COMPLEX(dp), DIMENSION(:,:), ALLOCATABLE :: Hinv
COMPLEX(dp), DIMENSION(:), ALLOCATABLE :: work ! work array for LAPACK
integer :: info
integer, DIMENSION(:), ALLOCATABLE :: ipiv ! pivot indices
! Get the size of the input arrays (m rows, n collums).
m = mxGetM(prhs(2))
n = mxGetN(prhs(2))
! Allocate:
ALLOCATE(H(m,n),Hinv(m,n),work(m),ipiv(m))
! Create matrix for the return argument. NB:1 to have complex elements
plhs(1) = mxCreateDoubleMatrix(m,n,1)
Hinv_RE_pr = mxGetPr(plhs(1))
Hinv_IM_pr = mxGetPi(plhs(1))
! Input:
mode_pr = mxGetPr(prhs(1))
H_RE_pr = mxGetPr(prhs(2))
H_IM_pr = mxGetPi(prhs(2))
! Load the data into Fortran arrays.
call mxCopyPtrToComplex16(H_RE_pr,H_IM_pr,H,m*n)
call mxCopyPtrToInteger4(mode_pr,mode,myOne)
! Compute inverse:
Hinv=H ! prevent H from being overwritten by LAPACK
call ZGETRF(n, n, Hinv, n, ipiv, info) ! Complex dp
call ZGETRI(n, Hinv, n, ipiv, work, n, info) ! Complex dp
! Load the data into the output to MATLAB.
call mxCopyComplex16ToPtr(Hinv,Hinv_RE_pr,Hinv_IM_pr,m*n)
return
end
1 Comment
Muthu Annamalai
on 24 Jun 2013
Have you run it on a debugger and gotten a stack trace? It seems to me like you are having a memory issue here.
Accepted Answer
More Answers (1)
Hi don't know anything with fortran.
1) From my experience, every time I used LAPACK I checked info.
2) What is the type of your matrix (general, symmetric positive-definite..), I see it complex.
3) And the big question WHY DO YOU WANT TO FIND INV ?? I am sure you do not need to do that ! Use Factorize matrix like ZGETRF and then Solve system like ZGETRS.
4) ZGETRF and ZGETRS depend on the type of your matrix.
5) Check this line: plhs(1) = mxCreateDoubleMatrix(m,n,1). m != n !?!?
2 Comments
Tue
on 24 Jun 2013
Muthu Annamalai
on 24 Jun 2013
Zohar means that your matrix maybe ill-conditioned, i.e. your det(A) \approxly 0, and inverse could be troublesome. Using LU, factoriazation and other associated transform methods are more reliable.
Categories
Find more on Fortran Source MEX Files in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!