void solve(TString outFileName){ ROOT::Math::Minimizer* min = ROOT::Math::Factory::CreateMinimizer("Minuit2", "MIGRAD"); min->SetMaxFunctionCalls(1000000); min->SetTolerance(0.001); min->SetPrintLevel(10); ROOT::Math::Functor f(&totalDist,4); double step[4] = {0.01,0.01,.01,.01}; double variable[4] = { 0,0,50,0}; min->SetFunction(f); min->SetVariable(0,"x" ,variable[0], step[0]); min->SetVariable(1,"y" ,variable[1], step[1]); min->SetVariable(2,"z" ,variable[2], step[2]); min->SetVariable(3,"phi",variable[3], step[3]); // do the minimization min->Minimize(); const double *xs = min->X(); std::cout << "Minimum: f(" << xs[0] << "," << xs[1]<< "," << xs[2]<< "," << xs[3] << "): " << min->MinValue() << std::endl; setZ=xs[2]; ROOT::Math::Minimizer* min2 = ROOT::Math::Factory::CreateMinimizer("Minuit2", "MIGRAD"); min2->SetMaxFunctionCalls(1000000); min2->SetTolerance(0.001); min2->SetPrintLevel(10); ROOT::Math::Functor f2(&totalDistWithoutZ,3); double step2[3] = {0.01,0.01,.01}; double variable2[3] = { xs[0],xs[1],xs[3]}; min2->SetFunction(f2); min2->SetVariable(0,"x" ,variable2[0], step2[0]); min2->SetVariable(1,"y" ,variable2[1], step2[1]); min2->SetVariable(2,"phi",variable2[2], step2[2]); // do the minimization min2->Minimize(); const double *xs2 = min2->X(); std::cout << "Minimum: f(" << xs2[0] << "," << xs2[1]<< "," << xs2[2] << "): " << min2->MinValue() << std::endl; // // expected minimum is 0 // if ( min->MinValue() < 1.E-4 && f(xs) < 1.E-4) // std::cout << " converged to the right minimum" << std::endl; // else { // std::cout << " failed to converge !!!" << std::endl; // Error("NumericalMinimization","fail to converge"); // } }
Asymmetry estimateAsymmetry( const TH1* hist, const TH2* cov, const char * minName = "Minuit2", const char *algoName = "" ) { TH1* normHist=(TH1*)hist->Clone("normHist"); TH2* normCov=(TH2*)cov->Clone("normCov"); normHist->Scale(1.0/hist->Integral()); normCov->Scale(1.0/hist->Integral()/hist->Integral()); const int N = hist->GetNbinsX(); TMatrixD covMatrix(N,N); for (int i=0; i<N;++i) { for (int j=0; j<N;++j) { covMatrix[i][j]=normCov->GetBinContent(i+1,j+1); } } TMatrixD invCovMatrix = TMatrixD(TMatrixD::kInverted,covMatrix); ROOT::Math::Minimizer* min = ROOT::Math::Factory::CreateMinimizer(minName, algoName); // set tolerance , etc... min->SetMaxFunctionCalls(1000000); // for Minuit/Minuit2 min->SetMaxIterations(10000); // for GSL min->SetTolerance(0.001); min->SetPrintLevel(1); //const double xx[1] = {0.5}; std::function<double(const TH1*, const TMatrixD*, const double*)> unboundFct = chi2A; std::function<double(const double*)> boundFct = std::bind(unboundFct,normHist, &invCovMatrix, std::placeholders::_1); //boundFct(xx); ROOT::Math::Functor fct(boundFct,1); min->SetFunction(fct); min->SetVariable(0,"A",0.2, 0.01); min->Minimize(); const double *xs = min->X(); const double *error = min->Errors(); log(INFO,"min: %f\n",xs[0]); log(INFO,"err: %f\n",error[0]); Asymmetry res; res.mean=xs[0]; res.uncertainty=error[0]; return res; }
void find_chisqMin() { chisq=0.; for(int i=0; i<numSpectra; i++) { // for more information see minimizer class documentation // https://root.cern.ch/root/html/ROOT__Math__Minimizer.html char minName[132] = "Minuit"; char algoName[132] = ""; // default conjugate gradient type method ROOT::Math::Minimizer* min = ROOT::Math::Factory::CreateMinimizer(minName, algoName); // set tolerance , etc... min->SetMaxFunctionCalls(1000000); // for Minuit min->SetMaxIterations(10000); // for GSL min->SetTolerance(0.001); min->SetPrintLevel(0); // set to 1 for more info // communication to the likelihood ratio function // (via global parameters) for(int j=0; j<S32K; j++) { expCurrent[j] = (double)expHist[spectrum[i]][j]; simCurrent[j] = (double)dOutHist[spectrum[i]][j]; } spCurrent = i; // create funciton wrapper for minmizer // a IMultiGenFunction type ROOT::Math::Functor lr(&lrchisq,3); // behaves best when these are small // starting point double variable[3] = {0.001,0.001,0.001}; // step size double step[3] = {0.0001,0.0001,0.0001}; min->SetFunction(lr); // Set pars for minimization min->SetVariable(0,"a0",variable[0],step[0]); min->SetVariable(1,"a1",variable[1],step[1]); min->SetVariable(2,"a2",variable[2],step[2]); // do the minimization min->Minimize(); // grab parameters from minimum const double *xs = min->X(); // print results /* std::cout << "Minimum: f(" << xs[0] << "," << xs[1] << "," << xs[2] << "): " */ /* << min->MinValue() << std::endl; */ // assuming 3 parameters // save pars for(int j=0;j<3;j++) aFinal[j][i] = xs[j]; // add to total chisq chisq += min->MinValue(); } }
/* Main part of macro */ void fitData( TGraphErrors *gdata , TF1* ffit , double *startval ) { cout << "\n***** fitData.C: Starting fitting procedure... *****" << endl; g_data_global = gdata; f_fit_global = ffit; if ( g_data_global == NULL ) { cout << "fitData.C: Did no find any data to fit." << endl; return NULL; } const char * minName = "Minuit2"; const char *algoName = "Migrad"; // create minimizer giving a name and a name (optionally) for the specific // algorithm // possible choices are: // minName algoName // Minuit /Minuit2 Migrad, Simplex,Combined,Scan (default is Migrad) // Minuit2 Fumili2 // Fumili // GSLMultiMin ConjugateFR, ConjugatePR, BFGS, // BFGS2, SteepestDescent // GSLMultiFit // GSLSimAn // Genetic ROOT::Math::Minimizer* min = ROOT::Math::Factory::CreateMinimizer(minName, algoName); /* Alternatice constructor for Minuit */ //ROOT::Minuit2::Minuit2Minimizer *min = new ROOT::Minuit2::Minuit2Minimizer(); //TMinuit *min = new TMinuit(); // set tolerance , etc... min->SetMaxFunctionCalls(1000000); // for Minuit/Minuit2 min->SetMaxIterations(10000); // for GSL min->SetTolerance(0.001); min->SetPrintLevel(1); // create funciton wrapper for minmizer // a IMultiGenFunction type ROOT::Math::Functor f(&Chi2_log,3); double step[3] = {0.1,0.1,10}; // starting point double variable[3] = { startval[0],startval[1],startval[2]}; // set function to minimize (this is the Chi2 function) min->SetFunction(f); // Set the free variables to be minimized! min->SetVariable(0,"x",variable[0], step[0]); min->SetVariable(1,"y",variable[1], step[1]); min->SetVariable(2,"z",variable[2], step[2]); // do the minimization min->Minimize(); /* set function parameters to best fit results */ const double *xs = min->X(); f_fit_global->SetParameter(0, xs[0]); f_fit_global->SetParameter(1, xs[1]); f_fit_global->SetParameter(2, xs[2]); /* Print summaries of minimization process */ std::cout << "Minimum: f(" << xs[0] << ", " << xs[1] << ", " << xs[2] << "): " << min->MinValue() << std::endl; // expected minimum is 0 if ( min->MinValue() < 1.E-4 && f(xs) < 1.E-4) std::cout << "Minimizer " << minName << " - " << algoName << " converged to the right minimum" << std::endl; else { std::cout << "Minimizer " << minName << " - " << algoName << " failed to converge !!!" << std::endl; Error("NumericalMinimization","fail to converge"); } /* Get degrees of freedom NDF */ unsigned ndf = 0; /* get range of function used for fit */ double fit_min, fit_max; f_fit_global->GetRange(fit_min,fit_max); /* count data points in range of function */ for ( int p = 0; p < g_data_global->GetN(); p++ ) { if ( g_data_global->GetX()[p] >= fit_min && g_data_global->GetX()[p] <= fit_max ) { ndf++; } } ndf -= 3; // 3 parameters in fit cout << "Degrees of freedom: " << ndf << " --> chi2 / NDF = " << min->MinValue() / ndf << endl; /* Get error covariance matrix from minimizer */ TMatrixD matrix0(3,3); for ( unsigned i = 0; i < 3; i++ ) { for ( unsigned j = 0; j < 3; j++ ) { matrix0[i][j] = min->CovMatrix(i,j); } } matrix0.Print(); /* Get minos error */ double par0_minos_error_up = 0; double par0_minos_error_low = 0; double par1_minos_error_up = 0; double par1_minos_error_low = 0; double par2_minos_error_up = 0; double par2_minos_error_low = 0; min->GetMinosError( 0, par0_minos_error_low, par0_minos_error_up ); min->GetMinosError( 1, par1_minos_error_low, par1_minos_error_up ); min->GetMinosError( 2, par2_minos_error_low, par2_minos_error_up ); cout << "Minos uncertainty parameter 0: up = " << par0_minos_error_up << ", low = " << par0_minos_error_low << endl; cout << "Minos uncertainty parameter 1: up = " << par1_minos_error_up << ", low = " << par1_minos_error_low << endl; cout << "Minos uncertainty parameter 2: up = " << par2_minos_error_up << ", low = " << par2_minos_error_low << endl; /* Plot chi2 */ /* sigmas symmetric from covariance matrix */ //double sigmas[6] = {sqrt(matrix0[0][0]), sqrt(matrix0[0][0]), sqrt(matrix0[1][1]), sqrt(matrix0[1][1]), sqrt(matrix0[2][2]), sqrt(matrix0[2][2])}; /* sigmas asymmetric from minos */ double sigmas[6] = {par0_minos_error_low, par0_minos_error_up, par1_minos_error_low, par1_minos_error_up, par2_minos_error_low, par2_minos_error_up}; plotChi2( g_data_global, f_fit_global, 3, sigmas ); /* Draw contour plots */ TGraph2D* gcontour3D = plotContour( min , 3 , ndf ); /* Find error boundaries */ TF1* flow = (TF1*)f_fit_global->Clone("flow"); TF1* fup = (TF1*)f_fit_global->Clone("fup"); flow->SetRange(0,100000); flow->SetLineColor(kBlue); flow->SetLineStyle(2); fup->SetRange(0,100000); fup->SetLineColor(kBlue); fup->SetLineStyle(2); findErrorBounds( f_fit_global, flow, fup, gcontour3D ); /* plot residuals data w.r.t. fit */ plotResiduals( g_data_global, f_fit_global, flow, fup ); /* Draw data, best fit, and 1-sigma band */ TCanvas *cfit = new TCanvas(); g_data_global->Draw("AP"); //f_fit_global->SetRange(0,4000); f_fit_global->Draw("same"); flow->Draw("same"); fup->Draw("same"); cfit->Print("new_FitResult.png"); /* Fit Extrapolation */ double t_extrapolate_months = 6; double t_extrapolate_s = t_extrapolate_months * 30 * 24 * 60 * 60; cout << "Extrapolation to " << t_extrapolate_months << " months: " << ffit->Eval( t_extrapolate_s ) << " , up: " << fup->Eval( t_extrapolate_s ) - ffit->Eval( t_extrapolate_s ) << " , low: " << flow->Eval( t_extrapolate_s ) - ffit->Eval( t_extrapolate_s ) << endl; return f_fit_global; }
const double* AmFitter::findmin() { double wdeg = _wdeg; // A is LNB gain -- "gain" // B is "slope" // C is "offset" // OLD STUFF FOR ROOT-BASED MINIMIZER double A_start = 66.0; double A_step = 0.01; double B_start = 0.025; //0.025; double B_step = 0.0001; double C_start = -63.0; double C_step = 0.01; double n_start = 0.0E-10; double n_step = 1.0E-12; double t_shift_start = 0.0; double t_shift_step = 1.0; double X_start = -126.9; double X_step = A_step; // FOR THE PARAMETER SCAN METHOD // i = 'initial', f = 'final', s = 'stepsize' /*double Bi = 0.01; double Bf = 0.045; double Bs = 0.001; double Xi = -160.0; double Xf = -110.0; double Xs = 0.1; double ni = 5.0e-10; double nf = 15.0e-10; double ns = 1.0e-11; double ti = 0.0; double tf = 0.0; double ts = 1.0; double Xpars[3]; Xpars[0] = Xi; Xpars[1] = Xf; Xpars[2] = Xs; double npars[3]; npars[0] = ni; npars[1] = nf; npars[2] = ns; double tpars[3]; tpars[0] = ti; tpars[1] = tf; tpars[2] = ts; double* minpars[10]; for(int i=0;i<10;i++) { minpars[i] = new double[5]; }*/ double val = -1; double minval = -1; // PARAMETER SCAN // burn in a non-NaN value /*for(double B = Bi; B <= Bf; B = B + Bs) { for(double X = Xi; X <= Xf; X = X + Xs) { for(double n = ni; n <= nf; n = n + ns) { for(double t = ti; t <= tf; t = t + ts) { val = chi_sq_sum(B,X,n,t); if(val == val) { minval = val; n = nf; X = Xf; B = Bf; break; } } } } }*/ double* ret = new double[4]; /*for(double B = 0.01; B <= 0.05; B = B + 0.01) { for(double X = -160.0; X <= -110.0; X = X + 1.0) { for(double n = 5.0e-10; n <= 15.0e-10; n = n + 1.0e-10) { for(double t = -10; t <= 10; t = t + 1.0) { val = chi_sq_sum(B,X,n,t); //cout << " " << B << " " << X << " " << n << " " << t << " " << val << endl; if(val<=minval) { minval = val; ret[0] = B; ret[1] = X; ret[2] = n; ret[3] = t; } } } } }*/ // PARAMETER SCAN /*boost::thread* scanthread[10]; for(int i=0; i<10; i++) { //scanfunc(0,minval,minpars[0],Xpars,npars,tpars); scanthread[i] = new boost::thread(&AmFitter::scanfunc, this, i, minval, minpars[i], Xpars, npars, tpars); } for(int i=0; i<10; i++) { scanthread[i]->join(); } minval = minpars[0][0]; for(int i=0; i<10; i++ ) { if(minpars[i][0] <= minval) { minval = minpars[i][0]; ret[0] = minpars[i][1]; ret[1] = minpars[i][2]; ret[2] = minpars[i][3]; ret[3] = minpars[i][4]; } } for(int i=0; i<10; i++ ) { delete scanthread[i]; }*/ // UNCOMMENT FOR MORE SUBTLE ROOT MINIMIZATION // not exactly as per tutorial -- didn't do 'algoName' double noise = 0.0; minval = chi_sq_sum(B_start,X_start,noise,t_shift_start); while(true) { /*if( !(val == val) && (_file_id != -1)) { noise -= 0.01e-10; noise -= 0.01e-10; }*/ ROOT::Math::Minimizer* min = ROOT::Math::Factory::CreateMinimizer("Minuit2","Migrad"); // just as in tutorial //min->SetMaxFunctionCalls(5000); //min->SetMaxFunctionCalls(1); min->SetMaxIterations(10000000); min->SetTolerance(0.0001); min->SetPrintLevel(0); // wrap up the function ROOT::Math::Functor f(this,&AmFitter::minfunc,4); // tricky, tricky min->SetFunction(f); //min->SetFixedVariable(0,"B",0.02462491128); //0.02462491128 //min->SetFixedVariable(1,"X",-128.3733503); //-128.3733503 //min->SetVariable(0,"B",B_start,B_step); //min->SetLimitedVariable(0,"B",B_start,B_step,0.022,0.032); // used to find reasonable fits for everything but C4 min->SetLimitedVariable(0,"B",B_start,B_step,0.022,0.045); min->SetVariable(1,"X",X_start,X_step); //min->SetLimitedVariable(2,"n",n_start,n_step,0.0,15.0E-10); min->SetFixedVariable(2,"n",noise); // 7.611546967e-10 //min->SetVariable(2,"n",noise,1.0e-12); // 7.611546967e-10 min->SetLimitedVariable(3,"t_shift",t_shift_start,t_shift_step,-400.0,400.0); //min->SetFixedVariable(3,"t_shift",0.0); min->Minimize(); val = chi_sq_sum(min->X()[0],min->X()[1],min->X()[2],min->X()[3]); if( !(val == val) /*&& (_file_id != -1)*/ ) { delete min; break; } if(val <= minval) { minval = val; ret[0] = min->X()[0]; ret[1] = min->X()[1]; ret[2] = min->X()[2]; ret[3] = min->X()[3]; } if( _file_id == -1 ) { //cout << "curr_val: " << val << " " << noise << endl; } noise += 0.01e-10; delete min; } // now let's check to see if this fit was pathological /*double B = ret[0]; //min->X()[0]; double X = ret[1]; //min->X()[1]; double n = ret[2]; //min->X()[2]; double t_shift = ret[3]; //min->X()[3]; double y1[216]; double y2[216]; double x[216]; // sum that we'll test against for the blacklist double testsum = 0; for(int i=0;i<215;i++) { y1[i-0] = 10*log10((5.0E8)*(1.38065E-23)*(temps_func(time_arr[0][i]))/.001); //y2[i] = 10*log((A*exp(amfitter.hsk_func(amfitter.time_arr[0][i])*B+C) - n)/1); y2[i-0] = 10*log10( (pow(10,0.1*(hsk_func(time_arr[0][i]+t_shift)*B+X)) - n)/1); x[i-0] = time_arr[0][i]; testsum += fabs( y1[i-0] - y2[i-0] ); if( (i>100) && (i<120) ) { //cout << x[i-0] << " " << y1[i-0] << " " << y2[i-0] << endl; } }*/ //cout << endl; if( false ) { //8.0 _blacklist[_file_id] = 1; } else if(_blacklist[_file_id] == 1) { _blacklist[_file_id] = 1; } else { _blacklist[_file_id] = 0; } cout << "Minimizer run completed " << ret[0]<< " " << ret[1] << " " << ret[2]<< " " << ret[3]<< " " << endl; return ret; //return min->X(); }
int NumericalMinimization(const char * minName = "Minuit2", const char *algoName = "" , int randomSeed = -1) { // create minimizer giving a name and a name (optionally) for the specific // algorithm // possible choices are: // minName algoName // Minuit /Minuit2 Migrad, Simplex,Combined,Scan (default is Migrad) // Minuit2 Fumili2 // Fumili // GSLMultiMin ConjugateFR, ConjugatePR, BFGS, // BFGS2, SteepestDescent // GSLMultiFit // GSLSimAn // Genetic ROOT::Math::Minimizer* minimum = ROOT::Math::Factory::CreateMinimizer(minName, algoName); // set tolerance , etc... minimum->SetMaxFunctionCalls(1000000); // for Minuit/Minuit2 minimum->SetMaxIterations(10000); // for GSL minimum->SetTolerance(0.001); minimum->SetPrintLevel(1); // create function wrapper for minimizer // a IMultiGenFunction type ROOT::Math::Functor f(&RosenBrock,2); double step[2] = {0.01,0.01}; // starting point double variable[2] = { -1.,1.2}; if (randomSeed >= 0) { TRandom2 r(randomSeed); variable[0] = r.Uniform(-20,20); variable[1] = r.Uniform(-20,20); } minimum->SetFunction(f); // Set the free variables to be minimized ! minimum->SetVariable(0,"x",variable[0], step[0]); minimum->SetVariable(1,"y",variable[1], step[1]); // do the minimization minimum->Minimize(); const double *xs = minimum->X(); std::cout << "Minimum: f(" << xs[0] << "," << xs[1] << "): " << minimum->MinValue() << std::endl; // expected minimum is 0 if ( minimum->MinValue() < 1.E-4 && f(xs) < 1.E-4) std::cout << "Minimizer " << minName << " - " << algoName << " converged to the right minimum" << std::endl; else { std::cout << "Minimizer " << minName << " - " << algoName << " failed to converge !!!" << std::endl; Error("NumericalMinimization","fail to converge"); } return 0; }