From d942ca36a07742e7caef5ce0b018a4f1da5e5629 Mon Sep 17 00:00:00 2001
From: Gennady Pospelov <g.pospelov@fz-juelich.de>
Date: Wed, 14 Sep 2016 15:45:15 +0200
Subject: [PATCH] New ObjectiveFunction on board of FitKernel

---
 Fit/Kernel/FitKernel.cpp                      |  7 ++-
 Fit/Kernel/FitKernel.h                        |  9 +--
 Fit/Kernel/FitKernelImp.cpp                   | 32 ++++++++--
 Fit/Kernel/FitKernelImp.h                     | 11 ++--
 Fit/Kernel/IMinimizer.h                       |  3 +-
 Fit/Kernel/KernelTypes.h                      | 25 ++++++++
 Fit/Kernel/ObjectiveFunction.cpp              | 41 +++++++++++++
 Fit/Kernel/ObjectiveFunction.h                | 47 +++++++++++++++
 Fit/RootAdapter/RootMinimizerAdapter.cpp      | 26 ++++----
 Fit/RootAdapter/RootMinimizerAdapter.h        |  3 +-
 Fit/RootAdapter/RootObjectiveFuncAdapter.cpp  | 44 +++++++++++---
 Fit/RootAdapter/RootObjectiveFuncAdapter.h    | 14 +++--
 .../Functional/Fit/ObjectiveTestFunctions.cpp |  2 +-
 Tests/Functional/Fit/ObjectiveTestFunctions.h |  2 +-
 Tests/Functional/Fit/StandaloneFitTest.cpp    |  6 +-
 auto/Wrap/libBornAgainFit.py                  |  6 +-
 auto/Wrap/libBornAgainFit_wrap.cpp            | 59 ++++++++-----------
 17 files changed, 255 insertions(+), 82 deletions(-)
 create mode 100644 Fit/Kernel/KernelTypes.h
 create mode 100644 Fit/Kernel/ObjectiveFunction.cpp
 create mode 100644 Fit/Kernel/ObjectiveFunction.h

diff --git a/Fit/Kernel/FitKernel.cpp b/Fit/Kernel/FitKernel.cpp
index ee41fd940a3..36334103d59 100644
--- a/Fit/Kernel/FitKernel.cpp
+++ b/Fit/Kernel/FitKernel.cpp
@@ -42,7 +42,7 @@ void FitKernel::addFitParameter(const std::string &name, double value,
 
 }
 
-void FitKernel::setObjectiveFunction(function_chi2_t func)
+void FitKernel::setObjectiveFunction(objective_function_t func)
 {
     m_impl->setObjectiveFunction(func);
 }
@@ -51,3 +51,8 @@ void FitKernel::minimize()
 {
     m_impl->minimize();
 }
+
+std::string FitKernel::reportResults() const
+{
+    return m_impl->reportResults();
+}
diff --git a/Fit/Kernel/FitKernel.h b/Fit/Kernel/FitKernel.h
index f9299ab42f9..56222b44d0c 100644
--- a/Fit/Kernel/FitKernel.h
+++ b/Fit/Kernel/FitKernel.h
@@ -17,8 +17,8 @@
 #define FITKERNEL_H
 
 #include "WinDllMacros.h"
+#include "KernelTypes.h"
 #include <memory>
-#include <vector>
 
 class FitKernelImp;
 class RealLimits;
@@ -31,8 +31,6 @@ class Attributes;
 class BA_CORE_API_ FitKernel
 {
 public:
-    typedef std::function<double(const std::vector<double>&)> function_chi2_t;
-
     FitKernel();
     ~FitKernel();
 
@@ -47,10 +45,13 @@ public:
                          const RealLimits& lim, const Attributes& attr,
                          double step=0.0);
 
-    void setObjectiveFunction(function_chi2_t func);
+    void setObjectiveFunction(objective_function_t func);
 
     void minimize();
 
+    //! Reports results of minimization in the form of multi-line string.
+    std::string reportResults() const;
+
 private:
     std::unique_ptr<FitKernelImp> m_impl;
 };
diff --git a/Fit/Kernel/FitKernelImp.cpp b/Fit/Kernel/FitKernelImp.cpp
index 9ccfc5ceb6d..b7d4c547f25 100644
--- a/Fit/Kernel/FitKernelImp.cpp
+++ b/Fit/Kernel/FitKernelImp.cpp
@@ -15,6 +15,7 @@
 
 #include "FitKernelImp.h"
 #include "IMinimizer.h"
+#include <sstream>
 
 FitKernelImp::FitKernelImp()
 {
@@ -36,15 +37,17 @@ void FitKernelImp::addFitParameter(FitParameter *par)
     m_fit_parameters.addFitParameter(par);
 }
 
-void FitKernelImp::setObjectiveFunction(function_chi2_t func)
+void FitKernelImp::setObjectiveFunction(objective_function_t func)
 {
-    m_chi2_func = func;
+    m_objective_function.setObjectiveFunction(func);
 }
 
 void FitKernelImp::minimize()
 {
-    // order matters
-    m_minimizer->setObjectiveFunction(m_chi2_func, m_fit_parameters.size());
+    objective_function_t func =
+        [&](const std::vector<double> &pars) { return m_objective_function.evaluate(pars); };
+
+    m_minimizer->setObjectiveFunction(func);
     m_minimizer->setParameters(m_fit_parameters);
 
     // minimize
@@ -57,3 +60,24 @@ void FitKernelImp::minimize()
 
 
 }
+
+std::string FitKernelImp::reportResults() const
+{
+    std::ostringstream result;
+
+     result << std::endl;
+     result
+         << "--- FitSuite::printResults -----------------------------------------------------\n";
+     result << "functionCalls: " << m_objective_function.functionCalls() << "\n";
+//     result << " Chi2:" << std::scientific << std::setprecision(8)
+//               << m_fit_objects.getChiSquaredValue()
+//               << "    chi2.NCall:" << m_function_chi2.getNCalls()
+//               << "  grad.NCall:" << m_function_gradient.getNCalls() << ","
+//               << m_function_gradient.getNCallsGradient() << ","
+//               << m_function_gradient.getNCallsTotal() << " (neval, ngrad, total)" << std::endl;
+
+     result << m_minimizer->reportResults();
+     result << m_fit_parameters.reportResults();
+
+     return result.str();
+}
diff --git a/Fit/Kernel/FitKernelImp.h b/Fit/Kernel/FitKernelImp.h
index 4b0c378cea6..be8bdaee989 100644
--- a/Fit/Kernel/FitKernelImp.h
+++ b/Fit/Kernel/FitKernelImp.h
@@ -17,7 +17,9 @@
 #define FITKERNELIMP_H
 
 #include "WinDllMacros.h"
+#include "KernelTypes.h"
 #include "FitSuiteParameters.h"
+#include "ObjectiveFunction.h"
 #include <memory>
 
 class IMinimizer;
@@ -30,8 +32,6 @@ class FitParameter;
 class BA_CORE_API_ FitKernelImp
 {
 public:
-    typedef std::function<double(const std::vector<double>&)> function_chi2_t;
-
     FitKernelImp();
     ~FitKernelImp();
 
@@ -41,14 +41,17 @@ public:
     //! Adds fit parameter
     void addFitParameter(FitParameter* par);
 
-    void setObjectiveFunction(function_chi2_t func);
+    void setObjectiveFunction(objective_function_t func);
 
     void minimize();
 
+    //! Reports results of minimization in the form of multi-line string.
+    std::string reportResults() const;
+
 private:
     FitSuiteParameters m_fit_parameters;
     std::unique_ptr<IMinimizer> m_minimizer;
-    function_chi2_t m_chi2_func;
+    ObjectiveFunction m_objective_function;
 };
 
 #endif
diff --git a/Fit/Kernel/IMinimizer.h b/Fit/Kernel/IMinimizer.h
index 0930c011969..62a35c102b3 100644
--- a/Fit/Kernel/IMinimizer.h
+++ b/Fit/Kernel/IMinimizer.h
@@ -18,6 +18,7 @@
 
 #include "WinDllMacros.h"
 #include "OptionContainer.h"
+#include "KernelTypes.h"
 #include <functional>
 #include <vector>
 
@@ -63,7 +64,7 @@ class BA_CORE_API_ IMinimizer
     virtual void setGradientFunction(
         function_gradient_t fun_gradient, size_t nparameters, size_t ndatasize);
 
-    virtual void setObjectiveFunction(std::function<double(const std::vector<double>&)>, int ){}
+    virtual void setObjectiveFunction(objective_function_t ){}
 
     //! Returns number of variables to fit
     virtual size_t getNumberOfVariables() const;
diff --git a/Fit/Kernel/KernelTypes.h b/Fit/Kernel/KernelTypes.h
new file mode 100644
index 00000000000..d6189cc07f3
--- /dev/null
+++ b/Fit/Kernel/KernelTypes.h
@@ -0,0 +1,25 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Fit/Minimizer/KernelTypes.h
+//! @brief     Defines common types for fitting library.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef KERNELTYPES_H
+#define KERNELTYPES_H
+
+#include <functional>
+#include <vector>
+
+typedef std::function<double(const std::vector<double>&)> objective_function_t;
+
+
+#endif
diff --git a/Fit/Kernel/ObjectiveFunction.cpp b/Fit/Kernel/ObjectiveFunction.cpp
new file mode 100644
index 00000000000..5a12a0bafab
--- /dev/null
+++ b/Fit/Kernel/ObjectiveFunction.cpp
@@ -0,0 +1,41 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Fit/Minimizer/ObjectiveFunction.h
+//! @brief     Declares class ObjectiveFunction
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include "ObjectiveFunction.h"
+#include <stdexcept>
+
+ObjectiveFunction::ObjectiveFunction()
+    : m_ncalls(0)
+{
+
+}
+
+void ObjectiveFunction::setObjectiveFunction(objective_function_t func)
+{
+    m_evaluate = func;
+}
+
+//! Evaluates the value of the function for given vector of function parameters using
+//! callback mechanism.
+
+double ObjectiveFunction::evaluate(const std::vector<double> &pars)
+{
+    if(!m_evaluate)
+        throw std::runtime_error("ObjectiveFunction::evaluate() -> Error. "
+                                 "Objective function is not set");
+
+    ++m_ncalls;
+    return m_evaluate(pars);
+}
diff --git a/Fit/Kernel/ObjectiveFunction.h b/Fit/Kernel/ObjectiveFunction.h
new file mode 100644
index 00000000000..503b440ef48
--- /dev/null
+++ b/Fit/Kernel/ObjectiveFunction.h
@@ -0,0 +1,47 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Fit/Minimizer/ObjectiveFunction.h
+//! @brief     Declares class ObjectiveFunction
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2015
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef OBJECTIVEFUNCTION_H
+#define OBJECTIVEFUNCTION_H
+
+#include "WinDllMacros.h"
+#include "KernelTypes.h"
+#include <vector>
+#include <functional>
+
+//! @class ObjectiveFunction
+//! @ingroup fitting_internal
+//! @brief The ObjectiveFunction class represents function to minimize.
+
+class BA_CORE_API_ ObjectiveFunction
+{
+public:
+
+    ObjectiveFunction();
+
+    void setObjectiveFunction(objective_function_t func);
+
+    double evaluate(const std::vector<double>& pars);
+
+    int functionCalls() const { return m_ncalls; }
+
+private:
+    objective_function_t m_evaluate;
+    int m_ncalls;
+};
+
+
+#endif
+
diff --git a/Fit/RootAdapter/RootMinimizerAdapter.cpp b/Fit/RootAdapter/RootMinimizerAdapter.cpp
index 67e93b07625..9f49bede798 100644
--- a/Fit/RootAdapter/RootMinimizerAdapter.cpp
+++ b/Fit/RootAdapter/RootMinimizerAdapter.cpp
@@ -24,6 +24,7 @@
 
 RootMinimizerAdapter::RootMinimizerAdapter(const MinimizerInfo &minimizerInfo)
     :  m_minimizerInfo(minimizerInfo)
