From 3b252c4edd775cf845eef0d0b0a0d73995dcb3bd Mon Sep 17 00:00:00 2001
From: Lorenzo Moneta <Lorenzo.Moneta@cern.ch>
Date: Fri, 8 Feb 2019 17:45:39 +0100
Subject: [PATCH] Add Support for setting/retrieve specific options for
 GSLSimAn,

the simulated annealing minimizer algorithm from GSL.
This fixes ROOT-4880
---
 math/mathmore/inc/Math/GSLSimAnMinimizer.h | 14 ++++++-
 math/mathmore/inc/Math/GSLSimAnnealing.h   |  5 ++-
 math/mathmore/src/GSLSimAnMinimizer.cxx    | 49 ++++++++++++++++++++++
 math/mathmore/src/GSLSimAnnealing.cxx      |  2 +-
 math/mathmore/test/simanTSP.cxx            |  2 +-
 5 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/math/mathmore/inc/Math/GSLSimAnMinimizer.h b/math/mathmore/inc/Math/GSLSimAnMinimizer.h
index ebd384c8e9d..630065337f2 100644
--- a/math/mathmore/inc/Math/GSLSimAnMinimizer.h
+++ b/math/mathmore/inc/Math/GSLSimAnMinimizer.h
@@ -96,9 +96,21 @@ public:
    /// method to perform the minimization
    virtual  bool Minimize();
 
-   //number of calls
+   /// number of calls
    unsigned int NCalls() const;
 
+   /// Get current minimizer options
+   virtual ROOT::Math::MinimizerOptions Options() const;
+
+   /// Get current minimizer option parameteres 
+   const GSLSimAnParams & MinimizerParameters() const { return fSolver.Params(); }
+   
+
+   /// set new minimizer options
+   virtual void SetOptions(const ROOT::Math::MinimizerOptions & opt);
+
+   /// set new minimizer option parameters using directly the GSLSimAnParams structure 
+   void SetParameters(const  GSLSimAnParams & params ) {  fSolver.SetParams(params); }
 
 protected:
 
diff --git a/math/mathmore/inc/Math/GSLSimAnnealing.h b/math/mathmore/inc/Math/GSLSimAnnealing.h
index f6f4e83bfb1..8a7aad4e8a3 100644
--- a/math/mathmore/inc/Math/GSLSimAnnealing.h
+++ b/math/mathmore/inc/Math/GSLSimAnnealing.h
@@ -168,7 +168,7 @@ struct GSLSimAnParams {
       // the following parameters are for the Boltzmann distribution */
       k = 1.0;
       t_initial =  0.002;
-      mu =  1.005;
+      mu_t =  1.005;
       t_min = 2.0E-6;
    }
 
@@ -179,7 +179,7 @@ struct GSLSimAnParams {
    /// parameters for the Boltzman distribution
    double k;
    double t_initial;
-   double mu;
+   double mu_t;
    double t_min;
 };
 
@@ -238,6 +238,7 @@ public:
 
    GSLSimAnParams & Params() { return fParams; }
    const GSLSimAnParams & Params() const { return fParams; }
+   void SetParams(const GSLSimAnParams & params) { fParams = params; }
 
 
 protected:
diff --git a/math/mathmore/src/GSLSimAnMinimizer.cxx b/math/mathmore/src/GSLSimAnMinimizer.cxx
index 37689961c92..cb19464aa95 100644
--- a/math/mathmore/src/GSLSimAnMinimizer.cxx
+++ b/math/mathmore/src/GSLSimAnMinimizer.cxx
@@ -17,6 +17,7 @@
 #include "Math/MinimTransformFunction.h"
 #include "Math/MultiNumGradFunction.h"   // needed to use transformation function
 #include "Math/FitMethodFunction.h"
+#include "Math/GenAlgoOptions.h"
 
 #include <iostream>
 #include <cassert>
@@ -124,6 +125,54 @@ unsigned int GSLSimAnMinimizer::NCalls() const {
    return 0;
 }
 
+ROOT::Math::MinimizerOptions  GSLSimAnMinimizer::Options() const {
+   ROOT::Math::MinimizerOptions opt;
+   opt.SetMinimizerType("GSLSimAn");
+   // set dummy values since those are not used 
+   opt.SetTolerance(-1);
+   opt.SetPrintLevel(0);
+   opt.SetMaxIterations(-1);
+   opt.SetMaxFunctionCalls(0);
+   opt.SetStrategy(-1);
+   opt.SetErrorDef(0);
+   opt.SetPrecision(0);
+   opt.SetMinimizerAlgorithm("");
+   
+   const GSLSimAnParams & params = MinimizerParameters(); 
+
+   ROOT::Math::GenAlgoOptions simanOpt;
+   simanOpt.SetValue("n_tries",params.n_tries);
+   simanOpt.SetValue("iters_fixed_T",params.iters_fixed_T);
+   simanOpt.SetValue("step_size",params.step_size);
+   simanOpt.SetValue("k",params.k);
+   simanOpt.SetValue("t_initial",params.t_initial);
+   simanOpt.SetValue("mu_t",params.mu_t);
+   simanOpt.SetValue("t_min",params.t_min);
+
+   opt.SetExtraOptions(simanOpt);
+   return opt;
+}
+
+void GSLSimAnMinimizer::SetOptions(const ROOT::Math::MinimizerOptions & opt) {
+
+   // get the specific siman options
+   const ROOT::Math::IOptions * simanOpt = opt.ExtraOptions();
+   if (!simanOpt) {
+      MATH_WARN_MSG("GSLSimAnMinimizer::SetOptions", "No specific sim. annealing minimizer options are provided. No options are set");
+      return;
+   }
+   GSLSimAnParams params; 
+   simanOpt->GetValue("n_tries",params.n_tries);
+   simanOpt->GetValue("iters_fixed_T",params.iters_fixed_T);
+   simanOpt->GetValue("step_size",params.step_size);
+   simanOpt->GetValue("k",params.k);
+   simanOpt->GetValue("t_initial",params.t_initial);
+   simanOpt->GetValue("mu_t",params.mu_t);
+   simanOpt->GetValue("t_min",params.t_min);
+
+   SetParameters(params);
+} 
+
 
    } // end namespace Math
 
diff --git a/math/mathmore/src/GSLSimAnnealing.cxx b/math/mathmore/src/GSLSimAnnealing.cxx
index 78ae368bd9e..baab0f683d3 100644
--- a/math/mathmore/src/GSLSimAnnealing.cxx
+++ b/math/mathmore/src/GSLSimAnnealing.cxx
@@ -215,7 +215,7 @@ int GSLSimAnnealing::Solve(GSLSimAnFunc & fx, bool debug) {
    // the following parameters are for the Boltzmann distribution */
    simanParams.k =              fParams.k;
    simanParams.t_initial =      fParams.t_initial;
-   simanParams.mu_t =           fParams.mu;
+   simanParams.mu_t =           fParams.mu_t;
    simanParams.t_min =          fParams.t_min;
 
 
diff --git a/math/mathmore/test/simanTSP.cxx b/math/mathmore/test/simanTSP.cxx
index 13e3ac06390..c7c35cd458f 100644
--- a/math/mathmore/test/simanTSP.cxx
+++ b/math/mathmore/test/simanTSP.cxx
@@ -257,7 +257,7 @@ void simanTSP(bool debug = true) {
    p.step_size = 1; // not used
    p.k = 1;
    p.t_initial = 5000;
-   p.mu = 1.01;
+   p.mu_t = 1.01;
    p.t_min = 0.5;
 
    // set the parameters
-- 
GitLab