FumiliErrorUpdator.cxx

Go to the documentation of this file.
00001 // @(#)root/minuit2:$Id: FumiliErrorUpdator.cxx 20880 2007-11-19 11:23:41Z rdm $
00002 // Authors: M. Winkler, F. James, L. Moneta, A. Zsenei   2003-2005  
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2005 LCG ROOT Math team,  CERN/PH-SFT                *
00007  *                                                                    *
00008  **********************************************************************/
00009 
00010 #include "Minuit2/FumiliErrorUpdator.h"
00011 #include "Minuit2/MnFcn.h"
00012 #include "Minuit2/MnStrategy.h"
00013 #include "Minuit2/MnUserParameterState.h"
00014 #include "Minuit2/FumiliGradientCalculator.h"
00015 #include "Minuit2/MinimumParameters.h"
00016 #include "Minuit2/FunctionGradient.h"
00017 #include "Minuit2/MnMatrix.h"
00018 #include "Minuit2/MinimumError.h"
00019 #include "Minuit2/MinimumState.h"
00020 #include "Minuit2/LaSum.h"
00021 #include <limits>
00022 
00023 #if defined(DEBUG) || defined(WARNINGMSG)
00024 #include "Minuit2/MnPrint.h" 
00025 #endif
00026 
00027 
00028 namespace ROOT {
00029 
00030 namespace Minuit2 {
00031 
00032 
00033 
00034 double sum_of_elements(const LASymMatrix&);
00035 
00036 
00037 MinimumError FumiliErrorUpdator::Update(const MinimumState& s0, 
00038                                         const MinimumParameters& p1,
00039                                         const FunctionGradient& g1) const {
00040    // dummy methods to suppress unused variable warnings
00041    // this member function should never be called within
00042    // the Fumili method...
00043    s0.Fval();
00044    p1.Fval();
00045    g1.IsValid();
00046    return MinimumError(2);
00047 }
00048 
00049 
00050 MinimumError FumiliErrorUpdator::Update(const MinimumState& s0, 
00051                                         const MinimumParameters& p1,
00052                                         const GradientCalculator&  gc , 
00053                                         double lambda) const {
00054    // calculate the error matrix using approximation of Fumili
00055    // use only first derivatives (see tutorial par. 5.1,5.2)
00056    // The Fumili Hessian is provided by the FumiliGRadientCalculator class
00057    // we apply also the Marquard lambda factor to increase weight of diagonal term
00058    // as suggester in Numerical Receipt for Marquard method
00059    
00060    // need to downcast to FumiliGradientCalculator
00061    FumiliGradientCalculator * fgc = dynamic_cast< FumiliGradientCalculator *>( const_cast<GradientCalculator *>(&gc) ); 
00062    assert(fgc != 0); 
00063    
00064    
00065    // get Hessian from Gradient calculator
00066    
00067    MnAlgebraicSymMatrix h = fgc->Hessian(); 
00068    
00069    int nvar = p1.Vec().size();
00070    
00071    // apply Marquard lambda factor 
00072    double eps = 8*std::numeric_limits<double>::min();
00073    for (int j = 0; j < nvar; j++) { 
00074       h(j,j) *= (1. + lambda);
00075       // if h(j,j) is zero what to do ?
00076       if ( fabs( h(j,j) ) < eps ) { // should use DBL_MIN 
00077                                        // put a cut off to avoid zero on diagonals
00078          if ( lambda > 1) 
00079             h(j,j) = lambda*eps; 
00080          else 
00081             h(j,j) = eps; 
00082       }
00083    }
00084    
00085    
00086    
00087    int ifail = Invert(h);
00088    if(ifail != 0) {
00089 #ifdef WARNINGMSG
00090       MN_INFO_MSG("FumiliErrorUpdator inversion fails; return diagonal matrix.");
00091 #endif
00092       for(unsigned int i = 0; i < h.Nrow(); i++) {
00093          h(i,i) = 1./h(i,i);
00094       }
00095    }
00096    
00097    
00098    const MnAlgebraicSymMatrix& v0 = s0.Error().InvHessian();
00099    
00100    // calculate by how much did the covariance matrix changed
00101    // (if it changed a lot since the last step, probably we 
00102    // are not yet near the Minimum)
00103    double dcov = 0.5*(s0.Error().Dcovar() + sum_of_elements(h-v0)/sum_of_elements(h)); 
00104    
00105    
00106    
00107    return MinimumError(h, dcov);
00108    
00109 }
00110 
00111 
00112 }  // namespace Minuit2
00113 
00114 }  // namespace ROOT

Generated on Tue Jul 5 14:36:48 2011 for ROOT_528-00b_version by  doxygen 1.5.1