Создайте исходный файл C++ MEX

Вот то, как создать основную MEX-функцию C++. Эта функция только добавляет смещение к каждому элементу входного массива, чтобы продемонстрировать основной ввод и вывод. Для более детального обсуждения создания исходного кода MEX-функции смотрите Структуру MEX-функции C++ и похожих тем.

Создание файла исходного кода

Используя ваш редактор, создайте файл с .cpp расширение и добавляет, прокомментировали инструкции. Например, MyMEXFunction.cpp.

/* MyMEXFunction
 * Adds second input to each  
 * element of first input
 * a = MyMEXFunction(a,b);
*/

Добавьте необходимые заголовочные файлы

Для MEX-функций C++ добавьте эти заголовочные файлы.

/* MyMEXFunction
 * Adds second input to each  
 * element of first input
 * a = MyMEXFunction(a,b);
*/

#include "mex.hpp"
#include "mexAdapter.hpp"

Используя определения удобства

Опционально задайте пространство имен для matlab::data и задайте другие удобства.

/* MyMEXFunction
 * Adds second input to each  
 * element of first input
 * a = MyMEXFunction(a,b);
*/

#include "mex.hpp"
#include "mexAdapter.hpp"

using namespace matlab::data;
using matlab::mex::ArgumentList;

Задайте класс MexFunction

Все MEX-функции C++ реализованы как класс под названием MexFunction. Этот класс должен вывести из matlab::mex::Function.

/* MyMEXFunction
 * Adds second input to each  
 * element of first input
 * a = MyMEXFunction(a,b);
*/

#include "mex.hpp"
#include "mexAdapter.hpp"

using namespace matlab::data;
using matlab::mex::ArgumentList;

class MexFunction : public matlab::mex::Function {

};

Задайте оператор ()

Весь MexFunction классы должны заменить оператор вызова функции, operator(), принять два аргумента типа matlab::mex::ArgumentList. Эти аргументы содержат вводы и выводы.

/* MyMEXFunction
 * Adds second input to each  
 * element of first input
 * a = MyMEXFunction(a,b);
*/

#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
 * Adds second input to each  
 * element of first input
 * a = MyMEXFunction(a,b);
*/

#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 first input argument
        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 second input argument
        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
 * Adds second input to each  
 * element of first input
 * a = MyMEXFunction(a,b);
*/

#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 first input argument
        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 second input argument
        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") }));
        }
    }
};

Setup и сборка

После установки поддерживаемого компилятора используйте mex команда, чтобы создать вашу MEX-функцию.

mex -setup c++
mex MyMEXFunction.cpp

Для получения дополнительной информации о создании MEX-функций смотрите Сборку Программы C++ MEX.

Вызовите MEX-функцию

Вызовите свою MEX-функцию из MATLAB.

b = MyMEXFunction(11.5, rand(1000));

Смотрите также

| |

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте