Main Content

CallMATLABFunctions from C++

Call MATLAB®从c++使用功能fevalandfevalAsyncmember functions of thematlab::engine::MATLABEngineclass. 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 MATLABfevalfunction.

To call a MATLAB function:

To evaluate MATLAB statements using variables in the MATLAB base workspace, use thematlab::engine::MATLABEngineevalandevalAsyncmember functions. These functions enable you to create and use variables in the MATLAB workspace, but do not return values. For more information, seeEvaluate MATLAB Statements from C++.

For information on how to setup and build C++ engine programs, seeBuild C++ Engine Programs.

Call Function with Single Returned Argument

This example uses the MATLABgcdfunction to find the greatest common divisor of two numbers. TheMATLABEngine::fevalmember function returns the results of thegcdfunction call.

Use thematlab::data::ArrayFactoryto create two scalarint16_targuments. Pass the arguments toMATLABEngine::fevalin astd::vector.

#include "MatlabEngine.hpp" #include "MatlabDataArray.hpp" #include 
void callFevalgcd() { // Pass vector containing MATLAB data array scalar using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr matlabPtr = startMATLAB(); // Create MATLAB data array factory matlab::data::ArrayFactory factory; // Pass vector containing 2 scalar args in vector std::vector args({ factory.createScalar(30), factory.createScalar(56) }); // Call MATLAB function and return result matlab::data::TypedArray result = matlabPtr->feval(u"gcd", args); int16_t v = result[0]; std::cout << "Result: " << v << std::endl; }

You can callMATLABEngine::fevalusing native C++ types. To do so, you must specify the returned type with the call toMATLABEngine::fevalas:

feval(...)

For example, the returned type isinthere:

int cresult = matlabPtr->feval(u"gcd", 30, 56);

This example defines amatlab::data::TypedArrayto pass an array of typedoubleto the MATLABsqrtfunction. Because one of the numbers in the array is negative, MATLAB returns a complex array as the result. Therefore, define the returned type as amatlab::data::TypedArray>.

# include“MatlabDataArray.hpp”# include"MatlabEngine.hpp" #include 
void callFevalsqrt() { // Call MATLAB sqrt function on array using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr matlabPtr = startMATLAB(); // Create MATLAB data array factory matlab::data::ArrayFactory factory; // Define a four-element array matlab::data::TypedArray const argArray = factory.createArray({ 1,4 }, { -2.0, 2.0, 6.0, 8.0 }); // Call MATLAB function matlab::data::TypedArray> 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 amatlab::data::Arrayfor returned types when calling MATLAB functions. For example, you can write the previous example using amatlab::data::Arrayfor the returned value.

void callFevalsqrt() { // Call MATLAB sqrt function on array using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr 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 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 astd::vectorto create a vector of arguments containing the names and values in correct sequence.

This sample code calls the MATLABmovsumfunction 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 arraysEndpointanddiscard

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 toMATLABEngine::fevalas astd::vectorcontaining these arguments for the MATLAB function. Create each argument using thematlab::data::ArrayFactory.

void callFevalmovsum() { //Pass vector containing various types of arguments using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr matlabPtr = startMATLAB(); // Create MATLAB data array factory matlab::data::ArrayFactory factory; // Create a vector of input arguments std::vector args({ factory.createArray({ 1, 10 }, { 4, 8, 6, -1, -2, -3, -1, 3, 4, 5 }), factory.createScalar(3), factory.createCharArray("Endpoints"), factory.createCharArray("discard") }); // Call MATLAB function matlab::data::TypedArray 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 MATLABconvfunction to multiply two polynomials. After callingMATLABEngine::fevalAsync, useFutureResult::getto get the result from MATLAB.

# include“MatlabDataArray.hpp”# include"MatlabEngine.hpp" #include 
static void callFevalAsync() { //Call MATLAB functions asynchronously using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr matlabPtr = startMATLAB(); // Create MATLAB data array factory matlab::data::ArrayFactory factory; // Create input argument arrays std::vector args({ factory.createArray({ 1, 3 },{ 1, 0, 1 }), factory.createArray({ 1, 2 },{ 2, 7 }) }); String func(u"conv"); // Call function asnychronously FutureResult future = matlabPtr->fevalAsync(func, args); // Get results matlab::data::TypedArray 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 MATLABgcdfunction to find the greatest common divisor and Bézout coefficients from the two numeric values passes as inputs. Thegcdfunction can return either one or three arguments, depending on how many outputs the function call requests. In this example, the call to the MATLABgcdfunction returns three outputs.

By default,MATLABEngine::fevalassumes that the number of returned values is one. Therefore, you must specify the actual number of returned values as the second argument toMATLABEngine::feval.

In this example,MATLABEngine::feval返回一个std::vectorcontaining the three results of thegcdfunction call. The returned values are scalar integers.

# include“MatlabDataArray.hpp”# include"MatlabEngine.hpp" #include 
void multiOutput() { //Pass vector containing MATLAB data array array using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr 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 args({ factory.createScalar(30), factory.createScalar(56) }); //Call gcd function, get 3 outputs const size_t numReturned = 3; std::vector 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::fevalandMATLABEngine::fevalAsyncaccept 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, seeMATLAB Data API for C++.

This example usesint16_tvalues as inputs and astd::tupleto return the results from the MATLABgcdfunction.

Here is the equivalent MATLAB code.

[G,U,V] = gcd(int16(30),int16(56));
#include "MatlabEngine.hpp" #include  #include 
空白multiOutputTuple(){/ /返回从MATL元组AB function call using namespace matlab::engine; // Start MATLAB engine synchronously std::unique_ptr matlabPtr = startMATLAB(); //Call MATLAB gcd function std::tuple nresults; nresults = matlabPtr->feval> (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, seematlab::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 MATLABpausefunction holds execution for a specified number of seconds. However, if you callpausewith 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 callspausewithout assigning an output. Withvoidoutput 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 matlabPtr = startMATLAB(); // Call pause function with no output matlabPtr->feval(u"pause", 20); }

This call toMATLABEngine::fevaluses the signature that defines the MATLAB function arguments as astd::vector. 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 matlabPtr = startMATLAB(); //Create MATLAB data array factory matlab::data::ArrayFactory factory; // Call pause function with no output matlab::data::Array arg = factory.createScalar(20); const size_t numReturned = 0; matlabPtr->feval(u"pause", numReturned, { arg }); }

The MATLABclockfunction returns the current date and time as a date vector. If you assign two outputs,clockreturns the second output as a Boolean value indicating if it is Daylight Saving Time in the system time zone.

This example calls theclockfunction with one output or two outputs, depending on the value of an input argument. The second argument passed to the call toMATLABEngine::fevaldetermines how many outputs to request fromclock.

CallMATLABEngine::fevalwith these arguments.

Inputs

MATLAB function name const matlab::engine::String
Number of outputs const size_t
Input arguments for MATLAB function (empty) std::vector

Outputs

All outputs std::vector
# include“MatlabDataArray.hpp”# include"MatlabEngine.hpp" #include 
空白varOutputs (const bool tZone)使用namespac {e matlab::engine; // Start MATLAB engine synchronously std::unique_ptr matlabPtr = startMATLAB(); std::cout << "Started MATLAB Engine" << std::endl; // Define number of outputs size_t numReturned(0); if (tZone) { numReturned = 2; } else { numReturned = 1; } std::vector dateTime = matlabPtr->feval(u"clock", numReturned, { }); matlab::data::Array dateVector = dateTime[0]; // Display results for (int i = 0; i < 6; i++) { std::cout << double(dateVector[i]) << " "; } if (tZone) { matlab::data::Array DTS = dateTime[1]; if (bool(DTS[0])) { std::cout << "It is Daylight Saving Time" << std::endl; } else { std::cout << "It is Standard Time" << std::endl; } } }

See Also

|

Related Topics