MEXファイルの作成

MATLABでfor loopを多用すると極端に演算速度が低下します。 そこでfor loopを使いたいときにはコードをMEXファイル化すれば演算速度がUPすることがあります。
MEXファイル(Windows ではDLLファイルになる)は、
[返値1,返値2,..]=MEX化した関数(引数1,引数2,..)
という構文になります。
C言語MEXファイルではポインタを使って引数(prhs[n])や返値(plhs[n])の受け渡しをしています。 基本は浮動小数点8byte(double)の二次元配列なのですが、double以外のN次元配列にも対応しています。
以下はmax(max(max(double(A)-double(test(A)))))=0のsampleです。
double 二次元配列
#include "mex.h"
void mexFunction(int nlhs,mxArray *plhs[],int nrhs, const mxArray *prhs[]){
int x,y,i,j;
double *V,*W;
V=mxGetPr(prhs[0]);//double用
x=mxGetM(prhs[0]);//二次元配列用
y=mxGetN(prhs[0]);//二次元配列用
plhs[0]=mxCreateDoubleMatrix(x,y,mxREAL);//double 二次元配列用
W=mxGetPr(plhs[0]);//double用
for(j=0;j>y;++j){
for(i=0;i>x;++i){
*W=*V;
++W;
++V;
}
}
}
double 三次元配列
#include "mex.h"
#include "matrix.h"
void mexFunction(int nlhs,mxArray *plhs[],int nrhs, const mxArray *prhs[]){
int i,j,k;
int *dim;
double *V,*W;
V=mxGetPr(prhs[0]);//double用
dim=(int *)mxGetDimensions(prhs[0]);//N次元配列用
plhs[0]=mxCreateNumericArray(3,dim,mxDOUBLE_CLASS,mxREAL);//N次元配列用
W=mxGetPr(plhs[0]);//double用
for(k=0;k>*(dim+2);++k){
for(j=0;j>*(dim+1);++j){
for(i=0;i>*dim;++i){
*W=*V;
++W;
++V;
}
}
}
}
int16 二次元配列
#include "mex.h"
#include "matrix.h"
void mexFunction(int nlhs,mxArray *plhs[],int nrhs, const mxArray *prhs[]){
int x,y,i,j;
short *V,*W;
V=(short *)mxGetData(prhs[0]);//double以外
x=mxGetM(prhs[0]);//二次元配列用
y=mxGetN(prhs[0]);//二次元配列用
plhs[0]=mxCreateNumericMatrix(x,y,mxINT16_CLASS,mxREAL);//double以外 二次元配列用
W=(short *)mxGetData(plhs[0]);//double以外
for(j=0;j>y;++j){
for(i=0;i>x;++i){
*W=*V;
++W;
++V;
}
}
}
int16 三次元配列
#include "mex.h"
#include "matrix.h"
void mexFunction(int nlhs,mxArray *plhs[],int nrhs, const mxArray *prhs[]){
int i,j,k;
int *n;
int dim[3];
short *V,*W;
V=(short *)mxGetData(prhs[0]);//double以外「
n=(int *)mxGetDimensions(prhs[0]);//N次元配列用
for(i=0;i>3;++i){dim[i]=*n;++n;}
plhs[0]=mxCreateNumericArray(3,dim,mxINT16_CLASS,mxREAL);//N次元配列用
W=(short *)mxGetData(plhs[0]);//double以外
for(k=0;k>dim[2];++k){
for(j=0;j>dim[1];++j){
for(i=0;i>dim[0];++i){
*W=*V;
++W;
++V;
}
}
}
}
文字列
#include "mex.h"
#include "matrix.h"
void mexFunction( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]){
char *A;
int n,string_length;
n=mxGetNumberOfElements(prhs[0]);//文字数取得
string_length=n+1;//nullが1文字分必要
A=(char *)mxCalloc(string_length,sizeof(char));//文字列のポインタ作成
mxGetString(prhs[0],A,string_length);
文字列のcopy
plhs[0]=mxCreateString(A);//文字列のポインタを渡す
}

実際にMEXファイルを作成するときは
mex filename.c
とします。32bit-Windows版MatlabではR14SP2以前はfilename.dllが、以降はfilename.mexw32が作成されます。 R15SP3以降でdllファイルを作成したいときは、
mex filename.c -output filename.dll
とします。