///////////////////////////////////////////////////////////////////////////// // Name: lm_lsqr.h // Purpose: Levenberg-Marquart nonlinear least squares 2-D curve fitting // Author: John Labenski, mostly others (see below) // Modified by: // Created: 6/5/2002 // Copyright: (c) John Labenski, mostly others (see below) // Licence: Public domain ///////////////////////////////////////////////////////////////////////////// /* * Solves or minimizes the sum of squares of m nonlinear * functions of n variables. * * From public domain Fortran version * of Argonne National Laboratories MINPACK * * argonne national laboratory. minpack project. march 1980. * burton s. garbow, kenneth e. hillstrom, jorge j. more * * C translation by Steve Moshier http://www.moshier.net/ * * C++ "translation" for use w/ wxWindows by John Labenski */ #ifndef _LM_LEASTSQUARE_H_ #define _LM_LEASTSQUARE_H_ #include "wx/plotctrl/plotdefs.h" class WXDLLIMPEXP_PLOTCTRL wxPlotData; class WXDLLIMPEXP_PLOTCTRL wxPlotFunction; // When SetLM_LeastSquareProgressHandler is called with a non NULL handler it will be // called when fitting a curve every SetLM_LeastSquareProgressHandlerTicks // text is the function name // current is the current iteration, max is max allowed iterations // note: current may exceed max by a few iterations in some cases // Usage: create a function like this // void LM_LeastSquareProgressHandler(const wxString &text, int current, int max) // { [ do stuff... for example update a progress dialog ] // wxString str = text + wxString::Format(wxT("\nIteration # %d of %d"), current, max); // int percent = wxMin(int(100.0*current/max), 99); // iterations may overflow! // return s_progressDialog->Update(percent, str); } // // then call SetLM_LeastSquareProgressHandler( LM_LeastSquareProgressHandler ); extern "C" { typedef bool (*LM_LeastSquareProgressHandler_)(const wxString &WXUNUSED(text), int WXUNUSED(current), int WXUNUSED(max)); extern void SetLM_LeastSquareProgressHandler( LM_LeastSquareProgressHandler_ handler ); extern void SetLM_LeastSquareProgressHandlerTicks( int iterations ); } //============================================================================= // LM_LeastSquare - Levenberg-Marquart nonlinear least squares 2-D curve fitting // // Fit the plot function to the plot data // // Notes : // the plot function must have fewer or equal vars than the plotdata has points // the plotfunction MUST! have the LAST variable as 'x' // you can set the starting values by filling 'initial_vals', size = (plotFunc.GetNumberVars - 1) // if initial_vars = NULL then they are all 0.1 // // Sample usage : // wxString message; // // Create some plotData, in this case from a known function // wxPlotData data(wxPlotFunction("2.5*x*x-3*x+5+3.3*log(x)+13*exp(15*x/(x+4))", "x",dummy), 0, 1E-4, 10000); // // Create the plotFunc we want to fit to the data, note: x is last var // wxPlotFunction func("a*x*x+b*x+c+d*log(x)+e*exp(f*x/(x+g))", "a,b,c,d,e,f,g,x", message); // LM_LeastSquare lmLeastSquare; // if (lmLeastSquare.Create(data, func)) { // lmLeastSquare.Fit(NULL); // or Fit(init, init_count) where double init[init_count] = { a, b, c, ... } // for (int k=0; k= m_m double *m_qtf; // output array the first n elements of the vector (q transpose)*fvec int *m_ipvt; // integer output array of length n int m_maxfev; // maximum number of iterations to try private: void Init(); }; #endif // _LM_LEASTSQUARE_H_