+    , m_obj_func(new RootObjectiveFunctionAdapter)
     , m_status(false)
 {
 
@@ -37,6 +38,9 @@ RootMinimizerAdapter::~RootMinimizerAdapter()
 void RootMinimizerAdapter::minimize()
 {
     propagateOptions();
+
+    rootMinimizer()->SetFunction(*m_obj_func->rootChiSquaredFunction());
+
     m_status = rootMinimizer()->Minimize();
 }
 
@@ -101,13 +105,15 @@ void RootMinimizerAdapter::setParameters(const FitSuiteParameters &parameters)
     for (auto par: parameters)
         setParameter(index++, par );
 
-    if( (int)parameters.size() != fitParameterCount())  {
-        std::ostringstream ostr;
-        ostr << "BasicMinimizer::setParameters() -> Error! Unconsistency in fit parameter number: ";
-        ostr << "fitParameterCount = " << fitParameterCount() << ",";
-        ostr << "parameters.size = " << parameters.size();
-        throw std::runtime_error(ostr.str());
-    }
+    m_obj_func->setNumberOfParameters(parameters.size());
+
+//    if( (int)parameters.size() != fitParameterCount())  {
+//        std::ostringstream ostr;
+//        ostr << "BasicMinimizer::setParameters() -> Error! Unconsistency in fit parameter number: ";
+//        ostr << "fitParameterCount = " << fitParameterCount() << ",";
+//        ostr << "parameters.size = " << parameters.size();
+//        throw std::runtime_error(ostr.str());
+//    }
 }
 
 void RootMinimizerAdapter::setChiSquaredFunction(IMinimizer::function_chi2_t fun_chi2, size_t nparameters)
@@ -122,11 +128,9 @@ void RootMinimizerAdapter::setGradientFunction(IMinimizer::function_gradient_t f
     if( isGradientBasedAgorithm() ) rootMinimizer()->SetFunction(*m_gradient_func);
 }
 
-void RootMinimizerAdapter::setObjectiveFunction(std::function<double (const std::vector<double> &)> func, int ndim)
+void RootMinimizerAdapter::setObjectiveFunction(objective_function_t func)
 {
-    m_obj_func.reset(new RootObjectiveFunctionAdapter);
-    m_obj_func->setFunction(func, ndim);
-    rootMinimizer()->SetFunction(*m_obj_func->rootChiSquaredFunction());
+    m_obj_func->setFunction(func);
 }
 
 std::vector<double> RootMinimizerAdapter::getValueOfVariablesAtMinimum() const
diff --git a/Fit/RootAdapter/RootMinimizerAdapter.h b/Fit/RootAdapter/RootMinimizerAdapter.h
index b61c725d768..cf9706671f5 100644
--- a/Fit/RootAdapter/RootMinimizerAdapter.h
+++ b/Fit/RootAdapter/RootMinimizerAdapter.h
@@ -58,8 +58,7 @@ public:
     virtual void setGradientFunction(
         function_gradient_t fun_gradient, size_t nparameters, size_t ndatasize);
 
-    virtual void setObjectiveFunction(std::function<double(const std::vector<double>&)> func, int ndim);
-
+    virtual void setObjectiveFunction(objective_function_t func);
 
     virtual std::vector<double> getValueOfVariablesAtMinimum() const;
     virtual std::vector<double> getErrorOfVariables() const;
diff --git a/Fit/RootAdapter/RootObjectiveFuncAdapter.cpp b/Fit/RootAdapter/RootObjectiveFuncAdapter.cpp
index 72b54bd3450..6127a236999 100644
--- a/Fit/RootAdapter/RootObjectiveFuncAdapter.cpp
+++ b/Fit/RootAdapter/RootObjectiveFuncAdapter.cpp
@@ -16,21 +16,49 @@
 #include "RootObjectiveFuncAdapter.h"
 #include "ROOTMinimizerFunction.h"
 #include "IMinimizer.h"
+#include <stdexcept>
 
-void RootObjectiveFunctionAdapter::setFunction(func_t func, int ndims)
+RootObjectiveFunctionAdapter::RootObjectiveFunctionAdapter()
+    : m_nparameters(0)
 {
-    m_ndims = ndims;
-    m_func = func;
-    IMinimizer::function_chi2_t fun_chi2 =
+
+}
+
+void RootObjectiveFunctionAdapter::setFunction(objective_function_t func)
+{
+    m_objective_function = func;
+}
+
+void RootObjectiveFunctionAdapter::setNumberOfParameters(int nparameters)
+{
+    m_nparameters = nparameters;
+}
+
+//! Creates objective function suitable for ROOT minimizers
+
+const ROOTMinimizerChiSquaredFunction*
+    RootObjectiveFunctionAdapter::rootChiSquaredFunction()
+{
+    if(!m_objective_function)
+        throw std::runtime_error("RootObjectiveFunctionAdapter::rootChiSquaredFunction() -> Error. "
+                                 "Objective function is not set.");
+
+    if(m_nparameters <= 0)
+        throw std::runtime_error("RootObjectiveFunctionAdapter::rootChiSquaredFunction() -> Error. "
+                                 "Number of parameters must be >0");
+
+    root_evaluate_t fun_chi2 =
         [&] (const double* pars) {return evaluate(pars);};
 
-    m_root_chi_function.reset(new ROOTMinimizerChiSquaredFunction(fun_chi2, ndims));
+    m_root_chi_function.reset(new ROOTMinimizerChiSquaredFunction(fun_chi2, m_nparameters));
+
+    return m_root_chi_function.get();
 }
 
 double RootObjectiveFunctionAdapter::evaluate(const double *pars)
 {
     std::vector<double> vec;
-    vec.resize(m_ndims, 0.0);
-    std::copy(pars, pars+m_ndims, vec.begin());
-    return m_func(vec);
+    vec.resize(m_nparameters, 0.0);
+    std::copy(pars, pars+m_nparameters, vec.begin());
+    return m_objective_function(vec);
 }
