How do I call Matlab polyfit function from C++?

10 vues (au cours des 30 derniers jours)
Nidal Bazzi
Nidal Bazzi le 5 Juin 2024
Commenté : Hassaan le 7 Juin 2024
Hello, I am trying to call the MATLAB polyfit function from a Windows application written in Visual Studio 2022 C++ and get the polynomial coefficients array, s, and mu from from polyfit.
int main(int argc, char* argv[])
{
double x[40];
double y[40];
double p[12]; // MATLAB returned array of coefficients
size_t dataSize;
// this function gets the data from a file and updates the unknown xy data size
// the data size = 40 elements
getXYpoints(x, y, &dataSize);
if (dataSize == 0)
{
cout << endl << "File Size is Zero, nothing to do";
return -2;
}
polyFit(x, y, p,dataSize, 12); // 12 is the order of the polynomials
}
The polyFit calls the MATLAB polyfit function
void polyFit(double* x, double* y, double* poly_coefficients, size_t xy_size, size_t poly_size)
{
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();
std::tuple<double, double, double> nresults;
// the following line gives a compile error for x, y, and the tuple definitions
nresults = matlabPtr->feval<std::tuple <double*, double, double>>(u"polyfit", x , y, poly_size);
//[p, s, mu] = polyfit (x,y, 12);
double P;
double S;
double MU;
std::tie(P, S, MU) = nresults;
for (auto it : p)
{
p[it] = P[it];
}
auto s = S;
auto mu = MU;
.
.
.
}
tuple <double*, double, double> tuple does not seem to support the first argument double*. Is there a better way to call polyfit from C++, or how do I overload the tuple class to accept a pointer to P (the polynomial coefficients array).

Réponse acceptée

