示例#1
0
  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;
}
示例#3
0
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;
}
示例#5
0
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();
}
示例#6
0
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;
}