00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Minuit2/FCNBase.h"
00011 #include "Minuit2/FunctionMinimum.h"
00012 #include "Minuit2/MnMigrad.h"
00013 #include "Minuit2/MnMinos.h"
00014 #include "Minuit2/MnUserParameterState.h"
00015 #include "Minuit2/MnPrint.h"
00016 #include "Minuit2/SimplexMinimizer.h"
00017
00018 #include <iostream>
00019 #include <fstream>
00020
00021 #ifdef USE_SEALBASE
00022 #include "SealBase/Filename.h"
00023 #include "SealBase/ShellEnvironment.h"
00024 #endif
00025
00026 using namespace ROOT::Minuit2;
00027
00028 class PowerLawFunc {
00029
00030 public:
00031
00032 PowerLawFunc(double p0, double p1) : fP0(p0), fP1(p1) {}
00033
00034 ~PowerLawFunc() {}
00035
00036 double operator()(double x) const {
00037 return p1()*exp(log(x)*p0());
00038 }
00039
00040 double p0() const {return fP0;}
00041 double p1() const {return fP1;}
00042
00043 private:
00044 double fP0;
00045 double fP1;
00046 };
00047
00048 class PowerLawChi2FCN : public FCNBase {
00049
00050 public:
00051
00052 PowerLawChi2FCN(const std::vector<double>& meas,
00053 const std::vector<double>& pos,
00054 const std::vector<double>& mvar) : fMeasurements(meas),
00055 fPositions(pos),
00056 fMVariances(mvar) {}
00057
00058 ~PowerLawChi2FCN() {}
00059
00060 double operator()(const std::vector<double>& par) const {
00061 assert(par.size() == 2);
00062 PowerLawFunc pl(par[0], par[1]);
00063 double chi2 = 0.;
00064
00065 for(unsigned int n = 0; n < fMeasurements.size(); n++) {
00066 chi2 += ((pl(fPositions[n]) - fMeasurements[n])*(pl(fPositions[n]) - fMeasurements[n])/fMVariances[n]);
00067 }
00068
00069 return chi2;
00070 }
00071
00072 double Up() const {return 1.;}
00073
00074 private:
00075 std::vector<double> fMeasurements;
00076 std::vector<double> fPositions;
00077 std::vector<double> fMVariances;
00078 };
00079
00080 class PowerLawLogLikeFCN : public FCNBase {
00081
00082 public:
00083
00084 PowerLawLogLikeFCN(const std::vector<double>& meas,
00085 const std::vector<double>& pos) :
00086 fMeasurements(meas), fPositions(pos) {}
00087
00088 ~PowerLawLogLikeFCN() {}
00089
00090 double operator()(const std::vector<double>& par) const {
00091 assert(par.size() == 2);
00092 PowerLawFunc pl(par[0], par[1]);
00093 double logsum = 0.;
00094
00095 for(unsigned int n = 0; n < fMeasurements.size(); n++) {
00096 double k = fMeasurements[n];
00097 double mu = pl(fPositions[n]);
00098 logsum += (k*log(mu) - mu);
00099 }
00100
00101 return -logsum;
00102 }
00103
00104 double Up() const {return 0.5;}
00105
00106 private:
00107 std::vector<double> fMeasurements;
00108 std::vector<double> fPositions;
00109 };
00110
00111 int main() {
00112
00113 std::vector<double> positions;
00114 std::vector<double> measurements;
00115 std::vector<double> var;
00116 {
00117
00118 #ifdef USE_SEALBASE
00119 seal::Filename inputFile (seal::Filename ("$SEAL/src/MathLibs/Minuit/tests/MnSim/paul4.txt").substitute (seal::ShellEnvironment ()));
00120 std::ifstream in(inputFile.Name() );
00121 #else
00122 std::ifstream in("paul4.txt");
00123 #endif
00124 if (!in) {
00125 std::cerr << "Error opening input data file" << std::endl;
00126 return 1;
00127 }
00128
00129
00130 double x = 0., y = 0., err = 0.;
00131 while(in>>x>>y>>err) {
00132
00133 positions.push_back(x);
00134 measurements.push_back(y);
00135 var.push_back(err*err);
00136 }
00137 std::cout<<"size= "<<var.size()<<std::endl;
00138 }
00139 {
00140
00141 std::cout<<">>> test Chi2"<<std::endl;
00142 PowerLawChi2FCN fFCN(measurements, positions, var);
00143
00144 MnUserParameters upar;
00145 upar.Add("p0", -2.3, 0.2);
00146 upar.Add("p1", 1100., 10.);
00147
00148 MnMigrad migrad(fFCN, upar);
00149 std::cout<<"start migrad "<<std::endl;
00150 FunctionMinimum min = migrad();
00151 if(!min.IsValid()) {
00152
00153 std::cout<<"FM is invalid, try with strategy = 2."<<std::endl;
00154 MnMigrad migrad(fFCN, upar, 2);
00155 min = migrad();
00156 }
00157 std::cout<<"minimum: "<<min<<std::endl;
00158 }
00159 {
00160 std::cout<<">>> test log LikeliHood"<<std::endl;
00161
00162 PowerLawLogLikeFCN fFCN(measurements, positions);
00163
00164 MnUserParameters upar;
00165 upar.Add("p0", -2.1, 0.2);
00166 upar.Add("p1", 1000., 10.);
00167
00168 MnMigrad migrad(fFCN, upar);
00169 std::cout<<"start migrad "<<std::endl;
00170 FunctionMinimum min = migrad();
00171 if(!min.IsValid()) {
00172
00173 std::cout<<"FM is invalid, try with strategy = 2."<<std::endl;
00174 MnMigrad migrad(fFCN, upar, 2);
00175 min = migrad();
00176 }
00177 std::cout<<"minimum: "<<min<<std::endl;
00178 }
00179 {
00180 std::cout<<">>> test Simplex"<<std::endl;
00181 PowerLawChi2FCN chi2(measurements, positions, var);
00182 PowerLawLogLikeFCN mlh(measurements, positions);
00183
00184 MnUserParameters upar;
00185 std::vector<double> par; par.push_back(-2.3); par.push_back(1100.);
00186 std::vector<double> err; err.push_back(1.); err.push_back(1.);
00187
00188 SimplexMinimizer simplex;
00189
00190 std::cout<<"start simplex"<<std::endl;
00191 FunctionMinimum min = simplex.Minimize(chi2, par, err);
00192 std::cout<<"minimum: "<<min<<std::endl;
00193 FunctionMinimum min2 = simplex.Minimize(mlh, par, err);
00194 std::cout<<"minimum: "<<min2<<std::endl;
00195 }
00196 return 0;
00197 }