MatlabCoderに基づいてmatlabコードをcコードに変換します



Convert Matlab Code C Code Based Matlab Coder



最近、信号処理関連の関数を実行しています。最初にmatlabでシミュレーションを実行し、次にc / c + +を使用して達成し、次にMatlabCoderを使用して変換関数を実行してみます。
参照:
MATLABCoderに基づいてmatlabコードをCコードに変換します
公式サイト動画解説
Matlabはc / c ++コードを呼び出します
どうもありがとうございました!

I.コンセプトと開発プロセス

MATLAB Coderは、MATLABコードからスタンドアロンで読み取り可能でポータブルなC / C ++コードを生成できます。
素人の言葉で言えば、書かれたmatlab汎用モジュールのコードはc / c ++コードに変換され、これに基づいて改善されます。
この記事の開発環境:Win10 64、VS2015、MatlabR2016A。



開発プロセス :MATLAB Coderを使用してCコードを生成する3つのステップ:

  1. 特定のアルゴリズム関数を実装するMATLABコードとテストファイルを開発する
  2. MATLABコードの互換性をチェックして、MATLABコードのステートメントをCコードに変換できることを確認します(matlabのimread、imshow、plot、その他の関数など、一部のmatlabコードステートメントはc / c + +コードを生成できません)
  3. MATLABCoderを使用してc / c ++コードを生成し、VS2015で検証します。

第二に、模擬試験

参照記事は、汎用モジュールコードをテストコードから分離するというアイデアを提供しているため、この記事はこのアイデアを利用して実際のテストを実施します。
もちろん、汎用モジュールa.mファイルはb.mファイルとして呼び出すことができます。コンパイル時にコンパイルするために両方を選択する必要があります(依存関係として理解できます)が、この記事にはこの関数の実装は含まれていません。



2.1Matlab汎用モジュールコードとそのテストコード

myfft.m
入力データからDC成分を取り除き、FFTを実行します。その中で、%#codegenは警告エラーを防ぐために使用されます

%#codegen function B = myfft(v1,N) v1=v1 - mean(v1) B = fft(v1,N)

test_main.m
データセットを生成してテストする

f=100 %Signal frequency Hz Fs=1000 %Sampling frequency N=256 %Sampling points t=(0:N-1)/Fs %Sampling time s S=1000*sin(2*pi*f*t)+20*randn(size(t)) %Signal sample value %B = meanVal(S,N) B = myfft(S,N) f =((-N/2):(N/2-1))*Fs/N plot(abs(B)) title('Amplitude Spectrum of S') xlabel('f (Hz)') ylabel('|P1(f)|')

Matlabの出力:
画像
f =(N-1) Fs / N = 26 1000/256 = 100Hz。



2.2 MATLABCoderを使用したc / c ++コードの生成
  1. コマンドウィンドウで、「mex -setup」と入力し、既存のコンパイラを選択します。作成者はここにcコンパイラが付属しています。読者は、c ++コンパイラに切り替えることもできます(入力mex -setup C++)。
    画像

  2. コマンドウィンドウにコーダー(グラフィカルインターフェイス)と入力し、Enterキーを押して、[MATLAB Coder Project]ダイアログボックスをポップアップします(またはmatlabソフトウェアインターフェイスをクリックします)。MatLab Coderアイコン)。
    (1)選択モジュールでコンパイルする汎用モジュールmyfft.mを選択します。
    画像
    (2)[次へ]をクリックします
    画像
    上の図の赤いボックスは、汎用モジュールの.mファイルを引き続き追加することもできます。
    (3)「次へ」をクリックして、「入力タイプの定義」インターフェースに入ります。 test_main.mテストファイルを入力し、[入力タイプの自動定義]ボタンをクリックして、matlabが汎用モジュール関数のインターフェイス変数のディメンションとタイプを自動的に検出できるようにします。
    画像
    (4)[次へ]をクリックし、[問題の確認]ボタンをクリックします。
    画像
    (5)[次へ]をクリックし、[生成]ボタンをクリックして、C / C ++コードを生成します。
    画像
    生成が成功すると、次の図がlibファイルに表示されます。
    画像

