C++ MEX ソース ファイルの作成
基本的な C++ MEX 関数を作成する方法は次のとおりです。この関数は、基本的な入出力を示すために、単純に入力配列の各要素にオフセットを追加します。MEX 関数のソース コードの作成に関する詳細な説明については、C++ MEX 関数の構造および関連トピックを参照してください。
ソース ファイルの作成
エディターを使用して、.cpp
拡張子をもつファイルを作成し、コメントとして説明を追加します。たとえば、MyMEXFunction.cpp
のようになります。
/* MyMEXFunction * c = MyMEXFunction(a,b); * Adds offset argument a to each element of double array b and * returns the modified array c. */
必要なヘッダー ファイルの追加
C++ MEX 関数については、次のヘッダー ファイルを追加します。
/* MyMEXFunction * c = MyMEXFunction(a,b); * Adds offset argument a to each element of double array b and * returns the modified array c. */ #include "mex.hpp" #include "mexAdapter.hpp"
便利な定義の使用
オプションで、matlab::data
の名前空間を指定し、他の便利な機能を定義します。
/* MyMEXFunction * c = MyMEXFunction(a,b); * Adds offset argument a to each element of double array b and * returns the modified array c. */ #include "mex.hpp" #include "mexAdapter.hpp" using namespace matlab::data; using matlab::mex::ArgumentList;
MexFunction クラスの定義
すべての C++ MEX 関数は、MexFunction
という名前のクラスとして実装されます。このクラスは matlab::mex::Function
から派生させなければなりません。
/* MyMEXFunction * c = MyMEXFunction(a,b); * Adds offset argument a to each element of double array b and * returns the modified array c. */ #include "mex.hpp" #include "mexAdapter.hpp" using namespace matlab::data; using matlab::mex::ArgumentList; class MexFunction : public matlab::mex::Function { };
operator() の定義
すべての MexFunction
クラスは、matlab::mex::ArgumentList
型の引数を 2 つ受け入れるために、関数呼び出し演算子 operator()
をオーバーライドしなければなりません。これらの引数には入力と出力が含まれます。
/* MyMEXFunction * c = MyMEXFunction(a,b); * Adds offset argument a to each element of double array b and * returns the modified array c. */ #include "mex.hpp" #include "mexAdapter.hpp" using namespace matlab::data; using matlab::mex::ArgumentList; class MexFunction : public matlab::mex::Function { public: void operator()(ArgumentList outputs, ArgumentList inputs) { } };
メンバー関数を追加して引数をチェック
引数の型とサイズが正しいかどうかをテストして確認します。テストが失敗した場合、MATLAB® 関数 error
を呼び出します。
/* MyMEXFunction * c = MyMEXFunction(a,b); * Adds offset argument a to each element of double array b and * returns the modified array c. */ #include "mex.hpp" #include "mexAdapter.hpp" using namespace matlab::data; using matlab::mex::ArgumentList; class MexFunction : public matlab::mex::Function { public: void operator()(ArgumentList outputs, ArgumentList inputs) { } void checkArguments(ArgumentList outputs, ArgumentList inputs) { // Get pointer to engine std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine(); // Get array factory ArrayFactory factory; // Check offset argument: First input must be scalar double if (inputs[0].getType() != ArrayType::DOUBLE || inputs[0].getNumberOfElements() != 1) { matlabPtr->feval(u"error", 0, std::vector<Array>({ factory.createScalar("First input must be scalar double") })); } // Check array argument: Second input must be double array if (inputs[1].getType() != ArrayType::DOUBLE) { matlabPtr->feval(u"error", 0, std::vector<Array>({ factory.createScalar("Input must be double array") })); } // Check number of outputs if (outputs.size() > 1) { matlabPtr->feval(u"error", 0, std::vector<Array>({ factory.createScalar("Only one output is returned") })); } } };
計算の実装
スカラー オフセットを取得し、const
double
に代入します。入力配列を取得し、それを matlab::data::TypedArray<double>
に移動して、配列を操作します。オフセットを配列の各要素に追加し、変更された配列を出力変数に代入します。
/* MyMEXFunction * c = MyMEXFunction(a,b); * Adds offset argument a to each element of double array b and * returns the modified array c. */ #include "mex.hpp" #include "mexAdapter.hpp" using namespace matlab::data; using matlab::mex::ArgumentList; class MexFunction : public matlab::mex::Function { public: void operator()(ArgumentList outputs, ArgumentList inputs) { checkArguments(outputs, inputs); const double offSet = inputs[0][0]; TypedArray<double> doubleArray = std::move(inputs[1]); for (auto& elem : doubleArray) { elem += offSet; } outputs[0] = doubleArray; } void checkArguments(ArgumentList outputs, ArgumentList inputs) { // Get pointer to engine std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine(); // Get array factory ArrayFactory factory; // Check offset argument: First input must be scalar double if (inputs[0].getType() != ArrayType::DOUBLE || inputs[0].getType() == ArrayType::COMPLEX_DOUBLE || inputs[0].getNumberOfElements() != 1) { matlabPtr->feval(u"error", 0, std::vector<Array>({ factory.createScalar("First input must be scalar double") })); } // Check array argument: Second input must be double array if (inputs[1].getType() != ArrayType::DOUBLE || inputs[1].getType() == ArrayType::COMPLEX_DOUBLE) { matlabPtr->feval(u"error", 0, std::vector<Array>({ factory.createScalar("Input must be double array") })); } // Check number of outputs if (outputs.size() > 1) { matlabPtr->feval(u"error", 0, std::vector<Array>({ factory.createScalar("Only one output is returned") })); } } };
設定とビルド
サポートされているコンパイラをインストールしたら、mex
コマンドを使用して MEX 関数をビルドします。
mex -setup c++ mex MyMEXFunction.cpp
MEX 関数のビルドの詳細については、C++ MEX プログラムのビルドを参照してください。
MEX 関数の呼び出し
MATLAB から MEX 関数を呼び出します。
b = MyMEXFunction(11.5, rand(1000));
参考
mex
| matlab::mex::Function
| matlab::mex::ArgumentList