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//=============================================================================================================
68{
69
70protected:
71 //=========================================================================================================
76
77public:
78 //=========================================================================================================
103 template <typename T, typename CostFunc, typename ReportFunc>
104 static bool simplex_minimize(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>& p,
105 Eigen::Matrix<T,Eigen::Dynamic, 1>& y,
106 T ftol,
107 T stol,
108 CostFunc&& func,
109 int max_eval,
110 int &neval,
111 int report,
112 ReportFunc&& report_func);
113
114 //=========================================================================================================
118 template <typename T, typename CostFunc>
119 static bool simplex_minimize(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>& p,
120 Eigen::Matrix<T,Eigen::Dynamic, 1>& y,
121 T ftol,
122 T stol,
123 CostFunc&& func,
124 int max_eval,
125 int &neval);
126
127private:
128
129 template <typename T, typename CostFunc>
130 static T tryit(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> &p,
131 Eigen::Matrix<T,Eigen::Dynamic, 1> &y,
132 Eigen::Matrix<T,Eigen::Dynamic, 1> &psum,
133 CostFunc&& func,
134 int ihi,
135 int &neval,
136 T fac);
137};
138
139//=============================================================================================================
140// DEFINE MEMBER METHODS
141//=============================================================================================================
142
143template <typename T, typename CostFunc>
144T SimplexAlgorithm::tryit(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> &p,
145 Eigen::Matrix<T,Eigen::Dynamic, 1> &y,
146 Eigen::Matrix<T,Eigen::Dynamic, 1> &psum,
147 CostFunc&& func,
148 int ihi,
149 int &neval,
150 T fac)
151{
152 int ndim = p.cols();
153 T fac1,fac2,ytry;
154
155 Eigen::Matrix<T,Eigen::Dynamic, 1> ptry(ndim);
156
157 fac1 = (1.0-fac)/ndim;
158 fac2 = fac1-fac;
159
160 ptry = psum * fac1 - p.row(ihi).transpose() * fac2;
161
162 ytry = func(ptry);
163 ++neval;
164
165 if (ytry < y[ihi]) {
166 y[ihi] = ytry;
167
168 psum += ptry - p.row(ihi).transpose();
169 p.row(ihi) = ptry;
170 }
171
172 return ytry;
173}
174
175//=============================================================================================================
176
177template <typename T, typename CostFunc>
178bool SimplexAlgorithm::simplex_minimize(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>& p,
179 Eigen::Matrix<T,Eigen::Dynamic, 1>& y,
180 T ftol,
181 T stol,
182 CostFunc&& func,
183 int max_eval,
184 int &neval)
185{
186 auto no_report = [](int, const Eigen::Matrix<T,Eigen::Dynamic,1>&, double, double, double) { return true; };
187 return simplex_minimize<T>(p, y, ftol, stol, std::forward<CostFunc>(func), max_eval, neval, -1, no_report);
188}
189
190//=============================================================================================================
191
192template <typename T, typename CostFunc, typename ReportFunc>
193bool SimplexAlgorithm::simplex_minimize(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>& p,
194 Eigen::Matrix<T,Eigen::Dynamic, 1>& y,
195 T ftol,
196 T stol,
197 CostFunc&& func,
198 int max_eval,
199 int &neval,
200 int report,
201 ReportFunc&& report_func)
202{
203 constexpr int MIN_STOL_LOOP = 5;
204 int ndim = p.cols();
205 int i,ilo,ihi,inhi;
206 int mpts = ndim+1;
207 T ytry,ysave,rtol;
208 double dsum;
209 Eigen::Matrix<T,Eigen::Dynamic, 1> psum(ndim);
210 bool result = true;
211 int count = 0;
212 int loop = 1;
213
214 neval = 0;
215 psum = p.colwise().sum();
216
217 constexpr T kAlpha = static_cast<T>(1.0);
218 constexpr T kBeta = static_cast<T>(0.5);
219 constexpr T kGamma = static_cast<T>(2.0);
220
221 if (report > 0)
222 report_func(0, static_cast<Eigen::Matrix<T,Eigen::Dynamic, 1>>(p.row(0)), -1.0, -1.0, 0.0);
223
224 dsum = 0.0;
225 for (;;count++,loop++) {
226 ilo = 1;
227 ihi = y[1]>y[2] ? (inhi = 2,1) : (inhi = 1,2);
228 for (i = 0; i < mpts; i++) {
229 if (y[i] < y[ilo]) ilo = i;
230 if (y[i] > y[ihi]) {
231 inhi = ihi;
232 ihi = i;
233 } else if (y[i] > y[inhi])
234 if (i != ihi) inhi = i;
235 }
236 rtol = 2.0*std::fabs(y[ihi]-y[ilo])/(std::fabs(y[ihi])+std::fabs(y[ilo]));
237 /*
238 * Report that we are proceeding...
239 */
240 if (count == report) {
241 if (!report_func(loop, static_cast<Eigen::Matrix<T,Eigen::Dynamic, 1>>(p.row(ilo)),
242 y[ilo], y[ihi], std::sqrt(dsum))) {
243 qWarning("Iteration interrupted.");
244 result = false;
245 break;
246 }
247 count = 0;
248 }
249 if (rtol < ftol) break;
250 if (neval >= max_eval) {
251 qWarning("Maximum number of evaluations exceeded.");
252 result = false;
253 break;
254 }
255 if (stol > 0) { /* Has the simplex collapsed? */
256 dsum = (p.row(ilo) - p.row(ihi)).squaredNorm();
257 if (loop > MIN_STOL_LOOP && std::sqrt(dsum) < stol)
258 break;
259 }
260 ytry = tryit<T>(p,y,psum,func,ihi,neval,-kAlpha);
261 if (ytry <= y[ilo])
262 tryit<T>(p,y,psum,func,ihi,neval,kGamma);
263 else if (ytry >= y[inhi]) {
264 ysave = y[ihi];
265 ytry = tryit<T>(p,y,psum,func,ihi,neval,kBeta);
266 if (ytry >= ysave) {
267 for (i = 0; i < mpts; i++) {
268 if (i != ilo) {
269 psum = static_cast<T>(0.5) * (p.row(i) + p.row(ilo));
270 p.row(i) = psum;
271 y[i] = func(psum);
272 }
273 }
274 neval += ndim;
275 psum = p.colwise().sum();
276 }
277 }
278 }
279 return result;
280}
281
282} //NAMESPACE
283
284#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)