forum.alglib.net http://forum.alglib.net/ |
|
Simple fit fails, is ALG Lib so bad, or am I bad ? http://forum.alglib.net/viewtopic.php?f=2&t=1850 |
Page 1 of 1 |
Author: | _zzyx_ [ Fri May 16, 2014 10:11 am ] | ||
Post subject: | Simple fit fails, is ALG Lib so bad, or am I bad ? | ||
Dear All, I am testing alglib. I started from the fitting example, that I modified to fit a sinusoid over sine-like data (See attached picture) And honnestly, it does not work at all. I am fitting a y = A*sin(2 \pi Bx +C) +D function (So a very classic one, that we meet daily in physics/engineering/signal processing or whatever else) and it seems that the fitting procedure set A to a very small value and then fails to converge Here is my source code, does someone knows what I made wrong and what I have to do to get it working Code: ude <cstdlib> #include <cstdio> #include <cmath> #include <string> #include <vector> #include <fstream> #include <iostream> #include "interpolation.h" using namespace alglib; void function_cx_1_func(const real_1d_array &c, const real_1d_array &x, double &func, void *ptr) { // this callback calculates f(c,x)=exp(-c0*sqr(x0)) // where x is a position on X-axis and c is adjustable parameter func = c[0] * sin( 2 * 3.14159 * c[1] * x[0] + c[2]) + c[3]; } int main(int argc, char **argv) { // using std::cout; using std::endl; const std::string infile="/path/to/data"; std::vector<double> vx; std::vector<double> vy; std::ifstream data(infile.c_str()); while (!data.eof() || !data.fail()) { double xx(0),yy(0); data >> xx >> yy ; if (data.fail()) break; vx.push_back(xx); vy.push_back(yy); } data.close(); real_1d_array c = "[2.5, 0.5, 0., 0.]"; //this is a rough guess but shouldn't be so wrong //Setting parameters from input file too x,y array, I don't know the lib but I am confident I did it the right way real_2d_array x; x.setcontent(vx.size(), 1, &vx.front()); real_1d_array y; y.setcontent(vy.size(), &vy.front()); double epsf = 0; double epsx = 0.0001; ae_int_t maxits = 0; ae_int_t info; lsfitstate state; lsfitreport rep; double diffstep = 0.0001; // // Fitting without weights // lsfitcreatef(x, y, c, 0.01, state); //played with params lsfitsetcond(state, epsf, epsx, maxits); alglib::lsfitfit(state, function_cx_1_func); lsfitresults(state, info, c, rep); cout << info << endl; // cout << x.tostring(1) << endl; // cout << y.tostring(1) << endl; std::cout << c[0] << "* sin (2 pi " << c[1] <<"x + " << c[2] << ") + " << c[3] <<std::endl; std::cout << rep.errpar[0] << " " << rep.errpar[1] << " " << rep.errpar[2] << " " << rep.errpar[3] << std::endl; return 0; } [img]testALG.png[/img]
|
Author: | Sergey.Bochkanov [ Fri May 16, 2014 10:48 am ] |
Post subject: | Re: Simple fit fails, is ALG Lib so bad, or am I bad ? |
Hello! I think that both ALGLIB and you are good! Your problem looks easy, but in fact it is very hard. Even minor change in parameter c[1] wildly changes function value at x=6...10 (sine wave may change its sign, number of periods, etc). It results in highly nonlinear function landscape with lots of local extrema. Algorithm successfully converges to one of these extrema. But "extremum" does not mean "solution for your problem". I have not seen your data (only chart, no exact numbers), but I experimented a bit with data similar to yours, generated with c_exact={2.6,X,0,0} (here X is varying parameter) and initial point c0={2.5,0.5,0,0). You may see slight difference in c[0] and c[1] for c_exact and c0, it is very important. Algorithm successfully converged to known solution for X in [0.45,0.55] (i.e. solver returned almost correct estimate for c[1]), but when X was set to 0.44 (remember, initial point is 0.5!), algorithm converged to another extrema. I am pretty sure that on your problem algorithm performed correct sequence of steps which decreased function value at each step, and that solution returned by algorithm: a) was better than initial approximation provided by you, b) was local extremum. So, technically, everything works as expected... I understand that it does not solve your problem, but maybe you should try choosing another example (if you want just to test ALGLIB). Or, if you really want to perform sine fit - to use some sophisticated method to choose initial point (say, something Fourier-based). |
Author: | _zzyx_ [ Fri May 16, 2014 12:41 pm ] |
Post subject: | Re: Simple fit fails, is ALG Lib so bad, or am I bad ? |
I must confess that I haven't choose the easiest test-case (but one does not test a fitting module with easy problem). However, ROOT and gnuplot are failing too. I will do more test with easier case and other functionalities in the comming days. |
Author: | Sergey.Bochkanov [ Fri May 16, 2014 1:12 pm ] |
Post subject: | Re: Simple fit fails, is ALG Lib so bad, or am I bad ? |
Quote: However, ROOT and gnuplot are failing too. The problem is that they are not failing - they do exactly what all nonlinear fitters promise you, converge to nearest local extremum. In most cases, local extremum is solution. In this case - not. I think that if we track convergence process, we will find out that solution returned by them is in fact closest extremum in the end of the always-descending trajectory. |
Page 1 of 1 | All times are UTC |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |