Skip to content

Commit 12a66c0

Browse files
committed
Minor bugfix to trust region subproblem solver - upgrade to version 1.0.1
1 parent 3f34cdc commit 12a66c0

File tree

11 files changed

+53
-33
lines changed

11 files changed

+53
-33
lines changed

README.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
===================================================================================
22
Py-BOBYQA: Derivative-Free Solver for Bound-Constrained Minimization |PyPI Version|
33
===================================================================================
4-
Py-BOBYQA is a flexible package for solving bound-constrained general objective minimization, without requiring derivatives of the objective. It is a Python implementation of the BOBYQA algorithm by Powell.
4+
Py-BOBYQA is a flexible package for solving bound-constrained general objective minimization, without requiring derivatives of the objective. It is a Python implementation of the BOBYQA algorithm by Powell. Py-BOBYQA is particularly useful when evaluations of the objective function are expensive and/or noisy.
55

66
More details about Py-BOBYQA can be found in our paper: C. Cartis, J. Fiala, B. Marteau and L. Roberts, Improving the Flexibility and Robustness of Model-Based Derivative-Free Optimization Solvers, technical report, University of Oxford, (2018).
77

88
The original paper by Powell is: M. J. D. Powell, The BOBYQA algorithm for bound constrained optimization without derivatives, technical report DAMTP 2009/NA06, University of Cambridge (2009), and the original Fortran implementation is available `here <http://mat.uc.pt/~zhang/software.html>`_.
99

