Mantid
Loading...
Searching...
No Matches
DerivMinimizer.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7//----------------------------------------------------------------------
8// Includes
9//----------------------------------------------------------------------
12
14
16
21double DerivMinimizer::fun(const gsl_vector *x, void *params) {
22 DerivMinimizer &minimizer = *static_cast<DerivMinimizer *>(params);
23 size_t n = minimizer.m_costFunction->nParams();
24 for (size_t i = 0; i < n; ++i) {
25 minimizer.m_costFunction->setParameter(i, gsl_vector_get(x, i));
26 }
27 std::shared_ptr<CostFunctions::CostFuncFitting> fitting =
28 std::dynamic_pointer_cast<CostFunctions::CostFuncFitting>(minimizer.m_costFunction);
29 if (fitting) {
30 fitting->getFittingFunction()->applyTies();
31 }
32 return minimizer.m_costFunction->val();
33}
34
40void DerivMinimizer::dfun(const gsl_vector *x, void *params, gsl_vector *g) {
41 DerivMinimizer &minimizer = *static_cast<DerivMinimizer *>(params);
42 size_t n = minimizer.m_costFunction->nParams();
43 for (size_t i = 0; i < n; ++i) {
44 minimizer.m_costFunction->setParameter(i, gsl_vector_get(x, i));
45 }
46 std::shared_ptr<CostFunctions::CostFuncFitting> fitting =
47 std::dynamic_pointer_cast<CostFunctions::CostFuncFitting>(minimizer.m_costFunction);
48 if (fitting) {
49 fitting->getFittingFunction()->applyTies();
50 }
51 std::vector<double> der(n);
52 minimizer.m_costFunction->deriv(der);
53 for (size_t i = 0; i < n; ++i) {
54 gsl_vector_set(g, i, der[i]);
55 }
56}
57
64void DerivMinimizer::fundfun(const gsl_vector *x, void *params, double *f, gsl_vector *g) {
65 DerivMinimizer &minimizer = *static_cast<DerivMinimizer *>(params);
66 size_t n = minimizer.m_costFunction->nParams();
67 for (size_t i = 0; i < n; ++i) {
68 minimizer.m_costFunction->setParameter(i, gsl_vector_get(x, i));
69 }
70 std::shared_ptr<CostFunctions::CostFuncFitting> fitting =
71 std::dynamic_pointer_cast<CostFunctions::CostFuncFitting>(minimizer.m_costFunction);
72 if (fitting) {
73 fitting->getFittingFunction()->applyTies();
74 }
75 std::vector<double> der(n);
76 *f = minimizer.m_costFunction->valAndDeriv(der);
77 for (size_t i = 0; i < n; ++i) {
78 gsl_vector_set(g, i, der[i]);
79 }
80}
81
84 : m_gslSolver(nullptr), m_x(nullptr), m_stopGradient(1e-3), m_stepSize(0.1), m_tolerance(0.0001) {
86}
87
93DerivMinimizer::DerivMinimizer(const double stepSize, const double tolerance)
94 : m_gslSolver(nullptr), m_x(nullptr), m_stopGradient(1e-3), m_stepSize(stepSize), m_tolerance(tolerance) {
96}
97
99 m_gslMultiminContainer.f = nullptr;
100 m_gslMultiminContainer.df = nullptr;
101 m_gslMultiminContainer.fdf = nullptr;
103 m_gslMultiminContainer.params = nullptr;
104}
105
110 if (m_gslSolver != nullptr) {
111 gsl_multimin_fdfminimizer_free(m_gslSolver);
112 gsl_vector_free(m_x);
113 }
114}
115
121void DerivMinimizer::initialize(API::ICostFunction_sptr function, size_t maxIterations) {
122 UNUSED_ARG(maxIterations);
123 m_costFunction = function;
128 m_gslMultiminContainer.params = this;
129
130 m_gslSolver = gsl_multimin_fdfminimizer_alloc(getGSLMinimizerType(), m_gslMultiminContainer.n);
131
132 size_t nParams = m_costFunction->nParams();
133 // Starting point
134 m_x = gsl_vector_alloc(nParams);
135 for (size_t i = 0; i < nParams; ++i) {
136 gsl_vector_set(m_x, i, m_costFunction->getParameter(i));
137 }
138
139 gsl_multimin_fdfminimizer_set(m_gslSolver, &m_gslMultiminContainer, m_x, m_stepSize, m_tolerance);
140}
141
146bool DerivMinimizer::iterate(size_t /*iteration*/) {
147 if (m_gslSolver == nullptr) {
148 throw std::runtime_error("Minimizer " + this->name() + " was not initialized.");
149 }
150 int status = gsl_multimin_fdfminimizer_iterate(m_gslSolver);
151 if (status) {
152 m_errorString = gsl_strerror(status);
153 return false;
154 }
155 status = gsl_multimin_test_gradient(m_gslSolver->gradient, m_stopGradient);
156 if (status != GSL_CONTINUE) {
157 m_errorString = (status == GSL_SUCCESS) ? API::MinimizerStatus::SUCCESS : gsl_strerror(status);
158 return false;
159 }
160 return true;
161}
162
168 if (value <= 0) {
169 throw std::invalid_argument("Gradient norm must be a positive number");
170 }
172}
173
175
176} // namespace Mantid::CurveFitting::FuncMinimisers
double value
The value of the point.
Definition FitMW.cpp:51
double tolerance
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition System.h:44
std::string m_errorString
Error string.
virtual std::string name() const =0
Get name of minimizer.
A wrapper around the GSL functions implementing a minimizer using derivatives.
void setStopGradient(const double value)
Set maximum value of the gradient at which iterations can stop.
static void fundfun(const gsl_vector *x, void *params, double *f, gsl_vector *g)
Used by the GSL.
void initialize(API::ICostFunction_sptr function, size_t maxIterations=0) override
Initialize minimizer, i.e. pass a function to minimize.
gsl_multimin_function_fdf m_gslMultiminContainer
GSL container.
double m_stopGradient
the norm of the gradient at which iterations stop
bool iterate(size_t) override
Do one iteration.
static void dfun(const gsl_vector *x, void *params, gsl_vector *g)
Used by the GSL.
static double fun(const gsl_vector *x, void *params)
Used by the GSL.
gsl_multimin_fdfminimizer * m_gslSolver
pointer to the GSL solver doing the work
void initGSLMMin()
simply init the values for the gsl minimizer
virtual const gsl_multimin_fdfminimizer_type * getGSLMinimizerType()=0
Return a concrete type to initialize m_gslSolver with.
double costFunctionVal() override
Return current value of the cost function.
API::ICostFunction_sptr m_costFunction
Function to minimize.
gsl_vector * m_x
GSL vector with function parameters.
const std::string SUCCESS
Reported when a minimizer has fully converged.
std::shared_ptr< ICostFunction > ICostFunction_sptr
define a shared pointer to a cost function