Nidal Bazzi
Nidal Bazzi le 6 Juin 2024
Thank you, the last update seems to work, there are no more exceptions when the code runs but I am unable to access the p, s, and mu in C++. p is supposed to be a 1X13 array of double, s is a 1X1 struct with fields R (13X13) double, df is integer, normr is a double, mu is 2X1 array of double.
FutureResult<std::vector<Array>> result = matlabPtr->fevalAsync(u"polyfit", 3, { mxArrayX, mxArrayY, factory.createScalar<double>(poly_size) }); // line 64
.
.
.
// Extract s and mu if needed
auto s_field1 = s[0][u"normr"]; // line 81
double mu_field1 = mu[0][u"field1"]; // line 82
std::cout >> poly_coefficients[0]; // line 83
These are the errors in Visual Studio
Rebuild started at 12:59 PM...
1>------ Rebuild All started: Project: ectCalFit, Configuration: Debug x64 ------
1>matlab_functions.cpp
1>D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(64,135): warning C4244: 'argument': conversion from 'size_t' to 'const T', possible loss of data
1>D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(64,135): warning C4244: with
1>D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(64,135): warning C4244: [
1>D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(64,135): warning C4244: T=double
1>D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(64,135): warning C4244: ]
1>D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(81,24): error C2679: binary '[': no operator found which takes a right-hand operand of type 'const char16_t [6]' (or there is no acceptable conversion)
1>C:\Program Files\MATLAB\R2020b\extern\include\MatlabDataArray\ArrayElementTypedRef.hpp(108,55):
1>could be 'matlab::data::ArrayElementTypedRef<T,false> matlab::data::ArrayElementTypedRef<matlab::data::Struct,false>::operator [](std::string)'
1> with
1> [
1> T=matlab::data::Array
1> ]
1>C:\Program Files\MATLAB\R2020b\extern\include\MatlabDataArray\ArrayElementTypedRef.hpp(86,51):
1>or 'matlab::data::ArrayElementTypedRef<matlab::data::Struct,false> matlab::data::ArrayElementTypedRef<matlab::data::Struct,false>::operator [](size_t)'
1>D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(81,24):
1>while trying to match the argument list '(matlab::data::ArrayElementTypedRef<matlab::data::Struct,false>, const char16_t [6])'
1>D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(82,28): error C2679: binary '[': no operator found which takes a right-hand operand of type 'const char16_t [7]' (or there is no acceptable conversion)
1>C:\Program Files\MATLAB\R2020b\extern\include\MatlabDataArray\ArrayElementTypedRef.hpp(108,55):
1>could be 'matlab::data::ArrayElementTypedRef<T,false> matlab::data::ArrayElementTypedRef<double,false>::operator [](std::string)'
1> with
1> [
1> T=matlab::data::Array
1> ]
1>C:\Program Files\MATLAB\R2020b\extern\include\MatlabDataArray\ArrayElementTypedRef.hpp(86,51):
1>or 'matlab::data::ArrayElementTypedRef<T,false> matlab::data::ArrayElementTypedRef<T,false>::operator [](size_t)'
1> with
1> [
1> T=double
1> ]
1>D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(82,28):
1>while trying to match the argument list '(matlab::data::ArrayElementTypedRef<T,false>, const char16_t [7])'
1> with
1> [
1> T=double
1> ]
1>D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(83,15): error C2676: binary '>>': 'std::ostream' does not define this operator or a conversion to a type acceptable to the predefined operator
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\include\xstring(5144,32):
1>could be 'std::basic_istream<_Elem,_Traits> &std::operator >>(std::basic_istream<_Elem,_Traits> &,std::basic_string<_Elem,_Traits,_Alloc> &)'
1> D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(83,10):
1> 'std::basic_istream<_Elem,_Traits> &std::operator >>(std::basic_istream<_Elem,_Traits> &,std::basic_string<_Elem,_Traits,_Alloc> &)': could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &' from 'std::ostream'
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\include\istream(842,32):
1>or 'std::basic_istream<_Elem,_Traits> &std::operator >>(std::basic_istream<_Elem,_Traits> &,_Elem *)'
1> D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(83,10):
1> 'std::basic_istream<_Elem,_Traits> &std::operator >>(std::basic_istream<_Elem,_Traits> &,_Elem *)': could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &' from 'std::ostream'
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\include\istream(847,31):
1>or 'std::basic_istream<char,_Traits> &std::operator >>(std::basic_istream<char,_Traits> &,signed char *)'
1> D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(83,10):
1> 'std::basic_istream<char,_Traits> &std::operator >>(std::basic_istream<char,_Traits> &,signed char *)': could not deduce template argument for 'std::basic_istream<char,_Traits> &' from 'std::ostream'
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\include\istream(852,31):
1>or 'std::basic_istream<char,_Traits> &std::operator >>(std::basic_istream<char,_Traits> &,unsigned char *)'
1> D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(83,10):
1> 'std::basic_istream<char,_Traits> &std::operator >>(std::basic_istream<char,_Traits> &,unsigned char *)': could not deduce template argument for 'std::basic_istream<char,_Traits> &' from 'std::ostream'
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\include\istream(858,32):
1>or 'std::basic_istream<_Elem,_Traits> &std::operator >>(std::basic_istream<_Elem,_Traits> &,_Elem &)'
1> D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(83,10):
1> 'std::basic_istream<_Elem,_Traits> &std::operator >>(std::basic_istream<_Elem,_Traits> &,_Elem &)': could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &' from 'std::ostream'
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\include\istream(881,31):
1>or 'std::basic_istream<char,_Traits> &std::operator >>(std::basic_istream<char,_Traits> &,signed char &)'
1> D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(83,10):
1> 'std::basic_istream<char,_Traits> &std::operator >>(std::basic_istream<char,_Traits> &,signed char &)': could not deduce template argument for 'std::basic_istream<char,_Traits> &' from 'std::ostream'
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\include\istream(887,31):
1>or 'std::basic_istream<char,_Traits> &std::operator >>(std::basic_istream<char,_Traits> &,unsigned char &)'
1> D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(83,10):
1> 'std::basic_istream<char,_Traits> &std::operator >>(std::basic_istream<char,_Traits> &,unsigned char &)': could not deduce template argument for 'std::basic_istream<char,_Traits> &' from 'std::ostream'
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\include\istream(900,9):
1>or '_Istr &&std::operator >>(_Istr &&,_Ty &&)'
1> D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(83,10):
1> '_Istr &&std::operator >>(_Istr &&,_Ty &&)': could not deduce template argument for '__formal'
1> C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\include\istream(899,102):
1> '<template-parameter>': you cannot create a pointer to a reference
1>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.38.33130\include\complex(2235,28):
1>or 'std::basic_istream<_Elem,_Traits> &std::operator >>(std::basic_istream<_Elem,_Traits> &,std::complex<_Other> &)'
1> D:\OneDrive - azureford\Documents\Visual Studio 2022\Projects\ectCalFit\ectCalFit\matlab_functions.cpp(83,10):
1> 'std::basic_istream<_Elem,_Traits> &std::operator >>(std::basic_istream<_Elem,_Traits> &,std::complex<_Other> &)': could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &' from 'std::ostream'
1>PolyFit.cpp
1>Generating Code...
1>Done building project "ectCalFit.vcxproj" -- FAILED.
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
========== Rebuild completed at 12:59 PM and took 04.647 seconds ==========

