ROOT Version: 6.16.00
Platform: CentOS Linux release 7.6.1810
Compiler: gcc (GCC) 4.8.5 20150623
I want to use the Class ROOT::Math::Minimizer in Python. I would need to define in python the Functor class in order to pass the function to the minimizer. I have written some code taking testpyfit.py
from How to pass fcn func defined on python side to ROOT.Fitter? as inspiration
Unfortunately the ROOT::TPyMultiGenFunction is quite different from ROOT::Math::Functor and my code fails with
32 myFunctor_instance = MyFunctor()
---> 33 minimum.SetFunction(myFunctor_instance)
34 minimum.SetVariable(0, "x0", x0_p, error_x0_p)
35 minimum.SetVariable(0, "x1", x1_p, error_x1_p)
TypeError: none of the 2 overloaded methods succeeded. Full details:
attempt to access a null-pointer
void ROOT::Math::Minimizer::SetFunction(const ROOT::Math::IGradientFunctionMultiDimTempl<double>& func) =>
could not convert argument 1
import ROOT
def main():
npar=2
x0_p = -2.0
x1_p = 1.0
x2_p = 0.5
error_x0_p = 0.05
error_x1_p = 0.2
error_x2_p = 0.1
minimum = ROOT.Math.Factory.CreateMinimizer("Minuit2", "")
# minimum.SetMaxFunctionCalls(1000000)
# minimum.SetMaxIterations(10000)
# minimum.SetTolerance(0.001)
# minimum.SetPrintLevel(1)
class MyFunctor( ROOT.Math.Functor ):
def __init__( self ):
ROOT.Math.Functor.__init__( self )
pass
def NDim( self ):
print 'PYTHON MyFunctor::NDim called'
return npar
def DoEval( self, x ):
#ret = chi2func(x[0], x[1], x[2])
ret = x[0] * x[0] + x[1] * x[1] + x[2] * x[2]
print 'PYTHON Functor::DoEval val=', ret
return ret
myFunctor_instance = MyFunctor()
minimum.SetFunction(myFunctor_instance)
minimum.SetVariable(0, "x0", x0_p, error_x0_p)
minimum.SetVariable(0, "x1", x1_p, error_x1_p)
minimum.SetVariable(0, "x2", x2_p, error_x2_p)
minimum.Minimize()
return