00001 // @(#)root/minuit2:$Id: GaussianModelFunction.h 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 #ifndef MN_GaussianModelFunction_H_ 00011 #define MN_GaussianModelFunction_H_ 00012 00013 #define _USE_MATH_DEFINES 00014 #include <math.h> 00015 00016 00017 #include "Minuit2/ParametricFunction.h" 00018 00019 #include "Minuit2/MnFcn.h" 00020 #include "Minuit2/MnStrategy.h" 00021 #include "Minuit2/MnUserParameterState.h" 00022 00023 #include <vector> 00024 #include <cassert> 00025 00026 namespace ROOT { 00027 00028 namespace Minuit2 { 00029 00030 00031 00032 00033 00034 /** 00035 00036 Sample implementation of a parametric function. It can be used for 00037 example for the Fumili method when minimizing with Minuit. 00038 In the present case the function is a one-dimensional Gaussian, 00039 which is described by its mean, standard deviation and the constant 00040 term describing the amplitude. As it is used for 00041 function minimization, the role of the variables (or coordinates) and 00042 parameters is inversed! I.e. in the case of a one-dimensional 00043 Gaussian it is x that will be the Parameter and the mean, standard 00044 deviation etc will be the variables. 00045 00046 @author Andras Zsenei and Lorenzo Moneta, Creation date: 26 Oct 2004 00047 00048 @see <A HREF="http://mathworld.wolfram.com/NormalDistribution.html"> Definition of 00049 the Normal/Gaussian distribution </A> (note: this Gaussian is normalized). 00050 00051 @see ParametricFunction 00052 00053 @see FumiliFCNBase 00054 00055 @see FumiliMaximumLikelihoodFCN 00056 00057 @ingroup Minuit 00058 00059 */ 00060 00061 00062 class GaussianModelFunction : public ParametricFunction { 00063 00064 public: 00065 00066 00067 /** 00068 00069 Constructor which initializes the normalized Gaussian with x = 0.0. 00070 00071 */ 00072 00073 GaussianModelFunction() : ParametricFunction(1) { 00074 00075 // setting some default values for the parameters 00076 std::vector<double> param; 00077 param.push_back(0.0); 00078 SetParameters(param); 00079 00080 } 00081 00082 00083 /** 00084 00085 Constructor which initializes the ParametricFunction with the 00086 parameters given as input. 00087 00088 @param params vector containing the initial Parameter Value. 00089 00090 */ 00091 00092 GaussianModelFunction(const std::vector<double>& params) : ParametricFunction(params) { 00093 00094 assert(params.size() == 1); 00095 00096 } 00097 00098 00099 00100 00101 ~GaussianModelFunction() {} 00102 00103 00104 00105 /** 00106 00107 Calculates the Gaussian as a function of the given input. 00108 00109 @param x vector containing the mean, standard deviation and amplitude. 00110 00111 @return the Value of the Gaussian for the given input. 00112 00113 @see <A HREF="http://mathworld.wolfram.com/NormalDistribution.html"> Definition of 00114 the Normal/Gaussian distribution </A> (note: this Gaussian is normalized). 00115 00116 */ 00117 00118 double operator()(const std::vector<double>& x) const { 00119 00120 assert(x.size() == 3); 00121 // commented out for speed-up (even though that is the object-oriented 00122 // way to do things) 00123 //std::vector<double> par = GetParameters(); 00124 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])); 00125 } 00126 00127 00128 00129 /** 00130 00131 Calculates the Gaussian as a function of the given input. 00132 00133 @param x vector containing the mean, the standard deviation and the constant 00134 describing the Gaussian. 00135 00136 @param par vector containing the x coordinate (which is the Parameter in 00137 the case of a minimization). 00138 00139 @return the Value of the Gaussian for the given input. 00140 00141 @see <A HREF="http://mathworld.wolfram.com/NormalDistribution.html"> Definition of 00142 the Normal/Gaussian distribution </A> (note: this Gaussian is normalized). 00143 00144 */ 00145 00146 00147 double operator()(const std::vector<double>& x, const std::vector<double>& param) const { 00148 00149 assert(param.size() == 1); 00150 assert(x.size() == 3); 00151 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])); 00152 } 00153 00154 00155 00156 /** 00157 00158 THAT SHOULD BE REMOVED, IT IS ONLY HERE, BECAUSE AT PRESENT FOR GRADIENT 00159 CALCULATION ONE NEEDS TO INHERIT FROM FCNBASE WHICH NEEDS THIS METHOD 00160 00161 */ 00162 00163 virtual double Up() const { return 1.0; } 00164 00165 00166 00167 std::vector<double> GetGradient(const std::vector<double>& x) const { 00168 00169 00170 const std::vector<double> & param = GetParameters(); 00171 assert(param.size() == 1); 00172 std::vector<double> grad(x.size()); 00173 00174 double y = (param[0]-x[0])/x[1]; 00175 double gaus = exp(-0.5*y*y )/(sqrt(2.*M_PI)*fabs(x[1])); 00176 00177 00178 grad[0] = y/(x[1])*gaus*x[2]; 00179 grad[1] = x[2]*gaus*( y*y - 1.0)/x[1]; 00180 grad[2] = gaus; 00181 //std::cout << "GRADIENT" << y << " " << gaus << " " << x[0] << " " << x[1] << " " << grad[0] << " " << grad[1] << std::endl; 00182 00183 return grad; 00184 00185 } 00186 00187 00188 00189 }; 00190 00191 } // namespace Minuit2 00192 00193 } // namespace ROOT 00194 00195 #endif // MN_GaussianModelFunction_H_