#define _USE_MATH_DEFINES #include "TMath.h" #include "Minuit2/FunctionMinimum.h" #include "Minuit2/MnMinimize.h" #include "Minuit2/MnMigrad.h" #include "Minuit2/MnUserParameterState.h" #include "Minuit2/FCNGradientBase.h" #include #include #include #include #include #include using namespace ROOT::Minuit2; class TheoryFunction { public: TheoryFunction(const std::vector &ini_par) : fpar(ini_par) {} ~TheoryFunction() {} std::vector FPar() const {return fpar;} double operator()(double t) const; std::vector Grad(double t) const; private: std::vector fpar; }; double TheoryFunction::operator()(double t) const { double asy1(fpar[2]); double asy2(fpar[4]); // double expo(TMath::Exp(-TMath::Power(t*fpar[3],fpar[5]))); double expo(TMath::Exp(-t*fpar[3])); double cosine(TMath::Cos(0.0174532925199432955*fpar[0]+6.28318530717958623*fpar[1]*t)); double asymmetry; asymmetry = cosine*expo; asymmetry = asy1*asymmetry; asymmetry = asymmetry+asy2; return asymmetry; } std::vector TheoryFunction::Grad(double t) const { double cosarg(0.0174532925199432955*fpar[0]+6.28318530717958623*fpar[1]*t); double exparg(t*fpar[3]); double cosine(TMath::Cos(cosarg)); double sine(TMath::Sin(cosarg)); // double expo(TMath::Exp(-TMath::Power(exparg,fpar[5]))); double expo(TMath::Exp(-exparg)); std::vector grad; grad.push_back(-0.0174532925199432955*fpar[2]*sine*expo); grad.push_back(-6.28318530717958623*t*fpar[2]*sine*expo); grad.push_back(cosine*expo); // if(exparg > 0.0) // grad.push_back(-fpar[2]*cosine*expo*fpar[5]/fpar[3]*TMath::Power(exparg,fpar[5])); // else // grad.push_back(0.0); grad.push_back(-t*fpar[2]*cosine*expo); grad.push_back(1.0); // if(exparg > 0.0) // grad.push_back(-fpar[2]*cosine*expo*TMath::Log(exparg)*TMath::Power(exparg,fpar[5])); // else // grad.push_back(0.0); grad.push_back(0.0); return grad; } class TheoryFcn : public FCNGradientBase { public: TheoryFcn(const std::vector &meas, const std::vector &err, double t0, double tstep, unsigned int nbins) : tMeasurements(meas),tErrors(err),tTzero(t0),tStep(tstep),tNbins(nbins),tErrorDef(1.) {} ~TheoryFcn() {} virtual double Up() const {return tErrorDef;} virtual double operator()(const std::vector&) const; virtual std::vector Gradient(const std::vector& ) const; virtual bool CheckGradient() const {return true;} std::vector Measurements() const {return tMeasurements;} void SetErrorDef(double def) {tErrorDef = def;} private: std::vector tMeasurements; std::vector tErrors; double tTzero; double tStep; unsigned int tNbins; double tErrorDef; }; double TheoryFcn::operator()(const std::vector& par) const { assert(par.size() == 8); double chi2(0.0); double diff(0.0); double x(0.0); TheoryFunction my_func(par); for(unsigned int n(0); n < tMeasurements.size() ; n++) { x=tTzero+(double)n*tStep; if(x>=0.1 && x<=10.0) { diff = tMeasurements[n]-(par[6]*TMath::Exp(-x/2.197019)*(1.0 + my_func(x)) + par[7]); chi2 += diff*diff/(tErrors[n]*tErrors[n]); } } return chi2; } std::vector TheoryFcn::Gradient(const std::vector &par ) const { assert(par.size() == 8); std::vector grad(par.size(),0.0); std::vector mygrad, theograd; double x(0.0), temp(0.0), myfunc(0.0); TheoryFunction my_func(par); for(unsigned int n(0); n < tMeasurements.size() ; n++) { x=tTzero+(double)n*tStep; if(x>=0.1 && x<=10.0) { myfunc = my_func(x); mygrad = my_func.Grad(x); for(unsigned int i(0); i(&tstart),sizeof(double)); // fin.read(reinterpret_cast(&tstep),sizeof(double)); // fin.read(reinterpret_cast(&noOfBins),sizeof(unsigned int)); // std::vector data(noOfBins), error(noOfBins); // for (unsigned int i(0); i(&data[i]),sizeof(double)); // for (unsigned int i(0); i(&error[i]),sizeof(double)); // fin.close(); double dat, err; std::vector data, error; std::ifstream fin("data.txt"); fin >> tstart >> tstep >> noOfBins; while(!fin.eof()) { fin >> dat >> err; data.push_back(dat); error.push_back(err); } fin.close(); // std::cout << "tstart: " << tstart << std::endl; // std::cout << "tstep: " << tstep << std::endl; // std::cout << "noOfBins: " << noOfBins << std::endl; // std::cout << "data[i] error[i]" << std::endl; // // for (unsigned int i=0; i::max()); double tolerance(0.1); double t1(0.); // get start time struct timeval tv_start, tv_stop; gettimeofday(&tv_start, 0); FunctionMinimum min = minimize(maxfcn, tolerance); gettimeofday(&tv_stop, 0); t1 = (tv_stop.tv_sec - tv_start.tv_sec)*1000.0 + (tv_stop.tv_usec - tv_start.tv_usec)/1000.0; std::cout << "# Calculation time: " << t1 << " ms" << std::endl; std::cout << "CHI^2: " << min.Fval() << std::endl << std::endl; for (unsigned int i(0); i