C++에서 MATLAB 함수 호출하기
matlab::engine::MATLABEngine
클래스의 feval 및 fevalAsync 멤버 함수를 사용하여 C++에서 MATLAB® 함수를 호출합니다. C++에서 MATLAB으로 함수 인수를 전달하고 함수 실행 결과를 C++로 반환하고 싶을 때 이런 함수를 사용합니다. 이러한 멤버 함수는 MATLAB feval
함수처럼 작동합니다.
MATLAB 함수를 호출하려면 다음을 수행하십시오.
함수 이름을
matlab::engine::String
으로 전달합니다.MATLAB 함수에 필요한 입력 인수를 정의합니다. 기본 C++ 데이터형 또는 MATLAB Data API를 사용할 수 있습니다. 자세한 내용은 C++용 MATLAB Data API 항목을 참조하십시오.
MATLAB 함수의 예상 출력값 개수를 지정합니다. 디폴트 값은 출력값 한 개입니다. 자세한 내용은 반환되는 인수가 여러 개인 함수 호출하기 항목과 출력값 개수 제어하기 항목을 참조하십시오.
MATLAB 함수의 결과에 대한 적절한 반환 유형을 정의합니다.
스트림 버퍼를 사용하여 MATLAB 명령 창에 표시되는 표준 출력값과 표준 오차를 C++로 리디렉션합니다. 자세한 내용은 Redirect MATLAB Command Window Output to C++ 항목을 참조하십시오.
MATLAB 기본 작업 공간에 있는 변수를 사용하여 MATLAB 명령문을 실행하려면 matlab::engine::MATLABEngine
eval 및 evalAsync 멤버 함수를 사용하십시오. 이러한 함수는 사용자가 MATLAB 작업 공간에서 변수를 만들고 사용하는 것을 허용하지만 값을 반환하지는 않습니다. 자세한 내용은 Evaluate MATLAB Statements from C++ 항목을 참조하십시오.
C++ 엔진 프로그램을 설정하고 빌드하는 방법에 관한 자세한 내용은 C++ 엔진 프로그램 빌드를 위한 요구 사항 항목을 참조하십시오.
반환되는 인수가 하나인 함수 호출하기
이 예제에서는 MATLAB gcd
함수를 사용하여 두 숫자의 최대공약수를 찾습니다. MATLABEngine::feval
멤버 함수는 gcd
함수 호출의 결과를 반환합니다.
matlab::data::ArrayFactory
를 사용하여 2개의 스칼라 int16_t
인수를 만듭니다. std::vector
의 MATLABEngine::feval
로 인수를 전달합니다.
#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; }
기본 C++ 유형을 사용하여 MATLABEngine::feval
을 호출할 수 있습니다. 이렇게 하려면 MATLABEngine::feval
에 대한 호출로 반환되는 유형을 다음과 같이 지정해야 합니다.
feval<type>(...)
예를 들어, 여기서 반환되는 유형은 int
입니다.
int cresult = matlabPtr->feval<int>(u"gcd", 30, 56);
이 예제에서는 double
형의 배열을 MATLAB sqrt
함수로 전달하기 위해 matlab::data::TypedArray
를 정의합니다. 배열에 있는 숫자 중 하나가 음수이므로, 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 함수를 호출할 때 반환되는 유형에 matlab::data::Array
를 사용하는 것이 안전합니다. 예를 들어, 앞의 예제에서 반환되는 값에 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
함수를 호출해 끝점 계산을 무시하고 행 벡터의 3점 중심 이동합을 계산합니다. 이 함수 호출에는 다음 인수가 필요합니다.
숫자형 배열
스칼라 윈도우 길이
문자형 배열
Endpoint
와discard
로 구성된 이름-값 쌍
다음은 이와 동일한 MATLAB 코드입니다.
A = [4 8 6 -1 -2 -3 -1 3 4 5]; M = movsum(A,3,'Endpoints','discard');
MATLAB 함수에 대해 다음과 같은 인수를 포함한 std::vector
를 MATLABEngine::feval
에 인수로 전달합니다. 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 coefficient)를 구합니다. gcd
함수는 함수 호출에서 요청하는 출력값의 개수에 따라 한 개 또는 세 개의 인수를 반환할 수 있습니다. 이 예제에서는 MATLAB gcd
함수에 대한 호출이 세 개의 출력값을 반환합니다.
기본적으로, MATLABEngine::feval
은 반환되는 값의 개수가 한 개인 것으로 가정합니다. 따라서 반환되는 값의 실제 개수를 MATLABEngine::feval
에 대한 두 번째 인수로 지정해야 합니다.
이 예제에서, MATLABEngine::feval
은 gcd
함수 호출의 세 결과를 포함한 std::vector
를 반환합니다. 반환되는 값은 정수 스칼라입니다.
#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 함수를 호출할 때 기본 C++ 유형을 사용할 수 있습니다. MATLABEngine::feval
과 MATLABEngine::fevalAsync
는 MATLAB 함수 인수로 전달되는 특정 스칼라 C++ 유형을 허용합니다. 배열과 기타 유형을 MATLAB 함수로 전달하려면 MATLAB Data API를 사용하십시오. 이 API에 대한 자세한 내용은 C++용 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::data::ArrayFactory
| matlab::engine::MATLABEngine