ROOT::Math::Minimizer with Minuit spontaneously fixes certain parameters


One-line Description:
The ROOT::Math::Minimizer object is fixing function parameters that need to be variable and it’s unclear how to force these parameters to behave as variables.

Longer description:
I am attempting to minimize (with the ROOT::Math::Minimizer) a custom function that compares a sum of filtered component histograms and a goal histogram with a chi-square statistic.

hist_test = sum(  filter( hist_i )  ) // sum over i
val_to_be_minimized = chi_square( hist_test, hist_goal )

The filter effect and relative heights of the component histograms (hist_i) are parameters for the minimization. I am using the ROOT::Math::Minimizer object to do this minimization, trying to copy the example at

The challenge I’m facing is that the minimizer is fixing parameters 0, 8,and 10 (1, 9, and 11) without my calling a function like FixVariable. When I try to release these parameters, it prints “PARAMETER 1/9/11 IS CONSTANT. IGNORED.”

I’ve included the portion of my code that makes and calls the ROOT::Math::Minimizer object. Can someone clarify what’s fixing these parameters and how to make them properly variable again?

  const char * minName = "Minuit";
  const char *algoName = "";
  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(.0001); //previously -1. Online NumbericalMinimizaiton example has .001

  // create funciton wrapper for minmizer
  // a IMultiGenFunction type
  ROOT::Math::Functor f(&HC,&HistoCompare::minimize,13);
  // step length
  double step[13] = {.2,4e-4,1.3e-2,8e-4,7e-4,2e-3,1e-3,1e-3,5e-2,1e-2,1e-2,1e-2,0.1};
  // starting point
  double variable[13] = {-6.4, 3.35e-02, 1.99e+04, 3.06e+04, 4.17e+03, 8.48e3, 6.87e+03, 6.02e+03, -20., 1.0813, -20., 1.0846, 0.};


  // Set the free variables to be minimized!
  min->SetVariable(0,"sigma1",   variable[0], step[0]);
  min->SetVariable(1,"sigma2",   variable[1], step[1]);
  min->SetVariable(2,"LiS",      variable[2], step[2]);
  min->SetVariable(3,"AS",       variable[3], step[3]);
  min->SetVariable(4,"S",        variable[4], step[4]);
  min->SetVariable(5,"Li",       variable[5], step[5]);
  min->SetVariable(6,"A",        variable[6], step[6]);
  min->SetVariable(7,"G",        variable[7], step[7]);
  min->SetVariable(8,"ELi1",     variable[8], step[8]);
  min->SetVariable(9,"ELi2",     variable[9], step[9]);
  min->SetVariable(10,"EA1",     variable[10],step[10]);
  min->SetVariable(11,"EA2",     variable[11],step[11]);

  // print warning if variables are fixed
  for(int i=0;i<13;i++){
      fprintf(stderr,"\nWARNING: variable %d was fixed.\n\n",i);

  // do the minimization

with the output:

1 sigma1 -6.40000e+00 constant
2 sigma2 3.35000e-02 1.16750e-02 no limits
3 LiS 1.99000e+04 9.95010e+02 no limits
4 AS 3.06000e+04 1.53001e+03 no limits
5 S 4.17000e+03 2.08510e+02 no limits
6 Li 8.48000e+03 4.24010e+02 no limits
7 A 6.87000e+03 3.43510e+02 no limits
8 G 6.02000e+03 3.01010e+02 no limits
9 ELi1 -2.00000e+01 constant
10 ELi2 1.08130e+00 6.40650e-02 no limits
11 EA1 -2.00000e+02 constant
12 EA2 1.08460e+00 6.42300e-02 no limits
13 ELiA-eps 0.00000e+00 1.00000e-02 no limits

ROOT Version: 6.04/02
Platform: linuxx8664gcc
Compiler: gcc version 4.9.2 (Debian 4.9.2-10+deb8u2)

I’ve noticed that changing the starting values for one of these forced constant variables

min->SetVariable(0,"sigma1",   variable[0], step[0]);


min->SetVariable(0,"sigma1",   variable[1], step[1]);

fixes things for that variable.

I’ve found the solution. I excluded a portion of code that throws out the hard-coded step values and replaced it with something like:

step[i] = 0.01*variable[i] + 1e-3

where the step is some percentage of the starting value plus epsilon (to prevent a step size of zero). The negative variable[i] values were the ones that were being converted to constants. My problem was fixed by changing the above snippet to:

step[i] = abs(0.01*variable[i]) + 1e-3

which forces each value of step[i] to be positive. I guess negative step values force the parameter as a constant and not a variable.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.