Convert Matlab function to Mex file - For loop conversion
조회 수: 10 (최근 30일)
이전 댓글 표시
I am trying to optimize my code by converting the following for loop to mex file. However, I am having a few problems converting them. Can anyone help me ?
Ixyz1 = zeros(xgridsize * ygridsize * zgridsize, 1,'single');
Ixyz2 = zeros(xgridsize * ygridsize * zgridsize, 1,'single');
Ixyz3 = zeros(xgridsize * ygridsize * zgridsize, 1,'single');
Ixyz4 = zeros(xgridsize * ygridsize * zgridsize, 1,'single');
Ixyz5 = zeros(xgridsize * ygridsize * zgridsize, 1,'single');
Ixyz6 = zeros(xgridsize * ygridsize * zgridsize, 1,'single');
Ixyz7 = zeros(xgridsize * ygridsize * zgridsize, 1,'single');
Ixyz8 = zeros(xgridsize * ygridsize * zgridsize, 1,'single');
Ixyz9 = zeros(xgridsize * ygridsize * zgridsize, 1,'single');
Ixyz10 = zeros(xgridsize * ygridsize * zgridsize, 1,'single');
for i = 1:1:length(Ixyz1)
Ixyz1(i) = Ixy(timedifference1(i) + 2001,1);
Ixyz2(i) = Ixy2(timedifference2(i) + 2001,1);
Ixyz3(i) = Ixy3(timedifference3(i) + 2001,1);
Ixyz4(i) = Ixy4(timedifference4(i) + 2001,1);
Ixyz5(i) = Ixy5(timedifference5(i) + 2001,1);
Ixyz6(i) = Ixy6(timedifference6(i) + 2001,1);
Ixyz7(i) = Ixy7(timedifference7(i) + 2001,1);
Ixyz8(i) = Ixy8(timedifference8(i) + 2001,1);
Ixyz9(i) = Ixy9(timedifference9(i) + 2001,1);
Ixyz10(i) = Ixy10(timedifference10(i) + 2001,1);
end
timedifference1 to timedifference10 have the same size as Ixyz1 to Ixyz10.
xgridsize , ygridsize are usually greater than 200. and zgridsize is around 100. Ixy to Ixy10 have the same size of 4000*1.
댓글 수: 2
Walter Roberson
2017년 12월 14일
Please say more about the difficulty you have in the conversion?
Is there a reason you did not use vectorized code
Ixyz1 = Ixy(timedifference1 + 2001);
Ixyz2 = Ixy2(timedifferenc2 + 2001);
and so on?
채택된 답변
OCDER
2017년 12월 14일
1st issue is that you called mxCreateDoubleMatrix BEFORE Ixyzlength was initialized. Also, mxCreateDoubleMatrix 1st input takes type mwSize (which is of size_t, not int), though it'll cast it. Careful of the casting rules.
//ERROR. Ixyzlength is declared but not initialized.
double Ixyzlength;
plhs[0] = mxCreateDoubleMatrix((int) Ixyzlength, 1,mxREAL);
//FIX by moving mxCreateDoubleMatrix after you get Ixyzlength.
double Ixyzlength = mxGetScalar(prhs[2]);
plhs[0] = mxCreateDoubleMatrix((mwSize) Ixyzlength, 1,mxREAL);
2nd issue is that you are destroying your Ixyz1 output array, which you shouldn't as stated here: https://www.mathworks.com/help/matlab/apiref/mxdestroyarray.html
//DELETE THIS
mxDestroyArray(Ixyz1);
3rd issue, it seems that Ixyzlength is just the size of Ixy. You could use mxGetM , mxGetN , or mxGetNumberOfElements to get this information as type mwSize. That way, you don't have to provide a 3rd input to your mex function.
4th issue, do not label variables Ixyz1/2/3/4/5/6/7/9/10 . That'll result in a huge code that's hard to modify. Instead, use cell arrays in your case so you can do this:
%Ixy is also converted to a cell array
Ixyz = repmat({zeros(xgridsize * ygridsize * zgridsize, 1,'single')}, 10, 1);
for j = 1:length(Ixyz)
for i = 1:length(Ixyz{1})
Ixyz{j}(i) = Ixy{j}(timedifference1(i) + 2001,1)
end
end
댓글 수: 4
James Tursa
2017년 12월 14일
편집: James Tursa
2017년 12월 14일
If "A" is an int16, then this
int *A;
should be this instead
short *A;
And of course all of the code that uses "A" needs to be adjusted as well. E.g., the (int *) cast should be (short *), the fillgrid "int A[]" needs to be "short A[]", etc.
Or, if you want to use the definitions from the tmwtypes.h file, you could use INT16_T instead of short.
You need to put in many more argument checks in your mex code to ensure that the inputs are exactly the type & size etc as expected.
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Install Products에 대해 자세히 알아보기
제품
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!