Вызов MATLAB® функции от C++ с использованием функций feval и fevalAsync представителя matlab::engine::MATLABEngine класс. Используйте эти функции, когда вы хотите передать аргументы функции от C++ в MATLAB и вернуть результат выполнения функции к C++. Эти представители функции работают, как MATLAB feval функция.
Для вызова функции MATLAB:
Передайте имя функции как matlab::engine::String.
Задайте входные параметры, требуемые функцией MATLAB. Можно использовать как собственные типы данных C++, так и MATLAB Data API. Для получения дополнительной информации см. MATLAB Data API.
Укажите количество выходов, ожидаемых от функции MATLAB. Одним из выходных параметров является выход по умолчанию. Для получения дополнительной информации смотрите Функцию вызова с несколькими возвращенными аргументами и Количество управляющих выходов.
Определите соответствующий возвращенный вид для результатов функции MATLAB.
Используйте буферы потоков для перенаправления стандартного выхода и стандартной ошибки из командного окна MATLAB на C++. Для получения дополнительной информации см. «Перенаправление Командного окна MATLAB Выхода на C++»
Чтобы вычислить выражения MATLAB с помощью переменных в базовом рабочем пространстве MATLAB, используйте matlab::engine::MATLABEngine
Функции eval и evalAsync представителя. Эти функции позволяют вам создавать и использовать переменные в рабочем пространстве MATLAB, но не возвращать значения. Для получения дополнительной информации смотрите Оценка выражений MATLAB из C++.
Для получения информации о том, как настроить и создать программы C++ engine, смотрите Сборка программ C++ Engine.
Этот пример использует MATLAB gcd функция для нахождения наибольшего общего делителя двух чисел. The MATLABEngine::feval Представителю функция возвращает результаты gcd вызов функции.
Используйте matlab::data::ArrayFactory для создания двух скалярных int16_t аргументы. Передайте аргументы в MATLABEngine::feval в 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;
}
Можно вызвать MATLABEngine::feval использование собственных типов C++. Для этого необходимо задать возвращаемый тип с вызовом, равным MATLABEngine::feval как:
feval<type>(...)
Например, возвращаемый тип int здесь:
int cresult = matlabPtr->feval<int>(u"gcd", 30, 56);
Этот пример задает matlab::data::TypedArray для прохождения массива типов double в MATLAB sqrt функция. Поскольку одно из чисел в массиве отрицательное, MATLAB возвращает комплексный массив в результате. Поэтому определите возвращенный тип как 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;
}
}Безопасно использовать matlab::data::Array для возвращаемых типов при вызове функций MATLAB. Например, можно записать предыдущий пример с помощью matlab::data::Array для возвращенного значения.
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;
}
}Некоторые функции MATLAB принимают необязательные аргументы пары "имя-значение". Имена являются символьными массивами, а значения могут быть любым типом значения. Использование std::vector создать вектор аргументов, содержащий имена и значения в правильной последовательности.
Этот пример кода вызывает MATLAB movsum функция для вычисления трехточечной центрированной движущейся суммы вектора-строки, отбрасывающей вычисления конечной точки. Этот вызов функции требует следующих аргументов:
Числовой массив
Длина скалярного окна
Пара "имя-значение", состоящая из символьных массивов Endpoint и discard
Вот эквивалентный код MATLAB:
A = [4 8 6 -1 -2 -3 -1 3 4 5]; M = movsum(A,3,'Endpoints','discard');
Передайте аргументы в MATLABEngine::feval как std::vector содержащие эти аргументы для функции MATLAB. Создайте каждый аргумент с помощью 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;
}
}
Этот пример вызывает MATLAB conv функция для умножения двух полиномов. После вызова MATLABEngine::fevalAsync, использовать FutureResult::get для получения результата от 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;
}
}Этот пример кода использует MATLAB gcd функция для нахождения наибольших коэффициентов общего делителя и Безу из двух числовых значений проходит как входы. The gcd функция может вернуть один или три аргумента в зависимости от того, сколько выходов запросов вызов функции. В этом примере вызов MATLAB gcd функция возвращает три выхода.
По умолчанию MATLABEngine::feval принимает, что количество возвращенных значений равно единице. Поэтому необходимо задать фактическое количество возвращенных значений в качестве второго аргумента для MATLABEngine::feval.
В этом примере MATLABEngine::feval возвращает std::vector содержащие три результата gcd вызов функции. Возвращенные значения являются скалярными целыми числами.
#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;
}
}Можно использовать собственные типы C++ при вызове функций MATLAB. MATLABEngine::feval и MATLABEngine::fevalAsync примите определенные скалярные типы C++, переданные как аргументы функции MATLAB. Чтобы передать массивы и другие типы функциям MATLAB, используйте MATLAB Data API. Для получения дополнительной информации об этом API см. MATLAB Data API.
Этот пример использует int16_t значения как входы и a std::tuple для возврата результатов из MATLAB gcd функция.
Вот эквивалентный код MATLAB.
[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;
}Для получения конкретной информации о синтаксисе представителя функции смотрите matlab::engine::MATLABEngine.
Функции MATLAB могут вести себя по-разному в зависимости от количества запрашиваемых выходов. Некоторые функции не могут вернуть выходов или заданное количество выходов.
Для примера, MATLAB pause функция содержит выполнение в течение заданного количества секунд. Однако, если вы звоните pause с выходным аргументом он немедленно возвращается со значением состояния без паузы.
pause(20) % Pause for 20 secondsstate = pause(20); % No pause, return pause stateЭтот пример вызывает pause без назначения выхода. С void заданный выход, MATLAB останавливает выполнение на 20 секунд.
#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);
}Этот вызов для MATLABEngine::feval использует сигнатуру, которая задает аргументы функции MATLAB как std::vector<matlab::data::Array>. Не присваивая выходной аргумент, MATLAB останавливает выполнение на 20 секунд.
#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 });
}MATLAB clock функция возвращает текущую дату и время в качестве вектора даты. Если вы присваиваете два выхода, clock возвращает второй выход в виде логического значения, указывающего, является ли это дневным Сохранением временем в системном часовом поясе.
Этот пример вызывает clock функция с одним выходом или двумя выходами, в зависимости от значения входного параметра. Второй аргумент передан вызову на MATLABEngine::feval определяет, сколько выходов запрашивается clock.
Функции MATLABEngine::feval с этими аргументами.
Исходные данные
| Имя функции MATLAB | const matlab::engine::String |
| Количество выходов | const size_t |
| Входные параметры для функции MATLAB (пустые) | std::vector<matlab::data::Array> |
Выходы
| Все выходы | std::vector<matlab::data::Array> |
#include "MatlabDataArray.hpp" #include "MatlabEngine.hpp" #include <iostream>
void varOutputs(const bool tZone) {
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr<MATLABEngine> 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<matlab::data::Array> 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;
}
}
}matlab::data::ArrayFactory | matlab::engine::MATLABEngine