FumiliGradientCalculator.cxx

Go to the documentation of this file.
00001 // @(#)root/minuit2:$Id: FumiliGradientCalculator.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/FumiliGradientCalculator.h"
00011 #include "Minuit2/FumiliFCNBase.h"
00012 #include "Minuit2/MnUserTransformation.h"
00013 #include "Minuit2/FunctionGradient.h"
00014 #include "Minuit2/MinimumParameters.h"
00015 #include "Minuit2/FumiliChi2FCN.h"
00016 #include "Minuit2/FumiliMaximumLikelihoodFCN.h"
00017 
00018 //to compare with N2P calculator
00019 //#define DEBUG 1
00020 #ifdef DEBUG
00021 #include "Minuit2/MnPrint.h"
00022 #include "Minuit2/Numerical2PGradientCalculator.h"
00023 #include "Minuit2/MnStrategy.h"
00024 #include "Minuit2/MnUserFcn.h"
00025 #endif
00026 
00027 namespace ROOT {
00028 
00029    namespace Minuit2 {
00030 
00031 
00032 FunctionGradient FumiliGradientCalculator::operator()(const MinimumParameters& par) const {
00033    
00034    // Calculate gradient for Fumili using the gradient and Hessian provided by the FCN Fumili function
00035    // applying the external to int trasformation. 
00036    
00037    int nvar = par.Vec().size();
00038    std::vector<double> extParam = fTransformation(  par.Vec() );
00039    //   std::vector<double> deriv; 
00040    //   deriv.reserve( nvar ); 
00041    //   for (int i = 0; i < nvar; ++i) {
00042    //     unsigned int ext = fTransformation.ExtOfInt(i);
00043    //     if ( fTransformation.Parameter(ext).HasLimits()) 
00044    //       deriv.push_back( fTransformation.DInt2Ext( i, par.Vec()(i) ) );
00045    //     else 
00046    //       deriv.push_back(1.0); 
00047    //   }
00048    
00049    // eval Gradient 
00050    FumiliFCNBase & fcn = const_cast<FumiliFCNBase &>(fFcn);  
00051    
00052    fcn.EvaluateAll(extParam);
00053    
00054    
00055    MnAlgebraicVector v(nvar);
00056    MnAlgebraicSymMatrix h(nvar);
00057    
00058    
00059    const std::vector<double> & fcn_gradient = fFcn.Gradient(); 
00060    assert( fcn_gradient.size() == extParam.size() ); 
00061    
00062    
00063    //   for (int i = 0; i < nvar; ++i) { 
00064    //     unsigned int iext = fTransformation.ExtOfInt(i);    
00065    //     double ideriv = 1.0; 
00066    //     if ( fTransformation.Parameter(iext).HasLimits()) 
00067    //       ideriv =  fTransformation.DInt2Ext( i, par.Vec()(i) ) ;
00068    
00069    
00070    //     //     v(i) = fcn_gradient[iext]*deriv;
00071    //     v(i) = ideriv*fcn_gradient[iext];
00072    
00073    //     for (int j = i; j < nvar; ++j) { 
00074    //       unsigned int jext = fTransformation.ExtOfInt(j);
00075    //       double jderiv = 1.0; 
00076    //       if ( fTransformation.Parameter(jext).HasLimits()) 
00077    //   jderiv =  fTransformation.DInt2Ext( j, par.Vec()(j) ) ;
00078    
00079    // //       h(i,j) = deriv[i]*deriv[j]*fFcn.Hessian(iext,jext); 
00080    //       h(i,j) = ideriv*jderiv*fFcn.Hessian(iext,jext); 
00081    //     }
00082    //   }
00083    
00084    
00085    // cache deriv and Index values . 
00086    // in large Parameter limit then need to re-optimize and see if better not caching
00087    
00088    std::vector<double> deriv(nvar); 
00089    std::vector<unsigned int> extIndex(nvar); 
00090    for (int i = 0; i < nvar; ++i) { 
00091       extIndex[i] = fTransformation.ExtOfInt(i);    
00092       deriv[i] = 1;
00093       if ( fTransformation.Parameter(extIndex[i]).HasLimits()) 
00094          deriv[i] =  fTransformation.DInt2Ext( i, par.Vec()(i) ) ;
00095       
00096       v(i) = fcn_gradient[extIndex[i]]*deriv[i];
00097       
00098       for (int j = 0; j <= i; ++j) {       
00099          h(i,j) = deriv[i]*deriv[j]*fFcn.Hessian(extIndex[i],extIndex[j]); 
00100       }
00101    }
00102    
00103 #ifdef DEBUG
00104    // compare with other Gradient 
00105    //   // calculate Gradient using Minuit method 
00106    
00107    Numerical2PGradientCalculator gc(MnUserFcn(fFcn,fTransformation), fTransformation, MnStrategy(1));
00108    FunctionGradient g2 = gc(par);
00109    
00110    std::cout << "Fumili Gradient " << v << std::endl;
00111    std::cout << "Minuit Gradient " << g2.Vec() << std::endl;
00112 #endif  
00113    
00114    // store calculated Hessian
00115    fHessian = h; 
00116    return FunctionGradient(v); 
00117 }
00118 
00119 FunctionGradient FumiliGradientCalculator::operator()(const MinimumParameters& par,
00120                                                       const FunctionGradient&) const
00121 
00122 { 
00123    // Needed for interface of base class. 
00124    return this->operator()(par); 
00125    
00126 }
00127 
00128    }  // namespace Minuit2
00129 
00130 }  // namespace ROOT

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