NegativeG2LineSearch.cxx

Go to the documentation of this file.
00001 // @(#)root/minuit2:$Id: NegativeG2LineSearch.cxx 30054 2009-09-07 14:13:12Z 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/NegativeG2LineSearch.h"
00011 #include "Minuit2/MnFcn.h"
00012 #include "Minuit2/MinimumState.h"
00013 #include "Minuit2/GradientCalculator.h"
00014 #include "Minuit2/MnMachinePrecision.h"
00015 #include "Minuit2/MnLineSearch.h"
00016 #include "Minuit2/MnParabolaPoint.h"
00017 #include "Minuit2/VariableMetricEDMEstimator.h"
00018 
00019 #include <cmath>
00020 //#define DEBUG
00021 #ifdef DEBUG
00022 #include <iostream>
00023 #endif
00024 
00025 namespace ROOT {
00026 
00027    namespace Minuit2 {
00028 
00029 
00030 
00031 
00032 MinimumState NegativeG2LineSearch::operator()(const MnFcn& fcn, const MinimumState& st, const  GradientCalculator& gc, const MnMachinePrecision& prec) const {
00033    
00034 //   when the second derivatives are negative perform a  line search  along Parameter which gives 
00035 //   negative second derivative and magnitude  equal to the Gradient step size. 
00036 //   Recalculate the gradients for all the Parameter after the correction and 
00037 //   continue iteration in case the second derivatives are still negative
00038 //
00039 
00040    bool negG2 = HasNegativeG2(st.Gradient(), prec);
00041    if(!negG2) return st;
00042    
00043    unsigned int n = st.Parameters().Vec().size();
00044    FunctionGradient dgrad = st.Gradient();
00045    MinimumParameters pa = st.Parameters();
00046    bool iterate = false;
00047    unsigned int iter = 0;
00048    do {
00049       iterate = false;
00050       for(unsigned int i = 0; i < n; i++) {
00051 
00052 #ifdef DEBUG         
00053          std::cout << "negative G2 - iter " << iter << " param " << i << "   " << pa.Vec()(i) << "  grad2 " << dgrad.G2()(i) << " grad " << dgrad.Vec()(i) 
00054                    << " grad step " << dgrad.Gstep()(i) << " step size " << pa.Dirin()(i) << std::endl; 
00055 #endif
00056          if(dgrad.G2()(i) <= 0) {      
00057 
00058             // check also the gradient (if it is zero ) I can skip the param) 
00059      
00060             if ( std::fabs(dgrad.Vec()(i) ) < prec.Eps() && std::fabs(dgrad.G2()(i) ) < prec.Eps() ) continue; 
00061             //       if(dgrad.G2()(i) < prec.Eps()) {
00062             // do line search if second derivative negative
00063             MnAlgebraicVector step(n);
00064             MnLineSearch lsearch;
00065 
00066             if ( dgrad.Vec()(i) < 0) 
00067                step(i) = dgrad.Gstep()(i); //*dgrad.Vec()(i);
00068             else 
00069                step(i) = - dgrad.Gstep()(i); // *dgrad.Vec()(i);
00070 
00071             double gdel = step(i)*dgrad.Vec()(i);
00072 
00073             // if using sec derivative information
00074             // double g2del = step(i)*step(i) * dgrad.G2()(i);
00075             bool debugLS = false;
00076 
00077 #ifdef DEBUG
00078             std::cout << "step(i) " << step(i) << " gdel " << gdel << std::endl; 
00079 //            std::cout << " g2del " << g2del << std::endl;
00080             debugLS = true;
00081 #endif
00082             MnParabolaPoint pp = lsearch(fcn, pa, step, gdel, prec,debugLS);
00083 
00084 
00085 
00086 #ifdef DEBUG
00087             std::cout << "\nLine search result " << pp.X() << " f(0)  " << pa.Fval() << " f(1) " << pp.Y() << std::endl;
00088 #endif
00089 
00090             step *= pp.X();
00091             pa = MinimumParameters(pa.Vec() + step, pp.Y());    
00092 
00093             dgrad = gc(pa, dgrad);         
00094 
00095 #ifdef DEBUG
00096             std::cout << "Line search - iter" << iter << " param " << i << "   " << pa.Vec()(i) << " step " << step(i) << " new grad2 " << dgrad.G2()(i) << " new grad " <<  dgrad.Vec()(i) << " grad step " << dgrad.Gstep()(i) << std::endl;
00097 #endif
00098 
00099             iterate = true;
00100             break;
00101             } 
00102          }
00103       } while(iter++ < 2*n && iterate);
00104    
00105    MnAlgebraicSymMatrix mat(n);
00106    for(unsigned int i = 0; i < n; i++)  
00107       mat(i,i) = (fabs(dgrad.G2()(i)) > prec.Eps2() ? 1./dgrad.G2()(i) : 1.);
00108    
00109    MinimumError err(mat, 1.);
00110    double edm = VariableMetricEDMEstimator().Estimate(dgrad, err);
00111    
00112    return MinimumState(pa, err, dgrad, edm, fcn.NumOfCalls());
00113 }
00114       
00115 bool NegativeG2LineSearch::HasNegativeG2(const FunctionGradient& grad, const MnMachinePrecision& /*prec */ ) const {
00116    // check if function gradient has any component which is neegative
00117          
00118    for(unsigned int i = 0; i < grad.Vec().size(); i++) 
00119 
00120       if(grad.G2()(i) <= 0 ) { 
00121 
00122          return true;
00123       }
00124          
00125    return false;
00126 }
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134    }  // namespace Minuit2
00135 
00136 }  // namespace ROOT

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