From: Samuel on 14 Jul 2010 22:54 Hello ! I am trying to optimize a clustering algorithm using MEX/cpp. It is the first time that I use mex, but I have done some cpp and some matlab before. Here is the problem : while in cpp file, I want to use the mexCallMATLAB function in order to use built in function such as inv() and det(). I can get the code to compile and transfer arrays of the correct size, but the arrays seems to be empty (zeros) : Here's the code, if anyone can finds the trouble, or direct me to information (I have looked a lot but have not find the same problem in other topics) it would be really appreciated, I have looked at it a lot and do not know what to do: /******************************************************/ // The mex file : void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //declare variables mxArray *k_m, *tab_m, *muInit_m, *maxIter_m, *mask_m, *mu_m, *covMat_m, *prop_m; const int *dims; double *tab, *muInit, *mu, *prop, *covMat; int k, maxIter,*mask; int nbPixTot, nb, numdims; int i,j; //associate inputs k_m = mxDuplicateArray(prhs[0]); tab_m = mxDuplicateArray(prhs[1]); muInit_m = mxDuplicateArray(prhs[2]); maxIter_m = mxDuplicateArray(prhs[3]); //figure out dimensions dims = mxGetDimensions(prhs[1]); numdims = mxGetNumberOfDimensions(prhs[1]); nb = (int)dims[1]; nbPixTot = (int)dims[0]; //associate pointers input k = (int)mxGetScalar(k_m); tab = mxGetPr(tab_m); muInit = mxGetPr(muInit_m); maxIter = (int)mxGetScalar(maxIter_m); //associate outputs mask_m = plhs[0] = mxCreateNumericMatrix(nbPixTot,1, mxINT32_CLASS, mxREAL); mu_m = plhs[1] = mxCreateDoubleMatrix(k,nb,mxREAL); covMat_m = plhs[2] = mxCreateDoubleMatrix(k,nb*nb,mxREAL); prop_m = plhs[3] = mxCreateDoubleMatrix(k,1,mxREAL); //associate pointers output mask = (int*) mxGetData(mask_m); mu = mxGetPr(mu_m); covMat = mxGetPr(covMat_m); prop = mxGetPr(prop_m); // calculate different things: calcMask(mask, tab, muInit, k, nb, nbPixTot); calcProp(mask, prop,k, nbPixTot); calcCovMat(covMat, tab, muInit, mask, k,nbPixTot, nb); .... /*************************************************************/ mxArray *sortie[2]; // Should I initialize my output mxArray ? sortie[1] = mxCreateDoubleMatrix(k, nb*nb, mxREAL); sortie[2] = mxCreateDoubleMatrix(k, 1, mxREAL); /* double *invCovMatP = mxGetPr(sortie[1]); double *detCovMatP = mxGetPr(sortie[2]); */ // With that line, the input is ok, but the output is only zeros mexCallMATLAB(2, sortie, 1, &plhs[2], "invAndDet"); /* But, I don't understant why that line is not equivalent : mexCallMATLAB(2, sortie, 1, &covMat_m, "invAndDet"); */ // Should I do that before or after the mexCallMATLAB double *invCovMatP = mxGetPr(sortie[1]); double *detCovMatP = mxGetPr(sortie[2]); for (int i =0; i<k ; i++) { mexPrintf("detMat : %f\n", detCovMatP[i]); } return; } /****************************************************/ // The m file I am trying to use : function [inverseMatrix detOfMatrix] = invAndDet(covMat); [k, nb] = size(covMat); nb =sqrt(nb); inverseMatrix = 0*covMat; detOfMatrix = zeros(k,1); for i = 1:k matrixTemp = reshape(covMat(i,:),nb,nb); invTemp = inv(matrixTemp); inverseMatrix(i,:) = reshape(invTemp,1,nb*nb); detOfMatrix(i) = det(matrixTemp); end; return; /*******************************************************/ Having used the debugger, I know that the results are not zeros inside the m-file, but it looks like I can't get them back in the cpp file. It might have to do with pointers since I have not used them often yet. Thanks to anyone that could help me or give me a link with some information ! Samuel
From: James Tursa on 15 Jul 2010 01:31 "Samuel " <sam030(a)gmail.com> wrote in message <i1lt8d$3gk$1(a)fred.mathworks.com>... > > /*************************************************************/ > mxArray *sortie[2]; > > // Should I initialize my output mxArray ? > sortie[1] = mxCreateDoubleMatrix(k, nb*nb, mxREAL); > sortie[2] = mxCreateDoubleMatrix(k, 1, mxREAL); > /* double *invCovMatP = mxGetPr(sortie[1]); > double *detCovMatP = mxGetPr(sortie[2]); No. You should not initialize the sortie array. Doing so simply creates a memory leak since the downstream mexCallMATLAB will wipe out the contents of sortie and you will lose your pointers to the mxArrays you just created. Besides, you are using the wrong indexing anyway (should be [0] and [1], not [1] and [2]). > double *invCovMatP = mxGetPr(sortie[1]); > double *detCovMatP = mxGetPr(sortie[2]); Wrong indexing again. Should be [0] and [1], not [1] and [2]. I'm surprised you didn't crash MATLAB since you are corrupting memory. I haven't had time to look at the rest of your code in detail yet. But at least you can fix this up right away. James Tursa
From: Samuel on 15 Jul 2010 06:41 "James Tursa" <aclassyguy_with_a_k_not_a_c(a)hotmail.com> wrote in message <i1m6eo$l51$1(a)fred.mathworks.com>... > "Samuel " <sam030(a)gmail.com> wrote in message <i1lt8d$3gk$1(a)fred.mathworks.com>... > > > > /*************************************************************/ > > mxArray *sortie[2]; > > > > // Should I initialize my output mxArray ? > > sortie[1] = mxCreateDoubleMatrix(k, nb*nb, mxREAL); > > sortie[2] = mxCreateDoubleMatrix(k, 1, mxREAL); > > /* double *invCovMatP = mxGetPr(sortie[1]); > > double *detCovMatP = mxGetPr(sortie[2]); > > No. You should not initialize the sortie array. Doing so simply creates a memory leak since the downstream mexCallMATLAB will wipe out the contents of sortie and you will lose your pointers to the mxArrays you just created. Besides, you are using the wrong indexing anyway (should be [0] and [1], not [1] and [2]). > > > double *invCovMatP = mxGetPr(sortie[1]); > > double *detCovMatP = mxGetPr(sortie[2]); > > Wrong indexing again. Should be [0] and [1], not [1] and [2]. I'm surprised you didn't crash MATLAB since you are corrupting memory. > > I haven't had time to look at the rest of your code in detail yet. But at least you can fix this up right away. > > James Tursa Thank you for your time. Of course you are right about the indexing ! Having done only matlab programming in the last two months or so I tried to be careful about indexing, but I did not catch this mistake. I will look again with this mistake corrected and see if things work now. I'll give you feedback once it is done. Thanks again, Samuel
From: Samuel on 15 Jul 2010 08:12 "Samuel " <sam030(a)gmail.com> wrote in message <i1mok8$rv$1(a)fred.mathworks.com>... > "James Tursa" <aclassyguy_with_a_k_not_a_c(a)hotmail.com> wrote in message <i1m6eo$l51$1(a)fred.mathworks.com>... > > "Samuel " <sam030(a)gmail.com> wrote in message <i1lt8d$3gk$1(a)fred.mathworks.com>... > > > > > > /*************************************************************/ > > > mxArray *sortie[2]; > > > > > > // Should I initialize my output mxArray ? > > > sortie[1] = mxCreateDoubleMatrix(k, nb*nb, mxREAL); > > > sortie[2] = mxCreateDoubleMatrix(k, 1, mxREAL); > > > /* double *invCovMatP = mxGetPr(sortie[1]); > > > double *detCovMatP = mxGetPr(sortie[2]); > > > > No. You should not initialize the sortie array. Doing so simply creates a memory leak since the downstream mexCallMATLAB will wipe out the contents of sortie and you will lose your pointers to the mxArrays you just created. Besides, you are using the wrong indexing anyway (should be [0] and [1], not [1] and [2]). > > > > > double *invCovMatP = mxGetPr(sortie[1]); > > > double *detCovMatP = mxGetPr(sortie[2]); > > > > Wrong indexing again. Should be [0] and [1], not [1] and [2]. I'm surprised you didn't crash MATLAB since you are corrupting memory. > > > > I haven't had time to look at the rest of your code in detail yet. But at least you can fix this up right away. > > > > James Tursa > > > Thank you for your time. > > Of course you are right about the indexing ! Having done only matlab programming in the last two months or so I tried to be careful about indexing, but I did not catch this mistake. > > I will look again with this mistake corrected and see if things work now. I'll give you feedback once it is done. > > Thanks again, > > Samuel Ok, so I've tested with the corrected indxing for the output (sortie) and it is now working. As for the input problem I had, it now seems to be gone... Thanks again for your time, I'm gonna be able to continue my work now Samuel
|
Pages: 1 Prev: mat file to pascal program Next: Cut out a circle in an image |