C 函数 arrayProduct
以下代码定义 arrayProduct 函数,它将 1×n 矩阵 y 与标量值 x 相乘,并以数组 z 形式返回结果。您可以在 C++ 应用程序中使用这些相同的 C 语句。
void arrayProduct(double x, double *y, double *z, int n)
{
int i;
for (i=0; i
z[i] = x * y[i];
}
}
创建源文件
打开 MATLAB 编辑器,创建一个文件,并在 MEX 文件中记录以下信息。
/*
* arrayProduct.c - example in MATLAB External Interfaces
*
* Multiplies an input scalar (multiplier)
* times a 1xN matrix (inMatrix)
* and outputs a 1xN matrix (outMatrix)
*
* The calling syntax is:
*
*outMatrix = arrayProduct(multiplier, inMatrix)
*
* This is a MEX file for MATLAB.
*/
添加包含 MATLAB API 函数声明的 C/C++ 头文件 mex.h。
#include "mex.h"
将文件保存在您的 MATLAB 路径(例如 c:\work)中,并将其命名为 arrayProduct.c。您的 MEX 文件名称为 arrayProduct。
创建入口例程
每个 C 程序都有一个 main() 函数。MATLAB 使用入口例程 mexFunction 作为函数的入口函数。添加以下 mexFunction 代码。
/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
/* variable declarations here */
/* code here */
}
下表描述了 mexFunction 的输入参数。
参数说明nlhs输出(左侧)参数的数量,或 plhs 数组的大小。
plhs输出参数的数组。
nrhs输入(右侧)参数的数量,或 prhs 数组的大小。
prhs输入参数的数组。
验证 MEX 文件的输入和输出参数
使用 nrhs 和 nlhs 参数验证 MEX 文件输入和输出参数的数量。
要检查两个输入参数 multiplier 和 inMatrix,请使用以下代码。
if(nrhs != 2) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs",
"Two inputs required.");
}
使用以下代码检查一个输出参数,即乘积 outMatrix。
if(nlhs != 1) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs",
"One output required.");
}
使用 plhs 和 prhs 参数验证参数类型。以下代码将验证 multiplier(由 prhs[0] 表示)为标量。
/* make sure the first input argument is scalar */
if( !mxIsDouble(prhs[0]) ||
mxIsComplex(prhs[0]) ||
mxGetNumberOfElements(prhs[0]) != 1 ) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notScalar",
"Input multiplier must be a scalar.");
}
以下代码将验证 inMatrix(由 prhs[1] 表示)为 double 类型。
if( !mxIsDouble(prhs[1]) ||
mxIsComplex(prhs[1])) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble",
"Input matrix must be type double.");
}
验证 inMatrix 为行向量。
/* check that number of rows in second input argument is 1 */
if(mxGetM(prhs[1]) != 1) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notRowVector",
"Input must be a row vector.");
}
创建计算例程
添加 arrayProduct 代码。以下函数是您的计算例程,即用于执行您希望在 MATLAB 中使用的功能的源代码。
void arrayProduct(double x, double *y, double *z, int n)
{
int i;
for (i=0; i
z[i] = x * y[i];
}
}
计算例程是可选的。您也可以将代码置于 mexFunction 函数块中。
编写代码以实现跨平台的灵活性
MATLAB 提供了基于平台表示整数大小值的预处理器宏 mwsize。计算例程将数组的大小声明为 int。将变量 n 和 i 的 int 声明替换为 mwsize。
void arrayProduct(double x, double *y, double *z, mwSize n)
{
mwSize i;
for (i=0; i
z[i] = x * y[i];
}
}
声明计算例程的变量
将以下变量声明置于 mexFunction 中。
声明输入参数的变量。
double multiplier; /* input scalar */
double *inMatrix; /* 1xN input matrix */
为输入矩阵的大小声明 ncols。
mwSize ncols; /* size of matrix */
声明输出参数 outMatrix。
double *outMatrix; /* output matrix */
稍后,将 mexFunction 参数赋给这些变量。
读取输入数据
要读取标量输入,请使用 mxGetScalar 函数。
/* get the value of the scalar input */
multiplier = mxGetScalar(prhs[0]);
使用 mxGetDoubles 函数指向输入矩阵数据。
/* create a pointer to the real data in the input matrix */
inMatrix = mxGetDoubles(prhs[1]);
使用 mxGetN 函数获取矩阵大小。
/* get dimensions of the input matrix */
ncols = mxGetN(prhs[1]);
准备输出数据
要创建输出参数 plhs[0],请使用 mxCreateDoubleMatrix 函数。
/* create the output matrix */
plhs[0] = mxCreateDoubleMatrix(1,ncols,mxREAL);
使用 mxGetDoubles 函数将 outMatrix 参数赋给 plhs[0]
/* get a pointer to the real data in the output matrix */
outMatrix = mxGetDoubles(plhs[0]);
执行计算
将参数传递给 arrayProduct。
/* call the computational routine */
arrayProduct(multiplier,inMatrix,outMatrix,ncols);
查看完整的源文件
将源文件与位于 matlabroot/extern/examples/mex 的 arrayProduct.c 进行比较。在编辑器中打开文件 arrayProduct.c。
有关使用 MATLAB 数据 API 的 C++ MEX 文件示例,请参阅 arrayProduct.cpp。有关使用此 API 创建 MEX 文件的信息,请参阅 C++ MEX 函数。
编译 MEX 函数
在 MATLAB 命令提示符下,使用 mex 命令编译该函数。
mex arrayProduct.c -R2018a
测试 MEX 函数
s = 5;
A = [1.5, 2, 9];
B = arrayProduct(s,A)
B =
7.5000 10.0000 45.0000
验证 MEX 文件输入参数
最好在调用 MEX 函数之前验证 MATLAB 变量的类型。要测试输入变量 inputArg 并在必要时将其转换为 double,请使用以下代码。
s = 5;
A = [1.5, 2, 9];
inputArg = int16(A);
if ~strcmp(class(inputArg),'double')
inputArg = double(inputArg);
end
B = arrayProduct(s,inputArg)