// @(#)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 MN_GaussianModelFunction_H_ #define MN_GaussianModelFunction_H_ #define _USE_MATH_DEFINES #include #include "Minuit2/ParametricFunction.h" #include "Minuit2/MnFcn.h" #include "Minuit2/MnStrategy.h" #include "Minuit2/MnUserParameterState.h" #include #include namespace ROOT { namespace Minuit2 { /** Sample implementation of a parametric function. It can be used for example for the Fumili method when minimizing with Minuit. In the present case the function is a one-dimensional Gaussian, which is described by its mean, standard deviation and the constant term describing the amplitude. As it is used for function minimization, the role of the variables (or coordinates) and parameters is inversed! I.e. in the case of a one-dimensional Gaussian it is x that will be the Parameter and the mean, standard deviation etc will be the variables. @author Andras Zsenei and Lorenzo Moneta, Creation date: 26 Oct 2004 @see Definition of the Normal/Gaussian distribution (note: this Gaussian is normalized). @see ParametricFunction @see FumiliFCNBase @see FumiliMaximumLikelihoodFCN @ingroup Minuit */ class GaussianModelFunction : public ParametricFunction { public: /** Constructor which initializes the normalized Gaussian with x = 0.0. */ GaussianModelFunction() : ParametricFunction(1) { // setting some default values for the parameters std::vector param; param.push_back(0.0); SetParameters(param); } /** Constructor which initializes the ParametricFunction with the parameters given as input. @param params vector containing the initial Parameter Value. */ GaussianModelFunction(const std::vector& params) : ParametricFunction(params) { assert(params.size() == 1); } ~GaussianModelFunction() {} /** Calculates the Gaussian as a function of the given input. @param x vector containing the mean, standard deviation and amplitude. @return the Value of the Gaussian for the given input. @see Definition of the Normal/Gaussian distribution (note: this Gaussian is normalized). */ double operator()(const std::vector& x) const { assert(x.size() == 3); // commented out for speed-up (even though that is the object-oriented // way to do things) //std::vector par = GetParameters(); return x[2]*exp(-0.5*(par[0]-x[0])*(par[0]-x[0])/(x[1]*x[1]))/(sqrt(2.*M_PI)*fabs(x[1])); } /** Calculates the Gaussian as a function of the given input. @param x vector containing the mean, the standard deviation and the constant describing the Gaussian. @param par vector containing the x coordinate (which is the Parameter in the case of a minimization). @return the Value of the Gaussian for the given input. @see Definition of the Normal/Gaussian distribution (note: this Gaussian is normalized). */ double operator()(const std::vector& x, const std::vector& param) const { assert(param.size() == 1); assert(x.size() == 3); return x[2]*exp(-0.5*(param[0]-x[0])*(param[0]-x[0])/(x[1]*x[1]))/(sqrt(2.*M_PI)*fabs(x[1])); } /** THAT SHOULD BE REMOVED, IT IS ONLY HERE, BECAUSE AT PRESENT FOR GRADIENT CALCULATION ONE NEEDS TO INHERIT FROM FCNBASE WHICH NEEDS THIS METHOD */ virtual double Up() const { return 1.0; } std::vector GetGradient(const std::vector& x) const { const std::vector & param = GetParameters(); assert(param.size() == 1); std::vector grad(x.size()); double y = (param[0]-x[0])/x[1]; double gaus = exp(-0.5*y*y )/(sqrt(2.*M_PI)*fabs(x[1])); grad[0] = y/(x[1])*gaus*x[2]; grad[1] = x[2]*gaus*( y*y - 1.0)/x[1]; grad[2] = gaus; //std::cout << "GRADIENT" << y << " " << gaus << " " << x[0] << " " << x[1] << " " << grad[0] << " " << grad[1] << std::endl; return grad; } }; } // namespace Minuit2 } // namespace ROOT #endif // MN_GaussianModelFunction_H_