BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
MinimizerAdapter.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Fit/Adapter/MinimizerAdapter.cpp
6 //! @brief Implements class MinimizerAdapter.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
17 #include "Fit/Adapter/Report.h"
20 #include "Fit/Tools/StringUtils.h"
21 #include <Math/Minimizer.h>
22 
23 #include <utility>
24 
25 using namespace mumufit;
26 
28  : m_minimizerInfo(std::move(minimizerInfo))
29  , m_adapter(new mumufit::ObjectiveFunctionAdapter)
30  , m_status(false)
31 {
32 }
33 
35 
37 {
38  // Genetic minimizer requires SetFunction before setParameters, others don't care
39  rootMinimizer()->SetFunction(*m_adapter->rootObjectiveFunction(fcn, parameters));
40  return minimize(parameters);
41 }
42 
44 {
45  // Genetic minimizer requires SetFunction before setParameters, others don't care
46  rootMinimizer()->SetFunction(*m_adapter->rootResidualFunction(fcn, parameters));
47  return minimize(parameters);
48 }
49 
51 {
52  setParameters(parameters);
54 
56  propagateResults(parameters);
57 
58  MinimizerResult result;
59  result.setParameters(parameters);
60  result.setMinValue(minValue());
61  result.setReport(internal::reportToString(*this));
62  result.setNumberOfCalls(m_adapter->numberOfCalls());
63  result.setNumberOfGradientCalls(m_adapter->numberOfGradientCalls());
64 
65  return result;
66 }
67 
69 {
70  return m_minimizerInfo.name();
71 }
72 
74 {
76 }
77 
79 {
80  unsigned int index(0);
81  for (const auto& par : parameters)
82  setParameter(index++, par);
83 }
84 
86 {
87  return rootMinimizer()->MinValue();
88 }
89 
91 {
92  return m_status ? "Minimum found" : "Error in solving";
93 }
94 
96 {
97  return rootMinimizer()->ProvidesError();
98 }
99 
100 std::map<std::string, std::string> MinimizerAdapter::statusMap() const
101 {
102  std::map<std::string, std::string> result;
103  result["Status"] = statusToString();
104 
105  if (providesError())
106  result["ProvidesError"] = "Provides parameters error and error matrix";
107  else
108  result["ProvidesError"] = "Doesn't provide error calculation";
109 
110  result["MinValue"] = mumufit::stringUtils::scientific(minValue());
111 
112  return result;
113 }
114 
115 void MinimizerAdapter::setOptions(const std::string& optionString)
116 {
117  options().setOptionString(optionString);
118 }
119 
120 //! Propagates results of minimization to fit parameter set
121 
123 {
124  parameters.setValues(parValuesAtMinimum());
125  parameters.setErrors(parErrorsAtMinimum());
126  // sets correlation matrix
127  if (providesError()) {
129  matrix.resize(fitRank());
130 
131  for (size_t i = 0; i < fitRank(); ++i) {
132  matrix[i].resize(fitRank(), 0.0);
133  for (size_t j = 0; j < fitRank(); ++j)
134  matrix[i][j] = rootMinimizer()->Correlation(static_cast<unsigned int>(i),
135  static_cast<unsigned int>(j));
136  }
137  parameters.setCorrelationMatrix(matrix);
138  }
139 }
140 
141 void MinimizerAdapter::setParameter(unsigned int index, const mumufit::Parameter& par)
142 {
143  bool success;
144  if (par.limits().isFixed())
145  success = rootMinimizer()->SetFixedVariable(index, par.name().c_str(), par.value());
146 
147  else if (par.limits().isLimited()) {
148  success = rootMinimizer()->SetLimitedVariable(index, par.name().c_str(), par.value(),
149  par.step(), par.limits().lowerLimit(),
150  par.limits().upperLimit());
151  }
152 
153  else if (par.limits().isLowerLimited()) {
154  success = rootMinimizer()->SetLowerLimitedVariable(index, par.name().c_str(), par.value(),
155  par.step(), par.limits().lowerLimit());
156  }
157 
158  else if (par.limits().isUpperLimited()) {
159  success = rootMinimizer()->SetUpperLimitedVariable(index, par.name().c_str(), par.value(),
160  par.step(), par.limits().upperLimit());
161  }
162 
163  else if (par.limits().isLimitless())
164  success = rootMinimizer()->SetVariable(index, par.name().c_str(), par.value(), par.step());
165 
166 
167  else
168  throw std::runtime_error("BasicMinimizer::setParameter() -> Error! Unexpected parameter.");
169 
170  if (!success) {
171  std::ostringstream ostr;
172  ostr << "BasicMinimizer::setParameter() -> Error! Can't set minimizer's fit parameter";
173  ostr << "Index:" << index << " name '" << par.name() << "'";
174  throw std::runtime_error(ostr.str());
175  }
176 }
177 
178 //! Returns number of fit parameters defined (i.e. dimension of the function to be minimized).
179 
181 {
182  return rootMinimizer()->NDim();
183 }
184 
185 //! Returns value of the variables at minimum.
186 
187 std::vector<double> MinimizerAdapter::parValuesAtMinimum() const
188 {
189  std::vector<double> result;
190  result.resize(fitRank(), 0.0);
191  std::copy(rootMinimizer()->X(), rootMinimizer()->X() + fitRank(), result.begin());
192  return result;
193 }
194 
195 //! Returns errors of the variables at minimum.
196 
197 std::vector<double> MinimizerAdapter::parErrorsAtMinimum() const
198 {
199  std::vector<double> result;
200  result.resize(fitRank(), 0.0);
201  if (rootMinimizer()->Errors() != nullptr) {
202  std::copy(rootMinimizer()->Errors(), rootMinimizer()->Errors() + fitRank(), result.begin());
203  }
204  return result;
205 }
206 
208 {
209  return const_cast<root_minimizer_t*>(
210  static_cast<const MinimizerAdapter*>(this)->rootMinimizer());
211 }
Defines a few helper functions.
Declares class MinimizerAdapter.
std::function< double(const mumufit::Parameters &)> fcn_scalar_t
Definition: Types.h:40
std::function< std::vector< double >(const mumufit::Parameters &)> fcn_residual_t
Definition: Types.h:41
Declares class ObjectiveFunctionAdapter.
Declares report namespace.
Declares class RootResidualFunction.
Defines classes RootScalarFunction.
double lowerLimit() const
Definition: AttLimits.cpp:91
double upperLimit() const
Definition: AttLimits.cpp:96
bool isUpperLimited() const
Definition: AttLimits.cpp:76
bool isFixed() const
Definition: AttLimits.cpp:66
bool isLimitless() const
Definition: AttLimits.cpp:86
bool isLimited() const
Definition: AttLimits.cpp:71
bool isLowerLimited() const
Definition: AttLimits.cpp:81
Abstract base class that adapts the CERN ROOT minimizer to our IMinimizer.
std::string algorithmName() const override
Returns name of the minimization algorithm.
mumufit::MinimizerResult minimize(mumufit::Parameters parameters)
virtual const root_minimizer_t * rootMinimizer() const =0
virtual std::map< std::string, std::string > statusMap() const
Returns map of string representing different minimizer statuses.
virtual void setParameter(unsigned int index, const mumufit::Parameter &par)
MinimizerAdapter(MinimizerInfo minimizerInfo)
void propagateResults(mumufit::Parameters &parameters)
Propagates results of minimization to fit parameter set.
double minValue() const override
Returns minimum function value.
void setParameters(const mumufit::Parameters &parameters)
size_t fitRank() const
Returns number of fit parameters defined (i.e. dimension of the function to be minimized).
virtual std::string statusToString() const
Returns string representation of current minimizer status.
~MinimizerAdapter() override
MinimizerInfo m_minimizerInfo
virtual void propagateOptions()=0
void setOptions(const std::string &optionString) override
Sets option string to the minimizer.
std::vector< double > parValuesAtMinimum() const
Returns value of the variables at minimum.
mumufit::MinimizerResult minimize_scalar(fcn_scalar_t fcn, mumufit::Parameters parameters) override
Runs minimization.
std::unique_ptr< mumufit::ObjectiveFunctionAdapter > m_adapter
std::string minimizerName() const override
Returns name of the minimizer.
MinimizerOptions & options()
mumufit::MinimizerResult minimize_residual(fcn_residual_t fcn, mumufit::Parameters parameters) override
Runs minimization.
bool providesError() const
Returns true if minimizer provides error and error matrix.
std::vector< double > parErrorsAtMinimum() const
Returns errors of the variables at minimum.
Info about a minimizer, including list of defined minimization algorithms.
Definition: MinimizerInfo.h:43
std::string algorithmName() const
Definition: MinimizerInfo.h:59
std::string name() const
Definition: MinimizerInfo.h:56
void setOptionString(const std::string &options)
Set options from their string representation.
virtual bool SetLowerLimitedVariable(unsigned int ivar, const std::string &name, double val, double step, double lower)
set a new lower limit variable (override if minimizer supports them )
Definition: Minimizer.h:155
virtual void SetFunction(const ROOT::Math::IMultiGenFunction &func)=0
set the function to minimize
virtual bool Minimize()=0
method to perform the minimization
virtual bool SetUpperLimitedVariable(unsigned int ivar, const std::string &name, double val, double step, double upper)
set a new upper limit variable (override if minimizer supports them )
Definition: Minimizer.h:159
virtual bool SetVariable(unsigned int ivar, const std::string &name, double val, double step)=0
set a new free variable
virtual bool ProvidesError() const
minimizer provides error and error matrix
Definition: Minimizer.h:275
virtual double Correlation(unsigned int i, unsigned int j) const
Definition: Minimizer.h:326
virtual bool SetFixedVariable(unsigned int ivar, const std::string &name, double val)
set a new fixed variable (override if minimizer supports them )
Definition: Minimizer.h:170
virtual bool SetLimitedVariable(unsigned int ivar, const std::string &name, double val, double step, double lower, double upper)
set a new upper/lower limited variable (override if minimizer supports them ) otherwise as default se...
Definition: Minimizer.h:163
virtual double MinValue() const =0
return minimum function value
virtual unsigned int NDim() const =0
this is <= Function().NDim() which is the total number of variables (free+ constrained ones)
Result of minimization round.
void setReport(const std::string &value)
void setMinValue(double value)
void setNumberOfGradientCalls(int value)
void setNumberOfCalls(int value)
void setParameters(const Parameters &parameters)
Converts user objective function to function ROOT expects. Handles time of life of function objects.
A fittable parameter with value, error, step, and limits.
Definition: Parameter.h:26
double step() const
Definition: Parameter.cpp:78
std::string name() const
Definition: Parameter.cpp:53
AttLimits limits() const
Definition: Parameter.cpp:63
double value() const
Definition: Parameter.cpp:68
A collection of fit parameters.
Definition: Parameters.h:26
void setValues(const std::vector< double > &values)
Definition: Parameters.cpp:64
void setCorrelationMatrix(const corr_matrix_t &matrix)
Definition: Parameters.cpp:122
void setErrors(const std::vector< double > &errors)
Definition: Parameters.cpp:90
std::vector< std::vector< double > > corr_matrix_t
Definition: Parameters.h:31
std::string reportToString(const MinimizerAdapter &minimizer)
Reports results of minimization in the form of multi-line string.
Definition: Report.cpp:77
std::string scientific(T value, int n=10)
Returns scientific string representing given value of any numeric type.
Definition: StringUtils.h:40
The multi-library, multi-algorithm fit wrapper library.