Registered Member
|
Hello!
Iam trying to get Eigen to fit a 4th polynomial to a data curve that i have gathered. aDataSetComplete is my gathered data... and regData.regPeakCurve is my regression curve. Here is my code: VectorXf x(iPeakSize); for (int i=0;i<iPeakSize; i++) x(i) = i; MatrixXf X(iPeakSize,5); VectorXf Xtemp(5); for (int i=0; i<iPeakSize; i++) { Xtemp << pow(x(i),4), pow(x(i),3), pow(x(i),2), x(i), 1; X.row(i) = Xtemp; } VectorXf D(iPeakSize); for(int i=0;i<iPeakSize; i++) D(i) = aDataSetComplete.at(i); VectorXf a = X.colPivHouseholderQr().solve(D); double fifth = a(0); double fourth = a(1); double third = a(2); double second = a(3); double first = a(4); for(int i=0; i<aDataSetComplete.size(); i++) { VALUE_TYPE dVal = fifth*i*i*i*i + fourth*i*i*i + third*i*i + second*i + first; regData.regPeakCurve.push_back(dVal); } Picture of the problem: [url]https://drive.google.com/file/d/0B8Dk8EdaYGLWX1MyUDk2bk0wSms/edit?usp=sharing[/url] red one is my data and the yellow one is the regression curve, Any suggestion why the curve is so strange looking? I have tried the 2th degree eigen curvfit and it works fine but i cant get the 4th degree to. Is there another way to calc the 4th degree curve with eigen? Btw. I can get the 4th degree plyfit to work in mathlab. |
Moderator
|
strange. What is the value of (X*a-D).norm() / D.norm() ? Which Eigen version?
|
Moderator
|
hm, I see your input range is not normalized with quite large values (300) that becomes huge once raised to power 4. Using float, your problem is likely very badly conditioned. So switch to double as Matlab.
|
Registered Member
|
Sorry for the late respons.
I will test your recommendations soon and will come back with the results Were can i find which version iam running? I didn´t make a version comment on the system folder :/ iam running it on windows ...CODE\Extras\Eigen |
Moderator
|
to be sure look at Eigen/src/Core/util/Macro.h
|
Registered Member
|
#define EIGEN_WORLD_VERSION 3
#define EIGEN_MAJOR_VERSION 1 #define EIGEN_MINOR_VERSION 2 Is my version |
Registered Member
|
Hi again Ggael!
Now i have made a new test with the 4th degree reg curve. The one on the left is a 2th degree reg curve (yellow) and on the right is the 4th degree one (yellow). you can see the value of: double dGgael = (X*a-D).norm() / D.norm(); in the Topic of the right graph window showing the 4th degree polynomial. https://drive.google.com/file/d/0B8Dk8EdaYGLWVF9hZ3FkRktWT0k/edit?usp=sharing I will fix those VALUE_TYPE (float) to double as soon as i get some spare time. Any suggestions? |
Moderator
|
yes, please move to double. It is also interesting to look at the condition number:
JacobiSVD<MatrixXd> svd(D); std::cout << svd.singularValues()(D.cols()-1) / svd.singularValues()(0); |
Registered Member
|
Hello Ggeal!
Now i made a change from float (VectorXf, MatrixXf) to double (VectorXd, MatrixXd). It seems to calculate the reggression curve correctly now Picture: Left 4th, right 2th https://drive.google.com/file/d/0B8Dk8EdaYGLWbkZoLWtVU1NsbXc/edit?usp=sharing You can also see the calculated values in the left graph. Thanks for the help Btw. do Eigen have any other functionality to fit a curve to a data set? |
Moderator
|
What exactly would you like to see? On my side I have multi-dimensional polynomial helper classes to ease the generation of the basis vector. You can also use different solvers. |
Registered users: Bing [Bot], Google [Bot], Sogou [Bot]