00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifdef _WIN32
00012 #define _USE_MATH_DEFINES
00013 #endif
00014 #include "Minuit2/FunctionMinimum.h"
00015 #include "Minuit2/MnMigrad.h"
00016 #include "Minuit2/MnMinos.h"
00017 #include "Minuit2/MnUserParameters.h"
00018 #include "Minuit2/MnPrint.h"
00019 #include "Minuit2/FCNBase.h"
00020 #include "Minuit2/MnScan.h"
00021 #include "Minuit2/MnPlot.h"
00022
00023 using namespace ROOT::Minuit2;
00024
00025 class ReneFcn : public FCNBase {
00026
00027
00028 public:
00029
00030 ReneFcn(const std::vector<double>& meas) : fMeasurements(meas) {}
00031
00032 virtual ~ReneFcn() {}
00033
00034 virtual double operator()(const std::vector<double>& par) const {
00035 double a = par[2];
00036 double b = par[1];
00037 double c = par[0];
00038 double p0 = par[3];
00039 double p1 = par[4];
00040 double p2 = par[5];
00041 double fval = 0.;
00042
00043 for(unsigned int i = 0; i < fMeasurements.size(); i++) {
00044 double ni = fMeasurements[i];
00045 if(ni < 1.e-10) continue;
00046
00047
00048
00049 double xi = (i+1.)/40. - 1./80.;
00050 double ei = ni;
00051
00052
00053
00054
00055 double nexp = a*xi*xi + b*xi + c + (0.5*p0*p1/M_PI)/std::max(1.e-10, (xi-p2)*(xi-p2) + 0.25*p1*p1);
00056 fval += (ni-nexp)*(ni-nexp)/ei;
00057 }
00058 return fval;
00059 }
00060
00061 virtual double Up() const {return 1.;}
00062
00063 private:
00064 std::vector<double> fMeasurements;
00065 };
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 int main() {
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 double tmp[120] = {38.,36.,46.,52.,54.,52.,61.,52.,64.,77.,
00125 60.,56.,78.,71.,81.,83.,89.,96.,118.,96.,
00126 109.,111.,107.,107.,135.,156.,196.,137.,
00127 160.,153.,185.,222.,251.,270.,329.,422.,
00128 543.,832.,1390.,2835.,3462.,2030.,1130.,
00129 657.,469.,411.,375.,295.,281.,281.,289.,
00130 273.,297.,256.,274.,287.,280.,274.,286.,
00131 279.,293.,314.,285.,322.,307.,313.,324.,
00132 351.,314.,314.,301.,361.,332.,342.,338.,
00133 396.,356.,344.,395.,416.,406.,411.,422.,
00134 393.,393.,409.,455.,427.,448.,459.,403.,
00135 441.,510.,501.,502.,482.,487.,506.,506.,
00136 526.,517.,534.,509.,482.,591.,569.,518.,
00137 609.,569.,598.,627.,617.,610.,662.,666.,
00138 652.,671.,647.,650.,701.};
00139
00140 std::vector<double> measurements(tmp, tmp+120);
00141
00142 ReneFcn fFCN(measurements);
00143
00144 MnUserParameters upar;
00145 upar.Add("p0", 100., 10.);
00146 upar.Add("p1", 100., 10.);
00147 upar.Add("p2", 100., 10.);
00148 upar.Add("p3", 100., 10.);
00149 upar.Add("p4", 1., 0.3);
00150 upar.Add("p5", 1., 0.3);
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 std::cout<<"initial parameters: "<<upar<<std::endl;
00170
00171 std::cout<<"start migrad "<<std::endl;
00172 MnMigrad migrad(fFCN, upar);
00173 FunctionMinimum min = migrad();
00174 if(!min.IsValid()) {
00175
00176 std::cout<<"FM is invalid, try with strategy = 2."<<std::endl;
00177 MnMigrad migrad2(fFCN, min.UserState(), MnStrategy(2));
00178 min = migrad2();
00179 }
00180 std::cout<<"minimum: "<<min<<std::endl;
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 {
00194 std::vector<double> params(6, 1.);
00195 std::vector<double> Error(6, 1.);
00196 MnScan scan(fFCN, params, Error);
00197 std::cout<<"scan parameters: "<<scan.Parameters()<<std::endl;
00198 MnPlot plot;
00199 for(unsigned int i = 0; i < upar.VariableParameters(); i++) {
00200 std::vector<std::pair<double, double> > xy = scan.Scan(i);
00201
00202 plot(xy);
00203 }
00204 std::cout<<scan.Parameters()<<std::endl;
00205 }
00206
00207 {
00208 std::vector<double> params(6, 1.);
00209 std::vector<double> Error(6, 1.);
00210 MnScan scan(fFCN, params, Error);
00211 std::cout<<"scan parameters: "<<scan.Parameters()<<std::endl;
00212 FunctionMinimum min = scan();
00213
00214 std::cout<<scan.Parameters()<<std::endl;
00215 }
00216
00217 return 0;
00218 }
00219