Этот пример показывает, как записать файл MEX, чтобы вызвать функцию C arrayProduct в MATLAB® с помощью массива MATLAB, заданного в Матричном API C. Можно просмотреть полный исходный файл здесь.
Этот пример использует редактора MATLAB, чтобы записать исходный код и команду mex MATLAB, чтобы создать MEX-функцию. Требования для создания файлов MEX перечислены в Исходных Файлах MEX на C. Если вы хотите использовать свою собственную среду разработки C, смотрите Сделанный на заказ с Опциями Скрипта MEX для получения дополнительной информации.
arrayProductСледующий код задает функцию arrayProduct, которая умножается 1xn матричный y скалярным значением x и возвращает результаты в массиве z. Можно использовать эти те же операторы C в приложении C++.
void arrayProduct(double x, double *y, double *z, int n)
{
int i;
for (i=0; i<n; 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. */
Добавьте заголовочный файл C/C++, mex.h, содержа объявления функции MATLAB API.
#include "mex.h"
Сохраните файл на своем пути MATLAB, например, в c:\work, и назовите его arrayProduct.c 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.
Чтобы проверить на два входных параметра, 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<n; i++) {
z[i] = x * y[i];
}
}
Вычислительная процедура является дополнительной. Также можно поместить код в функциональном блоке mexFunction.
MATLAB обеспечивает макрос препроцессора, mwsize, который представляет значения размера для целых чисел, на основе платформы. Вычислительная процедура объявляет размер массива как int. Замените объявление int для переменных n и i с mwsize.
void arrayProduct(double x, double *y, double *z, mwSize n)
{
mwSize i;
for (i=0; i<n; 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);
Сравните свой исходный файл с arrayProduct.c, расположенным в . Откройте файл matlabroot/extern/examples/mexarrayProduct.c в редакторе.
Для примера файла MEX C++ с помощью MATLAB Data API смотрите arrayProduct.cpp. Для получения информации о создании файлов MEX с этим API смотрите MEX-функции C++.
В подсказке команды MATLAB создайте функцию с командой mex.
mex arrayProduct.c -R2018a
s = 5; A = [1.5, 2, 9]; B = arrayProduct(s,A)
B =
7.5000 10.0000 45.0000
Это - хорошая практика, чтобы подтвердить тип переменной MATLAB прежде, чем вызвать MEX-функцию. Чтобы протестировать входную переменную, 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)
mEX | mexFunction | mwSize | mxCreateDoubleMatrix | mxGetDoubles | mxGetN | mxGetScalar