TMinuit::SetFCN() trouble

From: Eddy Offermann (eddy@rentec.com)
Date: Tue Nov 30 1999 - 20:11:08 MET


Hi Gerco,

I believe the function below addresses your problem. It takes
into account which parameter is fixed while doing the gradient calculation.

Eddy

//______________________________________________________________________________
void TImpFit1Chisquare(Int_t &nrPar,Double_t *grad,Double_t &chiSquare,
                         Double_t *par,Int_t flag)
{
// Minimization function for Time Series using a Chisquare method

  TImpFit1 *fit  = (TImpFit1 *) gMinuit->GetObjectFit();
  Int_t nrPoints = fit->GetN();
  Float_t *x     = (fit->GetX()).GetArray();
  Float_t *y     = (fit->GetY()).GetArray();
  Float_t *ey    = (fit->GetEY()).GetArray();

  Float_t xMin = gF1->GetXmin();
  Float_t xMax = gF1->GetXmax();

  Double_t xDble;
  gF1->InitArgs(&xDble,par);
  if (flag == 2 && gF1Der)
    gF1Der->InitArgs(&xDble,par);

  if (flag == 2)
  {
    for(Int_t ipar = 0; ipar < nrPar; ipar++)
      grad[gMinuit->fNexofi[ipar]-1] = 0.0;
  }

  Int_t nrPointsFit = 0;
  chiSquare = 0;
  for (Int_t ip = 0; ip < nrPoints; ip++)
  {
    xDble = x[ip];

    // Check if controlled variable x is in range
    if (Foption.Range)
    {
      if ((x[ip] < xMin) || (x[ip] > xMax))
        continue;
    }

    nrPointsFit++;

    Double_t xLow,xUp;

    Double_t pred;
    if (Foption.Integral)
    {
      if (ip > 0)
        xLow = (x[ip]+x[ip-1])/2.;
      else
        xLow = x[ip]-(x[ip+1]-x[ip])/2.;
      if (ip < nrPoints-1)
        xUp  = (x[ip]+x[ip+1])/2.;
      else
        xUp  = x[ip]+(x[ip]-x[ip-1])/2.;
      if (xUp-xLow > 1)
        pred = gF1->Integral(xLow,xUp,par)/(xUp-xLow);
      else
        pred = gF1->EvalPar(&xDble,par);
    }
    else
      pred = gF1->EvalPar(&xDble,par);

    Double_t diff = (pred-y[ip])/ey[ip];

    if (flag == 1) {}
    // will come here only at the start of the fit.
    // Calculate any necessary constants, etc.

    else if (flag == 2 && gF1Der)
    // Calculate  the first derivative of chiSquare.
    // This is optional !!
    {
      for (Int_t ipar = 0; ipar < nrPar; ipar++)
      {
        gSelectPar = gMinuit->fNexofi[ipar]-1;
        Double_t deriv;
        if (Foption.Integral)
        {
          if (xUp-xLow > 1)
            deriv = gF1Der->Integral(xLow,xUp,par)/(xUp-xLow)/ey[ip];
          else
            deriv = gF1Der->EvalPar(&xDble,par)/ey[ip];
        }
        else
          deriv = gF1Der->EvalPar(&xDble,par)/ey[ip];
        grad[gSelectPar] += 2*deriv*diff;
      }
    }

    else if (flag == 3) {}
    // will come here only after the fit is finished.
    // Perform any final calculations, output fitted data, etc.

    chiSquare += diff*diff;
  }
  gF1->SetNumberFitPoints(nrPointsFit);

}



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:43 MET