55import six
66import sys
77import os
8+ import warnings
89from contextlib import contextmanager
910from scipy .optimize import OptimizeResult
1011
@@ -31,18 +32,20 @@ def __init__(self, iters_to_raise, f):
3132 self .iters_to_raise , self .f = iters_to_raise , f
3233 self .count = 0
3334
34- def __call__ (self , * a , ** kw ):
35- self .count += 1
35+ def __call__ (self , X ):
3636 if self .count >= self .iters_to_raise :
3737 raise KeyboardInterrupt
38- return self .f (* a , ** kw )
38+ val = self .f (X )
39+ self .count += X .shape [0 ]
40+ return val
3941
4042
4143class _TestOptimizer (object ):
4244 _multiprocess_can_split_ = True
4345
4446 def setUp (self ):
4547 self .optimizer = None
48+ warnings .simplefilter ("once" , category = UserWarning )
4649
4750 @property
4851 def domain (self ):
@@ -71,9 +74,21 @@ def setUp(self):
7174 design = GPflowOpt .design .FactorialDesign (4 , self .domain )
7275 self .optimizer = GPflowOpt .optim .CandidateOptimizer (self .domain , design .generate ())
7376
77+ def test_default_initial (self ):
78+ self .assertTupleEqual (self .optimizer ._initial .shape , (0 , 2 ), msg = "Invalid shape of initial points array" )
79+
80+ def test_set_initial (self ):
81+ # When run separately this test works, however when calling nose to run all tests on python 2.7 this records
82+ # no warnings
83+ with warnings .catch_warnings (record = True ) as w :
84+ super (TestCandidateOptimizer , self ).test_set_initial ()
85+ assert len (w ) == 1
86+ assert issubclass (w [- 1 ].category , UserWarning )
87+
7488 def test_object_integrity (self ):
7589 self .assertTupleEqual (self .optimizer .candidates .shape , (16 , 2 ), msg = "Invalid shape of candidate property." )
76- self .assertTupleEqual (self .optimizer .get_initial ().shape , (17 , 2 ), msg = "Invalid shape of initial points" )
90+ self .assertTupleEqual (self .optimizer ._get_eval_points ().shape , (16 , 2 ))
91+ self .assertTupleEqual (self .optimizer .get_initial ().shape , (0 , 2 ), msg = "Invalid shape of initial points" )
7792 self .assertFalse (self .optimizer .gradient_enabled (), msg = "CandidateOptimizer supports no gradients." )
7893
7994 def test_set_domain (self ):
@@ -83,17 +98,17 @@ def test_set_domain(self):
8398 self .assertNotEqual (self .optimizer .domain , self .domain )
8499 self .assertEqual (self .optimizer .domain , GPflowOpt .domain .UnitCube (2 ))
85100 rescaled_candidates = GPflowOpt .design .FactorialDesign (4 , GPflowOpt .domain .UnitCube (2 )).generate ()
86- self .assertTrue (np .allclose (self .optimizer .get_initial (), np . vstack (( 0.5 * np . ones (( 1 , 2 )), rescaled_candidates )) ))
101+ self .assertTrue (np .allclose (self .optimizer .candidates , rescaled_candidates ))
87102
88103 def test_optimize (self ):
104+ self .optimizer .candidates = np .vstack ((self .optimizer .candidates , np .zeros ((1 ,2 ))))
89105 result = self .optimizer .optimize (parabola2d )
90106 self .assertTrue (result .success , msg = "Optimization should succeed." )
91107 self .assertTrue (np .allclose (result .x , 0 ), msg = "Optimum should be identified" )
92108 self .assertTrue (np .allclose (result .fun , 0 ), msg = "Function value in optimum is 0" )
93109 self .assertEqual (result .nfev , 17 , msg = "Number of function evaluations equals candidates + initial points" )
94110
95111 def test_optimize_second (self ):
96- self .optimizer .set_initial ([0.67 , 0.67 ])
97112 result = self .optimizer .optimize (parabola2d )
98113 self .assertGreater (result .fun , 0 , msg = "Optimum is not amongst candidates and initial points" )
99114 self .assertLess (result .fun , 2 , msg = "Function value not reachable within domain" )
@@ -131,33 +146,51 @@ class TestStagedOptimizer(_TestOptimizer, unittest.TestCase):
131146 def setUp (self ):
132147 super (TestStagedOptimizer , self ).setUp ()
133148 self .optimizer = GPflowOpt .optim .StagedOptimizer ([GPflowOpt .optim .MCOptimizer (self .domain , 5 ),
149+ GPflowOpt .optim .MCOptimizer (self .domain , 5 ),
134150 GPflowOpt .optim .SciPyOptimizer (self .domain , maxiter = 10 )])
135151
152+ def test_default_initial (self ):
153+ self .assertTupleEqual (self .optimizer ._initial .shape , (0 ,2 ))
154+
136155 def test_object_integrity (self ):
137- self .assertEqual (len (self .optimizer .optimizers ), 2 , msg = "Two optimizers expected in optimizerlist" )
156+ self .assertEqual (len (self .optimizer .optimizers ), 3 , msg = "Two optimizers expected in optimizerlist" )
138157 self .assertFalse (self .optimizer .gradient_enabled (), msg = "MCOptimizer supports no gradients => neither "
139158 "does stagedoptimizer." )
140159
141160 def test_optimize (self ):
142- result = self .optimizer .optimize (parabola2d )
143- self .assertTrue (result .success )
144- self .assertLessEqual (result .nfev , 20 , "Only 10 Iterations permitted" )
145- self .assertTrue (np .allclose (result .x , 0 ), msg = "Optimizer failed to find optimum" )
146- self .assertTrue (np .allclose (result .fun , 0 ), msg = "Incorrect function value returned" )
161+ with warnings .catch_warnings ():
162+ warnings .filterwarnings ("ignore" , category = UserWarning )
163+ result = self .optimizer .optimize (parabola2d )
164+ self .assertTrue (result .success )
165+ self .assertLessEqual (result .nfev , 20 , "Only 20 Iterations permitted" )
166+ self .assertTrue (np .allclose (result .x , 0 ), msg = "Optimizer failed to find optimum" )
167+ self .assertTrue (np .allclose (result .fun , 0 ), msg = "Incorrect function value returned" )
147168
148169 def test_optimizer_interrupt (self ):
149- self .optimizer .set_initial ([- 1 , - 1 ])
150- result = self .optimizer .optimize (KeyboardRaiser (3 , parabola2d ))
151- self .assertFalse (result .success , msg = "After two evaluations, a keyboard interrupt is raised, "
152- "non-succesfull result expected." )
153- self .assertFalse (np .allclose (result .x , 0.0 ), msg = "After one iteration, the optimum will not be found" )
154- self .assertEqual (result .nstages , 1 , msg = "Stage 1 should be in progress during interrupt" )
170+ with warnings .catch_warnings ():
171+ warnings .filterwarnings ("ignore" , category = UserWarning )
172+ result = self .optimizer .optimize (KeyboardRaiser (0 , parabola2d ))
173+ self .assertFalse (result .success , msg = "non-succesfull result expected." )
174+ self .assertEqual (result .nstages , 1 , msg = "Stage 2 should be in progress during interrupt" )
175+ self .assertEqual (result .nfev , 0 )
176+
177+ result = self .optimizer .optimize (KeyboardRaiser (3 , parabola2d ))
178+ self .assertFalse (result .success , msg = "non-succesfull result expected." )
179+ self .assertFalse (np .allclose (result .x , 0.0 ), msg = "The optimum will not be found" )
180+ self .assertEqual (result .nstages , 2 , msg = "Stage 2 should be in progress during interrupt" )
181+ self .assertEqual (result .nfev , 5 )
182+
183+ result = self .optimizer .optimize (KeyboardRaiser (12 , parabola2d ))
184+ print (result )
185+ self .assertFalse (result .success , msg = "non-succesfull result expected." )
186+ self .assertEqual (result .nfev , 12 )
187+ self .assertFalse (np .allclose (result .x [0 , :], 0.0 ), msg = "The optimum should not be found yet" )
188+ self .assertEqual (result .nstages , 3 , msg = "Stage 3 should be in progress during interrupt" )
155189
156- result = self .optimizer .optimize (KeyboardRaiser (8 , parabola2d ))
157- self .assertFalse (result .success , msg = "After 7 evaluations, a keyboard interrupt is raised, "
158- "non-succesfull result expected." )
159- self .assertFalse (np .allclose (result .x [0 , :], 0.0 ), msg = "The optimum should not be found yet" )
160- self .assertEqual (result .nstages , 2 , msg = "Stage 2 should be in progress during interrupt" )
190+ def test_set_domain (self ):
191+ super (TestStagedOptimizer , self ).test_set_domain ()
192+ for opt in self .optimizer .optimizers :
193+ self .assertEqual (opt .domain , GPflowOpt .domain .UnitCube (3 ))
161194
162195
163196class TestBayesianOptimizer (_TestOptimizer , unittest .TestCase ):
0 commit comments