Sorry for a lot of code.
I use ROOT’s minimizer for minimizing the following function:
double GKinFitter::Chi2PlusConstraints( const double* unitedArray ){
bool inBarrel;
chi2 = 0;
double e, theta, phi, rho, z, rhoInitial, zInitial, z0;
double sigmaE, sigmaP, sigmaR, sigmaZ;
//depending on detection photon either in barrel or edge
//this variable could have different meaning
double diffCur;
double dE = constraintE; //difference between required and measured E
double dPx = constraintPx; //... Px
double dPy = constraintPy; //... Py
double dPz = constraintPz; //... Pz
z0 = unitedArray[ nPars * nPhotons ];//zComInPoint
for( int iPh = 0; iPh < nPhotons; iPh++ ){
inBarrel = false;
e = unitedArray[ iPh * nPars ];
sigmaE = photons[iPh]->GetMeasurement(0)->GetError();
phi = unitedArray[ iPh * nPars + 2 ];
sigmaP = photons[iPh]->GetMeasurement(2)->GetError();
rhoInitial = photons[iPh]->GetMeasurement(3)->GetValue();
sigmaR = photons[iPh]->GetMeasurement(3)->GetError();
rho = unitedArray[ iPh * nPars + 3 ];
//check if photon was detected in barrel
if( rhoInitial > 37.8 ) inBarrel = true;
zInitial = photons[iPh]->GetMeasurement(4)->GetValue();
sigmaZ = photons[iPh]->GetMeasurement(4)->GetError();
z = unitedArray[ iPh * nPars + 4 ];
if( inBarrel ){
theta = ArctgPos( rhoInitial / (z + z0) );
diffCur = pow( (z - zInitial) / sigmaZ, 2 );
}
else{
theta = ArctgPos( rho / (zInitial + z0) );
diffCur = pow( (rho - rhoInitial) / sigmaR , 2 );
}
//Build expressions to minimize (chi2 + constraints)
chi2 += pow( (e - photons[iPh]->GetMeasurement(0)->GetValue() ) / sigmaE, 2 )\
+ pow( (phi - photons[iPh]->GetMeasurement(2)->GetValue() ) / sigmaP, 2 )\
+ diffCur;
dE -= e;
dPx -= e*sin(theta)*cos(phi);
dPy -= e*sin(theta)*sin(phi);
dPz -= e*cos(theta);
}
return chi2 + 5*dE*dE + 5*dPx*dPx + 5*dPy*dPy + 5*dPz*dPz;
}
NOTE: This function is a member-function of a class that has one another member function inside which minimizer used:
int GKinFitter::PerformMinimization( const char* minName = "Minuit2",
const char* algoName = "Combined")
{
//creates the ROOT::Minimizator,
//sets the minimization parameters ( Tolerance etc.),
int ind; //Current index
double s; //Current step
double ll, ul; //Current Limits
char parName[15]; //Current Name
double* unitedArray = GatherParameters();
ROOT::Math::Minimizer* minimizer =
ROOT::Math::Factory::CreateMinimizer( minName, algoName );
minimizer->SetMaxFunctionCalls( mfcs );
minimizer->SetMaxIterations( mis );
minimizer->SetTolerance( t );
//Is it correct?
ROOT::Math::Functor functor( this, &GKinFitter::Chi2PlusConstraints, ndf );
for ( int iPh = 0; iPh < nPhotons; iPh++ ){
for( int jPar = 0; jPar < nPars; jPar++ ){
ind = iPh*nPars + jPar;
s = photons[iPh]->GetMeasurement(jPar)->GetError() / sds;
ll = photons[iPh]->GetMeasurement(jPar)->GetLowerLimit();
ul = photons[iPh]->GetMeasurement(jPar)->GetUpperLimit();
sprintf( parName, "freePar%d", ind );
if( jPar != 1 ){
minimizer->SetLimitedVariable( ind, parName, unitedArray[ind], s, ll, ul );
}
else{
minimizer->SetFixedVariable( ind, parName, unitedArray[ind] );
}
}
}
//specify minimization's settings for zComInPoint
ind = nPars * nPhotons;
s = zComInPoint.GetError() / sds;
ll = zComInPoint.GetLowerLimit();
ul = zComInPoint.GetUpperLimit();
sprintf(parName,"zComInPoint");
minimizer->SetLimitedVariable( ind, parName, unitedArray[ind], s, ll, ul);
minimizer->SetFunction( functor );
minimizer->Minimize();
delete [] unitedArray;
delete [] fittedParams;
minimizer->Clear();
return 0;
}
After run this minimization I got the following:
Info in <Minuit2>: Minuit2Minimizer::Minimize : Minimization did NOT converge, Hesse is not valid
And I added in minimized function the following line (in order to monitor changes with variables during minimization (wrong order):
cout << e << " " << phi << " " << rho << " " << z << " " << theta << endl;
And that what I got (numbers are how many times function was called):
2
-2.36 -28.2677 0 40 1.77205 2.186
3
-2.36 -28.2677 0 40 1.77205 2.186
4
-2.36 -28.2677 0 40 1.77205 2.186
5
-2.36 -28.2677 0 40 1.77205 2.186
6
-2.36 -28.2677 0 40 1.77205 2.186
7
-2.36 -28.2677 0 40 1.77205 2.186
8
-2.36 -28.2677 0 40 1.77205 2.186
9
-2.36 -28.2677 0 40 1.77205 2.186
10
-2.36 -28.2677 0 40 1.77205 2.186
11
-2.36 -28.2677 0 40 1.77205 2.186
12
-2.36 -28.2677 0 40 1.77205 2.186
13
-2.36 -28.2677 0 40 1.77205 2.186
14
-2.36 -28.2677 0 40 1.77205 2.186
15
-2.36 -28.2677 0 40 1.77205 2.186
16
-2.36 -28.2677 0 40 1.77205 2.186
17
-2.36 -28.2677 0 40 1.77205 2.186
Why do they stay unchanged?