UtilsLite
Utilities for C++ programming
Loading...
Searching...
No Matches
Utils_NelderMead.hh
Go to the documentation of this file.
1/*--------------------------------------------------------------------------*\
2 | |
3 | Copyright (C) 2022 |
4 | |
5 | , __ , __ |
6 | /|/ \ /|/ \ |
7 | | __/ _ ,_ | __/ _ ,_ |
8 | | \|/ / | | | | \|/ / | | | |
9 | |(__/|__/ |_/ \_/|/|(__/|__/ |_/ \_/|/ |
10 | /| /| |
11 | \| \| |
12 | |
13 | Enrico Bertolazzi |
14 | Dipartimento di Ingegneria Industriale |
15 | Università degli Studi di Trento |
16 | email: enrico.bertolazzi@unitn.it |
17 | |
18\*--------------------------------------------------------------------------*/
19
20//
21// file: Utils_NelderMead.hh
22//
23
24#pragma once
25
26#ifndef UTILS_NELDER_MEAD_dot_HH
27#define UTILS_NELDER_MEAD_dot_HH
28
29#include <iostream>
30#include <sstream>
31#include <string>
32#include <algorithm>
33#include <functional>
34#include <cmath>
35
36#include "Utils.hh"
37#include "Utils_eigen.hh"
38
39namespace Utils {
44
64 template <typename Real>
65 class NelderMead {
66 public:
67
68 using Vec_t = Eigen::Matrix<Real,Eigen::Dynamic,1>;
69 using Mat_t = Eigen::Matrix<Real,Eigen::Dynamic,Eigen::Dynamic>;
70 using MapVec = Eigen::Map<Vec_t>;
71 using MapMat = Eigen::Map<Mat_t>;
72 using integer = int;
73 using NMFunc = std::function<Real(Real const[])>;
74 using NM_move = enum class NelderMead_move : integer {
75 INIT,
76 REFLECT,
77 EXPAND_FE,
78 EXPAND_FR,
79 CONTRACT_O,
80 CONTRACT_I,
81 SHRINK,
82 RESTART,
83 WORSE
84 };
85
86 static string to_string( NM_move n ) {
87 string res = "";
88 switch ( n ) {
89 case NM_move::INIT: res = "INIT"; break;
90 case NM_move::REFLECT: res = "REFLECT"; break;
91 case NM_move::EXPAND_FE: res = "EXPAND_FE"; break;
92 case NM_move::EXPAND_FR: res = "EXPAND_FR"; break;
93 case NM_move::CONTRACT_O: res = "CONTRACT_O"; break;
94 case NM_move::CONTRACT_I: res = "CONTRACT_I"; break;
95 case NM_move::SHRINK: res = "SHRINK"; break;
96 case NM_move::RESTART: res = "RESTART"; break;
97 case NM_move::WORSE: res = "WORSE"; break;
98 }
99 return res;
100 }
101
102 private:
103
104 string const m_name;
105
106 Malloc<Real> m_base_value;
107
108 NMFunc m_fun; // handle to the value function to minimize
109 Console const * m_console{nullptr};
110
111 integer m_dim{0}; // problem dimension (number of variables)
112 Real m_r_dim{0};
113 Real m_dim_factorial{0};
114 Real m_dim_regular_simplex_volume{0};
115 Real m_tolerance{Real(1e-8)};
116
117 integer m_low{0};
118 integer m_0high{0};
119 integer m_high{0};
120
121 MapVec m_f{nullptr,0};
122 MapMat m_p{nullptr,0,0};
123 MapVec m_psum{nullptr,0};
124 MapMat m_dist{nullptr,0,0};
125
126 MapMat m_p_work{nullptr,0,0};
127 MapVec m_f_work{nullptr,0};
128
129 Eigen::PartialPivLU<Mat_t> m_lu;
130
131 MapVec m_pr{nullptr,0};
132 MapVec m_pe{nullptr,0};
133 MapVec m_pc{nullptr,0};
134
135 MapVec m_grad{nullptr,0};
136 Real m_diameter{0};
137 Real m_simplex_volume{0};
138
139 Real m_rho{Real(1.0)};
140 Real m_chi{Real(2.0)};
141 Real m_gamma{Real(0.5)};
142 Real m_sigma{Real(0.25)};
143 Real m_prob{Real(0.3)};
144 Real m_volume_tolerance{Real(0.01)};
145
146 integer m_max_fun_evaluation{5000}; // max number of function evaluations
147 integer m_max_iteration{1000}; // max number of iterations
148
149 mutable integer m_iteration_count{0}; // explore iteration counter
150 mutable integer m_fun_evaluation_count{0};
151
152 NM_move m_which_step{NM_move::INIT};
153 integer m_verbose{1}; // flag to activate info printing
154
155 void allocate( integer n );
156
157 Real extrapolate( Real alpha, integer j, MapVec & pe ) const;
158 //void spendley( MapVec const & X0, Real len );
159 //void gradient( MapVec & G ) const;
160 void shrink();
161 void dist_init();
162 void dist_update( integer jpos );
163 void grad_update( integer jpos );
164 Real reflect( MapVec & pr ) { return this->extrapolate( m_rho, m_high, pr ); }
165 Real expand ( MapVec & pe ) { return this->extrapolate( m_rho*m_chi, m_high, pe ); }
166 Real outside( MapVec & po ) { return this->extrapolate( m_rho*m_gamma, m_high, po ); }
167 Real inside ( MapVec & pi ) { return this->extrapolate( -m_gamma, m_high, pi ); }
168
169 void replace_point( Real fj, MapVec const & pj, integer jpos );
170 void spendley( Real const X0[], Real delta );
171 void diamond( Real const X0[], Real delta );
172
173 Real
174 eval_function( Real const x[] ) const {
175 ++m_fun_evaluation_count;
176 return m_fun( x );
177 }
178
179 public:
180
186 explicit
187 NelderMead( string_view name )
188 : m_name(name)
189 , m_base_value( string("NelderMead_")+string(name) )
190 {}
191
197 string_view name(void) const { return m_name; }
198
206 void setup( integer dim, NMFunc & fun, Console const * console );
207
213 void change_console( Console const * console ) { m_console = console; }
214
220 void set_verbose( integer level ) { m_verbose = level; }
221
227 void set_tolerance( Real tol );
228
234 void set_max_iterations( integer mit );
235
241 void set_max_fun_evaluation( integer mfev );
242
248 void message( Real tol ) const;
249
255 string info() const;
256
262 void print_info( ostream_type & stream ) const { stream << info(); }
263
264 //void explore();
265
271 bool search();
272
281 bool run( Real const x_sol[], Real h );
282
289 Real
290 get_last_solution( Real x[] ) const {
291 std::copy_n( m_p.col(m_low).data(), m_dim, x );
292 return m_f.coeff(m_low);
293 }
294
300 Real get_better_value() const { return m_f.coeff(m_low); }
301
307 Real get_worst_value() const { return m_f.coeff(m_high); }
308 };
309
311
312}
313
314#endif
315
316//
317// eof: Utils_NelderMead.hh
318//
Class to handle console output with different styles and levels.
Definition Console.hxx:52
Class for dynamic memory allocation of objects.
Definition Malloc.hxx:79
string info() const
Provide information about the current state of the Nelder-Mead optimization.
Definition Utils_NelderMead.cc:305
Eigen::Matrix< Real, Eigen::Dynamic, 1 > Vec_t
Definition Utils_NelderMead.hh:68
string_view name(void) const
Get the name of the class.
Definition Utils_NelderMead.hh:197
std::function< Real(Real const [])> NMFunc
Definition Utils_NelderMead.hh:73
void set_max_fun_evaluation(integer mfev)
Set the maximum number of function evaluations allowed in the optimization process.
Definition Utils_NelderMead.cc:77
Real get_last_solution(Real x[]) const
Get the solution found by the Nelder-Mead algorithm after the last run.
Definition Utils_NelderMead.hh:290
void message(Real tol) const
Display a message with information about the current tolerance level.
Definition Utils_NelderMead.cc:331
void set_tolerance(Real tol)
Set the tolerance for stopping criteria in the optimization process.
Definition Utils_NelderMead.cc:49
int integer
Definition Utils_NelderMead.hh:72
void setup(integer dim, NMFunc &fun, Console const *console)
Setup the optimizer with the function and console interface.
Definition Utils_NelderMead.cc:123
static string to_string(NM_move n)
Definition Utils_NelderMead.hh:86
bool search()
Perform the search step of the optimization process.
Definition Utils_NelderMead.cc:361
enum class NelderMead_move :integer { INIT, REFLECT, EXPAND_FE, EXPAND_FR, CONTRACT_O, CONTRACT_I, SHRINK, RESTART, WORSE } NM_move
Definition Utils_NelderMead.hh:74
bool run(Real const x_sol[], Real h)
Run the optimization process starting from an initial guess and step size.
Definition Utils_NelderMead.cc:468
Eigen::Map< Vec_t > MapVec
Definition Utils_NelderMead.hh:70
NelderMead(string_view name)
Constructor that initializes the NelderMead instance with a specific name.
Definition Utils_NelderMead.hh:187
void set_max_iterations(integer mit)
Set the maximum number of iterations allowed in the optimization process.
Definition Utils_NelderMead.cc:63
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic > Mat_t
Definition Utils_NelderMead.hh:69
Eigen::Map< Mat_t > MapMat
Definition Utils_NelderMead.hh:71
Real get_worst_value() const
Get the worst function value encountered during the optimization process.
Definition Utils_NelderMead.hh:307
void print_info(ostream_type &stream) const
Print detailed information about the current state of the Nelder-Mead optimizer.
Definition Utils_NelderMead.hh:262
void change_console(Console const *console)
Change the console output interface.
Definition Utils_NelderMead.hh:213
Real get_better_value() const
Get the best function value found during the optimization process.
Definition Utils_NelderMead.hh:300
void set_verbose(integer level)
Set the verbosity level for logging during the optimization process.
Definition Utils_NelderMead.hh:220
Definition SystemUtils.cc:39
std::basic_ostream< char > ostream_type
Type for output stream.
Definition Console.hxx:28
std::string string
Type for string.
Definition Console.hxx:29