Main Content

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)

参考

関連するトピック