В этом примере показано, как записать файл MEX для вызова функции C arrayProduct в MATLAB ® с использованием массива MATLAB, определенного в C Matrix API. Полный исходный файл можно просмотреть здесь.
Для использования этого примера необходимо:
Возможность записи исходного кода C или C++. Эти файлы создаются с помощью редактора MATLAB.
Компилятор, поддерживаемый MATLAB. Обновленный список поддерживаемых компиляторов см. на веб-сайте Поддерживаемые и совместимые компиляторы.
Функции в C Matrix API и C MEX API.
mex сценарий построения.
Если вы хотите использовать собственную среду разработки 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, содержащий объявления функций API MATLAB.
#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 аргументы.
Чтобы проверить наличие двух входных аргументов, 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 в редакторе.
Пример файла C++ MEX с использованием API данных MATLAB см. в разделе arrayProduct.cpp. Сведения о создании файлов MEX с помощью этого API см. в разделе Функции C++ MEX.
В командной строке MATLAB создайте функцию с помощью mex команда.
mex arrayProduct.c -R2018a
s = 5; A = [1.5, 2, 9]; B = arrayProduct(s,A)
B =
7.5000 10.0000 45.0000
Перед вызовом функции 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)
mex | mexFunction | mwSize | mxCreateDoubleMatrix | mxGetDoubles | mxGetN | mxGetScalar