Вызовите функции 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 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