How to pass fcn func defined on python side to ROOT.Fitter?

Hi Wim,

the error handling is definitely much more helpful, thanks.

Concerning the TPyMultiGradFunction - if I run this code:

print 'EXAMPLE 2 - minimization using ROOT.TPyMultiGradFunction'

class PyMyMultiGradFCN( ROOT.TPyMultiGradFunction ):
    def __init__( self ):
        ROOT.TPyMultiGradFunction.__init__( self, self )

    def NDim( self ):
        print 'PYTHON PyMyMultiGradFCN::NDim called'
        return 2

    def DoEval( self, x ):
        ret = x[0]*x[0]+x[1]*x[1]
        print 'PYTHON MyMultiGradFCN::DoEval val=', ret
        return ret

    def DoDerivative( self, x,icoord):
        if icoord == 0: 
          ret = 2*x[0]
        elif icoord ==1:
          ret = 2*x[1]

        print 'PYTHON MyMultiGradFCN::DoDerivative val=', ret
        return ret

myMultiGradFCN = PyMyMultiGradFCN()
params2 = array('d',[1.,1.])
fitter.FitFCN(myMultiGradFCN,params2)
fitter.Result().Print(ROOT.cout,True)

x = array('d',[0.,0.])
g = array('d',[100.,100.])
myMultiGradFCN.Gradient(x,g)
print ' gradient = ', g 
print ' der0 = ', myMultiGradFCN.Derivative(x,0)
print ' der1 = ', myMultiGradFCN.Derivative(x,1)

then the fitting looks OK but when the gradient/derivatives is calculated I get these error(s):

TypeError                                 Traceback (most recent call last)
TypeError: DoEval() takes exactly 2 arguments (3 given)
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
...testpyfit.py in <module>()
     65 x = array('d',[0.,0.])
     66 g = array('d',[100.,100.])
---> 67 myMultiGradFCN.Gradient(x,g)
     68 print ' gradient = ', g 
     69 print ' der0 = ', myMultiGradFCN.Derivative(x,0)

Exception: Failure in TPyMultiGradFunction::Gradient (C++ exception)

Looking at bindings/pyroot/src/TPyFitFunction.cxx (root.cern.ch/viewcvs/trunk/bindi … ortby=date) I guess that in the functions TPyMultiGradFunction::{Gradient,Fdf,DoDerivative} there is one wrong line with “DoEval”

PyObject* pyresult = DispatchCall( fPySelf, "DoEval", xbuf, pycoord );

but “Gradient” , “Fdf” and “DoDerivative” should be there instead.

Cheers,
Jiri
testpyfit.py (2.22 KB)