Use MEX Functions for MATLAB Class Methods - MATLAB & Simulink (original) (raw)

Main Content

You can use MEX functions to implement methods for MATLABĀ® classes. Using MEX functions enables you to incorporate existing C++ algorithms and operations into class methods without rewriting the code in MATLAB.

To use MEX function methods:

Method to Multiply Matrix by Scalar

The arrayMultiplier class defined here implements themultiplyAllElements method as a MEX function.

This class stores a 2-D array in its Data property. ThemultiplyAllElements method accepts a class instance and a scalar multiplier as inputs. The method multiplies the elements of the array in theData property by the multiplier and assigns the result to the Data property. Because the arrayMultiplier class is a value class, the multiplyAllElements method returns the modified object.

Here is the definition of the arrayMultiplier class.

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

Here is the C++ MEX function implementation of themultiplyAllElements method.

/* 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") }));
        }

    }
};

To use the method, create an instance of the class. The default value for theData property is a 4-by-4 array returned by the expressionones(4).

a = arrayMultiplier; a.Data

ans =

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

Use the multiplyAllElements method to multiply each element in the array by a scalar value. Assign the returned object to the same variable.

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

See Also

matlab::data::Array | mex | matlab::mex::Function | matlab::mex::ArgumentList

Topics