Вызовите 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++.
Этот пример использует MATLAB gcd функционируйте, чтобы найти наибольший общий делитель двух чисел. 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 функционируйте, чтобы найти наибольший общий делитель и коэффициенты Bézout от этих двух передач числовых значений как входные параметры. gcd функция может возвратить или один или три аргумента, в зависимости от того, сколько выходных параметров запрашивает вызов функции. В этом примере, вызове gcd MATLAB функция возвращает три выходных параметра.
По умолчанию, 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 значения как входные параметры и 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