Skip to content

Commit 82dc346

Browse files
committed
sqistep, test: New option force_Brent to bypass the improvement requirement
1 parent 9e65a18 commit 82dc346

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

sqistep.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,18 @@ class SQISTEP(STEP):
6161
>>> print(optimize.xmin, optimize.fmin)
6262
6363
"""
64-
def __init__(self, fun, epsilon=1e-8, disp=False, tolx=1e-10, maxdiff=1e7, force_STEP=5, split_at_pred=True, posik_SQI=False, **options):
64+
def __init__(self, fun, epsilon=1e-8, disp=False, tolx=1e-10, maxdiff=1e7, force_STEP=0, force_Brent=10, split_at_pred=True, posik_SQI=False, **options):
6565
"""
6666
Set up a SQISTEP algorithm instance on a particular function.
6767
This does not evaluate it in any way yet - to start optimization,
6868
call .begin(), then repeatedly .one_step().
6969
7070
If force_STEP = N > 0, every N iterations STEP is forcibly invoked
7171
instead of (potentially) SQI. SQI may exhibit slow convergence
72-
when the function is quite non-quadratic.
72+
when the function is quite non-quadratic. On the other hand, if
73+
force_Brent = N > 0, every N iterations Brent (or SQI) is forcibly
74+
invoked instead of STEP when a suitable NIP is available, even if
75+
no improvement is predicted.
7376
7477
split_at_pred set to False will keep SQI in use for interval selection,
7578
but when an interval is selected, it is sampled in its half, not at the
@@ -82,6 +85,7 @@ def __init__(self, fun, epsilon=1e-8, disp=False, tolx=1e-10, maxdiff=1e7, force
8285
super(SQISTEP, self).__init__(fun, epsilon, disp, tolx, maxdiff, **options)
8386

8487
self.force_STEP = force_STEP
88+
self.force_Brent = force_Brent
8589
self.split_at_pred = split_at_pred
8690
self.posik_SQI = posik_SQI
8791

@@ -124,9 +128,11 @@ def easiest_sqi_interval(self):
124128
np.roll(self.points, -2) - self.qxmin > self.tolx)
125129
iqfmin = filter(lambda (i, qfmin): qxmin_suitable[i], enumerate(self.qfmin))
126130
if len(iqfmin) == 0:
131+
# print('stop split')
127132
return None # We cannot split further
128133
i, qfmin = min(iqfmin, key=itemgetter(1))
129-
if qfmin > self.fmin - self.epsilon:
134+
if qfmin > self.fmin - self.epsilon and (self.force_Brent == 0 or self.itercnt % self.force_Brent > 0):
135+
# print('%s > %s' % (qfmin, self.fmin - self.epsilon))
130136
return None # Even the best estimate is too high
131137
return i
132138

test.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ def run_ndstep(logfname, minimize_function, options, stclass=STEP, minf=step_min
279279
logf=logf, dimselect=options['dimselect'],
280280
stagiter=options['stagiter'],
281281
force_STEP=options['force_STEP'],
282+
force_Brent=options['force_Brent'],
282283
split_at_pred=options['split_at_pred'],
283284
posik_SQI=options['posik_SQI'],
284285
stclass=stclass, minf=minf,
@@ -304,7 +305,7 @@ def run_ndstep(logfname, minimize_function, options, stclass=STEP, minf=step_min
304305

305306
def usage(err=2):
306307
print('Benchmark ndstep, ndstep_seq, ndsqistep, ndsqistep_seq, scipy_seq')
307-
print('Usage: test.py [-b BURNIN] [-f {f4,bFID}] [-d DIM] [-e {rr,random,mindiff,maxdiff,diffpd,rdiffpd}] [-g EPSILON] [-i MAXITER] [-s SEED] [-r REPEATS] [-t STAGITER] [-I FORCE_STEP_I] [-p|-P] [-o] {nd[sqi]step,nd[sqi]step_seq,scipy_seq}')
308+
print('Usage: test.py [-b BURNIN] [-f {f4,bFID}] [-d DIM] [-e {rr,random,mindiff,maxdiff,diffpd,rdiffpd}] [-g EPSILON] [-i MAXITER] [-s SEED] [-r REPEATS] [-t STAGITER] [-I FORCE_STEP_I] [-B FORCE_BRENT_I] [-p|-P] [-o] {nd[sqi]step,nd[sqi]step_seq,scipy_seq}')
308309
sys.exit(err)
309310

310311

@@ -321,6 +322,7 @@ def usage(err=2):
321322
'burnin': 4, # *D iters are spend systematically sampling first
322323
'stagiter': None, # *D iters non-improving will cause a restart
323324
'force_STEP': 0, # SQISTEP specific
325+
'force_Brent': 10, # SQISTEP specific
324326
'split_at_pred': True, # SQISTEP specific
325327
'posik_SQI': False, # SQISTEP specific
326328
'disp': False,
@@ -330,7 +332,7 @@ def usage(err=2):
330332
bbob_experiment = None
331333

332334
try:
333-
opts, args = getopt.getopt(sys.argv[1:], "b:d:e:f:g:hi:nNopPr:s:I:t:v", ["help"])
335+
opts, args = getopt.getopt(sys.argv[1:], "b:B:d:e:f:g:hi:nNopPr:s:I:t:v", ["help"])
334336
except getopt.GetoptError as err:
335337
# print help information and exit:
336338
print(err) # will print something like "option -a not recognized"
@@ -361,6 +363,8 @@ def usage(err=2):
361363
options['egreedy'] = float(a)
362364
elif o == "-b":
363365
options['burnin'] = int(a)
366+
elif o == "-B":
367+
options['force_Brent'] = int(a)
364368
elif o == "-d":
365369
options['dim'] = int(a)
366370
elif o == "-i":

0 commit comments

Comments
 (0)