Используя MEX-функции для методов класса MATLAB

Можно использовать MEX-функции, чтобы реализовать методы для классов MATLAB®. Используя MEX-функции позволяет вам включить существующие алгоритмы C++ и операции в методы класса, не переписывая код в MATLAB.

Использовать методы MEX-функции:

  • Задайте класс MATLAB в @ папка так методы может содержаться в отдельных файлах. См. Методы в Отдельных Файлах.

  • Реализуйте MEX-функцию и поместите исполняемый файл в класс @ папка.

  • Сошлитесь на MEX-функцию в определении класса Methods блок.

  • Вызовите MEX-функцию как любой метод.

Метод, чтобы умножить матрицу на скаляр

arrayMultiplier класс, заданный здесь, реализует multiplyAllElements метод как MEX-функция.

Этот класс хранит 2D массив в своем Data свойство. multiplyAllElements метод принимает экземпляр класса и скалярный множитель как входные параметры. Метод умножает элементы массива в Data свойство множителем и присвоениями результат к Data свойство. Поскольку arrayMultiplier класс является классом значения, multiplyAllElements метод возвращает модифицированный объект.

Вот определение arrayMultiplier класс.

classdef arrayMultiplier
    % An object that contains an array and an operation
    % to multiply each element of the array by an input
    % value.
    % This class demonstrates how to use a MEX function
    % as a method.
    properties
        Data (:,:) double {mustBeNonempty(Data)} = ones(4);
    end
    methods
        function obj = arrayMultiplier(Matrix)
            %  Create object
            if nargin
                obj.Data = Matrix;
            end
        end
        % multiplyAllElements method implemented
        % as a MEX function
        obj = multiplyAllElements(obj,multplier)
    end
end

Вот реализация MEX-функции C++ multiplyAllElements метод.

/* C++ MEX file for MATLAB
*  returnObj = multiplyAllElements(obj, multiplier) modify object property.
*  Multiply all elements in obj.Data by multiplier.
*
*  Class method implemented as a MEX function
*
*/

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

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

class MexFunction : public matlab::mex::Function {
	std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
public:
    void operator()(ArgumentList outputs, ArgumentList inputs) {

        checkArguments(outputs, inputs);
        Array object(inputs[0]);
        double multiplier = inputs[1][0];
        assignProperty(object, multiplier);

        // Return modified object
        outputs[0] = object;
    }
     
    void assignProperty(Array& obj, double multiplier) {
        // Get matrix from Data property
		TypedArray<double> inMatrix = matlabPtr->getProperty(obj, u"Data");


		// Multiply matrix by multiplier
		for (auto& elem : inMatrix) {
			elem *= multiplier;
		}

		// Set the property value
		matlabPtr->setProperty(obj, u"Data", inMatrix);
    }

	void checkArguments(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
		matlab::data::ArrayFactory factory;

		if (inputs.size() != 2) {
			matlabPtr->feval(u"error",
				0, 
				std::vector<matlab::data::Array>({ factory.createScalar("Two inputs required") }));
		}

		if ((inputs[1].getType() != matlab::data::ArrayType::DOUBLE) || (inputs[1].getNumberOfElements() != 1)) {
			matlabPtr->feval(u"error", 
				0, 
				std::vector<matlab::data::Array>({ factory.createScalar("Input multiplier must be a noncomplex scalar double") }));
		}

	}
};

Чтобы использовать метод, создайте экземпляр класса. Значение по умолчанию для Data свойство является массивом 4 на 4, возвращенным выражением ones(4).

a = arrayMultiplier;
a.Data
ans =

     1     1     1     1
     1     1     1     1
     1     1     1     1
     1     1     1     1

Используйте multiplyAllElements метод, чтобы умножить каждый элемент в массиве скалярным значением. Присвойте возвращенный объект той же переменной.

a = multiplyAllElements(a,6.25);
a.Data
ans =

    6.2500    6.2500    6.2500    6.2500
    6.2500    6.2500    6.2500    6.2500
    6.2500    6.2500    6.2500    6.2500
    6.2500    6.2500    6.2500    6.2500

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

| | |

Похожие темы