/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Wolfgang Wittek 10/2003 ! ! Copyright: MAGIC Software Development, 2000-2003 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // // MMarquardt // // // // Marquardt method of solving nonlinear least-squares problems // // // // (see Numerical recipes (2nd ed.), W.H.Press et al., p.688 ff) // // // ///////////////////////////////////////////////////////////////////////////// #include "MMarquardt.h" #include // fabs #include #include #include #include "MLog.h" #include "MLogManip.h" #include "MParContainer.h" ClassImp(MMarquardt); using namespace std; // -------------------------------------------------------------------------- // // Default constructor. // MMarquardt::MMarquardt(const char *name, const char *title) { fName = name ? name : "MMarquardt"; fTitle = title ? title : "Marquardt minimization"; } // ----------------------------------------------------------------------- // // Set - the number of parameters // - the maximum number of steps allowed in the minimization and // - the change in chi2 signaling convergence void MMarquardt::SetNpar(Int_t numpar, Int_t numstepmax, Double_t loopchi2) { fNpar = numpar; fNumStepMax = numstepmax; fLoopChi2 = loopchi2; fdParam.ResizeTo(fNpar); fParam.ResizeTo(fNpar); fGrad.ResizeTo(fNpar); fCovar.ResizeTo(fNpar, fNpar); fmyParam.ResizeTo(fNpar); fmyGrad.ResizeTo(fNpar); fmyCovar.ResizeTo(fNpar, fNpar); fIxc.ResizeTo(fNpar); fIxr.ResizeTo(fNpar); fIp.ResizeTo(fNpar); } // ----------------------------------------------------------------------- // // do the minimization // // fcn is the function which calculates for a given set of parameters // - the function L to be minimized // - beta_k = -1/2 * dL/da_k (a kind of gradient of L) // - alfa_kl = 1/2 * dL/(da_k da_l) (a kind of 2nd derivative of L) // // Vinit contains the starting values of the parameters // Int_t MMarquardt::Loop( Bool_t (*fcn)(TVectorD &, TMatrixD &, TVectorD &, Double_t &), TVectorD &Vinit) { fFunc = fcn; // set the initial parameter values for (Int_t i=0; i fLoopChi2 && fNumStep < fNumStepMax); //------------------------------------------- // do the final calculations if (!rcnext) { *fLog << "MMarquardt::Loop; function call failed in step " << fNumStep << endl; return -2; } if (fdChi2 > fLoopChi2) { *fLog << "MMarquardt::Loop; minimization has not converged, fChi2, fdChi2 = " << fChi2 << ", " << fdChi2 << endl; return -3; } *fLog << "MMarquardt::Loop; minimization has converged, fChi2, fdChi2, fNumStep = " << fChi2 << ", " << fdChi2 << ", " << fNumStep << endl; Bool_t rccov = CovMatrix(); if (!rccov) { *fLog << "MMarquardt::Loop; calculation of covariance matrix failed " << endl; return 1; } //------------------------------------------- // results *fLog << "MMarquardt::Loop; Results of fit : fChi2, fNumStep, fdChi2 =" << fChi2 << ", " << fNumStep << ", " << fdChi2 << endl; for (Int_t i=0; i= h) { h = fabs(covar(j,k)); ir = j; ic = k; } } else { if (fIp(k) > 1) return kFALSE; } } } } fIp(ic)++; if (ir != ic) { for (l=0; l=0; l--) { if (fIxr(l) != fIxc(l)) { for (k=0; k