diff --git a/Fit/RootAdapter/RootObjectiveFuncAdapter.h b/Fit/RootAdapter/RootObjectiveFuncAdapter.h
index 9f66378b18c..3fc50b72e5f 100644
--- a/Fit/RootAdapter/RootObjectiveFuncAdapter.h
+++ b/Fit/RootAdapter/RootObjectiveFuncAdapter.h
@@ -17,6 +17,7 @@
 #define ROOTOBJECTIVEFUNCTIONADAPTER_H
 
 #include "WinDllMacros.h"
+#include "KernelTypes.h"
 #include <memory>
 #include <vector>
 
@@ -29,20 +30,23 @@ class ROOTMinimizerChiSquaredFunction;
 class BA_CORE_API_ RootObjectiveFunctionAdapter
 {
 public:
-    typedef std::function<double(const std::vector<double>&)> func_t;
+    typedef std::function<double(const double*)> root_evaluate_t;
 
-    void setFunction(func_t func, int ndims);
+    RootObjectiveFunctionAdapter();
 
+    void setFunction(objective_function_t func);
 
-    const ROOTMinimizerChiSquaredFunction  *rootChiSquaredFunction() const { return m_root_chi_function.get(); }
+    void setNumberOfParameters(int nparameters);
+
+    const ROOTMinimizerChiSquaredFunction* rootChiSquaredFunction();
 
 private:
     double evaluate(const double *pars);
 
-    func_t m_func;
+    objective_function_t m_objective_function;
 
     std::unique_ptr<ROOTMinimizerChiSquaredFunction> m_root_chi_function;
-    int m_ndims;
+    int m_nparameters;
 };
 
 #endif
diff --git a/Tests/Functional/Fit/ObjectiveTestFunctions.cpp b/Tests/Functional/Fit/ObjectiveTestFunctions.cpp
index 9d1cddc7877..0aec2fb4e9b 100644
--- a/Tests/Functional/Fit/ObjectiveTestFunctions.cpp
+++ b/Tests/Functional/Fit/ObjectiveTestFunctions.cpp
@@ -19,7 +19,7 @@
 
 //! RosenBrock function: F(x,y) = 100 (y-x^2)^2 + (1-x)^2
 
