00001
00002
00003
00004
00005
00006
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
00041
00042
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
00055
00056
00057
00058
00059
00060
00061 FumiliGradientCalculator * fgc = dynamic_cast< FumiliGradientCalculator *>( const_cast<GradientCalculator *>(&gc) );
00062 assert(fgc != 0);
00063
00064
00065
00066
00067 MnAlgebraicSymMatrix h = fgc->Hessian();
00068
00069 int nvar = p1.Vec().size();
00070
00071
00072 double eps = 8*std::numeric_limits<double>::min();
00073 for (int j = 0; j < nvar; j++) {
00074 h(j,j) *= (1. + lambda);
00075
00076 if ( fabs( h(j,j) ) < eps ) {
00077
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
00101
00102
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 }
00113
00114 }