00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "GaussRandomGen.h"
00012 #include "Minuit2/FunctionMinimum.h"
00013 #include "Minuit2/MnUserParameterState.h"
00014 #include "Minuit2/MnPrint.h"
00015 #include "Minuit2/MnMigrad.h"
00016 #include "Minuit2/MnMinos.h"
00017 #include "Minuit2/MnPlot.h"
00018 #include "Minuit2/MinosError.h"
00019 #include "Minuit2/FCNBase.h"
00020 #include <cmath>
00021 #include <iostream>
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 using namespace ROOT::Minuit2;
00032
00033 const int default_ndim = 20;
00034 const int default_ndata = 1000;
00035
00036
00037 double GaussPdf(double x, double x0, double sigma) {
00038 double tmp = (x-x0)/sigma;
00039 return (1.0/(std::sqrt(2 * M_PI) * std::fabs(sigma))) * std::exp(-tmp*tmp/2);
00040 }
00041
00042 double LogMultiGaussPdf(const std::vector<double> & x, const std::vector<double> & p) {
00043 double f = 0;
00044 int ndim = x.size();
00045 for (int k = 0; k < ndim; ++k) {
00046 double y = GaussPdf( x[k], p[ 2*k], p[2*k + 1] );
00047
00048 y = std::max(y, 1.E-300);
00049 double lgaus = std::log( y );
00050 f += lgaus;
00051 }
00052 return f;
00053 }
00054
00055 typedef std::vector< std::vector< double> > Data;
00056
00057 struct LogLikeFCN : public FCNBase {
00058
00059 LogLikeFCN( const Data & data) : fData(data) {}
00060
00061 double operator() (const std::vector<double> & p ) const {
00062 double logl = 0;
00063 int ndata = fData.size();
00064 for (int i = 0; i < ndata; ++i) {
00065 logl -= LogMultiGaussPdf(fData[i], p);
00066 }
00067 return logl;
00068 }
00069 double Up() const { return 0.5; }
00070 const Data & fData;
00071 };
00072
00073 int doFit(int ndim, int ndata) {
00074
00075
00076
00077 Data data(ndata);
00078 std::vector< double> event(ndim);
00079
00080 std::vector<double> mean(ndim);
00081 std::vector<double> sigma(ndim);
00082 for (int k = 0; k < ndim; ++k) {
00083 mean[k] = -double(ndim)/2 + k;
00084 sigma[k] = 1. + 0.1*k;
00085 }
00086
00087
00088 for (int i = 0; i < ndata; ++i) {
00089 for (int k = 0; k < ndim;++k) {
00090 GaussRandomGen rgaus(mean[k],sigma[k] );
00091 event[k] = rgaus();
00092 }
00093 data[i] = event;
00094 }
00095
00096
00097 LogLikeFCN fcn(data);
00098
00099
00100 std::vector<double> init_par(2*ndim);
00101 for (int k = 0; k < ndim; ++k) {
00102 init_par[2*k] = 0;
00103 init_par[2*k+1] = 1;
00104 }
00105
00106 std::vector<double> init_err(2*ndim);
00107 for (int k = 0; k < 2*ndim; ++k) {
00108 init_err[k] = 0.1;
00109 }
00110
00111 VariableMetricMinimizer fMinimizer;
00112
00113
00114 FunctionMinimum min = fMinimizer.Minimize(fcn, init_par, init_err);
00115
00116
00117 std::cout<<"minimum: "<<min<<std::endl;
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 return 0;
00145 }
00146
00147 int main(int argc, char **argv) {
00148 int ndim = default_ndim;
00149 int ndata = default_ndata;
00150 if (argc > 1) {
00151 ndim = atoi(argv[1] );
00152 }
00153 if (argc > 2) {
00154 ndata = atoi(argv[2] );
00155 }
00156 std::cout << "do fit of " << ndim << " dimensional data on " << ndata << " events " << std::endl;
00157 doFit(ndim,ndata);
00158 }