C MEX ファイルでの複素数データの処理
convec.c の例では 2 つの複素数行ベクトルを取り、それらを畳み込みます。MEX ファイルは C 行列 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)