Plus de réponses (4)

Hassaan
Hassaan le 5 Juin 2024
Modifié(e) : Hassaan le 7 Juin 2024
#include <iostream>
#include "MatlabEngine.hpp"
#include "MatlabDataArray.hpp"
void getXYpoints(double* x, double* y, size_t* dataSize);
void polyFit(double* x, double* y, double* poly_coefficients, size_t xy_size, size_t poly_size) {
using namespace matlab::engine;
using namespace matlab::data;
// Start MATLAB engine synchronously
std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();
// Create MATLAB data arrays
ArrayFactory factory;
TypedArray<double> mxArrayX = factory.createArray<double>({xy_size});
TypedArray<double> mxArrayY = factory.createArray<double>({xy_size});
for (size_t i = 0; i < xy_size; ++i) {
mxArrayX[i] = x[i];
mxArrayY[i] = y[i];
}
// Call polyfit and get the result
FutureResult<std::vector<Array>> result = matlabPtr->fevalAsync(u"polyfit", 3, {mxArrayX, mxArrayY, factory.createScalar<double>(poly_size)});
std::vector<Array> results = result.get();
TypedArray<double> poly_coefficients_array = results[0];
StructArray s = results[1];
TypedArray<double> mu = results[2];
// Extract polynomial coefficients
for (size_t i = 0; i < poly_coefficients_array.getNumberOfElements(); ++i) {
poly_coefficients[i] = poly_coefficients_array[i];
}
// Extract s and mu if needed
// auto s_field1 = s[0][u"field1"];
// auto mu_field1 = mu[0][u"field1"];
}
int main(int argc, char* argv[]) {
double x[40];
double y[40];
double p[12]; // MATLAB returned array of coefficients
size_t dataSize;
// This function gets the data from a file and updates the unknown xy data size
// The data size = 40 elements
getXYpoints(x, y, &dataSize);
if (dataSize == 0) {
std::cout << "File Size is Zero, nothing to do" << std::endl;
return -2;
}
polyFit(x, y, p, dataSize, 12); // 12 is the order of the polynomials
return 0;
}
------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
Professional Interests
  • Technical Services and Consulting
  • Embedded Systems | Firmware Developement | Simulations
  • Electrical and Electronics Engineering
Feel free to contact me.

Nidal Bazzi
Nidal Bazzi le 5 Juin 2024
Thanks Hassaan for the quick response. Line 56 gives these errors.
error C2440: 'initializing': cannot convert from 'matlab::data::Array' to 'std::vector<matlab::data::Array,std::allocator<matlab::data::Array>>'
line 56:
std::vector<Array> results = matlabPtr->feval(u"polyfit", { mxArrayX, mxArrayY, factory.createScalar<double>(poly_size) });
  1 commentaire
Hassaan
Hassaan le 5 Juin 2024
@Nidal Bazzi I have updated my code above. Try re-run.

Connectez-vous pour commenter.


Nidal Bazzi
Nidal Bazzi le 5 Juin 2024
It still will not compile unless I added the 3 on this line:
FutureResult<std::vector<Array>> result = matlabPtr->fevalAsync(u"polyfit",3, { mxArrayX, mxArrayY, factory.createScalar<double>(poly_size) });
polyfit defaults to returning one argument unless we specify 3 argument. This change enable the code to compile, but an exception is encountered on this line:
StructArray mu = results[2];
  1 commentaire
Hassaan
Hassaan le 6 Juin 2024
@Nidal Bazzi I have updated my code above. Try re-run.

Connectez-vous pour commenter.


Nidal Bazzi
Nidal Bazzi le 7 Juin 2024
It turned out that I only need the polynomial coefficients vector p which I am able to get. Thank you for all your help.
  2 commentaires
Nidal Bazzi
Nidal Bazzi le 7 Juin 2024
@Hassaan the last update fixed my issue.
Hassaan
Hassaan le 7 Juin 2024
@Nidal Bazzi You are welcome.
------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
Professional Interests
  • Technical Services and Consulting
  • Embedded Systems | Firmware Developement | Simulations
  • Electrical and Electronics Engineering
Feel free to contact me.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Call MATLAB from C++ dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by