MnMinos.cxx

Go to the documentation of this file.
00001 // @(#)root/minuit2:$Id: MnMinos.cxx 23654 2008-05-06 07:30:34Z moneta $
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/MnMinos.h"
00011 #include "Minuit2/FunctionMinimum.h"
00012 #include "Minuit2/FCNBase.h"
00013 #include "Minuit2/MnFunctionCross.h"
00014 #include "Minuit2/MnCross.h"
00015 #include "Minuit2/MinosError.h"
00016 
00017 //#define DEBUG
00018 
00019 #if defined(DEBUG) || defined(WARNINGMSG)
00020 #include "Minuit2/MnPrint.h" 
00021 #endif
00022 
00023 
00024 namespace ROOT {
00025 
00026    namespace Minuit2 {
00027 
00028 
00029 MnMinos::MnMinos(const FCNBase& fcn, const FunctionMinimum& min, unsigned int stra ) : 
00030    fFCN(fcn), 
00031    fMinimum(min), 
00032    fStrategy(MnStrategy(stra)) 
00033 {
00034    // construct from FCN + Minimum
00035    // check if Error definition  has been changed, in case re-update errors
00036    if (fcn.Up() != min.Up() ) { 
00037 #ifdef WARNINGMSG
00038       MN_INFO_MSG("MnMinos UP value has changed, need to update FunctionMinimum class");
00039 #endif            
00040    }
00041 } 
00042 
00043 MnMinos::MnMinos(const FCNBase& fcn, const FunctionMinimum& min,  const MnStrategy& stra) : 
00044    fFCN(fcn), 
00045    fMinimum(min), 
00046    fStrategy(stra) 
00047 {
00048    // construct from FCN + Minimum
00049    // check if Error definition  has been changed, in case re-update errors
00050    if (fcn.Up() != min.Up() ) { 
00051 #ifdef WARNINGMSG
00052       MN_INFO_MSG("MnMinos UP value has changed, need to update FunctionMinimum class");
00053 #endif            
00054    }
00055 } 
00056 
00057 
00058 std::pair<double,double> MnMinos::operator()(unsigned int par, unsigned int maxcalls) const {
00059    // do Minos analysis given the parameter index returning a pair for (lower,upper) errors
00060    MinosError mnerr = Minos(par, maxcalls);
00061    return mnerr();
00062 }
00063 
00064 double MnMinos::Lower(unsigned int par, unsigned int maxcalls) const {
00065    // get lower error for parameter par
00066    MnUserParameterState upar = fMinimum.UserState();
00067    double err = fMinimum.UserState().Error(par);
00068    
00069    MnCross aopt = Loval(par, maxcalls);
00070    
00071    double lower = aopt.IsValid() ? -1.*err*(1.+ aopt.Value()) : (aopt.AtLimit() ? upar.Parameter(par).LowerLimit() : upar.Value(par));
00072    
00073    return lower;
00074 }
00075 
00076 double MnMinos::Upper(unsigned int par, unsigned int maxcalls) const {
00077    // upper error for parameter par
00078    MnCross aopt = Upval(par, maxcalls);
00079    
00080    MnUserParameterState upar = fMinimum.UserState();
00081    double err = fMinimum.UserState().Error(par);
00082    
00083    double upper = aopt.IsValid() ? err*(1.+ aopt.Value()) : (aopt.AtLimit() ? upar.Parameter(par).UpperLimit() : upar.Value(par));
00084    
00085    return upper;
00086 }
00087 
00088 MinosError MnMinos::Minos(unsigned int par, unsigned int maxcalls) const {
00089    // do full minos error anlysis (lower + upper) for parameter par 
00090    assert(fMinimum.IsValid());  
00091    assert(!fMinimum.UserState().Parameter(par).IsFixed());
00092    assert(!fMinimum.UserState().Parameter(par).IsConst());
00093    
00094    MnCross up = Upval(par, maxcalls);
00095 #ifdef DEBUG
00096    std::cout << "Function calls to find upper error " << up.NFcn() << std::endl; 
00097 #endif
00098 
00099    MnCross lo = Loval(par, maxcalls);
00100 
00101 #ifdef DEBUG
00102    std::cout << "Function calls to find lower error " << lo.NFcn() << std::endl; 
00103 #endif
00104    
00105    return MinosError(par, fMinimum.UserState().Value(par), lo, up);
00106 }
00107 
00108 
00109 MnCross MnMinos::FindCrossValue(int direction, unsigned int par, unsigned int maxcalls) const {
00110    // get crossing value in the parameter direction : 
00111    // direction = + 1 upper value
00112    // direction = -1 lower value
00113 
00114    assert(direction == 1 || direction == -1); 
00115 #ifdef DEBUG
00116    if (direction == 1) 
00117       std::cout << "\n--------- MnMinos --------- \n Determination of positive Minos error for parameter " 
00118                 << par << std::endl;
00119    else 
00120       std::cout << "\n--------- MnMinos --------- \n Determination of positive Minos error for parameter " 
00121                 << par << std::endl;
00122 #endif
00123 
00124    assert(fMinimum.IsValid());  
00125    assert(!fMinimum.UserState().Parameter(par).IsFixed());
00126    assert(!fMinimum.UserState().Parameter(par).IsConst());
00127    if(maxcalls == 0) {
00128       unsigned int nvar = fMinimum.UserState().VariableParameters();
00129       maxcalls = 2*(nvar+1)*(200 + 100*nvar + 5*nvar*nvar);
00130    }
00131    
00132    std::vector<unsigned int> para(1, par);
00133    
00134    MnUserParameterState upar = fMinimum.UserState();
00135    double err = direction * upar.Error(par);
00136    double val = upar.Value(par) +  err;
00137    std::vector<double> xmid(1, val);
00138    std::vector<double> xdir(1, err);
00139    
00140    double up = fFCN.Up();
00141    unsigned int ind = upar.IntOfExt(par);
00142    // get error matrix (methods return a copy)
00143    MnAlgebraicSymMatrix m = fMinimum.Error().Matrix();  
00144    // get internal paramaters 
00145    const MnAlgebraicVector & xt = fMinimum.Parameters().Vec(); 
00146    //LM:  change to use err**2 (m(i,i) instead of err as in F77 version
00147    double xunit = sqrt(up/m(ind,ind));
00148    // LM (29/04/08) bug: change should be done in internal variables 
00149    for(unsigned int i = 0; i < m.Nrow(); i++) {
00150       if(i == ind) continue;
00151       double xdev = xunit*m(ind,i);
00152       double xnew = xt(i) + direction *  xdev;
00153 
00154       // transform to external values 
00155       unsigned int ext = upar.ExtOfInt(i);
00156       
00157       double unew = upar.Int2ext(i, xnew); 
00158 
00159 #ifdef DEBUG     
00160       std::cout << "Parameter " << ext << " is set from " << upar.Value(ext) << " to " <<  unew << std::endl;
00161 #endif
00162       upar.SetValue(ext, unew);
00163    }
00164    
00165    upar.Fix(par);
00166    upar.SetValue(par, val);
00167 
00168 #ifdef DEBUG
00169    std::cout << "Parameter " << par << " is fixed and set from " << fMinimum.UserState().Value(par) << " to " << val << std::endl;
00170 #endif   
00171    
00172    //   double edmmax = 0.5*0.1*fFCN.Up()*1.e-3;
00173    double toler = 0.01; // value used in F77
00174    MnFunctionCross cross(fFCN, upar, fMinimum.Fval(), fStrategy);
00175    
00176    MnCross aopt = cross(para, xmid, xdir, toler, maxcalls);
00177    
00178 #ifdef DEBUG
00179    std::cout<<"----- MnMinos: aopt found from MnFunctionCross = "<<aopt.Value()<<std::endl << std::endl;
00180 #endif
00181    
00182 #ifdef WARNINGMSG
00183    if(aopt.AtMaxFcn())
00184       MN_INFO_VAL2("MnMinos maximum number of function calls exceeded for Parameter ",par);
00185    if(aopt.NewMinimum())
00186       MN_INFO_VAL2("MnMinos new Minimum found while looking for Parameter ",par);
00187    if (direction ==1) {
00188       if(aopt.AtLimit())  
00189          MN_INFO_VAL2("MnMinos Parameter is at Upper limit.",par);
00190       if(!aopt.IsValid()) 
00191          MN_INFO_VAL2("MnMinos could not find Upper Value for Parameter ",par);
00192    }
00193    else {  
00194       if(aopt.AtLimit())  
00195          MN_INFO_VAL2("MnMinos Parameter is at Lower limit.",par);
00196       if(!aopt.IsValid()) 
00197          MN_INFO_VAL2("MnMinos could not find Lower Value for Parameter ",par);
00198    }
00199 #endif
00200    
00201    return aopt;
00202 }
00203 
00204 MnCross MnMinos::Upval(unsigned int par, unsigned int maxcalls) const {
00205    // return crossing in the lower parameter direction
00206    return FindCrossValue(1,par,maxcalls);
00207 }
00208 
00209 MnCross MnMinos::Loval(unsigned int par, unsigned int maxcalls) const {
00210    // return crossing in the lower parameter direction
00211    return FindCrossValue(-1,par,maxcalls);
00212 }
00213 
00214 // #ifdef DEBUG
00215 //    std::cout << "\n--------- MnMinos --------- \n Determination of negative Minos error for parameter " 
00216 //              << par << std::endl;
00217 // #endif   
00218 
00219 //    assert(fMinimum.IsValid());  
00220 //    assert(!fMinimum.UserState().Parameter(par).IsFixed());
00221 //    assert(!fMinimum.UserState().Parameter(par).IsConst());
00222 //    if(maxcalls == 0) {
00223 //       unsigned int nvar = fMinimum.UserState().VariableParameters();
00224 //       maxcalls = 2*(nvar+1)*(200 + 100*nvar + 5*nvar*nvar);
00225 //    }
00226 //    std::vector<unsigned int> para(1, par);
00227    
00228 //    MnUserParameterState upar = fMinimum.UserState();
00229 //    double err = upar.Error(par);
00230 //    double val = upar.Value(par) - err;
00231 //    std::vector<double> xmid(1, val);
00232 //    std::vector<double> xdir(1, -err);
00233    
00234 //    double up = fFCN.Up();
00235 //    unsigned int ind = upar.IntOfExt(par);
00236 //    MnAlgebraicSymMatrix m = fMinimum.Error().Matrix();
00237 //    double xunit = sqrt(up/m(ind,ind));
00238 //    // get internal paramaters 
00239 //    const MnAlgebraicVector & xt = fMinimum.Parameters().Vec(); 
00240 
00241 //    for(unsigned int i = 0; i < m.Nrow(); i++) {
00242 //       if(i == ind) continue;
00243 //       double xdev = xunit*m(ind,i);
00244 
00245 //       double xnew = xt(i) - xdev;
00246 
00247 //       // transform to external values 
00248 //       double unew = upar.Int2ext(i, xnew); 
00249 
00250 //       unsigned int ext = upar.ExtOfInt(i);
00251 
00252 // #ifdef DEBUG     
00253 //       std::cout << "Parameter " << ext << " is set from " << upar.Value(ext) << " to " <<  unew << std::endl;
00254 // #endif
00255 //       upar.SetValue(ext, unew);
00256 //    }
00257    
00258 //    upar.Fix(par);
00259 //    upar.SetValue(par, val);
00260 
00261 // #ifdef DEBUG
00262 //    std::cout << "Parameter " << par << " is fixed and set from " << fMinimum.UserState().Value(par) << " to " << val << std::endl;
00263 // #endif   
00264    
00265 //    //   double edmmax = 0.5*0.1*fFCN.Up()*1.e-3;
00266 //    double toler = 0.01;
00267 //    MnFunctionCross cross(fFCN, upar, fMinimum.Fval(), fStrategy);
00268    
00269 //    MnCross aopt = cross(para, xmid, xdir, toler, maxcalls);
00270    
00271 // #ifdef DEBUG
00272 //    std::cout<<"----- MnMinos: aopt found from MnFunctionCross = "<<aopt.Value()<<std::endl << std::endl;
00273 // #endif
00274    
00275 // #ifdef WARNINGMSG
00276 //    if(aopt.AtLimit()) 
00277 //       MN_INFO_VAL2("MnMinos Parameter is at Lower limit.",par);
00278 //    if(aopt.AtMaxFcn())
00279 //       MN_INFO_VAL2("MnMinos maximum number of function calls exceeded for Parameter ",par);
00280 //    if(aopt.NewMinimum())
00281 //       MN_INFO_VAL2("MnMinos new Minimum found while looking for Parameter ",par);
00282 //    if(!aopt.IsValid()) 
00283 //       MN_INFO_VAL2("MnMinos could not find Lower Value for Parameter ",par);
00284 // #endif
00285    
00286 //    return aopt;
00287    
00288 // }
00289 
00290 
00291    }  // namespace Minuit2
00292 
00293 }  // namespace ROOT

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