2.3VS2015検証

VS2015を使用して、libディレクトリのlibvsフォルダーにプロジェクトmyfftprjを作成し、すべての.c.hをプロジェクトにインポートします。
物理パスが原因で、現在のプロジェクトヘッダーファイルのパスを変更します。
画像
プロジェクトの入力インスタンス入力が空であることがわかったため、test_main.mファイルに従って変更する必要があります。

/* * Arguments : double result[256] * Return Type : void */ static void argInit_1x256_real_T(double result[256]) { int idx1 const double pi = 3.141592653589793 const double Fs = 1000 //Sampling frequency /* Loop over the array to initialize each element. */ for (idx1 = 0 idx1 < 256 idx1++) { /* Set the value of the array element. Change this value to the value that the application requires. */ double t = idx1 / Fs result[idx1] = 100 * sin(2 * pi * 100 * t)//argInit_real_T() } }

同時に、入力パラメータNも適切に修正および追加する必要があります。また、getchar()などの補助印刷関数も必要です。
生成されたc ++コード出力変数は、実際の出力に従って決定される構造型変数であることに注意してください。構造の理解に基づいてデバッグと印刷を行う必要があります。
たとえば、複素数を出力する場合、タイプはemxArray_creal_T実数を出力する場合、タイプはemxArray_real_Tです。
コード:

/* Include Files */ #include '../rt_nonfinite.h' #include '../myfft.h' #include 'main.h' #include '../myfft_terminate.h' #include '../myfft_emxAPI.h' #include '../myfft_initialize.h' #include /* Function Definitions */ void printArr(emxArray_creal_T *arr, int size) { for (int i = 0 i < size i++) { printf('%4d %8.4f %8.4f ', i, (arr->data[i]).re, (arr->data[i]).im) //printf('%4d %8.4f ', i, arr->data[i]) } } /* Function Declarations */ static void argInit_1x256_real_T(double result[256]) static double argInit_real_T(void) static void main_myfft(void) /* Function Definitions */ /* * Arguments : double result[256] * Return Type : void */ static void argInit_1x256_real_T(double result[256]) { int idx1 const double pi = 3.141592653589793 const double Fs = 1000 //Sampling frequency /* Loop over the array to initialize each element. */ for (idx1 = 0 idx1 < 256 idx1++) { /* Set the value of the array element. Change this value to the value that the application requires. */ double t = idx1 / Fs result[idx1] = 100 * sin(2 * pi * 100 * t)//argInit_real_T() } } /* * Arguments : void * Return Type : double */ static double argInit_real_T(void) { return 0.0 } /* * Arguments : void * Return Type : void */ static void main_myfft(void) { emxArray_creal_T *B double dv0[256] emxInitArray_creal_T(&B, 2) /* Initialize function 'myfft' input arguments. */ /* Initialize function input argument 'v1'. */ /* Call the entry-point 'myfft'. */ argInit_1x256_real_T(dv0) myfft(dv0,256 , B) //argInit_real_T() printArr(B, 256) emxDestroyArray_creal_T(B) } /* * Arguments : int argc * const char * const argv[] * Return Type : int */ int main(int argc, const char * const argv[]) { (void)argc (void)argv /* Initialize the application. You do not need to do this more than one time. */ myfft_initialize() /* Invoke the entry-point functions. You can call entry-point functions multiple times. */ main_myfft() /* Terminate the application. You do not need to do this more than one time. */ myfft_terminate() getchar() return 0 }

出力:
画像

第三に、Matlabのヒント

  • 科学的記数法では表示されません(参照 論文 )。
format short g #include 'mex.h' / / Use the header file that MEX must contain void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){ mexPrintf('hello world ') } mex hello.c hello %Script run