From: Aino on 4 Aug 2010 20:11 Hi all! I have tried to speed up my Matlab code (parfor was not enough to do that..) and now decided to try with mex-file. Turned out to be a bit challenging.. The code below gives 12 error messages, all "type error: pointer expected". But I feel like I have a pointer to all of my variables. So, is there something wrong with the way I'm using the mxCalloc-function, have I understood it completely wrong? Also in m-files I could use a statement such as: a=A(1:3), do I really need to use for loops in here (loops ii and jj in my code)? In my code, cop is a column vector, M is a scalar integer, and r and c are scalars (type double). I am starting to wonder if this mex-file will ever speed my code, which is something I need to do (regardless of my ability to do that.. ;) ). Any comments (also the ones that do not concern the pointer problem) are appreciated! Thank You so much, Aino #include <math.h> #include "mex.h" /*Subroutine to calculate the Fuzzy Sample Entropy*/ void FSE(double *cop, int M, double r, double c, mwSize N, double *FuzzSampEnt) { mwSize m, i, ii, j, jj, k, l; int *countii, *countjj; double *expo, *d, *seg_i, *seg_j, *count, *sumCim, *Cim, *CIM; expo=mxCalloc(1,sizeof(double)); d=mxCalloc(1,sizeof(double)); count=mxCalloc(1,sizeof(double)); sumCim=mxCalloc(1,sizeof(double)); countii=mxCalloc(1,sizeof(int)); countjj=mxCalloc(1,sizeof(int)); CIM=mxCalloc(2,sizeof(double)); *expo=(log(log(pow(2, c)))/log(r)); for (m=M;m<M+2;m++) { seg_i=mxCalloc(m, sizeof(double)); seg_j=mxCalloc(m, sizeof(double)); Cim=mxCalloc(N-m, sizeof(double)); for (i=0; i<N-m; i++) { *count=0; *countii=-1; for (ii=i; ii<i+m; ii++){ *countii=*countii++; *seg_i[*countii]=cop[ii]; } for (j=0; j<N-m; j++) { *countjj=-1; for (jj=j; jj<j+m; jj++) { *countjj=*countjj++; *seg_j[*countjj]=cop[jj]; } *d=0; /*Finding the maximum absolut value of seg_i-seg_j*/ for (k=0; k<N; k++) { if (*d < abs(*seg_i[k]-*seg_j[k])) { *d=abs(*seg_i[k]-*seg_j[k]); } } /*if d=0, self match*/ if (*d>0) { *count+=exp(-(pow(*d, *expo/c))); } } *Cim[i]=*count/(N-m-1); } *sumCim=0; for(l=0;l<N-m;l++){ *sumCim+=*Cim[l]; } if (m==M){ *CIM[0]=*sumCim/(N-m); } else if (m==M+1){ *CIM[1]=*sumCim/(N-m); } } *FuzzSampEnt=-log(*CIM[1]/ *CIM[0]); mxFree(seg_i); mxFree(seg_j); mxFree(Cim); mxFree(expo); mxFree(CIM); mxFree(count); mxFree(d); } /*the gateway function*/ void mexFunction(int nlhs, mxArray *plhs[ ], int nrhs, const mxArray *prhs[ ]) { int M; double *cop, *FuzzSampEnt; double c, r; mwSize N; if(nrhs!=4) { mexErrMsgTxt("Four inputs required (cop,M,r,c)."); } /*Assign pointers*/ cop=mxGetPr(prhs[0]); N=mxGetM(prhs[0]);//Not sure if this should be mxGetN M=(int)(mxGetScalar(prhs[1])); r=mxGetScalar(prhs[2]); c=mxGetScalar(prhs[3]); plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); FuzzSampEnt = mxGetPr(plhs[0]); /*Call the subroutine */ FSE(cop, M, r, c, N, FuzzSampEnt); return; }
From: Aino on 4 Aug 2010 22:14 I forgot, here are the lines where the pointer errors are found. -Aino #include <math.h> #include "mex.h" /*Subroutine to calculate the Fuzzy Sample Entropy*/ void FSE(double *cop, int M, double r, double c, mwSize N, double *FuzzSampEnt) { mwSize m, i, ii, j, jj, k, l; int *countii, *countjj; double *expo, *d, *seg_i, *seg_j, *count, *sumCim, *Cim, *CIM; expo=mxCalloc(1,sizeof(double)); d=mxCalloc(1,sizeof(double)); count=mxCalloc(1,sizeof(double)); sumCim=mxCalloc(1,sizeof(double)); countii=mxCalloc(1,sizeof(int)); countjj=mxCalloc(1,sizeof(int)); CIM=mxCalloc(2,sizeof(double)); *expo=(log(log(pow(2, c)))/log(r)); for (m=M;m<M+2;m++) { seg_i=mxCalloc(m, sizeof(double)); seg_j=mxCalloc(m, sizeof(double)); Cim=mxCalloc(N-m, sizeof(double)); for (i=0; i<N-m; i++) { *count=0; *countii=-1; for (ii=i; ii<i+m; ii++){ *countii=*countii++; *seg_i[*countii]=cop[ii];//ERROR } for (j=0; j<N-m; j++) { *countjj=-1; for (jj=j; jj<j+m; jj++) { *countjj=*countjj++; *seg_j[*countjj]=cop[jj];//ERROR } *d=0; /*Finding the maximum absolut value of seg_i-seg_j*/ for (k=0; k<N; k++) { if (*d < abs(*seg_i[k]-*seg_j[k])) {//ERROR x 2 *d=abs(*seg_i[k]-*seg_j[k]);//ERROR x 2 } } /*if d=0, self match*/ if (*d>0) { *count+=exp(-(pow(*d, *expo/c))); } } *Cim[i]=*count/(N-m-1);//ERROR } *sumCim=0; for(l=0;l<N-m;l++){ *sumCim+=*Cim[l];//ERROR } if (m==M){ *CIM[0]=*sumCim/(N-m);//ERROR } else if (m==M+1){ *CIM[1]=*sumCim/(N-m);//ERROR } } *FuzzSampEnt=-log(*CIM[1]/ *CIM[0]);//ERROR x 2 mxFree(seg_i); mxFree(seg_j); mxFree(Cim); mxFree(expo); mxFree(CIM); mxFree(count); mxFree(d); } /*the gateway function*/ void mexFunction(int nlhs, mxArray *plhs[ ], int nrhs, const mxArray *prhs[ ]) { int M; double *cop, *FuzzSampEnt; double c, r; mwSize N; if(nrhs!=4) { mexErrMsgTxt("Four inputs required (cop,M,r,c)."); } /*Assign pointers*/ cop=mxGetPr(prhs[0]); N=mxGetM(prhs[0]); M=(int)(mxGetScalar(prhs[1])); r=mxGetScalar(prhs[2]); c=mxGetScalar(prhs[3]); plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); FuzzSampEnt = mxGetPr(plhs[0]); /*Call the subroutine */ FSE(cop, M, r, c, N, FuzzSampEnt); return; }
From: Aino on 4 Aug 2010 23:26 Hi again, I cleaned up the code a little bit, now it compiles (I had to change several variables *var[i]->var[i], I guess that asterisk does not always have to be there). It still doesn't do what it is supposed to, though, something wrong with the seg_i and seg_j variables.. Need to continue tomorrow.. -Aino #include <math.h> #include "mex.h" /*Subroutine to calculate the Fuzzy Sample Entropy*/ void FSE(double *cop, int M, double r, double c, mwSize N, double *FuzzSampEnt) { mwIndex m, i, ii, j, jj, k, l; double *expo, *d, *seg_i, *seg_j, *count, *sumCim, *Cim, *CIM; expo=mxCalloc(1,sizeof(double)); d=mxCalloc(1,sizeof(double)); count=mxCalloc(1,sizeof(double)); sumCim=mxCalloc(1,sizeof(double)); CIM=mxCalloc(2,sizeof(double)); *expo=(log(log(pow(2, c)))/log(r)); for (m=M;m<M+2;m++) { seg_i=mxCalloc(m, sizeof(double)); seg_j=mxCalloc(m, sizeof(double)); Cim=mxCalloc(N-m, sizeof(double)); for (i=0; i<N-m; i++) { *count=0; for (ii=0; ii<m; ii++){ seg_i[ii]=cop[i+ii]; } for (j=0; j<N-m; j++) { for (jj=0; jj<m; jj++) { seg_j[jj]=cop[j+jj]; } *d=0; /*Finding the maximum absolut value of seg_i-seg_j*/ for (k=0; k<m; k++) { if (*d < abs(seg_i[k]-seg_j[k])) { *d=abs(seg_i[k]-seg_j[k]); } } /*if d=0, self match*/ if (*d>0) { *count+=exp(-(pow(*d, *expo/c))); } } Cim[i]=*count/(N-m-1); } *sumCim=0; for(l=0;l<N-m;l++){ *sumCim+=Cim[l]; } if (m==M){ CIM[0]=*sumCim/(N-m); } else if (m==M+1){ CIM[1]=*sumCim/(N-m); } } *FuzzSampEnt=-log(CIM[1]/ CIM[0]); mxFree(seg_i); mxFree(seg_j); mxFree(Cim); mxFree(expo); mxFree(CIM); mxFree(count); mxFree(d); } /*the gateway function*/ void mexFunction(int nlhs, mxArray *plhs[ ], int nrhs, const mxArray *prhs[ ]) { int M; double *cop, *FuzzSampEnt; double c, r; mwSize N; if(nrhs!=4) { mexErrMsgTxt("Four inputs required (cop,M,r,c)."); } /*Assign pointers*/ cop=mxGetPr(prhs[0]); N=mxGetM(prhs[0]); M=(int)(mxGetScalar(prhs[1])); r=mxGetScalar(prhs[2]); c=mxGetScalar(prhs[3]); plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); FuzzSampEnt = mxGetPr(plhs[0]); /*Call the subroutine */ FSE(cop, M, r, c, N, FuzzSampEnt); return; }
From: James Tursa on 4 Aug 2010 23:37 "Aino" <aino.tietavainen(a)removeThis.helsinki.fi> wrote in message <i3d6pc$5rd$1(a)fred.mathworks.com>... > > double *expo, *d, *seg_i, *seg_j, *count, *sumCim, *Cim, *CIM; > > expo=mxCalloc(1,sizeof(double)); > d=mxCalloc(1,sizeof(double)); > count=mxCalloc(1,sizeof(double)); > sumCim=mxCalloc(1,sizeof(double)); > countii=mxCalloc(1,sizeof(int)); > countjj=mxCalloc(1,sizeof(int)); > CIM=mxCalloc(2,sizeof(double)); Why the heck are you doing this??? What is the point of declaring these as pointers and then allocating them to size 1 or 2? Why not just declare them as scalars or arrays of length 2 and be done with it? I don't understand this unnecessary complication. (snip) > *seg_i[*countii]=cop[ii];//ERROR OK. So just follow the syntax to see what is going on. seg_i is type (double *). Then the brackets [ ] come next, and that dereferences seg_i, so the type of seg_i[*countii] is (double). So next comes the * dereference operator. So when the compiler sees *seg_i[*countii] it means you are trying to dereference something of type (double), which of course makes no sense, so you get a compiler error. You repeat this problem over and over again in your code. You have a fundamental misunderstanding of the use of pointers and dereferencing them via the * and [ ] operators. When looking at this type of syntax, basically follow these rules: Do everything inside any parentheses first ( ) Then do any [ ] dereferencing Then do any * dereferencing You might want to consult a good C/C++ text or look online for some tutorials. James Tursa
From: Aino on 5 Aug 2010 10:50
Dear Mr. Tursa, thank you for your useful comments! "James Tursa" <aclassyguy_with_a_k_not_a_c(a)hotmail.com> wrote in message <i3dbl0$907$1(a)fred.mathworks.com>... > "Aino" <aino.tietavainen(a)removeThis.helsinki.fi> wrote in message <i3d6pc$5rd$1(a)fred.mathworks.com>... > > > > double *expo, *d, *seg_i, *seg_j, *count, *sumCim, *Cim, *CIM; > > > > expo=mxCalloc(1,sizeof(double)); > > d=mxCalloc(1,sizeof(double)); > > count=mxCalloc(1,sizeof(double)); > > sumCim=mxCalloc(1,sizeof(double)); > > countii=mxCalloc(1,sizeof(int)); > > countjj=mxCalloc(1,sizeof(int)); > > CIM=mxCalloc(2,sizeof(double)); > > Why the heck are you doing this??? What is the point of declaring these as pointers and then allocating them to size 1 or 2? Why not just declare them as scalars or arrays of length 2 and be done with it? I don't understand this unnecessary complication. I read somewhere that the pointers are the most difficult part in C to understand so I tried to look at examples that used them. Maybe I looked at too many.. End of my post is another code where I have tried to get rid of these mxCallocs. > > (snip) > > > *seg_i[*countii]=cop[ii];//ERROR > > OK. So just follow the syntax to see what is going on. seg_i is type (double *). Then the brackets [ ] come next, and that dereferences seg_i, so the type of seg_i[*countii] is (double). So next comes the * dereference operator. So when the compiler sees *seg_i[*countii] it means you are trying to dereference something of type (double), which of course makes no sense, so you get a compiler error. You repeat this problem over and over again in your code. I think I didn't realize that brackets dereference. I got rid of them already in my previous post. > > You have a fundamental misunderstanding of the use of pointers and dereferencing them via the * and [ ] operators. Agreed. When looking at this type of syntax, basically follow these rules: > > Do everything inside any parentheses first ( ) > Then do any [ ] dereferencing > Then do any * dereferencing > > You might want to consult a good C/C++ text or look online for some tutorials. I am going to a book store hopefully today, my problem is not so much laziness but lack of time (I guess I'm not the only one). I am trying to get the code to calculate my results ASAP so that I have any possibility to meet my DL. > > > James Tursa So below is my code as it is now. I left the seg_i, seg_j and Cim as they were previously (I tried to declare them as arrays of size M+1 or N-M as "double seg_i[M+1], seg_j[M+1], Cim[N-M];", but this just created new errors). It compiles, but doesn't still work as it should. I believe the problem lies in here: seg_i[ii]=cop[i+ii];//TROUBLE, and more particularly in the left hand side (so again pointer stuff..). I don't understand why seg_i is not getting the cop[i+ii]-value in ii. Is it so that I am now trying to put double (cop[i+ii]) in to a double (seg_i[ii])? If so, I cannot figure out how to get around it. I know this must seen trivial to you, but I am really stuck here.. Thank you, Aino #include <math.h> #include "mex.h" /*Subroutine to calculate the Fuzzy Sample Entropy*/ void FSE(double *cop, int M, double r, double c, mwSize N, double *FuzzSampEnt) { mwIndex m, i, ii, j, jj, k, l; double expo, d, *seg_i, *seg_j, count, sumCim, *Cim, CIM[2]; expo=(log(log(pow(2, c)))/log(r)); for (m=M;m<M+2;m++) { seg_i=mxCalloc(m, sizeof(double)); seg_j=mxCalloc(m, sizeof(double)); Cim=mxCalloc(N-m, sizeof(double)); for (i=0; i<N-m; i++) { count=0; for (ii=0; ii<m; ii++){ seg_i[ii]=cop[i+ii];//TROUBLE? } for (j=0; j<N-m; j++) { for (jj=0; jj<m; jj++) { seg_j[jj]=cop[j+jj];//TROUBLE? } d=0; /*Finding the maximum absolut value of seg_i-seg_j*/ for (k=0; k<m; k++) { if (d < fabs(seg_i[k]-seg_j[k])) { d=fabs(seg_i[k]-seg_j[k]); } } /*if d=0, self match*/ if (d>0) { count+=exp(-(pow(d, expo/c))); } } Cim[i]=count/(N-m-1);//MORE TROUBLE? } sumCim=0; for(l=0;l<N-m;l++){ sumCim+=Cim[l]; } if (m==M){ CIM[0]=sumCim/(N-m); } else if (m==M+1){ CIM[1]=sumCim/(N-m); } } *FuzzSampEnt=-log(CIM[1]/ CIM[0]); mxFree(seg_i); mxFree(seg_j); mxFree(Cim); } /*the gateway function*/ void mexFunction(int nlhs, mxArray *plhs[ ], int nrhs, const mxArray *prhs[ ]) { int M; double *cop, *FuzzSampEnt; double c, r; mwSize N; if(nrhs!=4) { mexErrMsgTxt("Four inputs required (cop,M,r,c)."); } /*Assign pointers*/ cop=mxGetPr(prhs[0]); N=mxGetM(prhs[0]); M=(int)(mxGetScalar(prhs[1])); r=mxGetScalar(prhs[2]); c=mxGetScalar(prhs[3]); plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); FuzzSampEnt = mxGetPr(plhs[0]); /*Call the subroutine */ FSE(cop, M, r, c, N, FuzzSampEnt); return; } |