Skip to content

Commit b88fc68

Browse files
committed
Math Scipy: extracted informatio for the results
1 parent b525dc1 commit b88fc68

File tree

2 files changed

+65
-62
lines changed

2 files changed

+65
-62
lines changed

math/scipy/inc/Math/ScipyMinimizer.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ namespace Experimental {
4343
@ingroup MultiMin
4444
*/
4545

46-
4746
//_____________________________________________________________________________________
4847
/**
4948
* \class ScipyMinimizer
@@ -58,11 +57,13 @@ namespace Experimental {
5857

5958
class ScipyMinimizer : public BasicMinimizer {
6059
private:
61-
PyObject *fMinimize;
62-
PyObject *fTarget;
60+
PyObject *fMinimize;
61+
PyObject *fTarget;
62+
6363
protected:
64-
PyObject *fGlobalNS;
65-
PyObject *fLocalNS;
64+
PyObject *fGlobalNS;
65+
PyObject *fLocalNS;
66+
6667
public:
6768
/**
6869
Default constructor
@@ -91,14 +92,15 @@ class ScipyMinimizer : public BasicMinimizer {
9192
/**
9293
Checks if Python was initialized
9394
*/
94-
int PyIsInitialized();
95+
int PyIsInitialized();
9596

9697
/*
9798
Python finalization
9899
*/
99100
void PyFinalize();
100-
void PyRunString(TString code, TString errorMessage="Failed to run python code", int start=Py_single_input);
101+
void PyRunString(TString code, TString errorMessage = "Failed to run python code", int start = Py_single_input);
101102
void LoadWrappers();
103+
102104
private:
103105
// usually copying is non trivial, so we make this unaccessible
104106

@@ -107,13 +109,12 @@ class ScipyMinimizer : public BasicMinimizer {
107109
*/
108110
ScipyMinimizer(const ScipyMinimizer &) : BasicMinimizer() {}
109111

110-
111112
public:
112113
/// set the function to minimize
113-
//virtual void SetFunction(const ROOT::Math::IMultiGenFunction &func);
114+
// virtual void SetFunction(const ROOT::Math::IMultiGenFunction &func);
114115

115116
/// set the function to minimize
116-
//virtual void SetFunction(const ROOT::Math::IMultiGradFunction &func) { BasicMinimizer::SetFunction(func); }
117+
// virtual void SetFunction(const ROOT::Math::IMultiGradFunction &func) { BasicMinimizer::SetFunction(func); }
117118

118119
/// method to perform the minimization
119120
virtual bool Minimize();
@@ -132,6 +133,7 @@ class ScipyMinimizer : public BasicMinimizer {
132133
The ordering of the variables is the same as in errors
133134
*/
134135
virtual double CovMatrix(unsigned int, unsigned int) const { return 0; }
136+
135137
protected:
136138
ClassDef(ScipyMinimizer, 0) //
137139
};

math/scipy/src/ScipyMinimizer.cxx

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,12 @@ using namespace ROOT::Math;
1414
using namespace ROOT::Math::Experimental;
1515
using namespace ROOT::Fit;
1616

17-
1817
/// function wrapper for the function to be minimized
1918
const ROOT::Math::IMultiGenFunction *gFunction;
2019
/// function wrapper for the gradient of the function to be minimized
2120
const ROOT::Math::IMultiGradFunction *gGradFunction;
2221

23-
PyObject * target_function(PyObject */*self*/, PyObject *args)
22+
PyObject *target_function(PyObject * /*self*/, PyObject *args)
2423
{
2524
PyArrayObject *arr = (PyArrayObject *)PyTuple_GetItem(args, 0);
2625

@@ -30,7 +29,6 @@ PyObject * target_function(PyObject */*self*/, PyObject *args)
3029
return PyFloat_FromDouble(r);
3130
};
3231

33-
3432
//_______________________________________________________________________
3533
ScipyMinimizer::ScipyMinimizer() : BasicMinimizer()
3634
{
@@ -39,11 +37,8 @@ ScipyMinimizer::ScipyMinimizer() : BasicMinimizer()
3937
if (!PyIsInitialized()) {
4038
PyInitialize();
4139
}
42-
4340
}
4441

45-
46-
4742
//_______________________________________________________________________
4843
ScipyMinimizer::ScipyMinimizer(const char *type)
4944
{
@@ -59,22 +54,17 @@ void ScipyMinimizer::PyInitialize()
5954
{
6055
static PyObject *ParamsError;
6156
static PyMethodDef ParamsMethods[] = {
62-
{"target_function", target_function, METH_VARARGS,
63-
"Target function to minimize."},
64-
{NULL, NULL, 0, NULL} /* Sentinel */
57+
{"target_function", target_function, METH_VARARGS, "Target function to minimize."},
58+
{NULL, NULL, 0, NULL} /* Sentinel */
6559
};
6660

67-
static struct PyModuleDef paramsmodule = {
68-
PyModuleDef_HEAD_INIT,
69-
"params", /* name of module */
70-
"ROOT Scipy parameters", /* module documentation, may be NULL */
71-
-1, /* size of per-interpreter state of the module,
72-
or -1 if the module keeps state in global variables. */
73-
ParamsMethods
74-
};
61+
static struct PyModuleDef paramsmodule = {PyModuleDef_HEAD_INIT, "params", /* name of module */
62+
"ROOT Scipy parameters", /* module documentation, may be NULL */
63+
-1, /* size of per-interpreter state of the module,
64+
or -1 if the module keeps state in global variables. */
65+
ParamsMethods};
7566

76-
auto PyInit_params = [](void)->PyObject *
77-
{
67+
auto PyInit_params = [](void) -> PyObject * {
7868
PyObject *m;
7969

8070
m = PyModule_Create(&paramsmodule);
@@ -99,15 +89,15 @@ void ScipyMinimizer::PyInitialize()
9989

10090
bool pyIsInitialized = PyIsInitialized();
10191
if (!pyIsInitialized) {
102-
Py_Initialize(); // Python initialization
92+
Py_Initialize(); // Python initialization
10393
}
10494
fLocalNS = PyDict_New();
10595
fGlobalNS = PyDict_New();
10696

10797
if (!pyIsInitialized) {
10898
_import_array(); // Numpy initialization
10999
}
110-
//Scipy initialization
100+
// Scipy initialization
111101
PyRunString("from scipy.optimize import minimize");
112102
fMinimize = PyDict_GetItemString(fLocalNS, "minimize");
113103
PyRunString("from params import target_function");
@@ -118,76 +108,87 @@ void ScipyMinimizer::PyInitialize()
118108
// Finalize Python interpreter
119109
void ScipyMinimizer::PyFinalize()
120110
{
121-
if (fMinimize) Py_DECREF(fMinimize);
111+
if (fMinimize)
112+
Py_DECREF(fMinimize);
122113
Py_Finalize();
123114
}
124115

125116
//_______________________________________________________________________
126117
int ScipyMinimizer::PyIsInitialized()
127118
{
128-
if (!Py_IsInitialized()) return kFALSE;
119+
if (!Py_IsInitialized())
120+
return kFALSE;
129121
return kTRUE;
130122
}
131123

132124
//_______________________________________________________________________
133-
ScipyMinimizer::~ScipyMinimizer()
134-
{
135-
}
125+
ScipyMinimizer::~ScipyMinimizer() {}
136126

137127
//_______________________________________________________________________
138128
bool ScipyMinimizer::Minimize()
139129
{
140-
(gFunction)= ObjFunction();
130+
(gFunction) = ObjFunction();
141131
(gGradFunction) = GradObjFunction();
142132
auto method = fOptions.MinimizerAlgorithm();
143133

144-
std::cout<<"=== Scipy Minimization"<<std::endl;
145-
std::cout<<"=== Method: "<<method<<std::endl;
146-
std::cout<<"=== Initial value: (";
147-
for(uint i=0;i<NDim();i++ )
148-
{
149-
std::cout<<X()[i];
150-
if(i<NDim()-1)
151-
std::cout<<",";
134+
std::cout << "=== Scipy Minimization" << std::endl;
135+
std::cout << "=== Method: " << method << std::endl;
136+
std::cout << "=== Initial value: (";
137+
for (uint i = 0; i < NDim(); i++) {
138+
std::cout << X()[i];
139+
if (i < NDim() - 1)
140+
std::cout << ",";
152141
}
153-
std::cout<<")"<<std::endl;
142+
std::cout << ")" << std::endl;
154143

155-
double *values = const_cast<double*>(X());
156-
npy_intp dims[1] = { NDim()};
157-
PyObject *py_array= PyArray_SimpleNewFromData(1, dims, NPY_DOUBLE, values);
144+
double *values = const_cast<double *>(X());
145+
npy_intp dims[1] = {NDim()};
146+
PyObject *py_array = PyArray_SimpleNewFromData(1, dims, NPY_DOUBLE, values);
158147

159-
PyObject *pargs=PyTuple_New(0);
148+
PyObject *pargs = PyTuple_New(0);
160149

161-
auto pyvalues = Py_BuildValue("(OOOs)",fTarget,py_array,pargs,method.c_str());
150+
auto pyvalues = Py_BuildValue("(OOOs)", fTarget, py_array, pargs, method.c_str());
162151

163-
PyObject *result = PyObject_CallObject(fMinimize,pyvalues);
152+
PyObject *result = PyObject_CallObject(fMinimize, pyvalues);
164153
Py_DECREF(pyvalues);
165154
Py_DECREF(py_array);
166155

167-
168-
//if the minimization works
169-
PyObject *pstatus = PyObject_GetAttrString(result,"status");
170-
bool status = PyBool_Check(pstatus );
156+
// if the minimization works
157+
PyObject *pstatus = PyObject_GetAttrString(result, "status");
158+
bool status = PyBool_Check(pstatus);
171159
Py_DECREF(pstatus);
172160

173-
//the x values for the minimum
174-
PyArrayObject *pyx = (PyArrayObject *)PyObject_GetAttrString(result,"x");
175-
const double *x =(const double *)PyArray_DATA(pyx);
161+
// the x values for the minimum
162+
PyArrayObject *pyx = (PyArrayObject *)PyObject_GetAttrString(result, "x");
163+
const double *x = (const double *)PyArray_DATA(pyx);
176164
Py_DECREF(pyx);
177165

166+
// number of function evaluations
167+
PyObject *pynfev = PyObject_GetAttrString(result, "nfev");
168+
long nfev = PyLong_AsLong(pynfev);
169+
Py_DECREF(pynfev);
170+
171+
PyObject *pymessage = PyObject_GetAttrString(result, "message");
172+
const char *message = (const char *)PyUnicode_DATA(pymessage);
173+
Py_DECREF(pymessage);
174+
178175
SetFinalValues(x);
179176
auto obj_value = (*gFunction)(x);
180177
SetMinValue(obj_value);
181178

179+
std::cout << "=== Status: " << status << std::endl;
180+
std::cout << "=== Message: " << message << std::endl;
181+
std::cout << "=== Function calls: " << nfev << std::endl;
182182
return status;
183183
}
184184

185185
//_______________________________________________________________________
186-
void ScipyMinimizer::PyRunString(TString code, TString errorMessage, int start) {
186+
void ScipyMinimizer::PyRunString(TString code, TString errorMessage, int start)
187+
{
187188
auto fPyReturn = PyRun_String(code, start, fGlobalNS, fLocalNS);
188189
if (!fPyReturn) {
189-
auto msg = errorMessage + Form(" \ncode = \"%s\"",code.Data());
190-
MATH_ERROR_MSG("ScipyMinimizer::PyRunString", msg.Data() );
190+
auto msg = errorMessage + Form(" \ncode = \"%s\"", code.Data());
191+
MATH_ERROR_MSG("ScipyMinimizer::PyRunString", msg.Data());
191192
PyErr_Print();
192193
exit(1);
193194
}

0 commit comments

Comments
 (0)