Anaphe Home Page Reference Documentation

Main Page     Namespaces     Classes     Source Code    

FitFunction.cpp

Go to the documentation of this file.
00001  /**********************************************************************
00002   *                                                                    *
00003   * Copyright (c) 2002 Jakub MOSCICKI, CERN/IT                       *
00004   *                   <Jakub.MOSCICKI@cern.ch>                       *
00005   *                                                                    *
00006   * This library is free software; you can redistribute it and/or      *
00007   * modify it under the terms of the GNU Lesser General Public         *
00008   * License as published by the Free Software Foundation; either       *
00009   * version 2.1 of the License, or (at your option) any later version. *
00010   *                                                                    *
00011   * This library is distributed in the hope that it will be useful,    *
00012   * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
00013   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   *
00014   * Lesser General Public License for more details.                    *
00015   *                                                                    *
00016   * You should have received a copy of the GNU Lesser General Public   *
00017   * License along with this library (see file COPYING); if not, write  *
00018   * to the Free Software Foundation, Inc., 59 Temple Place, Suite      *
00019   * 330, Boston, MA 02111-1307 USA, or contact the author at           *
00020   *  <Jakub.MOSCICKI@cern.ch>                                        *
00021   **********************************************************************/
00022 
00023 // Implementation file for class FitFunction 
00024 // 
00025 // Created by: Jakub MOSCICKI at Tue Jan 15 13:05:34 2002
00026 // 
00027 // Last update: Tue Jan 15 13:05:34 2002
00028 // 
00029 
00030 # include "FitFunction.h" 
00031 
00032 class IHistogram;
00033 class IHistogram1D;
00034 class IHistogram2D;
00035 class ICloud;
00036 
00037 namespace Anaphe
00038 {
00039   class IHistogram;
00040   class IHistogram1D;
00041   class IHistogram2D;
00042 }
00043 
00044 # include "VoPAdapter/VoPHist.h"
00045 # include "VoPAdapter/VoPCloud.h"
00046 
00047 
00048 # include "Interfaces/IVector.h"
00049 # include "Interfaces/IVectorFactory.h"
00050 # include "Interfaces/IObjectiveFunction.h"
00051 
00052 # include "FML/IExtendedFitter.h"
00053 # include "FML/IMinimizer.h"
00054 # include "FML/IMinimizerResult.h"
00055 
00056 //# include "FML/IMinimizer.h" // for print_level
00057 
00058 # include <iostream>
00059 
00060 FitFunction::FitFunction(const std::string & label, const std::string& type, const std::string& options) : m_model(0), m_fitter(0), m_method(options)
00061 {
00062   // create fitter (two step assignment - bug in gcc (?) when in one line)
00063   std::auto_ptr<FML::IFitter_impl> fitter( new FML::IFitter_impl );
00064   m_fitter = fitter;
00065   assert(m_fitter.get());
00066 
00067 
00068   // create model function by a successful call to setModel()
00069   m_fitter->setModel(type.c_str());
00070   assert(m_fitter->internalModelFunction()); 
00071 
00072   // create plain wrapper for model function
00073   std::auto_ptr<Function_plain_wrapper> model(new Function_plain_wrapper(label, m_fitter->internalModelFunction()));
00074   m_model = model;
00075   assert(m_model.get());
00076 
00077   m_fitter->setPrintLevel(FML::IMinimizer::minimum_printout);
00078   
00079   m_version = std::string(AIDA_VERSION);
00080 }
00081 
00082 FitFunction::~FitFunction() 
00083 {
00084   //  delete m_model;
00085   //  delete m_fitter;
00086 }
00087 
00088 FitFunction::FitFunction(const FitFunction &) 
00089 {
00090 }
00091 
00092 FitFunction & FitFunction::operator = (const FitFunction &rhs) 
00093 {
00094    if (this == &rhs) return *this;  // time saving self-test
00095 
00096    return *this;
00097 }
00098 
00099 bool FitFunction::setFixed ( const std::string & name, bool state )
00100 {
00101   Anaphe::IFitParameter *par = m_fitter->fitParameter(name.c_str());
00102 
00103   if(!par) return false;
00104 
00105   if(state)
00106     par->setBounds(par->value(), par->value());
00107   else
00108     par->release();
00109 
00110   return true;
00111 }
00112     
00113 bool FitFunction::setBounds ( const std::string & name, double lower, double upper )
00114 {
00115   Anaphe::IFitParameter *par = m_fitter->fitParameter(name.c_str());
00116 
00117   if(!par) return false;
00118   
00119   par->setBounds(lower, upper);
00120 
00121   return true;
00122 }
00123     
00124 bool FitFunction::setStart ( const std::string & name, double start )
00125 {
00126   Anaphe::IFitParameter *par = m_fitter->fitParameter(name.c_str());
00127 
00128   if(!par) return false;
00129   
00130   par->setStart(start);
00131 
00132   return true;
00133 }
00134     
00135 bool FitFunction::clearBounds ( const std::string & name )
00136 {
00137   Anaphe::IFitParameter *par = m_fitter->fitParameter(name.c_str());
00138 
00139   if(!par) return false;
00140   
00141   par->release();
00142 
00143   return true;
00144 }
00145     
00146 bool FitFunction::setStepSize ( const std::string & name, double step )
00147 {
00148   Anaphe::IFitParameter *par = m_fitter->fitParameter(name.c_str());
00149 
00150   if(!par) return false;
00151   
00152   par->setStep(step);
00153 
00154   return true;  
00155 }
00156 
00157 double FitFunction::error ( const std::string & name )
00158 {
00159   Anaphe::IFitParameter *par = m_fitter->fitParameter(name.c_str());
00160 
00161   return par ? par->error() : 0.0;
00162 
00163   return true; 
00164 }
00165     
00166 
00167 const std::vector< double > & FitFunction::errors (  )
00168 {
00169   //  std::vector<double> v;
00170 
00171   m_errors_ret.clear();
00172 
00173   FML::IExtendedFitter *ef = m_fitter->internalExtendedFitter();
00174 
00175   if(ef&&ef->minimizer())
00176     for(int i=0; i<ef->minimizer()->result().dimension(); ++i)
00177       m_errors_ret.push_back(ef->minimizer()->result().error(i));
00178 
00179   return m_errors_ret;
00180 }
00181     
00182 
00183 double FitFunction::chiSquare (  )
00184 {
00185   FML::IExtendedFitter *ef = m_fitter->internalExtendedFitter();
00186 
00187   if(ef&&ef->minimizer())
00188     return ef->minimizer()->result().minimumValue();
00189 
00190   return 0.0;
00191 }
00192 
00193 
00194 double FitFunction::degreeOfFreedom (  )
00195 {
00196  
00197   FML::IExtendedFitter *ef = m_fitter->internalExtendedFitter();
00198 
00199   if(ef&&ef->minimizer())
00200     {
00201       // PENDING: this does not take into account the range restriction
00202       int npts = 0;
00203       if(ef->data())
00204         npts = ef->data()->nPoints();
00205       
00206       int pnum = 0;
00207 
00208       if(ef->modelFunction())
00209         pnum = ef->modelFunction()->numberOfParameters();
00210 
00211       return npts-pnum-1;
00212     }
00213 
00214   return 0.0;
00215 }
00216 
00217 bool FitFunction::setErrors ( const std::vector< double > & errors )
00218 {
00219   nyi();
00220   return false;
00221 }
00222     
00223 bool FitFunction::setChiSquare ( double chiSquare )
00224 {
00225   nyi();
00226   return false;
00227 }
00228     
00229 bool FitFunction::setDegreeOfFreedom ( double degreeOfFreedom )
00230 {
00231   nyi();
00232   return false;
00233 }
00234 
00235 bool FitFunction::hasGradient (  ) const
00236 {
00237   FML::IExtendedFitter *ef = m_fitter->internalExtendedFitter();
00238 
00239   if(ef&&ef->minimizer()&&ef->minimizer()->objectiveFunction())
00240     return ef->minimizer()->objectiveFunction()->hasGradient();
00241 
00242   return false;
00243 }
00244     
00248 const std::vector< double > & FitFunction::getGradient ( const std::vector< double > & one, const std::vector< double > & orTwo )
00249 {
00250   nyi();
00251   return vector<double>();
00252 }
00253 
00254 bool FitFunction::fit(const IHistogram & histogram) {
00255   return fit( histogram,0,0);
00256 } 
00257 
00258 // convert to a vector then perform the fit
00259 bool FitFunction::fit(const IHistogram & histogram, int imin, int imax)
00260 {
00261   std::auto_ptr<Anaphe::IVectorFactory> vm(createIVectorFactory());
00262   if(!vm.get()) return false;
00263 
00264   std::auto_ptr<Anaphe::IVector> new_vector(vm->create());
00265 
00266   m_source_data = new_vector;
00267 
00268   if(!m_source_data.get()) return false;
00269 
00270   Anaphe::VoPHist converter;
00271 
00272   if(!converter.fromHistogram(const_cast<IHistogram*>(&histogram), m_source_data.get()))
00273     return false;
00274 
00275   return m_fit(imin,imax); 
00276 
00277 }
00278 
00279 // convert to a vector then perform the fit
00280 bool FitFunction::fit(const ICloud & cloud, int imin, int imax)
00281 {
00282   // convert to a Vop  
00283   std::auto_ptr<Anaphe::IVectorFactory> vm(createIVectorFactory());
00284   if(!vm.get()) return false;
00285 
00286   std::auto_ptr<Anaphe::IVector> new_vector(vm->create());
00287 
00288   m_source_data = new_vector;
00289 
00290   if(!m_source_data.get()) return false;
00291 
00292   Anaphe::VoPCloud converter;
00293 
00294   if(!converter.fromCloud(const_cast<ICloud*>(&cloud), m_source_data.get()))
00295     return false;
00296 
00297   // unbinned fit for clouds
00298   m_method = "UL"; 
00299 
00300   return m_fit(imin,imax); 
00301 
00302 }
00303 
00304   //-----------------------------------------------------------------------
00305   // IFunction Interface
00306   //-----------------------------------------------------------------------
00307 
00308 const std::string & FitFunction::label (  ) const
00309 {
00310   return m_model->label();
00311 }
00312     
00313 double FitFunction::value ( const std::vector< double > & point ) const
00314 {
00315   return m_model->value(point);
00316 }
00317 
00318 int FitFunction::dimension (  ) const
00319 {
00320   return m_model->dimension();
00321 }
00322     
00323 const std::vector< std::string > & FitFunction::parameterNames (  ) const
00324 {
00325   return m_model->parameterNames();
00326 }
00327 
00328 const std::vector< double > & FitFunction::parameterValues (  ) const
00329 {
00330   return m_model->parameterValues();
00331 }
00332     
00333 const string & FitFunction::version (  ) const
00334 {
00335   return m_version;
00336 }
00337 
00338 bool FitFunction::setParameterValue ( const std::string & name, double value )
00339 {
00340   bool ok = m_fitter->setParameter(name.c_str(), value);
00341 
00342   if(!ok) return false;
00343 
00344   return m_model->setParameterValue(name,value);
00345 }
00346 
00347 
00348 void FitFunction::nyi() const
00349 {
00350   cerr << "FitFunction:: Not yet implemented" << endl;
00351 }
00352 
00353 
00354   //-----------------------------------------------------------------------
00355   // protected methods 
00356   //-----------------------------------------------------------------------
00357 
00358 // here  perform the fit on the requested range  
00359 bool FitFunction::m_fit(int imin, int imax)
00360 {
00361   m_fitter->setData(m_source_data.get());
00362 
00363   if(imax!=0 ||  imin != 0) {
00364     m_fitter->excludeAll();
00365     m_fitter->includeRange(imin, imax);
00366     cout << " Fitting range : " << imin << " - " << imax << endl; 
00367   }
00368 
00369   // debug
00370   m_fitter->printParameters(std::cout); 
00371 
00372   bool ok = false; 
00373   if (m_method == "L" || m_method == "ML") 
00374     ok = m_fitter->poissonMLFit(); 
00375   else if (m_method == "UL")
00376     ok = m_fitter->unbinnedMLFit();
00377   else  
00378     ok = m_fitter->chiSquareFit();
00379 
00380   if(ok)
00381     {
00382       // update model function with current parameter values!
00383       m_model->setParameterValues(m_fitter->parameterValueVector());
00384     }
00385 
00386   // debug
00387   m_fitter->printResult(std::cout);
00388 
00389   return ok;
00390 }
00391 


Anaphe documentation generated by Doxygen (www.doxygen.org)