Вызов 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 seconds
state = 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