Inverse matrix in fortran mexFunction - matlab lapack library
Mostrar comentarios más antiguos
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 comentario
Muthu Annamalai
el 24 de Jun. de 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.
Respuesta aceptada
Más respuestas (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 comentarios
Tue
el 24 de Jun. de 2013
Muthu Annamalai
el 24 de Jun. de 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.
Categorías
Más información sobre Fortran Source MEX Files en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!