Вызовите функции MATLAB ® из C++, используя функции-члены feval и fevalAsync matlab::engine::MATLABEngine класс. Эти функции используются для передачи аргументов функции из C++ в MATLAB и возврата результата выполнения функции в C++. Эти функции-члены работают подобно MATLAB feval функция.
Для вызова функции MATLAB:
Передать имя функции как matlab::engine::String.
Определите входные аргументы, необходимые для функции MATLAB. Можно использовать либо собственные типы данных C++, либо API данных MATLAB. Дополнительные сведения см. в разделе API данных MATLAB.
Укажите количество выходов, ожидаемых от функции MATLAB. Одним из выходных данных является значение по умолчанию. Дополнительные сведения см. в разделе Функция вызова с несколькими возвращенными аргументами и контрольным количеством выходов.
Определите соответствующий возвращаемый тип для результатов функции MATLAB.
Используйте буферы потока для перенаправления стандартных выходных данных и стандартных ошибок из окна команд MATLAB в C++. Дополнительные сведения см. в разделе Перенаправление выходных данных командного окна MATLAB на C++
Для анализа инструкций MATLAB с использованием переменных в базовой рабочей области MATLAB используйте matlab::engine::MATLABEngine
функции-члены eval и evalAsync. Эти функции позволяют создавать и использовать переменные в рабочей области MATLAB, но не возвращают значения. Дополнительные сведения см. в разделе Оценка операторов MATLAB на языке C++.
Сведения о настройке и сборке программ ядра C++ см. в разделе Сборка программ ядра 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 функция для нахождения наибольших общих коэффициентов делителя и Безаута из двух числовых значений, передаваемых в качестве входных данных. 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;
}
}При вызове функций MATLAB можно использовать собственные типы C++. MATLABEngine::feval и MATLABEngine::fevalAsync принимать определенные скалярные типы C++, переданные в качестве аргументов функции MATLAB. Для передачи массивов и других типов функциям MATLAB используется API данных MATLAB. Дополнительные сведения об этом 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