10+
If you are interested in solving least-squares minimization problems, you may wish to try `DFO-LS <https://github.com/numericalalgorithmsgroup/dfols>`_, which has the same features as Py-BOBYQA (plus some more), and exploits the least-squares problem structure, so performs better on such problems.
11+
1012
Documentation
1113
-------------
1214
See manual.pdf or `here <http://people.maths.ox.ac.uk/robertsl/pybobyqa>`_.
@@ -25,7 +27,7 @@ Additionally, the following python packages should be installed (these will be i
2527

2628
Installation using pip
2729
----------------------
28-
For easy installation, use *pip* (http://www.pip-installer.org/) as root::
30+
For easy installation, use `pip <http://www.pip-installer.org/>`_ as root::
2931

3032
$ [sudo] pip install Py-BOBYQA
3133

docs/history.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Version History
2+
===============
3+
This section lists the different versions of Py-BOBYQA and the updates between them.
4+
5+
Version 1.0 (6 Feb 2018)
6+
------------------------
7+
* Initial release of Py-BOBYQA
8+
9+
Version 1.0.1 (20 Feb 2018)
10+
---------------------------
11+
* Minor bug fix to trust region subproblem solver (the output :code:`crvmin` is calculated correctly) - this has minimal impact on the performance of Py-BOBYQA.
12+

docs/index.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Py-BOBYQA: Derivative-Free Optimizer for Bound-Constrained Minimization
1212

1313
**Author:** `Lindon Roberts <lindon.roberts@maths.ox.ac.uk>`_
1414

15-
Py-BOBYQA is a flexible package for finding local solutions to nonlinear, nonconvex minimization problems (with optional bound constraints), without requiring any derivatives of the objective. Py-BOBYQA is a Python implementation of the `BOBYQA <http://mat.uc.pt/~zhang/software.html#powell_software>`_ solver by Powell (documentation `here <http://www.damtp.cam.ac.uk/user/na/NA_papers/NA2009_06.pdf>`_).
15+
Py-BOBYQA is a flexible package for finding local solutions to nonlinear, nonconvex minimization problems (with optional bound constraints), without requiring any derivatives of the objective. Py-BOBYQA is a Python implementation of the `BOBYQA <http://mat.uc.pt/~zhang/software.html#powell_software>`_ solver by Powell (documentation `here <http://www.damtp.cam.ac.uk/user/na/NA_papers/NA2009_06.pdf>`_). It is particularly useful when evaluations of the objective function are expensive and/or noisy.
1616

1717
That is, Py-BOBYQA solves
1818

@@ -23,6 +23,8 @@ That is, Py-BOBYQA solves
2323
2424
Full details of the Py-BOBYQA algorithm are given in our paper: C. Cartis, J. Fiala, B. Marteau and L. Roberts, Improving the Flexibility and Robustness of Model-Based Derivative-Free Optimization Solvers, technical report, University of Oxford, (2018).
2525

26+
If you are interested in solving least-squares minimization problems, you may wish to try `DFO-LS <https://github.com/numericalalgorithmsgroup/dfols>`_, which has the same features as Py-BOBYQA (plus some more), and exploits the least-squares problem structure, so performs better on such problems.
27+
2628
Py-BOBYQA is released under the GNU General Public License. Please `contact NAG <http://www.nag.com/content/worldwide-contact-information>`_ for alternative licensing.
2729

2830
.. toctree::
@@ -34,6 +36,7 @@ Py-BOBYQA is released under the GNU General Public License. Please `contact NAG
3436
userguide
3537
advanced
3638
diagnostic
39+
history
3740

3841
Acknowledgements
3942
----------------

docs/userguide.rst

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,11 @@ Note that Py-BOBYQA is a randomized algorithm: in its first phase, it builds an
124124
125125
****** Py-BOBYQA Results ******
126126
Solution xmin = [ 1. 1.]
127-
Objective value f(xmin) = 2.790048765e-19
128-
Needed 211 objective evaluations (at 211 points)
129-
Approximate gradient = [ -1.57869863e-08 7.96417081e-09]
130-
Approximate Hessian = [[ 803.2582815 -399.50964113]
131-
[-399.50964113 199.12578708]]
127+
Objective value f(xmin) = 2.964036794e-19
128+
Needed 213 objective evaluations (at 213 points)
129+
Approximate gradient = [ -2.57280154e-08 1.26855793e-08]
130+
Approximate Hessian = [[ 802.90904563 -400.46022134]
131+
[-400.46022134 200.23335154]]
132132
Exit flag = 0
133133
Success: rho has reached rhoend
134134
******************************
@@ -155,10 +155,10 @@ Py-BOBYQA correctly finds the solution to the constrained problem:
155155
****** Py-BOBYQA Results ******
156156
Solution xmin = [ 0.9 0.81]
157157
Objective value f(xmin) = 0.01
158-
Needed 129 objective evaluations (at 129 points)
159-
Approximate gradient = [ -2.00000002e-01 -4.01842008e-09]
160-
Approximate Hessian = [[ 649.34361541 -364.85712365]
161-
[-364.85712365 200.53013142]]
158+
Needed 134 objective evaluations (at 134 points)
159+
Approximate gradient = [ -1.99999226e-01 -4.31078784e-07]
160+
Approximate Hessian = [[ 649.6790222 -360.18361979]
161+
[-360.18361979 200.00205196]]
162162
Exit flag = 0
163163
Success: rho has reached rhoend
164164
******************************
@@ -189,8 +189,8 @@ And we can now see each evaluation of :code:`objfun`:
189189
Function eval 2 at point 2 has f = 14.337296 at x = [-1.08 0.85]
190190
Function eval 3 at point 3 has f = 55.25 at x = [-1.2 0.73]
191191
...
192-
Function eval 128 at point 128 has f = 0.0100000000000225 at x = [ 0.9 0.81000002]
193-
Function eval 129 at point 129 has f = 0.00999999999999997 at x = [ 0.9 0.81]
192+
Function eval 133 at point 133 has f = 0.0100000000000165 at x = [ 0.9 0.81000001]
193+
Function eval 134 at point 134 has f = 0.00999999999999997 at x = [ 0.9 0.81]
194194
Did a total of 1 run(s)
195195
196196
If we wanted to save this output to a file, we could replace the above call to :code:`logging.basicConfig()` with
@@ -287,18 +287,18 @@ As noted above, Py-BOBYQA has an input parameter :code:`objfun_has_noise` to ind
287287
288288
soln = pybobyqa.solve(rosenbrock_noisy, x0, objfun_has_noise=True)
289289
290-
Using this setting, we get a more accurate solution, and better estimates of the gradient and Hessian:
290+
This time, we find the true solution, and better estimates of the gradient and Hessian:
291291

292292
.. code-block:: none
293293
294294
****** Py-BOBYQA Results ******
295295
Solution xmin = [ 1. 1.]
296-
Objective value f(xmin) = 3.559647071e-18
296+
Objective value f(xmin) = 3.418770987e-18
297297
Needed 300 objective evaluations (at 300 points)
298298
Did a total of 4 runs
299-
Approximate gradient = [ -3.70447710e-07 1.81205404e-07]
300-
Approximate Hessian = [[ 804.44834579 -394.71053944]
301-
[-394.71053944 194.52019795]]
299+
Approximate gradient = [ -1.36175005e-08 2.12249758e-09]
300+
Approximate Hessian = [[ 805.93202374 -394.16671315]
301+
[-394.16671315 192.99451721]]
302302
Exit flag = 1
303303
Warning (max evals): Objective has been called MAXFUN times
304304
******************************

examples/rosenbrock_noisy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ def rosenbrock_noisy(x):
2323
print("")
2424

2525
# Call Py-BOBYQA
26-
soln = pybobyqa.solve(rosenbrock_noisy, x0)
27-
#soln = pybobyqa.solve(rosenbrock_noisy, x0, objfun_has_noise=True)
26+
#soln = pybobyqa.solve(rosenbrock_noisy, x0)
27+
soln = pybobyqa.solve(rosenbrock_noisy, x0, objfun_has_noise=True)
2828

2929
# Display output
3030
print(soln)

manual.pdf

2.11 KB
Binary file not shown.

pybobyqa/tests/test_solver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def runTest(self):
121121
soln = pybobyqa.solve(objfun, x0)
122122
self.assertTrue(array_compare(soln.x, xmin, thresh=1e-2), "Wrong xmin")
123123
self.assertTrue(array_compare(soln.gradient, gradfun(soln.x), thresh=1e-2), "Wrong gradient")
124-
self.assertTrue(array_compare(soln.hessian, hessfun, thresh=1e-1), "Wrong Hessian")
124+
self.assertTrue(array_compare(soln.hessian, hessfun, thresh=0.5), "Wrong Hessian")
125125
self.assertTrue(abs(soln.f - fmin) < 1e-4, "Wrong fmin")
126126

127127

pybobyqa/tests/test_trust_region.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ def runTest(self):
9292
s_cauchy, red_cauchy, crvmin_cauchy = cauchy_pt(g, hess, Delta)
9393
self.assertTrue(est_min <= red_cauchy, 'Cauchy reduction not achieved')
9494
self.assertTrue(np.all(gnew == g + hess.vec_mul(d)), 'Wrong gnew')
95-
self.assertAlmostEqual(crvmin, -1.0, 'Wrong crvmin')
95+
print(crvmin)
96+
self.assertAlmostEqual(crvmin, 1.2, 'Wrong crvmin')
9697

9798

9899
class TestUncBdry(unittest.TestCase):
@@ -210,7 +211,8 @@ def runTest(self):
210211
# print(d)
211212
self.assertTrue(est_min <= red_cauchy, 'Cauchy reduction not achieved')
212213
self.assertTrue(np.all(gnew == g + hess.vec_mul(d)), 'Wrong gnew')
213-
self.assertAlmostEqual(crvmin, 1.5, 'Wrong crvmin')
214+
print(crvmin)
215+
self.assertAlmostEqual(crvmin, -1.0, 'Wrong crvmin')
214216

215217

216218
class TestConBdry(unittest.TestCase):
@@ -233,7 +235,8 @@ def runTest(self):
233235
s_cauchy, red_cauchy, crvmin_cauchy = cauchy_pt_box(g, hess, Delta, sl - xopt, su - xopt)
234236
self.assertTrue(est_min <= red_cauchy, 'Cauchy reduction not achieved')
235237
self.assertTrue(np.max(np.abs(gnew - g - hess.vec_mul(d))) < 1e-10, 'Wrong gnew')
236-
self.assertAlmostEqual(crvmin, 1.0, 'Wrong crvmin')
238+
print(crvmin)
239+
self.assertAlmostEqual(crvmin, -1.0, 'Wrong crvmin')
237240
# self.assertAlmostEqual(crvmin, crvmin_cauchy, 'Wrong crvmin')
238241

239242

pybobyqa/trust_region.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def trsbox(xopt, g, hess, sl, su, delta):
140140

141141
# Reduce STPLEN if necessary in order to preserve the simple bounds,
142142
# letting IACT be the index of the new constrained variable.
143-
iact = -1
143+
iact = None
144144
for i in range(n):
145145
if s[i] != 0.0:
146146
temp = (su[i] - xopt[i] - d[i] if s[i] > 0.0 else sl[i] - xopt[i] - d[i]) / s[i]
@@ -153,8 +153,8 @@ def trsbox(xopt, g, hess, sl, su, delta):
153153
if stplen > 0.0:
154154
iterc += 1
155155
temp = shs / stepsq
156-
if iact == 0 and temp > 0.0:
157-
crvmin = (min(crvmin, temp) if crvmin != -1.0 else temp)
156+
if iact is None and temp > 0.0:
157+
crvmin = min(crvmin, temp) if crvmin != -1.0 else temp
158158
ggsav = gredsq
159159
gnew += stplen * hs
160160
d += stplen * s
@@ -163,7 +163,7 @@ def trsbox(xopt, g, hess, sl, su, delta):
163163
qred += sdec
164164

165165
# Restart the conjugate gradient method if it has hit a new bound.
166-
if iact > -1:
166+
if iact is not None:
167167
nact += 1
168168
xbdi[iact] = (1 if s[iact] >= 0.0 else -1)
169169
delsq = delsq - d[iact] ** 2
@@ -240,7 +240,7 @@ def alt_trust_step(n, xopt, hess, sl, su, d, xbdi, nact, gnew, qred):
240240
# bound, there is a branch back to label 100 after fixing that variable.
241241
free_variable_reached_bound = False
242242
angbd = 1.0
243-
iact = -1
243+
iact = None
244244
for i in range(n):
245245
if xbdi[i] == 0:
246246
tempa = xopt[i] + d[i] - sl[i]
@@ -334,7 +334,7 @@ def alt_trust_step(n, xopt, hess, sl, su, d, xbdi, nact, gnew, qred):
334334
hred = cth * hred + sth * hs
335335

336336
qred += sdec
337-
if iact > -1 and isav == iu - 1:
337+
if iact is not None and isav == iu - 1:
338338
nact += 1
339339
xbdi[iact] = xsav
340340
restart_alt_loop = True

pybobyqa/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@
2222
2323
"""
2424

25-
__version__ = '1.0'
25+
__version__ = '1.0.1'

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
author='Lindon Roberts',
3636
author_email='lindon.roberts@maths.ox.ac.uk',
3737
url="https://github.com/numericalalgorithmsgroup/pybobyqa/",
38-
download_url="https://github.com/numericalalgorithmsgroup/pybobyqa/archive/v1.0.tar.gz",
38+
download_url="https://github.com/numericalalgorithmsgroup/pybobyqa/archive/v1.0.1.tar.gz",
3939
packages=['pybobyqa'],
4040
license='GNU GPL',
4141
keywords = "mathematics derivative free optimization",

0 commit comments

Comments
 (0)