Вызов функций MATLAB с C++

Вызовите MATLAB® функции с C++ с помощью feval и fevalAsync функций членства matlab::engine::MATLABEngine класс. Используйте эти функции, когда это необходимо, чтобы передать аргументы функции от C++ до MATLAB и возвратить результат функционального выполнения на C++. Эти функции членства работают как MATLAB feval функция.

Вызывать функцию MATLAB:

Чтобы оценить переменные использования выражений 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++

Можно использовать нативные типы 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 с этими аргументами.

Входные параметры

Имя функции MATLABconst matlab::engine::String
Количество выходных параметровconst size_t
Входные параметры для (пустой) функции MATLABstd::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;
        }
    }
}

Смотрите также

|

Похожие темы