v2.0.0
Loading...
Searching...
No Matches
simplex_algorithm.h
Go to the documentation of this file.
1//=============================================================================================================
33
34#ifndef SIMPLEXALGORITHM_H
35#define SIMPLEXALGORITHM_H
36
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
41#include "math_global.h"
42
43//=============================================================================================================
44// EIGEN INCLUDES
45//=============================================================================================================
46
47#include <Eigen/Core>
48
49//=============================================================================================================
50// DEFINE NAMESPACE UTILSLIB
51//=============================================================================================================
52
53namespace UTILSLIB
54{
55
56//=============================================================================================================
70{
71protected:
72 //=========================================================================================================
77
78public:
79 //=========================================================================================================
104 template<typename T, typename CostFunc, typename ReportFunc>
105 static bool simplex_minimize(Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& p,
106 Eigen::Matrix<T, Eigen::Dynamic, 1>& y,
107 T ftol,
108 T stol,
109 CostFunc&& func,
110 int max_eval,
111 int& neval,
112 int report,
113 ReportFunc&& report_func);
114
115 //=========================================================================================================
129 template<typename T, typename CostFunc>
130 static bool simplex_minimize(Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& p,
131 Eigen::Matrix<T, Eigen::Dynamic, 1>& y,
132 T ftol,
133 T stol,
134 CostFunc&& func,
135 int max_eval,
136 int& neval);
137
138private:
139 template<typename T, typename CostFunc>
140 static T tryit(Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& p,
141 Eigen::Matrix<T, Eigen::Dynamic, 1>& y,
142 Eigen::Matrix<T, Eigen::Dynamic, 1>& psum,
143 CostFunc&& func,
144 int ihi,
145 int& neval,
146 T fac);
147};
148
149//=============================================================================================================
150// DEFINE MEMBER METHODS
151//=============================================================================================================
152
153template<typename T, typename CostFunc>
154T SimplexAlgorithm::tryit(Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& p,
155 Eigen::Matrix<T, Eigen::Dynamic, 1>& y,
156 Eigen::Matrix<T, Eigen::Dynamic, 1>& psum,
157 CostFunc&& func,
158 int ihi,
159 int& neval,
160 T fac)
161{
162 int ndim = p.cols();
163 T fac1, fac2, ytry;
164
165 Eigen::Matrix<T, Eigen::Dynamic, 1> ptry(ndim);
166
167 fac1 = (1.0 - fac) / ndim;
168 fac2 = fac1 - fac;
169
170 ptry = psum * fac1 - p.row(ihi).transpose() * fac2;
171
172 ytry = func(ptry);
173 ++neval;
174
175 if (ytry < y[ihi]) {
176 y[ihi] = ytry;
177
178 psum += ptry - p.row(ihi).transpose();
179 p.row(ihi) = ptry;
180 }
181
182 return ytry;
183}
184
185//=============================================================================================================
186
187template<typename T, typename CostFunc>
188bool SimplexAlgorithm::simplex_minimize(Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& p,
189 Eigen::Matrix<T, Eigen::Dynamic, 1>& y,
190 T ftol,
191 T stol,
192 CostFunc&& func,
193 int max_eval,
194 int& neval)
195{
196 auto no_report = [](int, const Eigen::Matrix<T, Eigen::Dynamic, 1>&, double, double, double) {
197 return true;
198 };
199 return simplex_minimize<T>(p, y, ftol, stol, std::forward<CostFunc>(func), max_eval, neval, -1, no_report);
200}
201
202//=============================================================================================================
203
204template<typename T, typename CostFunc, typename ReportFunc>
205bool SimplexAlgorithm::simplex_minimize(Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& p,
206 Eigen::Matrix<T, Eigen::Dynamic, 1>& y,
207 T ftol,
208 T stol,
209 CostFunc&& func,
210 int max_eval,
211 int& neval,
212 int report,
213 ReportFunc&& report_func)
214{
215 constexpr int MIN_STOL_LOOP = 5;
216 int ndim = p.cols();
217 int i, ilo, ihi, inhi;
218 int mpts = ndim + 1;
219 T ytry, ysave, rtol;
220 double dsum;
221 Eigen::Matrix<T, Eigen::Dynamic, 1> psum(ndim);
222 bool result = true;
223 int count = 0;
224 int loop = 1;
225
226 neval = 0;
227 psum = p.colwise().sum();
228
229 constexpr T kAlpha = static_cast<T>(1.0);
230 constexpr T kBeta = static_cast<T>(0.5);
231 constexpr T kGamma = static_cast<T>(2.0);
232
233 if (report > 0)
234 report_func(0, static_cast<Eigen::Matrix<T, Eigen::Dynamic, 1>>(p.row(0)), -1.0, -1.0, 0.0);
235
236 dsum = 0.0;
237 for (;; count++, loop++) {
238 ilo = 1;
239 ihi = y[1] > y[2] ? (inhi = 2, 1) : (inhi = 1, 2);
240 for (i = 0; i < mpts; i++) {
241 if (y[i] < y[ilo])
242 ilo = i;
243 if (y[i] > y[ihi]) {
244 inhi = ihi;
245 ihi = i;
246 } else if (y[i] > y[inhi])
247 if (i != ihi)
248 inhi = i;
249 }
250 rtol = 2.0 * std::fabs(y[ihi] - y[ilo]) / (std::fabs(y[ihi]) + std::fabs(y[ilo]));
251 /*
252 * Report that we are proceeding...
253 */
254 if (count == report) {
255 if (!report_func(loop, static_cast<Eigen::Matrix<T, Eigen::Dynamic, 1>>(p.row(ilo)),
256 y[ilo], y[ihi], std::sqrt(dsum))) {
257 qWarning("Iteration interrupted.");
258 result = false;
259 break;
260 }
261 count = 0;
262 }
263 if (rtol < ftol)
264 break;
265 if (neval >= max_eval) {
266 qWarning("Maximum number of evaluations exceeded.");
267 result = false;
268 break;
269 }
270 if (stol > 0) { /* Has the simplex collapsed? */
271 dsum = (p.row(ilo) - p.row(ihi)).squaredNorm();
272 if (loop > MIN_STOL_LOOP && std::sqrt(dsum) < stol)
273 break;
274 }
275 ytry = tryit<T>(p, y, psum, func, ihi, neval, -kAlpha);
276 if (ytry <= y[ilo])
277 tryit<T>(p, y, psum, func, ihi, neval, kGamma);
278 else if (ytry >= y[inhi]) {
279 ysave = y[ihi];
280 ytry = tryit<T>(p, y, psum, func, ihi, neval, kBeta);
281 if (ytry >= ysave) {
282 for (i = 0; i < mpts; i++) {
283 if (i != ilo) {
284 psum = static_cast<T>(0.5) * (p.row(i) + p.row(ilo));
285 p.row(i) = psum;
286 y[i] = func(psum);
287 }
288 }
289 neval += ndim;
290 psum = p.colwise().sum();
291 }
292 }
293 }
294 return result;
295}
296
297} //NAMESPACE
298
299#endif // SIMPLEXALGORITHM_H
Export/import macros and build-stamp accessors for MATHLIB.
#define MATHSHARED_EXPORT
Definition math_global.h:51
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, CostFunc &&func, int max_eval, int &neval, int report, ReportFunc &&report_func)