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

4 views (last 30 days)
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).

Accepted Answer

Nidal Bazzi
Nidal Bazzi on 6 Jun 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 ==========

More Answers (4)

Hassaan
Hassaan on 5 Jun 2024
Edited: Hassaan on 7 Jun 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 on 5 Jun 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) });

Nidal Bazzi
Nidal Bazzi on 5 Jun 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];

Nidal Bazzi
Nidal Bazzi on 7 Jun 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 Comments
Hassaan
Hassaan on 7 Jun 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.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!