HepLib
HookeJeeves.cpp
Go to the documentation of this file.
1 
5 #include "SD.h"
6 #include <math.h>
7 #include <cmath>
8 
9 namespace HepLib::SD {
10 
11 dREAL 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 
34 int 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 
99 dREAL 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 
106 dREAL 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 
165 void 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