So apparently the problem was that when calling Lapack functions in MEX all the input indices should be of type "mwSignedIndex" instead of "int".This successfully solved the problem. I found this while trying to find a solution, however I don't know exactly why can someone explain ?!
SVD of a complex matrix in Matlab's MEX interface
4 views (last 30 days)
Show older comments
Hello, I have been trying to implement a MEX function to calculate the pseudo inverse of a complex matrix and when looking for the best technique to implement this I came upon the proposed C algorithm by JULIEN LANGOU in the following thread
the above proposed algorithm in my understanding comprises of three steps: 1) Calculate the SVD. 2) calculating the inverse of S 3) calculating the inverse which is (V * S^(-1) * U^H)
I encountered a problem while trying to calculate the SVD using the "zgesvd" function as the pre-allocated random valued matrices S,VT,U values' don't change after calling the "zgesvd" function, I don't fully understand why this happens as this is actually my first time using C-MEX. my code is as follows:
if true
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *A, *PINV; /* pointers to input & output matrices*/
int M,N; /* matrix dimensions */
M = (int)mxGetM(prhs[0]);
N = (int)mxGetN(prhs[0]);
A = (double*)mat2fort(prhs[0], M, N);
PINV = mxMalloc(2*N*M*sizeof(*PINV));
/* dimensions of input matrices */
int K, L, LDA, LDAxN;
int LDU, LDVT, LWORK, INFO;
char JOBU, JOBVT;
mxArray *temp1, *temp2, *temp3;
double *S, *U, *VT, *WORK, *RWORK ;
K = M < N ? M : N;
L = M > N ? M : N;
LDA = M;
LDAxN = LDA * N;
LDU = M;
LDVT = K;
JOBU = 'S';
JOBVT = 'S';
LWORK = 1 > 2*K+L ? 1 : 2*K+L;
S = (double * )mxMalloc(1*K*sizeof(double));
U = (double * )mxMalloc(2*LDU*K*sizeof(double));
VT = (double * )mxMalloc(2*LDVT*K*sizeof(double));
WORK = (double * )mxMalloc(2*1*LWORK*sizeof(double));
RWORK = (double * )mxMalloc(1*5*K*sizeof(double));
/* Compute the SVD of input matrix */
zgesvd( &JOBU, &JOBVT, &M, &N, A, &LDA, S, U, &LDU, VT, &LDVT, WORK, &LWORK, RWORK, &INFO );
temp1 = fort2mat(U, LDU, LDU, K);
temp2 = mxCreateDoubleMatrix(1,K,mxREAL);
double * temp2R = mxGetPr(temp2);
for( int i=0; i< K; i++ ) {
*temp2R++ = *S++;
}
temp3 = fort2mat(VT, LDVT, LDVT, K);
plhs[0] = temp1;
plhs[1] = temp2;
plhs[2] = temp3;
} end
Any help regarding this problem would be much appreciated and also if you have any other suggestions to implement the pseudo inverse in MEX and many thanks in advance.
0 Comments
Answers (1)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!