Resultant matrix is rotated 90 whether I use MEX or MatLab function
조회 수: 2 (최근 30일)
이전 댓글 표시
Dear all,
I am puzzled by something odd. I have written a MEX function using C of a Matlab function that contains 2 nested loops to calculate stress on a 2D grid.
The inputs of the MEX function and Matlab function are identical and are in the form of a 1D array (of the 2D grid).
The outputs of the MEX function and the Matlab function are not identical in the sense that if I reshape into a 2D array using reshape(answer,m,n) and surf() I get that the MEX and Matlab answers are rotated by 90 degrees!
I literally copy and pasted the C function into Matlab, so I am 99% certain that there are no computational differences (apart from the minor changes like brackets etc.)
My code is structured as follows:
for (coord=0; coord<N; coord++) {
for (seg=0; seg<S; seg++) {
...accessing arrays with index coord: px,py,pz
...accessing arrays with index seg: p1x,p1y,p1z,p2x,p2y,p2z,bx,by,bz
sxx[coord] += ...maths
}
}
Similarly in Matlab,
for coord=1:N
for seg=1:S
...accessing arrays with index coord: px,py,pz
...accessing arrays with index seg: p1x,p1y,p1z,p2x,p2y,p2z,bx,by,bz
sxx(coord) = sxx(coord) + ...maths
end
end
Both functions have the same identical nomenclature and variable order. I use the same input arrays in the workspace, and yet the 2D grids after reshape are rotated!
My mexFunction for the C code is: void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int N,S; double *px,*py,*pz; double *p1x,*p1y,*p1z,*p2x,*p2y,*p2z; double *bx,*by,*bz; double a,MU,NU; double *sxx,*syy,*szz,*sxy,*syz,*sxz; int i;
//get the scalar inputs N,S,a,MU,NU
//create pointers to the input matrices
N=mxGetScalar(prhs[0]);
S=mxGetScalar(prhs[1]);
px=(double *) mxGetPr(prhs[2]);
py=(double *) mxGetPr(prhs[3]);
pz=(double *) mxGetPr(prhs[4]);
p1x=(double *) mxGetPr(prhs[5]);
p1y=(double *) mxGetPr(prhs[6]);
p1z=(double *) mxGetPr(prhs[7]);
p2x=(double *) mxGetPr(prhs[8]);
p2y=(double *) mxGetPr(prhs[9]);
p2z=(double *) mxGetPr(prhs[10]);
bx=(double *) mxGetPr(prhs[11]);
by=(double *) mxGetPr(prhs[12]);
bz=(double *) mxGetPr(prhs[13]);
a=mxGetScalar(prhs[14]);
MU=mxGetScalar(prhs[15]);
NU=mxGetScalar(prhs[16]);
//call the output pointer to the output matrix
plhs[0]=mxCreateDoubleMatrix(N,1,mxREAL);
plhs[1]=mxCreateDoubleMatrix(N,1,mxREAL);
plhs[2]=mxCreateDoubleMatrix(N,1,mxREAL);
plhs[3]=mxCreateDoubleMatrix(N,1,mxREAL);
plhs[4]=mxCreateDoubleMatrix(N,1,mxREAL);
plhs[5]=mxCreateDoubleMatrix(N,1,mxREAL);
//create a C pointer to a copy of the output matrix
sxx=(double *) mxGetPr(plhs[0]);
syy=(double *) mxGetPr(plhs[1]);
szz=(double *) mxGetPr(plhs[2]);
sxy=(double *) mxGetPr(plhs[3]);
syz=(double *) mxGetPr(plhs[4]);
sxz=(double *) mxGetPr(plhs[5]);
//call the C subroutine
StressDueToSeg(N,S, px, py, pz,p1x, p1y, p1z,
p2x, p2y, p2z, bx, by, bz,
a, MU, NU,
sxx, syy, szz, sxy, syz, sxz);
}
I wonder whether some kind of indexing difference in the mexFunction leads to this problem? I know I could just rotate the answer by 90 degrees, but seeing as I want to use the MEX function to speed up my computation, rotating large 2D arrays doesn't sound very efficient.
Thank you,
Kind Regards,
F
댓글 수: 0
답변 (2개)
James Tursa
2013년 7월 30일
It is the code that you don't show that is likely at the heart of the problem ... the indexing you use and how it relates to the mxArray variables you are passing in and returning to the workspace. E.g., are any of your inputs 2D? If so, how do you index into them in your mex function? Can you show us the actual indexing code?
dpb
2013년 7월 30일
편집: dpb
2013년 7월 30일
Matlab and C differ in internal storage order--Matlab is column major whereas C is row major. IOW, the first index in 2D array in Matlab goes down the first column whereas in C the same index traverses the first row.
The result you see is directly the result of that. For speed you want to operate on arrays in linear memory order so you would reorder the indices between the two languages to make that happen. So, in the C mex-function, order the array loops to traverse by row.
댓글 수: 7
dpb
2013년 7월 31일
편집: dpb
2013년 8월 2일
OK, I did paste the code into an editor so could pare it down to the essence--
The problem has to be as IA says in what you haven't shown...the declarations and calling sequences and how you then manipulated the results.
You've somehow transposed the data before going into the routine (the round translucent orb tells me... :) )
Shows us the minimum steps you used to illustrate the problem from the start...specifically, the form/shape of the input and all steps prior to and including the call and then any manipulations afterwards up until the point at which you think there's a problem (for both solutions, of course).
참고 항목
카테고리
Help Center 및 File Exchange에서 Conway's Game of Life에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!