C MEX 파일의 복소수 데이터 처리하기
예제 convec.c는 두 개의 복소수 행 벡터를 받아 컨벌루션합니다. MEX 파일은 C Matrix API의 함수를 사용합니다.
소스 파일 만들기
다음 명령문은 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)