Вызовите функции MATLAB® с C++ с помощью feval и fevalAsync функций членства класса matlab::engine::MATLABEngine
. Используйте эти функции когда это необходимо, чтобы передать аргументы функции от C++ до MATLAB и возвратить результат функционального выполнения на C++. Эти функции членства работают как функция feval
MATLAB.
Вызывать функцию MATLAB:
Передайте имя функции как matlab::engine::String
.
Задайте входные параметры, требуемые функцией MATLAB. Можно использовать или нативные типы данных C++ или MATLAB Data API. Для получения дополнительной информации см. MATLAB Data API.
Задайте количество выходных параметров, ожидаемых от функции MATLAB. Один вывод является значением по умолчанию. Для получения дополнительной информации смотрите, Вызывают Функцию с Многократными возвращаемыми параметрами и Контрольным числом Выходных параметров.
Задайте соответствующий возвращенный тип для результатов функции MATLAB.
Используйте потоковые буферы, чтобы перенаправить стандартный вывод и стандартную погрешность от окна команды MATLAB до C++. Для получения дополнительной информации смотрите Перенаправление Окно Команды MATLAB Вывод на C++
Чтобы оценить переменные использования выражений MATLAB в базовом рабочем пространстве MATLAB, используйте
eval matlab::engine::MATLABEngine
и evalAsync функции членства. Эти функции позволяют вам создать и использовать переменные в рабочем пространстве MATLAB, но сделать не возвращаемые значения. Для получения дополнительной информации смотрите, Оценивают Выражения MATLAB с C++.
Для получения информации о том, как установить и создать программы механизма C++, видит Сборку Программы Engine C++.
Этот пример использует функцию gcd
MATLAB, чтобы найти наибольший общий делитель двух чисел. Функция членства 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
к функции sqrt
MATLAB. Поскольку одно из чисел в массиве отрицательно, 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
, чтобы создать вектор аргументов, содержащих имена и значения в правильной последовательности.
Этот пример кода вызывает функцию movsum
MATLAB, чтобы вычислить движущуюся сумму в центре с тремя точками вектора - строки, отбрасывая вычисления конечной точки. Этот вызов функции требует этих аргументов:
Числовой массив
Скалярная длина окна
Пара "имя-значение", состоящая из символьных массивов 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; } }
Этот пример вызывает функцию conv
MATLAB, чтобы умножить два полинома. После вызова 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; } }
Этот пример кода использует функцию gcd
MATLAB, чтобы найти наибольший общий делитель и коэффициенты 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
, чтобы возвратить результаты функции gcd
MATLAB.
Вот эквивалентный код 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 могут вести себя по-другому в зависимости от количества выходных параметров, которые требуют. Некоторые функции не могут возвратить выходные параметры или конкретное количество выходных параметров.
Например, функция pause
MATLAB содержит выполнение для конкретного количества секунд. Однако, если вы вызываете 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 }); }
Функция clock
MATLAB возвращает текущую дату и время как вектор даты. Если вы присваиваете два выходных параметров, 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, { }); auto dateVector = dateTime[0]; // Display results for (int i = 0; i < 6; i++) { std::cout << double(dateVector[i]) << " "; } if (tZone) { auto 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