// @(#)root/minuit2:$Id$
// Authors: M. Winkler, F. James, L. Moneta, A. Zsenei   2003-2005

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2005 LCG ROOT Math team,  CERN/PH-SFT                *
 *                                                                    *
 **********************************************************************/

#ifndef ROOT_Minuit2_FumiliFCNBase
#define ROOT_Minuit2_FumiliFCNBase

#include "Minuit2/FCNBase.h"
#include <cassert>

namespace ROOT {

   namespace Minuit2 {


//____________________________________________________________________________________________
/**

Extension of the FCNBase for the Fumili method. Fumili applies only to
minimization problems used for fitting. The method is based on a
linearization of the model function negleting second derivatives.
User needs to provide the model function. The figure-of-merit describing
the difference between the model function and the actual measurements
has to be implemented by the user in a subclass of FumiliFCNBase.
For an example see the FumiliChi2FCN and FumiliStandardChi2FCN classes.


@author  Andras Zsenei and Lorenzo Moneta, Creation date: 23 Aug 2004

@see <A HREF="http://www.cern.ch/winkler/minuit/tutorial/mntutorial.pdf">MINUIT Tutorial</A> on function minimization, section 5

@see FumiliChi2FCN

@see FumiliStandardChi2FCN

@ingroup Minuit

 */



class FumiliFCNBase : public FCNBase {

public:

   /**
      Default Constructor. Need in this case to create when implementing EvaluateAll the Gradient and Hessian vectors with the right size
   */

   FumiliFCNBase()  :
      fNumberOfParameters(0),
      fValue(0)
   {}

   /**

      Constructor which initializes the class with the function provided by the
      user for modeling the data.

      @param npar the number of parameters

   */


   FumiliFCNBase(unsigned int npar) :
      fNumberOfParameters(npar),
      fValue(0),
      fGradient(std::vector<double>(npar)),
      fHessian(std::vector<double>(static_cast<int>( 0.5*npar*(npar+1) )) )
   {}



//   FumiliFCNBase(const ParametricFunction& modelFCN) { fModelFunction = &modelFCN; }



   virtual ~FumiliFCNBase() {}




   /**

      Evaluate function Value, Gradient and Hessian using Fumili approximation, for values of parameters p
      The resul is cached inside and is return from the FumiliFCNBase::Value ,  FumiliFCNBase::Gradient and
      FumiliFCNBase::Hessian methods

      @param par vector of parameters

   **/

   virtual  void EvaluateAll( const std::vector<double> & par ) = 0;


   /**
      Return cached Value of objective function estimated previously using the  FumiliFCNBase::EvaluateAll method

   **/

   virtual double Value() const { return fValue; }

   /**
      Return cached Value of function Gradient estimated previously using the  FumiliFCNBase::EvaluateAll method
   **/

   virtual const std::vector<double> & Gradient() const { return fGradient; }

   /**
      Return Value of the i-th j-th element of the Hessian matrix estimated previously using the  FumiliFCNBase::EvaluateAll method
      @param row row Index of the matrix
      @param col col Index of the matrix
   **/

   virtual double Hessian(unsigned int row, unsigned int col) const {
      assert( row < fGradient.size() && col < fGradient.size() );
      if(row > col)
         return fHessian[col+row*(row+1)/2];
      else
         return fHessian[row+col*(col+1)/2];
   }

   /**
      return number of function variable (parameters) , i.e. function dimension
   */

   virtual unsigned int Dimension() { return fNumberOfParameters; }

protected :

   /**
      initialize and reset values of gradien and Hessian
   */

   virtual void InitAndReset(unsigned int npar) {
      fNumberOfParameters = npar;
      fGradient = std::vector<double>(npar);
      fHessian = std::vector<double>(static_cast<int>( 0.5*npar*(npar+1) ));
   }

   // methods to be used by the derived classes to set the values
   void SetFCNValue(double value) { fValue = value; }

   std::vector<double> & Gradient() { return fGradient; }

   std::vector<double> & Hessian() { return fHessian; }




private:

   unsigned int fNumberOfParameters;
   double fValue;
   std::vector<double> fGradient;
   std::vector<double> fHessian;


};

  }  // namespace Minuit2

}  // namespace ROOT

