20 ClassImp(TPyMultiGenFunction);
21 ClassImp(TPyMultiGradFunction);
25 static PyObject* GetOverriddenPyMethod( PyObject* pyself,
const char* method )
28 PyObject* pymethod = 0;
30 if ( pyself && pyself != Py_None ) {
31 pymethod = PyObject_GetAttrString( (PyObject*)pyself, const_cast< char* >( method ) );
32 if ( ! PyROOT::MethodProxy_CheckExact( pymethod ) )
35 Py_XDECREF( pymethod );
42 static PyObject* DispatchCall( PyObject* pyself,
const char* method, PyObject* pymethod = NULL,
43 PyObject* arg1 = NULL, PyObject* arg2 = NULL, PyObject* arg3 = NULL )
51 pymethod = GetOverriddenPyMethod( pyself, method );
54 result = PyObject_CallFunctionObjArgs( pymethod, arg1, arg2, arg3, NULL );
58 PyErr_Format( PyExc_AttributeError,
59 "method %s needs implementing in derived class", const_cast< char* >( method ) );
62 Py_XDECREF( pymethod );
69 TPyMultiGenFunction::TPyMultiGenFunction( PyObject*
self ) : fPySelf( 0 )
84 TPyMultiGenFunction::~TPyMultiGenFunction()
86 if ( fPySelf == Py_None ) {
93 unsigned int TPyMultiGenFunction::NDim()
const
96 PyObject* pyresult = DispatchCall( fPySelf,
"NDim" );
100 throw std::runtime_error(
"Failure in TPyMultiGenFunction::NDim" );
103 unsigned int cppresult = (
unsigned int)PyLong_AsLong( pyresult );
104 Py_XDECREF( pyresult );
112 double TPyMultiGenFunction::DoEval(
const double* x )
const
114 PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
115 PyObject* pyresult = DispatchCall( fPySelf,
"DoEval", NULL, xbuf );
120 throw std::runtime_error(
"Failure in TPyMultiGenFunction::DoEval" );
123 double cppresult = (double)PyFloat_AsDouble( pyresult );
124 Py_XDECREF( pyresult );
132 TPyMultiGradFunction::TPyMultiGradFunction( PyObject*
self )
139 Py_INCREF( Py_None );
147 TPyMultiGradFunction::~TPyMultiGradFunction()
149 if ( fPySelf == Py_None ) {
150 Py_DECREF( fPySelf );
156 unsigned int TPyMultiGradFunction::NDim()
const
159 PyObject* pyresult = DispatchCall( fPySelf,
"NDim" );
163 throw std::runtime_error(
"Failure in TPyMultiGradFunction::NDim" );
166 unsigned int cppresult = (
unsigned int)PyLong_AsLong( pyresult );
167 Py_XDECREF( pyresult );
175 double TPyMultiGradFunction::DoEval(
const double* x )
const
177 PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
178 PyObject* pyresult = DispatchCall( fPySelf,
"DoEval", NULL, xbuf );
183 throw std::runtime_error(
"Failure in TPyMultiGradFunction::DoEval" );
186 double cppresult = (double)PyFloat_AsDouble( pyresult );
187 Py_XDECREF( pyresult );
195 void TPyMultiGradFunction::Gradient(
const double* x,
double* grad )
const {
196 PyObject* pymethod = GetOverriddenPyMethod( fPySelf,
"Gradient" );
199 PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
200 PyObject* gbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)grad );
201 PyObject* pyresult = DispatchCall( fPySelf,
"Gradient", pymethod, xbuf, gbuf );
207 throw std::runtime_error(
"Failure in TPyMultiGradFunction::Gradient" );
210 Py_DECREF( pyresult );
213 return ROOT::Math::IMultiGradFunction::Gradient( x, grad );
219 void TPyMultiGradFunction::FdF(
const double* x,
double& f,
double* df )
const
221 PyObject* pymethod = GetOverriddenPyMethod( fPySelf,
"FdF" );
224 PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
225 PyObject* pyf = PyList_New( 1 );
226 PyList_SetItem( pyf, 0, PyFloat_FromDouble( f ) );
227 PyObject* dfbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)df );
229 PyObject* pyresult = DispatchCall( fPySelf,
"FdF", pymethod, xbuf, pyf, dfbuf );
230 f = PyFloat_AsDouble( PyList_GetItem( pyf, 0 ) );
238 throw std::runtime_error(
"Failure in TPyMultiGradFunction::FdF" );
241 Py_DECREF( pyresult );
244 return ROOT::Math::IMultiGradFunction::FdF( x, f, df );
250 double TPyMultiGradFunction::DoDerivative(
const double * x,
unsigned int icoord )
const
252 PyObject* xbuf = PyROOT::TPyBufferFactory::Instance()->PyBuffer_FromMemory( (Double_t*)x );
253 PyObject* pycoord = PyLong_FromLong( icoord );
255 PyObject* pyresult = DispatchCall( fPySelf,
"DoDerivative", NULL, xbuf, pycoord );
256 Py_DECREF( pycoord );
261 throw std::runtime_error(
"Failure in TPyMultiGradFunction::DoDerivative" );
264 double cppresult = (double)PyFloat_AsDouble( pyresult );
265 Py_XDECREF( pyresult );