Call MATLAB Functions from C++
Call MATLAB® functions from C++ using the feval and fevalAsync member functions of the matlab::engine::MATLABEngine
class. Use
these functions when you want to pass function arguments from C++ to MATLAB and to return the result of the function execution to C++. These member
functions work like the MATLAB
feval
function.
To call a MATLAB function:
Pass the function name as a
matlab::engine::String
.Define the input arguments required by the MATLAB function. You can use either native C++ data types or the MATLAB Data API. For more information, see MATLAB Data API for C++.
Specify the number of outputs expected from the MATLAB function. One output is the default. For more information, see Call Function with Multiple Returned Arguments and Control Number of Outputs.
Define the appropriate returned type for the results of the MATLAB function.
Use stream buffers to redirect standard output and standard error from the MATLAB command window to C++. For more information, see Redirect MATLAB Command Window Output to C++
To evaluate MATLAB statements using variables in the MATLAB base workspace, use the matlab::engine::MATLABEngine
eval and evalAsync member functions. These functions enable you
to create and use variables in the MATLAB workspace, but do not return values. For more information, see Evaluate MATLAB Statements from C++.
For information on how to setup and build C++ engine programs, see Requirements to Build C++ Engine Programs.
Call Function with Single Returned Argument
This example uses the MATLAB
gcd
function to find the greatest
common divisor of two numbers. The MATLABEngine::feval
member
function returns the results of the gcd
function call.
Use the matlab::data::ArrayFactory
to create two scalar
int16_t
arguments. Pass the arguments to
MATLABEngine::feval
in a std::vector
.
#include "MatlabEngine.hpp" #include "MatlabDataArray.hpp" #include <iostream>
void callFevalgcd() { // Pass vector containing MATLAB data array scalar using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Create MATLAB data array factory matlab::data::ArrayFactory factory; // Pass vector containing 2 scalar args in vector std::vector<matlab::data::Array> args({ factory.createScalar<int16_t>(30), factory.createScalar<int16_t>(56) }); // Call MATLAB function and return result matlab::data::TypedArray<int16_t> result = matlabPtr->feval(u"gcd", args); int16_t v = result[0]; std::cout << "Result: " << v << std::endl; }
You can call MATLABEngine::feval
using native C++ types. To do
so, you must specify the returned type with the call to
MATLABEngine::feval
as:
feval<type>(...)
For example, the returned type is int
here:
int cresult = matlabPtr->feval<int>(u"gcd", 30, 56);
This example defines a matlab::data::TypedArray
to pass an
array of type double
to the MATLAB
sqrt
function. Because one of the
numbers in the array is negative, MATLAB returns a complex array as the result. Therefore, define the returned
type as a
matlab::data::TypedArray<std::complex<double>>
.
#include "MatlabDataArray.hpp" #include "MatlabEngine.hpp" #include <iostream>
void callFevalsqrt() { // Call MATLAB sqrt function on array using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Create MATLAB data array factory matlab::data::ArrayFactory factory; // Define a four-element array matlab::data::TypedArray<double> const argArray = factory.createArray({ 1,4 }, { -2.0, 2.0, 6.0, 8.0 }); // Call MATLAB function matlab::data::TypedArray<std::complex<double>> const results = matlabPtr->feval(u"sqrt", argArray); // Display results int i = 0; for (auto r : results) { double a = argArray[i++]; double realPart = r.real(); double imgPart = r.imag(); std::cout << "Square root of " << a << " is " << realPart << " + " << imgPart << "i" << std::endl; } }
It is safe to use a matlab::data::Array
for returned
types when calling MATLAB functions. For example, you can write the previous example using a
matlab::data::Array
for the returned value.
void callFevalsqrt() { // Call MATLAB sqrt function on array using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Create MATLAB data array factory matlab::data::ArrayFactory factory; // Define a four-element array matlab::data::Array const argArray = factory.createArray({ 1,4 }, { -2.0, 2.0, 6.0, 8.0 }); // Call MATLAB function matlab::data::Array results = matlabPtr->feval(u"sqrt", argArray); // Display results for (int i = 0; i < results.getNumberOfElements(); i++) { double a = argArray[i]; std::complex<double> v = results[i]; double realPart = v.real(); double imgPart = v.imag(); std::cout << "Square root of " << a << " is " << realPart << " + " << imgPart << std::endl; } }
Call Function with Name/Value Arguments
Some MATLAB functions accept optional name-value pair arguments. The names are
character arrays and the values can be any type of value. Use a
std::vector
to create a vector of arguments containing the
names and values in correct sequence.
This sample code calls the MATLAB
movsum
function to compute the
three-point centered moving sum of a row vector, discarding endpoint calculations.
This function call requires these arguments:
Numeric array
Scalar window length
Name-value pair consisting of the character arrays
Endpoint
anddiscard
Here is the equivalent MATLAB code:
A = [4 8 6 -1 -2 -3 -1 3 4 5]; M = movsum(A,3,'Endpoints','discard');
Pass the arguments to MATLABEngine::feval
as a
std::vector
containing these arguments for the MATLAB function. Create each argument using the matlab::data::ArrayFactory
.
void callFevalmovsum() { //Pass vector containing various types of arguments using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Create MATLAB data array factory matlab::data::ArrayFactory factory; // Create a vector of input arguments std::vector<matlab::data::Array> args({ factory.createArray<double>({ 1, 10 }, { 4, 8, 6, -1, -2, -3, -1, 3, 4, 5 }), factory.createScalar<int32_t>(3), factory.createCharArray("Endpoints"), factory.createCharArray("discard") }); // Call MATLAB function matlab::data::TypedArray<double> const result = matlabPtr->feval(u"movsum", args); // Display results int i = 0; for (auto r : result) { std::cout << "results[" << i++ << "] = " << r << std::endl; } }
Call Function Asynchronously
This example calls the MATLAB
conv
function to multiply two
polynomials. After calling MATLABEngine::fevalAsync
, use
FutureResult::get
to get the result from MATLAB.
#include "MatlabDataArray.hpp" #include "MatlabEngine.hpp" #include <iostream>
static void callFevalAsync() { //Call MATLAB functions asynchronously using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Create MATLAB data array factory matlab::data::ArrayFactory factory; // Create input argument arrays std::vector<matlab::data::Array> args({ factory.createArray<double>({ 1, 3 },{ 1, 0, 1 }), factory.createArray<double>({ 1, 2 },{ 2, 7 }) }); String func(u"conv"); // Call function asnychronously FutureResult<matlab::data::Array> future = matlabPtr->fevalAsync(func, args); // Get results matlab::data::TypedArray<double> results = future.get(); // Display results std::cout << "Coefficients: " << std::endl; for (auto r : results) { std::cout << r << " " << std::endl; } }
Call Function with Multiple Returned Arguments
This sample code uses the MATLAB
gcd
function to find the greatest
common divisor and Bézout coefficients from the two numeric values passes as
inputs. The gcd
function can return either one or three
arguments, depending on how many outputs the function call requests. In this
example, the call to the MATLAB
gcd
function returns three outputs.
By default, MATLABEngine::feval
assumes that the number of
returned values is one. Therefore, you must specify the actual number of returned
values as the second argument to MATLABEngine::feval
.
In this example, MATLABEngine::feval
returns a
std::vector
containing the three results of the
gcd
function call. The returned values are scalar
integers.
#include "MatlabDataArray.hpp" #include "MatlabEngine.hpp" #include <iostream>
void multiOutput() { //Pass vector containing MATLAB data array array using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); std::cout << "Started MATLAB Engine" << std::endl; //Create MATLAB data array factory matlab::data::ArrayFactory factory; //Create vector of MATLAB data array arrays std::vector<matlab::data::Array> args({ factory.createScalar<int16_t>(30), factory.createScalar<int16_t>(56) }); //Call gcd function, get 3 outputs const size_t numReturned = 3; std::vector<matlab::data::Array> result = matlabPtr->feval(u"gcd", numReturned, args); //Display results for (auto r : result) { std::cout << "gcd output: " << int16_t(r[0]) << std::endl; } }
Call Function with Native C++ Types
You can use native C++ types when calling MATLAB functions. MATLABEngine::feval
and MATLABEngine::fevalAsync
accept
certain scalar C++ types passed as MATLAB function arguments. To pass arrays and other types to MATLAB functions, use the MATLAB Data API. For more information on this API, see MATLAB Data API for C++.
This example uses int16_t
values as inputs and a
std::tuple
to return the results from the MATLAB
gcd
function.
Here is the equivalent MATLAB code.
[G,U,V] = gcd(int16(30),int16(56));
#include "MatlabEngine.hpp" #include <iostream> #include <tuple>
void multiOutputTuple() { //Return tuple from MATLAB function call using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); //Call MATLAB gcd function std::tuple<int16_t, int16_t, int16_t> nresults; nresults = matlabPtr->feval<std::tuple<int16_t, int16_t, int16_t>> (u"gcd", int16_t(30), int16_t(56)); // Display results int16_t G; int16_t U; int16_t V; std::tie(G, U, V) = nresults; std::cout << "GCD : " << G << ", " << "Bezout U: " << U << ", " << "Bezout V: " << V << std::endl; }
For specific information on member function syntax, see matlab::engine::MATLABEngine
.
Control Number of Outputs
MATLAB functions can behave differently depending on the number of outputs requested. Some functions can return no outputs or a specified number of outputs.
For example, the MATLAB
pause
function holds execution for
a specified number of seconds. However, if you call pause
with
an output argument, it returns immediately with a status value without
pausing.
pause(20) % Pause for 20 seconds
state = pause(20); % No pause, return pause state
This example calls pause
without assigning an output. With
void
output specified, MATLAB pauses execution for 20 seconds.
#include "MatlabEngine.hpp"
void voidOutput() { // No output from feval using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Call pause function with no output matlabPtr->feval<void>(u"pause", 20); }
This call to MATLABEngine::feval
uses the signature that
defines the MATLAB function arguments as a
std::vector<matlab::data::Array>
. Without assigning an
output argument, MATLAB pauses execution for 20 seconds.
#include "MatlabDataArray.hpp" #include "MatlabEngine.hpp"
void zeroOutput() { // No output from feval using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); //Create MATLAB data array factory matlab::data::ArrayFactory factory; // Call pause function with no output matlab::data::Array arg = factory.createScalar<int16_t>(20); const size_t numReturned = 0; matlabPtr->feval(u"pause", numReturned, { arg }); }
See Also
matlab::data::ArrayFactory
| matlab::engine::MATLABEngine