Main Content

Using MEX Functions for MATLAB Class Methods

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:

  • Define the MATLAB class in an @ folder so the methods can be contained in separate files. See Methods in Separate Files.

  • Implement the MEX function and put the executable file in the class @ folder.

  • Reference the MEX function in the class definition Methods block.

  • Call the MEX function like any method.

Method to Multiply Matrix by Scalar

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

This class stores a 2-D array in its Data property. The multiplyAllElements method accepts a class instance and a scalar multiplier as inputs. The method multiplies the elements of the array in the Data 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 the multiplyAllElements 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 the Data property is a 4-by-4 array returned by the expression ones(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

| | |

Related Topics