Convert Matlab function to Mex file - For loop conversion
6 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
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 Commenti
Walter Roberson
il 14 Dic 2017
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?
Risposta accettata
OCDER
il 14 Dic 2017
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 Commenti
James Tursa
il 14 Dic 2017
Modificato: James Tursa
il 14 Dic 2017
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.
Più risposte (0)
Vedere anche
Categorie
Scopri di più su Install Products in Help Center e File Exchange
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!