Этот пример convec.c
берет два комплексных вектора - строки и применяет операцию свертки к ним. Пример принимает основное понимание файлов MEX, как описано в Создании исходного файла MEX на C.
Следующие операторы документируют MEX-функцию.
/*========================================================= * convec.c * example for passing complex data from MATLAB to C and back again * * convolves two complex input vectors * * This is a MEX-file for MATLAB. * Copyright 1984-2017 The MathWorks, Inc. *=======================================================*/
Следующие операторы добавляют заголовочный файл C/C++ mex.h
, и создает точку входа mexFunction
.
#include "mex.h" /* The gateway routine. */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { return; }
Следующие операторы подтверждают количество параметров.
/* check for the proper number of arguments */ if(nrhs != 2) mexErrMsgIdAndTxt( "MATLAB:convec:invalidNumInputs", "Two inputs required."); if(nlhs > 1) mexErrMsgIdAndTxt( "MATLAB:convec:maxlhs", "Too many output arguments.");
Следующий оператор проверяет, что входные параметры являются векторами - строками.
/*Check that both inputs are row vectors*/ if( mxGetM(prhs[0]) != 1 || mxGetM(prhs[1]) != 1 ) mexErrMsgIdAndTxt( "MATLAB:convec:inputsNotVectors", "Both inputs must be row vectors.");
Следующий оператор проверяет, что входные параметры являются комплексными.
/* Check that both inputs are complex*/ if( !mxIsComplex(prhs[0]) || !mxIsComplex(prhs[1]) ) mexErrMsgIdAndTxt( "MATLAB:convec:inputsNotComplex", "Inputs must be complex.\n");
mxArray
Следующие операторы задают параметры для создания вывода mxArray
.
size_t rows, cols; size_t nx, ny; /* get the length of each input vector */ nx = mxGetN(prhs[0]); ny = mxGetN(prhs[1]); rows = 1; cols = nx + ny - 1;
Следующий оператор создает массив и устанавливает выходной указатель plhs[0]
на него.
plhs[0] = mxCreateDoubleMatrix( (mwSize)rows, (mwSize)cols, mxCOMPLEX);
Следующие операторы задают convec
, вычислительную процедуру.
void convec(mxArray * x, mxArray * y, mxArray * z, size_t nx, size_t ny) { mwSize i,j; /* get pointers to the complex arrays */ mxComplexDouble * xc = mxGetComplexDoubles(x); mxComplexDouble * yc = mxGetComplexDoubles(y); mxComplexDouble * zc = mxGetComplexDoubles(z); zc[0].real = 0; zc[0].imag = 0; /* perform the convolution of the complex vectors */ for(i=0; i<nx; i++) { for(j=0; j<ny; j++) { zc[i+j].real = zc[i+j].real + xc[i].real * yc[j].real - xc[i].imag * yc[j].imag; zc[i+j].imag = zc[i+j].imag + xc[i].real * yc[j].imag + xc[i].imag * yc[j].real; } } }
convec
Следующий оператор вызывает вычислительную процедуру.
convec(prhs[0], prhs[1], plhs[0], nx, ny);
В типе командной строки MATLAB®:
mex -R2018a convec.c
Тестирование файла MEX.
x = [3.000 - 1.000i, 4.000 + 2.000i, 7.000 - 3.000i]; y = [8.000 - 6.000i, 12.000 + 16.000i, 40.000 - 42.000i]; z = convec(x,y)
z = 1.0e+02 * Columns 1 through 4 0.1800 - 0.2600i 0.9600 + 0.2800i 1.3200 - 1.4400i 3.7600 - 0.1200i Column 5 1.5400 - 4.1400i
Сравните результаты со встроенной функцией MATLAB conv
.
conv(x,y)