flexiblesusy is hosted by Hepforge, IPPP Durham
FlexibleSUSY
minimizer.hpp
Go to the documentation of this file.
1// ====================================================================
2// This file is part of FlexibleSUSY.
3//
4// FlexibleSUSY is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published
6// by the Free Software Foundation, either version 3 of the License,
7// or (at your option) any later version.
8//
9// FlexibleSUSY is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with FlexibleSUSY. If not, see
16// <http://www.gnu.org/licenses/>.
17// ====================================================================
18
19#ifndef MINIMIZER_H
20#define MINIMIZER_H
21
22#include <utility>
23#include <Eigen/Core>
24#include <gsl/gsl_vector.h>
25
26#include "error.hpp"
27#include "ewsb_solver.hpp"
28#include "logger.hpp"
30#include "gsl_utils.hpp"
31#include "gsl_vector.hpp"
32
33namespace flexiblesusy {
34
56template <std::size_t dimension>
57class Minimizer : public EWSB_solver {
58public:
59 using Vector_t = Eigen::Matrix<double,dimension,1>;
60 using Function_t = std::function<double(const Vector_t&)>;
62
63 Minimizer() = default;
64 template <typename F>
65 Minimizer(F&&, std::size_t, double, Solver_type solver_type_ = GSLSimplex2);
66 virtual ~Minimizer() = default;
67
68 double get_minimum_value() const { return minimum_value; }
69 template <typename F>
70 void set_function(F&& f) { function = std::forward<F>(f); }
71 void set_precision(double p) { precision = p; }
72 void set_max_iterations(std::size_t n) { max_iterations = n; }
74 int minimize(const Vector_t&);
75
76 // EWSB_solver interface methods
77 virtual std::string name() const override { return "Minimizer"; }
78 virtual int solve(const Eigen::VectorXd&) override;
79 virtual Eigen::VectorXd get_solution() const override { return minimum_point; }
80
81private:
82 std::size_t max_iterations{100};
83 double precision{1.e-2};
84 double minimum_value{0.};
85 Vector_t minimum_point{Vector_t::Zero()};
88
89 static double gsl_function(const gsl_vector*, void*);
90 const gsl_multimin_fminimizer_type* solver_type_to_gsl_pointer() const;
91};
92
101template <std::size_t dimension>
102template <typename F>
104 F&& function_,
105 std::size_t max_iterations_,
106 double precision_,
107 Solver_type solver_type_
108)
109 : max_iterations(max_iterations_)
110 , precision(precision_)
111 , function(std::forward<F>(function_))
112 , solver_type(solver_type_)
113{
114}
115
123template <std::size_t dimension>
125{
126 if (!function)
127 throw SetupError("Minimizer: function not callable");
128
129 GSL_vector min_point = to_GSL_vector(start);
130
131 // Set initial step sizes
132 GSL_vector step_size(dimension);
133 step_size.set_all(1.0);
134
135 // initialize function
136 gsl_multimin_function func;
137 func.n = dimension;
138 func.f = gsl_function;
139 func.params = &function;
140
141 GSL_multimin_fminimizer minimizer(solver_type_to_gsl_pointer(), dimension,
142 &func, min_point, step_size);
143
144 size_t iter = 0;
145 int status;
146
147 do {
148 iter++;
149 status = minimizer.iterate();
150
151 if (status)
152 break;
153
154 status = minimizer.test_residual(precision);
155 minimizer.print_state(iter);
156 } while (status == GSL_CONTINUE && iter < max_iterations);
157
158 VERBOSE_MSG("\t\t\tMinimization status = " << gsl_strerror(status));
159
160 // save minimum point and function value
161 minimum_point = to_eigen_vector<dimension>(minimizer.get_minimum_point().raw());
162 minimum_value = minimizer.get_minimum_value();
163
164 return status;
165}
166
167template <std::size_t dimension>
168int Minimizer<dimension>::solve(const Eigen::VectorXd& start)
169{
170 return (minimize(start) == GSL_SUCCESS ?
172}
173
174template <std::size_t dimension>
175double Minimizer<dimension>::gsl_function(const gsl_vector* x, void* params)
176{
177 if (!is_finite(x))
178 return std::numeric_limits<double>::max();
179
180 Function_t* fun = static_cast<Function_t*>(params);
181 const Vector_t arg(to_eigen_vector<dimension>(x));
182 double result = std::numeric_limits<double>::max();
183
184 try {
185 result = (*fun)(arg);
186 } catch (const flexiblesusy::Error&) {
187 }
188
189 return result;
190}
191
192template <std::size_t dimension>
193const gsl_multimin_fminimizer_type* Minimizer<dimension>::solver_type_to_gsl_pointer() const
194{
195 switch (solver_type) {
196 case GSLSimplex : return gsl_multimin_fminimizer_nmsimplex;
197 case GSLSimplex2 : return gsl_multimin_fminimizer_nmsimplex2;
198 case GSLSimplex2Rand: return gsl_multimin_fminimizer_nmsimplex2rand;
199 default:
200 throw SetupError("Unknown minimizer solver type: "
201 + std::to_string(solver_type));
202 }
203
204 return nullptr;
205}
206
207} // namespace flexiblesusy
208
209#endif
interface for numeric EWSB solvers
Definition: ewsb_solver.hpp:31
int test_residual(double precision) const noexcept
void print_state(std::size_t iteration) const
void set_all(double) noexcept
set all elemets to same value
Definition: gsl_vector.cpp:201
const gsl_vector * raw() const noexcept
get raw pointer
Definition: gsl_vector.cpp:191
Function minimizer.
Definition: minimizer.hpp:57
int minimize(const Vector_t &)
Definition: minimizer.hpp:124
virtual Eigen::VectorXd get_solution() const override
Definition: minimizer.hpp:79
void set_precision(double p)
Definition: minimizer.hpp:71
std::function< double(const Vector_t &)> Function_t
Definition: minimizer.hpp:60
void set_solver_type(Solver_type t)
Definition: minimizer.hpp:73
Eigen::Matrix< double, dimension, 1 > Vector_t
Definition: minimizer.hpp:59
void set_function(F &&f)
Definition: minimizer.hpp:70
virtual std::string name() const override
Definition: minimizer.hpp:77
Function_t function
function to minimize
Definition: minimizer.hpp:86
const gsl_multimin_fminimizer_type * solver_type_to_gsl_pointer() const
Definition: minimizer.hpp:193
virtual ~Minimizer()=default
Vector_t minimum_point
vector of minimum point
Definition: minimizer.hpp:85
Solver_type solver_type
solver type
Definition: minimizer.hpp:87
virtual int solve(const Eigen::VectorXd &) override
Definition: minimizer.hpp:168
double get_minimum_value() const
Definition: minimizer.hpp:68
static double gsl_function(const gsl_vector *, void *)
Definition: minimizer.hpp:175
std::size_t max_iterations
maximum number of iterations
Definition: minimizer.hpp:82
void set_max_iterations(std::size_t n)
Definition: minimizer.hpp:72
double precision
precision goal
Definition: minimizer.hpp:83
double minimum_value
minimum function value found
Definition: minimizer.hpp:84
Spectrum generator was not setup correctly.
Definition: error.hpp:46
#define VERBOSE_MSG(msg)
Definition: logger.hpp:57
std::complex< double > f(double tau) noexcept
constexpr T arg(const Complex< T > &z) noexcept
Definition: complex.hpp:42
std::string to_string(char a)
GSL_vector to_GSL_vector(const Eigen::DenseBase< Derived > &v)
Definition: gsl_utils.hpp:34
bool is_finite(const gsl_vector *x)
Returns true if GSL vector contains only finite elements, false otherwise.
Definition: gsl_utils.cpp:32