-double ObjectiveFunctions::RosenBrock(const std::vector<double> &par)
+double TestFunctions::RosenBrock(const std::vector<double> &par)
 {
     if(par.size() != 2)
         throw std::runtime_error("ObjectiveFunctions::RosenBrock() -> Error. Expected 2 input "
diff --git a/Tests/Functional/Fit/ObjectiveTestFunctions.h b/Tests/Functional/Fit/ObjectiveTestFunctions.h
index b9bd6f53bc6..f1e42ec840c 100644
--- a/Tests/Functional/Fit/ObjectiveTestFunctions.h
+++ b/Tests/Functional/Fit/ObjectiveTestFunctions.h
@@ -24,7 +24,7 @@
 //! @brief Collection of objective functions for minimization library testing.
 //! Borrowed from StressFit test framework of http://root.cern.ch.
 
-namespace ObjectiveFunctions
+namespace TestFunctions
 {
 
     BA_CORE_API_ double RosenBrock(const std::vector<double>& par);
diff --git a/Tests/Functional/Fit/StandaloneFitTest.cpp b/Tests/Functional/Fit/StandaloneFitTest.cpp
index 68cacb8c5d0..697e570c433 100644
--- a/Tests/Functional/Fit/StandaloneFitTest.cpp
+++ b/Tests/Functional/Fit/StandaloneFitTest.cpp
@@ -41,10 +41,10 @@ bool StandaloneFitTest::runTest()
     fitKernel->addFitParameter("par2", 1.0, RealLimits::limited(-5.0, 5.0), Attributes::free(), 0.01);
 
 
-    FitKernel::function_chi2_t func = ObjectiveFunctions::RosenBrock;
-
-    fitKernel->setObjectiveFunction(func);
+    fitKernel->setObjectiveFunction(TestFunctions::RosenBrock);
     fitKernel->minimize();
 
+    std::cout << fitKernel->reportResults() << std::endl;
+
     return true;
 }
diff --git a/auto/Wrap/libBornAgainFit.py b/auto/Wrap/libBornAgainFit.py
index 118a57115be..f2e2f20cc8e 100644
--- a/auto/Wrap/libBornAgainFit.py
+++ b/auto/Wrap/libBornAgainFit.py
@@ -1879,9 +1879,9 @@ class IMinimizer(_object):
         return _libBornAgainFit.IMinimizer_setGradientFunction(self, fun_gradient, nparameters, ndatasize)
 
 
-    def setObjectiveFunction(self, arg2, arg3):
-        """setObjectiveFunction(IMinimizer self, std::function< double (std::vector< double,std::allocator< double > > const &) > arg2, int arg3)"""
-        return _libBornAgainFit.IMinimizer_setObjectiveFunction(self, arg2, arg3)
+    def setObjectiveFunction(self, arg2):
+        """setObjectiveFunction(IMinimizer self, objective_function_t arg2)"""
+        return _libBornAgainFit.IMinimizer_setObjectiveFunction(self, arg2)
 
 
     def getNumberOfVariables(self):
diff --git a/auto/Wrap/libBornAgainFit_wrap.cpp b/auto/Wrap/libBornAgainFit_wrap.cpp
index 5cf7bf3e587..b8bcf7f1ae6 100644
--- a/auto/Wrap/libBornAgainFit_wrap.cpp
+++ b/auto/Wrap/libBornAgainFit_wrap.cpp
@@ -3470,19 +3470,19 @@ namespace Swig {
 #define SWIGTYPE_p_function_gradient_t swig_types[13]
 #define SWIGTYPE_p_int swig_types[14]
 #define SWIGTYPE_p_long_long swig_types[15]
-#define SWIGTYPE_p_p_PyObject swig_types[16]
-#define SWIGTYPE_p_short swig_types[17]
-#define SWIGTYPE_p_signed_char swig_types[18]
-#define SWIGTYPE_p_size_type swig_types[19]
-#define SWIGTYPE_p_std__allocatorT_double_t swig_types[20]
-#define SWIGTYPE_p_std__allocatorT_int_t swig_types[21]
-#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[22]
-#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[23]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[24]
-#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[25]
-#define SWIGTYPE_p_std__functionT_double_fdouble_const_pF_t swig_types[26]
-#define SWIGTYPE_p_std__functionT_double_fdouble_const_p_unsigned_int_double_pF_t swig_types[27]
-#define SWIGTYPE_p_std__functionT_double_fstd__vectorT_double_std__allocatorT_double_t_t_const_RF_t swig_types[28]
+#define SWIGTYPE_p_objective_function_t swig_types[16]
+#define SWIGTYPE_p_p_PyObject swig_types[17]
+#define SWIGTYPE_p_short swig_types[18]
+#define SWIGTYPE_p_signed_char swig_types[19]
+#define SWIGTYPE_p_size_type swig_types[20]
+#define SWIGTYPE_p_std__allocatorT_double_t swig_types[21]
+#define SWIGTYPE_p_std__allocatorT_int_t swig_types[22]
+#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[23]
+#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[24]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[25]
+#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[26]
+#define SWIGTYPE_p_std__functionT_double_fdouble_const_pF_t swig_types[27]
+#define SWIGTYPE_p_std__functionT_double_fdouble_const_p_unsigned_int_double_pF_t swig_types[28]
 #define SWIGTYPE_p_std__invalid_argument swig_types[29]
 #define SWIGTYPE_p_std__shared_ptrT_IFitObserver_t swig_types[30]
 #define SWIGTYPE_p_std__shared_ptrT_IMultiLayerBuilder_t swig_types[31]
@@ -19544,43 +19544,34 @@ fail:
 SWIGINTERN PyObject *_wrap_IMinimizer_setObjectiveFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IMinimizer *arg1 = (IMinimizer *) 0 ;
-  std::function< double (std::vector< double,std::allocator< double > > const &) > arg2 ;
-  int arg3 ;
+  objective_function_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 ;
   int res2 = 0 ;
-  int val3 ;
-  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:IMinimizer_setObjectiveFunction",&obj0,&obj1,&obj2)) SWIG_fail;
+  if (!PyArg_ParseTuple(args,(char *)"OO:IMinimizer_setObjectiveFunction",&obj0,&obj1)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IMinimizer, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IMinimizer_setObjectiveFunction" "', argument " "1"" of type '" "IMinimizer *""'"); 
   }
   arg1 = reinterpret_cast< IMinimizer * >(argp1);
   {
-    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__functionT_double_fstd__vectorT_double_std__allocatorT_double_t_t_const_RF_t,  0  | 0);
+    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_objective_function_t,  0  | 0);
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IMinimizer_setObjectiveFunction" "', argument " "2"" of type '" "std::function< double (std::vector< double,std::allocator< double > > const &) >""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IMinimizer_setObjectiveFunction" "', argument " "2"" of type '" "objective_function_t""'"); 
     }  
     if (!argp2) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IMinimizer_setObjectiveFunction" "', argument " "2"" of type '" "std::function< double (std::vector< double,std::allocator< double > > const &) >""'");
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IMinimizer_setObjectiveFunction" "', argument " "2"" of type '" "objective_function_t""'");
     } else {
-      std::function< double (std::vector< double,std::allocator< double > > const &) > * temp = reinterpret_cast< std::function< double (std::vector< double,std::allocator< double > > const &) > * >(argp2);
+      objective_function_t * temp = reinterpret_cast< objective_function_t * >(argp2);
       arg2 = *temp;
       if (SWIG_IsNewObj(res2)) delete temp;
     }
   }
