v2.0.0
Loading...
Searching...
No Matches
simplex_algorithm.h
Go to the documentation of this file.
1//=============================================================================================================
35
36#ifndef SIMPLEXALGORITHM_H
37#define SIMPLEXALGORITHM_H
38
39//=============================================================================================================
40// INCLUDES
41//=============================================================================================================
42
43#include "math_global.h"
44
45//=============================================================================================================
46// EIGEN INCLUDES
47//=============================================================================================================
48
49#include <Eigen/Core>
50
51//=============================================================================================================
52// DEFINE NAMESPACE UTILSLIB
53//=============================================================================================================
54
55namespace UTILSLIB
56{
57
58//=============================================================================================================
65{
66
67protected:
68 //=========================================================================================================
73
74public:
75 //=========================================================================================================
97 template <typename T>
98 static bool simplex_minimize(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>& p,
99 Eigen::Matrix<T,Eigen::Dynamic, 1>& y,
100 T ftol,
101 T stol,
102 T (*func)(const Eigen::Matrix<T,Eigen::Dynamic, 1>& x, const void *user_data),
103 const void *user_data,
104 int max_eval,
105 int &neval,
106 int report,
107 bool (*report_func)(int loop,
108 const Eigen::Matrix<T,Eigen::Dynamic, 1>& fitpar,
109 double fval_lo,
110 double fval_hi,
111 double par_diff));
112
113private:
114
115 template <typename T>
116 static T tryit(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> &p,
117 Eigen::Matrix<T,Eigen::Dynamic, 1> &y,
118 Eigen::Matrix<T,Eigen::Dynamic, 1> &psum,
119 T (*func)( const Eigen::Matrix<T,Eigen::Dynamic, 1> &x,const void *user_data), /* The function to be evaluated */
120 const void *user_data, /* Data to be passed to the above function in each evaluation */
121 int ihi,
122 int &neval,
123 T fac);
124};
125
126//=============================================================================================================
127// DEFINE MEMBER METHODS
128//=============================================================================================================
129
130template <typename T>
131T SimplexAlgorithm::tryit(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> &p,
132 Eigen::Matrix<T,Eigen::Dynamic, 1> &y,
133 Eigen::Matrix<T,Eigen::Dynamic, 1> &psum,
134 T (*func)( const Eigen::Matrix<T,Eigen::Dynamic, 1> &x,const void *user_data), /* The function to be evaluated */
135 const void *user_data, /* Data to be passed to the above function in each evaluation */
136 int ihi,
137 int &neval,
138 T fac)
139{
140 int ndim = p.cols();
141 T fac1,fac2,ytry;
142
143 Eigen::Matrix<T,Eigen::Dynamic, 1> ptry(ndim);
144
145 fac1 = (1.0-fac)/ndim;
146 fac2 = fac1-fac;
147
148 ptry = psum * fac1 - p.row(ihi).transpose() * fac2;
149
150 ytry = (*func)(ptry,user_data);
151 ++neval;
152
153 if (ytry < y[ihi]) {
154 y[ihi] = ytry;
155
156 psum += ptry - p.row(ihi).transpose();
157 p.row(ihi) = ptry;
158 }
159
160 return ytry;
161}
162
163//=============================================================================================================
164
165template <typename T>
166bool SimplexAlgorithm::simplex_minimize(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>& p,
167 Eigen::Matrix<T,Eigen::Dynamic, 1>& y,
168 T ftol,
169 T stol,
170 T (*func)(const Eigen::Matrix<T,Eigen::Dynamic, 1>& x, const void *user_data),
171 const void *user_data,
172 int max_eval,
173 int &neval,
174 int report,
175 bool (*report_func)(int loop,
176 const Eigen::Matrix<T,Eigen::Dynamic, 1>& fitpar,
177 double fval_lo,
178 double fval_hi,
179 double par_diff))
180{
181 constexpr int MIN_STOL_LOOP = 5;
182 int ndim = p.cols();
183 int i,ilo,ihi,inhi;
184 int mpts = ndim+1;
185 T ytry,ysave,rtol;
186 double dsum;
187 Eigen::Matrix<T,Eigen::Dynamic, 1> psum(ndim);
188 bool result = true;
189 int count = 0;
190 int loop = 1;
191
192 neval = 0;
193 psum = p.colwise().sum();
194
195 constexpr T kAlpha = static_cast<T>(1.0);
196 constexpr T kBeta = static_cast<T>(0.5);
197 constexpr T kGamma = static_cast<T>(2.0);
198
199 if (report_func != nullptr && report > 0)
200 report_func(0, static_cast<Eigen::Matrix<T,Eigen::Dynamic, 1>>(p.row(0)), -1.0, -1.0, 0.0);
201
202 dsum = 0.0;
203 for (;;count++,loop++) {
204 ilo = 1;
205 ihi = y[1]>y[2] ? (inhi = 2,1) : (inhi = 1,2);
206 for (i = 0; i < mpts; i++) {
207 if (y[i] < y[ilo]) ilo = i;
208 if (y[i] > y[ihi]) {
209 inhi = ihi;
210 ihi = i;
211 } else if (y[i] > y[inhi])
212 if (i != ihi) inhi = i;
213 }
214 rtol = 2.0*std::fabs(y[ihi]-y[ilo])/(std::fabs(y[ihi])+std::fabs(y[ilo]));
215 /*
216 * Report that we are proceeding...
217 */
218 if (count == report && report_func != nullptr) {
219 if (!report_func(loop, static_cast<Eigen::Matrix<T,Eigen::Dynamic, 1>>(p.row(ilo)),
220 y[ilo], y[ihi], std::sqrt(dsum))) {
221 qWarning("Iteration interrupted.");
222 result = false;
223 break;
224 }
225 count = 0;
226 }
227 if (rtol < ftol) break;
228 if (neval >= max_eval) {
229 qWarning("Maximum number of evaluations exceeded.");
230 result = false;
231 break;
232 }
233 if (stol > 0) { /* Has the simplex collapsed? */
234 dsum = (p.row(ilo) - p.row(ihi)).squaredNorm();
235 if (loop > MIN_STOL_LOOP && std::sqrt(dsum) < stol)
236 break;
237 }
238 ytry = tryit<T>(p,y,psum,func,user_data,ihi,neval,-kAlpha);
239 if (ytry <= y[ilo])
240 tryit<T>(p,y,psum,func,user_data,ihi,neval,kGamma);
241 else if (ytry >= y[inhi]) {
242 ysave = y[ihi];
243 ytry = tryit<T>(p,y,psum,func,user_data,ihi,neval,kBeta);
244 if (ytry >= ysave) {
245 for (i = 0; i < mpts; i++) {
246 if (i != ilo) {
247 psum = static_cast<T>(0.5) * (p.row(i) + p.row(ilo));
248 p.row(i) = psum;
249 y[i] = (*func)(psum,user_data);
250 }
251 }
252 neval += ndim;
253 psum = p.colwise().sum();
254 }
255 }
256 }
257 return result;
258}
259
260} //NAMESPACE
261
262#endif // SIMPLEXALGORITHM_H
math library export/import macros.
#define MATHSHARED_EXPORT
Definition math_global.h:55
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
static bool simplex_minimize(Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &p, Eigen::Matrix< T, Eigen::Dynamic, 1 > &y, T ftol, T stol, T(*func)(const Eigen::Matrix< T, Eigen::Dynamic, 1 > &x, const void *user_data), const void *user_data, int max_eval, int &neval, int report, bool(*report_func)(int loop, const Eigen::Matrix< T, Eigen::Dynamic, 1 > &fitpar, double fval_lo, double fval_hi, double par_diff))