Matlab是一种矩阵语言,是为vector和matrix操作设计的,这两种类型的运算速度非常快,但是当涉及到大量的循环处理时,Matlab的速度就有点慢了。因此,Matlab提供了MEX脚本来使用C/C++函数以提高循环的运算速度。
现在我们来介绍一下如何编写相应的C/C++函数以生成对应的mexw32或mexw64文件。
MEX文件的编写和编译需要两个基本条件:一是必须按照Matlab应用程序接口组件设计;二是要有相应的C/C++编译器。这些我们先不谈,先来看看如何编写Source File。
我们以一个例子来讲——编写一个Mex文件来调用一个C函数:arrayProduct【这个函数实现一个常量与数组相乘】
文件信息,非必需,可选:
1:2: /*==========================================================
3: * arrayProduct.c - example in MATLAB External Interfaces4: *5: * Multiplies an input scalar (multiplier)6: * times a 1xN matrix (inMatrix)7: * and outputs a 1xN matrix (outMatrix)8: *9: * The calling syntax is:10: *11: * outMatrix = arrayProduct(multiplier, inMatrix)12: *13: * This is a MEX-file for MATLAB.14: * Copyright 2007-2012 The MathWorks, Inc.15: *16: *========================================================*/17: /* $Revision: 1.1.10.4 $ */
18:
添加头文件mex.h,该文件包含相应的MATLAB API函数声明。
1: #include "mex.h"
核心计算程序。
1: /* The computational routine */
2: void arrayProduct(double x, double *y, double *z, mwSize n)3: {4: mwSize i;5: /* multiply each element y by x */
6: for (i=0; i<n; i++) {
7: z[i] = x * y[i];8: }9: }10:
MEX文件的入口函数——mexFunction
参数 | 描述 |
nlhs | # of output arguments, or the size of the plhs array |
plhs | Array of output arguments |
nrhs | # of input arguments, or the size of the prhs array |
prhs | Array of input arguments. |
1:2: /* The gateway function */
3: void mexFunction( int nlhs, mxArray *plhs[],4: int nrhs, const mxArray *prhs[])5: {6: double multiplier; /* input scalar */7: double *inMatrix; /* 1xN input matrix */8: size_t ncols; /* size of matrix */
9: double *outMatrix; /* output matrix */10:11: /* check for proper number of arguments */
12: if(nrhs!=2) {
13: mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs","Two inputs required.");14: }15: if(nlhs!=1) {
16: mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs","One output required.");17: }18: /* make sure the first input argument is scalar */
19: if( !mxIsDouble(prhs[0]) ||
20: mxIsComplex(prhs[0]) ||21: mxGetNumberOfElements(prhs[0])!=1 ) {22: mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notScalar","Input multiplier must be a scalar.");23: }24:25: /* make sure the second input argument is type double */
26: if( !mxIsDouble(prhs[1]) ||
27: mxIsComplex(prhs[1])) {28: mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble","Input matrix must be type double.");29: }30:31: /* check that number of rows in second input argument is 1 */
32: if(mxGetM(prhs[1])!=1) {
33: mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notRowVector","Input must be a row vector.");34: }35:36: /* get the value of the scalar input */
37: multiplier = mxGetScalar(prhs[0]);38:39: /* create a pointer to the real data in the input matrix */
40: inMatrix = mxGetPr(prhs[1]);41:42: /* get dimensions of the input matrix */
43: ncols = mxGetN(prhs[1]);44:45: /* create the output matrix */
46: plhs[0] = mxCreateDoubleMatrix(1,(mwSize)ncols,mxREAL);47:48: /* get a pointer to the real data in the output matrix */
49: outMatrix = mxGetPr(plhs[0]);50:51: /* call the computational routine */
52: arrayProduct(multiplier,inMatrix,outMatrix,(mwSize)ncols);53: }