#endif  // ROOT_Minuit2_FumiliFCNBase
 FumiliFCNBase.h:1
 FumiliFCNBase.h:2
 FumiliFCNBase.h:3
 FumiliFCNBase.h:4
 FumiliFCNBase.h:5
 FumiliFCNBase.h:6
 FumiliFCNBase.h:7
 FumiliFCNBase.h:8
 FumiliFCNBase.h:9
 FumiliFCNBase.h:10
 FumiliFCNBase.h:11
 FumiliFCNBase.h:12
 FumiliFCNBase.h:13
 FumiliFCNBase.h:14
 FumiliFCNBase.h:15
 FumiliFCNBase.h:16
 FumiliFCNBase.h:17
 FumiliFCNBase.h:18
 FumiliFCNBase.h:19
 FumiliFCNBase.h:20
 FumiliFCNBase.h:21
 FumiliFCNBase.h:22
 FumiliFCNBase.h:23
 FumiliFCNBase.h:24
 FumiliFCNBase.h:25
 FumiliFCNBase.h:26
 FumiliFCNBase.h:27
 FumiliFCNBase.h:28
 FumiliFCNBase.h:29
 FumiliFCNBase.h:30
 FumiliFCNBase.h:31
 FumiliFCNBase.h:32
 FumiliFCNBase.h:33
 FumiliFCNBase.h:34
 FumiliFCNBase.h:35
 FumiliFCNBase.h:36
 FumiliFCNBase.h:37
 FumiliFCNBase.h:38
 FumiliFCNBase.h:39
 FumiliFCNBase.h:40
 FumiliFCNBase.h:41
 FumiliFCNBase.h:42
 FumiliFCNBase.h:43
 FumiliFCNBase.h:44
 FumiliFCNBase.h:45
 FumiliFCNBase.h:46
 FumiliFCNBase.h:47
 FumiliFCNBase.h:48
 FumiliFCNBase.h:49
 FumiliFCNBase.h:50
 FumiliFCNBase.h:51
 FumiliFCNBase.h:52
 FumiliFCNBase.h:53
 FumiliFCNBase.h:54
 FumiliFCNBase.h:55
 FumiliFCNBase.h:56
 FumiliFCNBase.h:57
 FumiliFCNBase.h:58
 FumiliFCNBase.h:59
 FumiliFCNBase.h:60
 FumiliFCNBase.h:61
 FumiliFCNBase.h:62
 FumiliFCNBase.h:63
 FumiliFCNBase.h:64
 FumiliFCNBase.h:65
 FumiliFCNBase.h:66
 FumiliFCNBase.h:67
 FumiliFCNBase.h:68
 FumiliFCNBase.h:69
 FumiliFCNBase.h:70
 FumiliFCNBase.h:71
 FumiliFCNBase.h:72
 FumiliFCNBase.h:73
 FumiliFCNBase.h:74
 FumiliFCNBase.h:75
 FumiliFCNBase.h:76
 FumiliFCNBase.h:77
 FumiliFCNBase.h:78
 FumiliFCNBase.h:79
 FumiliFCNBase.h:80
 FumiliFCNBase.h:81
 FumiliFCNBase.h:82
 FumiliFCNBase.h:83
 FumiliFCNBase.h:84
 FumiliFCNBase.h:85
 FumiliFCNBase.h:86
 FumiliFCNBase.h:87
 FumiliFCNBase.h:88
 FumiliFCNBase.h:89
 FumiliFCNBase.h:90
 FumiliFCNBase.h:91
 FumiliFCNBase.h:92
 FumiliFCNBase.h:93
 FumiliFCNBase.h:94
 FumiliFCNBase.h:95
 FumiliFCNBase.h:96
 FumiliFCNBase.h:97
 FumiliFCNBase.h:98
 FumiliFCNBase.h:99
 FumiliFCNBase.h:100
 FumiliFCNBase.h:101
 FumiliFCNBase.h:102
 FumiliFCNBase.h:103
 FumiliFCNBase.h:104
 FumiliFCNBase.h:105
 FumiliFCNBase.h:106
 FumiliFCNBase.h:107
 FumiliFCNBase.h:108
 FumiliFCNBase.h:109
 FumiliFCNBase.h:110
 FumiliFCNBase.h:111
 FumiliFCNBase.h:112
 FumiliFCNBase.h:113
 FumiliFCNBase.h:114
 FumiliFCNBase.h:115
 FumiliFCNBase.h:116
 FumiliFCNBase.h:117
 FumiliFCNBase.h:118
 FumiliFCNBase.h:119
 FumiliFCNBase.h:120
 FumiliFCNBase.h:121
 FumiliFCNBase.h:122
 FumiliFCNBase.h:123
 FumiliFCNBase.h:124
 FumiliFCNBase.h:125
 FumiliFCNBase.h:126
 FumiliFCNBase.h:127
 FumiliFCNBase.h:128
 FumiliFCNBase.h:129
 FumiliFCNBase.h:130
 FumiliFCNBase.h:131
 FumiliFCNBase.h:132
 FumiliFCNBase.h:133
 FumiliFCNBase.h:134
 FumiliFCNBase.h:135
 FumiliFCNBase.h:136
 FumiliFCNBase.h:137
 FumiliFCNBase.h:138
 FumiliFCNBase.h:139
 FumiliFCNBase.h:140
 FumiliFCNBase.h:141
 FumiliFCNBase.h:142
 FumiliFCNBase.h:143
 FumiliFCNBase.h:144
 FumiliFCNBase.h:145
 FumiliFCNBase.h:146
 FumiliFCNBase.h:147
 FumiliFCNBase.h:148
 FumiliFCNBase.h:149
 FumiliFCNBase.h:150
 FumiliFCNBase.h:151
 FumiliFCNBase.h:152
 FumiliFCNBase.h:153
 FumiliFCNBase.h:154
 FumiliFCNBase.h:155
 FumiliFCNBase.h:156
 FumiliFCNBase.h:157
 FumiliFCNBase.h:158
 FumiliFCNBase.h:159
 FumiliFCNBase.h:160
 FumiliFCNBase.h:161
 FumiliFCNBase.h:162
 FumiliFCNBase.h:163
 FumiliFCNBase.h:164
 FumiliFCNBase.h:165
 FumiliFCNBase.h:166
 FumiliFCNBase.h:167
 FumiliFCNBase.h:168
 FumiliFCNBase.h:169
 FumiliFCNBase.h:170