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