44 BasicMinimizer::BasicMinimizer( ) :
53 int niter = ROOT::Math::MinimizerOptions::DefaultMaxIterations();
54 if (niter <=0 ) niter = 1000;
55 SetMaxIterations(niter);
56 SetPrintLevel(ROOT::Math::MinimizerOptions::DefaultPrintLevel());
60 BasicMinimizer::~BasicMinimizer () {
61 if (fObjFunc)
delete fObjFunc;
64 bool BasicMinimizer::SetVariable(
unsigned int ivar,
const std::string & name,
double val,
double step) {
67 if (ivar > fValues.size() )
return false;
68 if (ivar == fValues.size() ) {
69 fValues.push_back(val);
70 fNames.push_back(name);
71 fSteps.push_back(step);
72 fVarTypes.push_back(kDefault);
78 fVarTypes[ivar] = kDefault;
81 std::map<unsigned int, std::pair<double, double> >::iterator iter = fBounds.find(ivar);
82 if ( iter != fBounds.end() ) fBounds.erase (iter);
89 bool BasicMinimizer::SetLowerLimitedVariable(
unsigned int ivar,
const std::string & name,
double val,
double step,
double lower) {
91 bool ret = SetVariable(ivar, name, val, step);
92 if (!ret)
return false;
93 const double upper = std::numeric_limits<double>::infinity();
94 fBounds[ivar] = std::make_pair( lower, upper);
95 fVarTypes[ivar] = kLowBound;
98 bool BasicMinimizer::SetUpperLimitedVariable(
unsigned int ivar,
const std::string & name,
double val,
double step,
double upper ) {
100 bool ret = SetVariable(ivar, name, val, step);
101 if (!ret)
return false;
102 const double lower = -std::numeric_limits<double>::infinity();
103 fBounds[ivar] = std::make_pair( lower, upper);
104 fVarTypes[ivar] = kUpBound;
108 bool BasicMinimizer::SetLimitedVariable(
unsigned int ivar,
const std::string & name,
double val,
double step,
double lower,
double upper) {
110 bool ret = SetVariable(ivar, name, val, step);
111 if (!ret)
return false;
112 fBounds[ivar] = std::make_pair( lower, upper);
113 fVarTypes[ivar] = kBounds;
117 bool BasicMinimizer::SetFixedVariable(
unsigned int ivar ,
const std::string & name ,
double val ) {
119 bool ret = SetVariable(ivar, name, val, 0.);
120 if (!ret)
return false;
121 fVarTypes[ivar] = kFix;
126 bool BasicMinimizer::SetVariableValue(
unsigned int ivar,
double val) {
129 if (ivar >= fValues.size() )
return false;
134 bool BasicMinimizer::SetVariableValues(
const double * x) {
136 if (x == 0)
return false;
137 std::copy(x,x+fValues.size(), fValues.begin() );
141 bool BasicMinimizer::SetVariableStepSize(
unsigned int ivar,
double step) {
143 if (ivar > fValues.size() )
return false;
148 bool BasicMinimizer::SetVariableLowerLimit(
unsigned int ivar,
double lower) {
150 double upper = (fBounds.count(ivar)) ? fBounds[ivar].second : std::numeric_limits<double>::infinity();
151 return SetVariableLimits(ivar, lower, upper);
154 bool BasicMinimizer::SetVariableUpperLimit(
unsigned int ivar,
double upper) {
156 double lower = (fBounds.count(ivar)) ? fBounds[ivar].first : - std::numeric_limits<double>::infinity();
157 return SetVariableLimits(ivar, lower, upper);
160 bool BasicMinimizer::SetVariableLimits(
unsigned int ivar,
double lower,
double upper) {
162 if (ivar > fVarTypes.size() )
return false;
164 fBounds[ivar] = std::make_pair( lower, upper);
165 if (lower > upper || (lower == - std::numeric_limits<double>::infinity() &&
166 upper == std::numeric_limits<double>::infinity() ) ) {
168 fVarTypes[ivar] = kDefault;
170 else if (lower == upper)
173 if (lower == - std::numeric_limits<double>::infinity() )
174 fVarTypes[ivar] = kLowBound;
175 else if (upper == std::numeric_limits<double>::infinity() )
176 fVarTypes[ivar] = kUpBound;
178 fVarTypes[ivar] = kBounds;
183 bool BasicMinimizer::FixVariable(
unsigned int ivar) {
185 if (ivar >= fVarTypes.size() )
return false;
186 fVarTypes[ivar] = kFix;
190 bool BasicMinimizer::ReleaseVariable(
unsigned int ivar) {
192 if (ivar >= fVarTypes.size() )
return false;
193 if (fBounds.count(ivar) == 0) {
194 fVarTypes[ivar] = kDefault;
197 if (fBounds[ivar].first == - std::numeric_limits<double>::infinity() )
198 fVarTypes[ivar] = kLowBound;
199 else if (fBounds[ivar].second == std::numeric_limits<double>::infinity() )
200 fVarTypes[ivar] = kUpBound;
202 fVarTypes[ivar] = kBounds;
207 bool BasicMinimizer::IsFixedVariable(
unsigned int ivar)
const {
208 if (ivar >= fVarTypes.size() )
return false;
209 return (fVarTypes[ivar] == kFix ) ;
212 bool BasicMinimizer::GetVariableSettings(
unsigned int ivar, ROOT::Fit::ParameterSettings & varObj)
const {
213 if (ivar >= fValues.size() )
return false;
214 assert(fValues.size() == fNames.size() && fValues.size() == fVarTypes.size() );
215 varObj.Set(fNames[ivar],fValues[ivar],fSteps[ivar]);
216 std::map< unsigned int , std::pair< double, double> >::const_iterator itr = fBounds.find(ivar);
217 if (itr != fBounds.end() ) {
218 double lower = (itr->second).first;
219 double upper = (itr->second).second;
220 if (fVarTypes[ivar] == kLowBound) varObj.SetLowerLimit( lower );
221 if (fVarTypes[ivar] == kUpBound) varObj.SetUpperLimit( upper );
222 else varObj.SetLimits( lower,upper);
224 if (fVarTypes[ivar] == kFix ) varObj.Fix();
228 std::string BasicMinimizer::VariableName(
unsigned int ivar)
const {
229 if (ivar >= fNames.size() )
return "";
233 int BasicMinimizer::VariableIndex(
const std::string & name)
const {
234 std::vector<std::string>::const_iterator itr = std::find( fNames.begin(), fNames.end(), name);
235 if (itr == fNames.end() )
return -1;
236 return itr - fNames.begin();
241 void BasicMinimizer::SetFunction(
const ROOT::Math::IMultiGenFunction & func) {
243 fObjFunc = func.Clone();
244 fDim = fObjFunc->NDim();
247 void BasicMinimizer::SetFunction(
const ROOT::Math::IMultiGradFunction & func) {
249 fObjFunc =
dynamic_cast<const ROOT::Math::IMultiGradFunction *
>( func.Clone());
250 assert(fObjFunc != 0);
251 fDim = fObjFunc->NDim();
255 bool BasicMinimizer::CheckDimension()
const {
256 unsigned int npar = fValues.size();
257 if (npar == 0 || npar < fDim ) {
258 MATH_ERROR_MSGVAL(
"BasicMinimizer::CheckDimension",
"Wrong number of parameters",npar);
264 bool BasicMinimizer::CheckObjFunction()
const {
266 MATH_ERROR_MSG(
"BasicMinimizer::CheckFunction",
"Function has not been set");
273 MinimTransformFunction * BasicMinimizer::CreateTransformation(std::vector<double> & startValues,
const ROOT::Math::IMultiGradFunction * func) {
275 bool doTransform = (fBounds.size() > 0);
276 unsigned int ivar = 0;
277 while (!doTransform && ivar < fVarTypes.size() ) {
278 doTransform = (fVarTypes[ivar++] != kDefault );
281 startValues = std::vector<double>(fValues.begin(), fValues.end() );
283 MinimTransformFunction * trFunc = 0;
288 const IMultiGradFunction * gradObjFunc = (func) ? func : dynamic_cast<const IMultiGradFunction *>(fObjFunc);
289 doTransform &= (gradObjFunc != 0);
293 trFunc =
new MinimTransformFunction ( gradObjFunc, fVarTypes, fValues, fBounds );
295 trFunc->InvTransformation(&fValues.front(), &startValues[0]);
298 startValues.resize( trFunc->NDim() );
303 if (func) fObjFunc = func;
317 bool BasicMinimizer::Minimize() {
323 void BasicMinimizer::SetFinalValues(
const double * x) {
325 const MinimTransformFunction * trFunc = TransformFunction();
327 assert(fValues.size() >= trFunc->NTot() );
328 trFunc->Transformation(x, &fValues[0]);
332 assert( fValues.size() >= NDim() );
333 std::copy(x, x + NDim(), fValues.begin() );
337 void BasicMinimizer::PrintResult()
const {
338 int pr = std::cout.precision(18);
339 std::cout <<
"FVAL = " << fMinVal << std::endl;
340 std::cout.precision(pr);
342 std::cout <<
"Niterations = " << NIterations() << std::endl;
343 unsigned int ncalls = NCalls();
344 if (ncalls) std::cout <<
"NCalls = " << ncalls << std::endl;
345 for (
unsigned int i = 0; i < fDim; ++i)
346 std::cout << fNames[i] <<
"\t = " << fValues[i] << std::endl;
349 const ROOT::Math::IMultiGradFunction * BasicMinimizer::GradObjFunction()
const {
350 return dynamic_cast<const ROOT::Math::IMultiGradFunction *
>(fObjFunc);
353 const MinimTransformFunction * BasicMinimizer::TransformFunction()
const {
354 return dynamic_cast<const MinimTransformFunction *
>(fObjFunc);
357 unsigned int BasicMinimizer::NFree()
const {
359 unsigned int nfree = fValues.size();
360 for (
unsigned int i = 0; i < fVarTypes.size(); ++i)
361 if (fVarTypes[i] == kFix) nfree--;