I'm trying to run MATLAB from C++ and return the MATLAB output in a structure to C++. The structure could contain any number of things, including arrays of different dimensions and lengths. There's a similar question here, but the answer doesn't give enough detail for me to understand and extrapolate.
I'm running MATLAB using the MatlabEngine.hpp
and MatlabDataArray.hpp
. I need to return a lot of outputs and have tried other methods which don't quite do what I'm after. Using a structure seems the most logical / readable way to do things. I'll try to explain my case with the following examples, which are hopefully written in a way which will be most useful for anyone else with a similar problems.
MWE 1 - return n by n array
MATLAB code
function output = simple_fun1(a, bc)
% Takes input values of a and an array [a,b]
b = bc(1);
c = bc(2);
sum = a+b+c;
prod = a*b*c;
output = [sum, prod; 3, 4];
This can be run using the C++ code:
C++ code
#include "MatlabEngine.hpp"
#include "MatlabDataArray.hpp"
#include <iostream>
int main()
{
using namespace matlab::engine;
matlab::data::ArrayFactory factory; // Create MATLAB data array factory
std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Start MATLAB engine
matlabPtr->eval(u"addpath(genpath('C:/Users/...your path here...'))"); // Add the path to where MATLAB functions are.
std::vector<double> bc{ 10, 13};
std::vector<matlab::data::Array> args({
factory.CreateScalar<double>(7),
factory.CreateArray({ 1, 2 }, bc.cbegin(), bc.cend())
});
matlab::data::TypedArray<double> results = matlabPtr->feval(u"simple_fun1",args); // Run simple_fun1
std::cout << "Sum: " << results[0][0] << std::endl;
std::cout << "Prod: " << results[0][1] << std:endl;
std::cout << "Three: " << results[1][0] << std::endl;
}
This works for a single return of an n by n array. But if I want to return data separately, i.e. function [sum, prod] = simple_fun1(a,bc)
it doesn't work.
MWE2 - return multiple outputs
I've managed to return multiple outputs using tuples, but then I can only access the first element of the array (if it was an array output) since I've been unable to define a tuple of MATLAB arrays. For example
MATLAB code
function [sum, prod] = simple_fun2(a, bc)
% Takes input values of a and an array [a,b]
b = bc(1);
c = bc(2);
sum = a+b+c;
prod = a*b*c;
C++ code
std::tuple<double, double> results;
results = matlabPtr->feval< std::tuple<double, double>>(u"simple_fun2", double(7), std::vector<double>{ 10, 13}); // Just as another example of how to enter inputs in case that's helpful for anyone.
double s;
double p;
std::tie(s, p) = results;
std::cout << "Sum: " << s << ", Prod: " << p << std::endl;
Return structure
Instead, I would like to write my MATLAB function so that it returns a structure, which should hopefully simplify the code for large amounts of data being passed and allow the data to have different dimensions. However, I've been unable to create a working example.
MATLAB code
function output = simple_fun3(a, bc)
b = bc(1);
c = bc(2);
output.sum = a+b+c;
output.prod = a*b*c;
output.a_sq = a*a;
output.b_sq = b*b;
C++ code
#include "MatlabEngine.hpp"
#include "MatlabDataArray.hpp"
#include <iostream>
int main()
{
using namespace matlab::engine;
matlab::data::ArrayFactory factory; // Create MATLAB data array factory
std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Start MATLAB engine
matlabPtr->eval(u"addpath(genpath('C:/Users/...your path here...'))"); // Add the path to where MATLAB functions are.
std::vector<double> bc{ 10, 13};
std::vector<matlab::data::Array> args({
factory.CreateScalar<double>(7),
factory.CreateArray({ 1, 2 }, bc.cbegin(), bc.cend())
});
matlab::data::StructArray my_matlab_struct = factory.createStructArray(matlab::data::ArrayDimensions{ 1, 4}, std::vector<std::string>{'sum', 'prod', 'a_sq', 'b_sq'});
my_matlab_struct = matlabPtr->feval(u"simple_fun3",args);
The above C++ code doesn't work and I don't understand how the structure is being defined; i.e. what the ArrayDimensions are dimensions of. Any help is appreciated. Thanks