1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
#include "pybind11.hpp"
#include <Minuit2/FCNBase.h>
#include <Minuit2/FunctionMinimum.h>
#include <Minuit2/MnHesse.h>
#include <Minuit2/MnUserFcn.h>
#include <Minuit2/MnUserParameterState.h>
namespace py = pybind11;
using namespace ROOT::Minuit2;
void update_fmin(MnHesse& self, const FCNBase& fcn, FunctionMinimum& min,
unsigned maxcalls, float maxedm) {
// We reset call counter here in contrast to MnHesse.cxx:83
MnUserFcn mfcn(fcn, min.UserState().Trafo(), 0);
// Run Hesse
MinimumState st = self(mfcn, min.State(), min.UserState().Trafo(), maxcalls);
// Need to re-evalute status of minimum, EDM could now be over max EDM or
// maxcalls could be exhausted, see MnMigrad.cxx:187
const auto edm = st.Edm();
if (edm > 10 * maxedm)
min.Add(st, FunctionMinimum::MnAboveMaxEdm);
else if (st.Error().HasReachedCallLimit())
// communicate to user that call limit was reached in MnHesse
min.Add(st, FunctionMinimum::MnReachedCallLimit);
else if (st.Error().IsAvailable())
min.Add(st);
}
void bind_hesse(py::module m) {
py::class_<MnHesse>(m, "MnHesse")
.def(py::init<const MnStrategy&>())
.def("__call__", update_fmin)
;
}
|