-  ecode3 = SWIG_AsVal_int(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IMinimizer_setObjectiveFunction" "', argument " "3"" of type '" "int""'");
-  } 
-  arg3 = static_cast< int >(val3);
-  (arg1)->setObjectiveFunction(arg2,arg3);
+  (arg1)->setObjectiveFunction(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22606,7 +22597,7 @@ static PyMethodDef SwigMethods[] = {
 		"Sets gradient function to minimize. \n"
 		"\n"
 		""},
-	 { (char *)"IMinimizer_setObjectiveFunction", _wrap_IMinimizer_setObjectiveFunction, METH_VARARGS, (char *)"IMinimizer_setObjectiveFunction(IMinimizer self, std::function< double (std::vector< double,std::allocator< double > > const &) > arg3, int arg4)"},
+	 { (char *)"IMinimizer_setObjectiveFunction", _wrap_IMinimizer_setObjectiveFunction, METH_VARARGS, (char *)"IMinimizer_setObjectiveFunction(IMinimizer self, objective_function_t arg3)"},
 	 { (char *)"IMinimizer_getNumberOfVariables", _wrap_IMinimizer_getNumberOfVariables, METH_VARARGS, (char *)"\n"
 		"IMinimizer_getNumberOfVariables(IMinimizer self) -> size_t\n"
 		"\n"
@@ -22915,6 +22906,7 @@ static swig_type_info _swigt__p_function_chi2_t = {"_p_function_chi2_t", "functi
 static swig_type_info _swigt__p_function_gradient_t = {"_p_function_gradient_t", "function_gradient_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_objective_function_t = {"_p_objective_function_t", "objective_function_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_p_PyObject = {"_p_p_PyObject", "PyObject **", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0};
@@ -22927,7 +22919,6 @@ static swig_type_info _swigt__p_std__allocatorT_std__vectorT_double_std__allocat
 static swig_type_info _swigt__p_std__allocatorT_unsigned_long_t = {"_p_std__allocatorT_unsigned_long_t", "std::vector< unsigned long >::allocator_type *|std::allocator< unsigned long > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__functionT_double_fdouble_const_pF_t = {"_p_std__functionT_double_fdouble_const_pF_t", "std::function< double (double const *) > *|IMinimizer::function_chi2_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__functionT_double_fdouble_const_p_unsigned_int_double_pF_t = {"_p_std__functionT_double_fdouble_const_p_unsigned_int_double_pF_t", "IMinimizer::function_gradient_t *|std::function< double (double const *,unsigned int,double *) > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__functionT_double_fstd__vectorT_double_std__allocatorT_double_t_t_const_RF_t = {"_p_std__functionT_double_fstd__vectorT_double_std__allocatorT_double_t_t_const_RF_t", "std::function< double (std::vector< double,std::allocator< double > > const &) > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__invalid_argument = {"_p_std__invalid_argument", "std::invalid_argument *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__shared_ptrT_IFitObserver_t = {"_p_std__shared_ptrT_IFitObserver_t", "std::shared_ptr< IFitObserver > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__shared_ptrT_IMultiLayerBuilder_t = {"_p_std__shared_ptrT_IMultiLayerBuilder_t", "std::shared_ptr< IMultiLayerBuilder > *", 0, 0, (void*)0, 0};
@@ -22965,6 +22956,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_function_gradient_t,
   &_swigt__p_int,
   &_swigt__p_long_long,
+  &_swigt__p_objective_function_t,
   &_swigt__p_p_PyObject,
   &_swigt__p_short,
   &_swigt__p_signed_char,
@@ -22977,7 +22969,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_std__allocatorT_unsigned_long_t,
   &_swigt__p_std__functionT_double_fdouble_const_pF_t,
   &_swigt__p_std__functionT_double_fdouble_const_p_unsigned_int_double_pF_t,
-  &_swigt__p_std__functionT_double_fstd__vectorT_double_std__allocatorT_double_t_t_const_RF_t,
   &_swigt__p_std__invalid_argument,
   &_swigt__p_std__shared_ptrT_IFitObserver_t,
   &_swigt__p_std__shared_ptrT_IMultiLayerBuilder_t,
@@ -23015,6 +23006,7 @@ static swig_cast_info _swigc__p_function_chi2_t[] = {  {&_swigt__p_function_chi2
 static swig_cast_info _swigc__p_function_gradient_t[] = {  {&_swigt__p_function_gradient_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_int[] = {  {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_long_long[] = {  {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_objective_function_t[] = {  {&_swigt__p_objective_function_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_p_PyObject[] = {  {&_swigt__p_p_PyObject, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_short[] = {  {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_signed_char[] = {  {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}};
@@ -23027,7 +23019,6 @@ static swig_cast_info _swigc__p_std__allocatorT_std__vectorT_double_std__allocat
 static swig_cast_info _swigc__p_std__allocatorT_unsigned_long_t[] = {  {&_swigt__p_std__allocatorT_unsigned_long_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__functionT_double_fdouble_const_pF_t[] = {  {&_swigt__p_std__functionT_double_fdouble_const_pF_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__functionT_double_fdouble_const_p_unsigned_int_double_pF_t[] = {  {&_swigt__p_std__functionT_double_fdouble_const_p_unsigned_int_double_pF_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__functionT_double_fstd__vectorT_double_std__allocatorT_double_t_t_const_RF_t[] = {  {&_swigt__p_std__functionT_double_fstd__vectorT_double_std__allocatorT_double_t_t_const_RF_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__invalid_argument[] = {  {&_swigt__p_std__invalid_argument, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__shared_ptrT_IFitObserver_t[] = {  {&_swigt__p_std__shared_ptrT_IFitObserver_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__shared_ptrT_IMultiLayerBuilder_t[] = {  {&_swigt__p_std__shared_ptrT_IMultiLayerBuilder_t, 0, 0, 0},{0, 0, 0, 0}};
@@ -23065,6 +23056,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_function_gradient_t,
   _swigc__p_int,
   _swigc__p_long_long,
+  _swigc__p_objective_function_t,
   _swigc__p_p_PyObject,
   _swigc__p_short,
   _swigc__p_signed_char,
@@ -23077,7 +23069,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_std__allocatorT_unsigned_long_t,
   _swigc__p_std__functionT_double_fdouble_const_pF_t,
   _swigc__p_std__functionT_double_fdouble_const_p_unsigned_int_double_pF_t,
-  _swigc__p_std__functionT_double_fstd__vectorT_double_std__allocatorT_double_t_t_const_RF_t,
   _swigc__p_std__invalid_argument,
   _swigc__p_std__shared_ptrT_IFitObserver_t,
   _swigc__p_std__shared_ptrT_IMultiLayerBuilder_t,
-- 
GitLab