HepLib
Loading...
Searching...
No Matches
HookeJeeves.cpp
Go to the documentation of this file.
1
5#include "SD.h"
6#include <math.h>
7#include <cmath>
8
9namespace HepLib::SD {
10
11dREAL HookeJeeves::best_nearby(dREAL* delta, dREAL* point, dREAL prevbest, int nvars) {
12 dREAL z[nvars];
13 dREAL minf, ftmp;
14 int i;
15 minf = prevbest;
16 for (i = 0; i < nvars; i++) z[i] = point[i];
17 for (i = 0; i < nvars; i++) {
18 if(Exit) return (minf);
19 z[i] = point[i] + delta[i];
20 ftmp = ObjectWrapper(nvars, z);
21 if (ftmp < minf) minf = ftmp;
22 else {
23 delta[i] = 0.0L - delta[i];
24 z[i] = point[i] + delta[i];
25 ftmp = ObjectWrapper(nvars, z);
26 if (ftmp < minf) minf = ftmp;
27 else z[i] = point[i];
28 }
29 }
30 for (i = 0; i < nvars; i++) point[i] = z[i];
31 return (minf);
32}
33
34int HookeJeeves::hooke(int nvars, dREAL* startpt, dREAL* endpt, dREAL rho, dREAL epsilon, int itermax) {
35 dREAL delta[nvars];
36 dREAL newf, fbefore, steplength, tmp;
37 dREAL xbefore[nvars], newx[nvars];
38 int i, j, keep;
39 int iters, iadj;
40 for (i = 0; i < nvars; i++) {
41 newx[i] = xbefore[i] = startpt[i];
42 delta[i] = std::fabs(startpt[i] * rho);
43 if (delta[i] == 0.0) delta[i] = rho;
44 }
45 iadj = 0;
46 steplength = rho;
47 iters = 0;
48 fbefore = ObjectWrapper(nvars, newx);
49 newf = fbefore;
50 while ((iters < itermax) && (steplength > epsilon)) {
51 if(Exit) return (iters);
52 iters++;
53 iadj++;
54 /* find best new point, one coord at a time */
55 for (i = 0; i < nvars; i++) {
56 newx[i] = xbefore[i];
57 }
58 newf = best_nearby(delta, newx, fbefore, nvars);
59 /* if we made some improvements, pursue that direction */
60 keep = 1;
61 while ((newf < fbefore) && (keep == 1)) {
62 if(Exit) return (iters);
63 iadj = 0;
64 for (i = 0; i < nvars; i++) {
65 /* firstly, arrange the sign of delta[] */
66 if (newx[i] <= xbefore[i]) delta[i] = 0.0 - std::fabs(delta[i]);
67 else delta[i] = std::fabs(delta[i]);
68 /* now, move further in this direction */
69 tmp = xbefore[i];
70 xbefore[i] = newx[i];
71 newx[i] = newx[i] + newx[i] - tmp;
72 }
73 fbefore = newf;
74 newf = best_nearby(delta, newx, fbefore, nvars);
75 /* if the further (optimistic) move was bad.... */
76 if (newf >= fbefore) break;
77 /* make sure that the differences between the new */
78 /* and the old points are due to actual */
79 /* displacements; beware of roundoff errors that */
80 /* might cause newf < fbefore */
81 keep = 0;
82 for (i = 0; i < nvars; i++) {
83 keep = 1;
84 if (std::fabs(newx[i] - xbefore[i]) > (0.5 * std::fabs(delta[i]))) break;
85 else keep = 0;
86 }
87 }
88 if ((steplength >= epsilon) && (newf >= fbefore)) {
89 steplength = steplength * rho;
90 for (i = 0; i < nvars; i++) {
91 delta[i] *= rho;
92 }
93 }
94 }
95 for (i = 0; i < nvars; i++) endpt[i] = xbefore[i];
96 return (iters);
97}
98
99dREAL HookeJeeves::ObjectWrapper(int nvars, dREAL* x) {
100 for(int i=0; i<nvars; i++) {
101 if(x[i]<LowerBound[i] || (UpperBound[i]>0 && x[i]>UpperBound[i])) return 1.E101L;
102 }
103 return ObjectFunction(nvars, x, PL, LAS);
104}
105
106dREAL HookeJeeves::FindMinimum(int nvars, FunctionType func, dREAL *pl, dREAL *las, dREAL *UB, dREAL *LB, dREAL *IP, bool compare0, int TryPTS, int SavePTS) {
107 ObjectFunction = func;
108 PL = pl;
109 LAS = las;
110
111 if(UB != NULL) for(int i=0; i<nvars; i++) UpperBound[i] = UB[i];
112 else for(int i=0; i<nvars; i++) UpperBound[i] = 1;
113
114 if(LB != NULL) for(int i=0; i<nvars; i++) LowerBound[i] = LB[i];
115 else for(int i=0; i<nvars; i++) LowerBound[i] = 0;
116
117 dREAL RhoParameter = 0.95;
118 dREAL EpsParameter = 1E-4;
119 size_t MaxParameter = 100000;
120
121 if(SavePTS<=0) SavePTS = 1;
122 if(TryPTS<=0) TryPTS= 1;
123 double mPoints[SavePTS][nvars], mValue[SavePTS];
124 for(int i=0; i<SavePTS; i++) mValue[i] = 1E5;
125 int max_index = 0;
126 dREAL pts[TryPTS+1];
127 pts[0] = 1E-4;
128 pts[TryPTS] = 1-1E-4;
129 for(int i=1; i<TryPTS; i++) pts[i] = i*1.0/TryPTS;
130 for(size_t ii=0; ii<std::pow(TryPTS+1, nvars); ii++) {
131 dREAL iPoints[nvars];
132 int li = ii;
133 for(int i=0; i<nvars; i++) {
134 int mi = li % (1+TryPTS);
135 iPoints[i] = LowerBound[i] + pts[mi]*(UpperBound[i]-LowerBound[i]);
136 li /= (1+TryPTS);
137 }
138 auto tmp = ObjectWrapper(nvars, iPoints);
139 if(mValue[max_index] > tmp) {
140 mValue[max_index] = tmp;
141 for(int j=0; j<nvars; j++) mPoints[max_index][j] = iPoints[j];
142 max_index = 0;
143 for(int j=0; j<SavePTS && j<std::pow(TryPTS+1, nvars); j++) {
144 if(mValue[j] > mValue[max_index]) max_index = j;
145 }
146 }
147 }
148
149 double ret = 1E5;
150 for(int ii=0; ii<SavePTS && ii<std::pow(TryPTS+1, nvars); ii++) {
151 dREAL iPoints[nvars], oPoints[nvars];
152 for(int i=0; i<nvars; i++) iPoints[i] = mPoints[ii][i];
153 hooke(nvars, iPoints, oPoints, RhoParameter, EpsParameter, MaxParameter);
154 auto tmp_ret = ObjectWrapper(nvars, oPoints);
155 if(tmp_ret < ret) ret = tmp_ret;
156 }
157
158 return ret;
159}
160
162 Exit = true;
163}
164
165void HookeJeeves::Minimize(int nvars, FunctionType func, dREAL *ip) {
166 ObjectFunction = func;
167 PL = NULL;
168 LAS = NULL;
169
170 for(int i=0; i<nvars; i++) UpperBound[i] = -1;
171 for(int i=0; i<nvars; i++) LowerBound[i] = 0;
172
173 dREAL EpsParameter = 1E-3;
174 size_t MaxParameter = 100000;
175
176 dREAL iPoints[nvars], oPoints[nvars];
177 for(int i=0; i<nvars; i++) {
178 iPoints[i] = ip[i];
179 if(ip[i] * 1E-3 > EpsParameter) EpsParameter = ip[i] * 1E-3;
180 }
181 hooke(nvars, iPoints, oPoints, ErrMin::hjRHO, EpsParameter, MaxParameter);
182}
183
184
185}
long double dREAL
Definition HCubature.cpp:17
SecDec header file.
static dREAL hjRHO
Definition SD.h:379
virtual void Minimize(int nvars, FunctionType func, dREAL *ip) override
virtual dREAL FindMinimum(int nvars, FunctionType func, dREAL *PL=NULL, dREAL *las=NULL, dREAL *UB=NULL, dREAL *LB=NULL, dREAL *IP=NULL, bool compare0=false, int TryPTS=0, int SavePTS=0) override
virtual void ForceStop() override
namespace for Numerical integration with Sector Decomposition method
Definition AsyMB.cpp:10
long double dREAL
Definition SD.h:121