11import numpy as np
22from bayes_opt import BayesianOptimization , ConstraintModel
33from pytest import approx , raises
4+ from scipy .optimize import NonlinearConstraint
45
56np .random .seed (42 )
67
78
8- def test_single_constraint ():
9+ def test_single_constraint_upper ():
910
1011 def target_function (x , y ):
1112 return np .cos (2 * x ) * np .cos (y ) + np .sin (x )
1213
1314 def constraint_function (x , y ):
1415 return np .cos (x ) * np .cos (y ) - np .sin (x ) * np .sin (y )
1516
16- constraint_limit = 0.5
17+ constraint_limit_upper = 0.5
1718
18- conmod = ConstraintModel (constraint_function , constraint_limit )
19+ constraint = NonlinearConstraint (constraint_function , - np . inf , constraint_limit_upper )
1920 pbounds = {'x' : (0 , 6 ), 'y' : (0 , 6 )}
2021
2122 optimizer = BayesianOptimization (
2223 f = target_function ,
23- constraint = conmod ,
24+ constraint = constraint ,
2425 pbounds = pbounds ,
2526 verbose = 0 ,
2627 random_state = 1 ,
@@ -31,23 +32,25 @@ def constraint_function(x, y):
3132 n_iter = 10 ,
3233 )
3334
35+ assert constraint_function (** optimizer .max ["params" ]) <= constraint_limit_upper
36+
3437
35- def test_single_constraint_max_is_allowed ():
38+ def test_single_constraint_lower ():
3639
3740 def target_function (x , y ):
3841 return np .cos (2 * x ) * np .cos (y ) + np .sin (x )
3942
4043 def constraint_function (x , y ):
4144 return np .cos (x ) * np .cos (y ) - np .sin (x ) * np .sin (y )
4245
43- constraint_limit = 0.5
46+ constraint_limit_lower = - 0.5
4447
45- conmod = ConstraintModel (constraint_function , constraint_limit )
48+ constraint = NonlinearConstraint (constraint_function , constraint_limit_lower , np . inf )
4649 pbounds = {'x' : (0 , 6 ), 'y' : (0 , 6 )}
4750
4851 optimizer = BayesianOptimization (
4952 f = target_function ,
50- constraint = conmod ,
53+ constraint = constraint ,
5154 pbounds = pbounds ,
5255 verbose = 0 ,
5356 random_state = 1 ,
@@ -58,45 +61,55 @@ def constraint_function(x, y):
5861 n_iter = 10 ,
5962 )
6063
61- assert constraint_function (** optimizer .max ["params" ]) <= constraint_limit
64+ assert constraint_function (** optimizer .max ["params" ]) >= constraint_limit_lower
6265
6366
64- def test_accurate_approximation_when_known ():
67+ def test_single_constraint_lower_upper ():
6568
6669 def target_function (x , y ):
6770 return np .cos (2 * x ) * np .cos (y ) + np .sin (x )
6871
6972 def constraint_function (x , y ):
7073 return np .cos (x ) * np .cos (y ) - np .sin (x ) * np .sin (y )
7174
72- constraint_limit = 0.5
75+ constraint_limit_lower = - 0.5
76+ constraint_limit_upper = 0.5
7377
74- conmod = ConstraintModel (constraint_function , constraint_limit )
78+ constraint = NonlinearConstraint (constraint_function , constraint_limit_lower , constraint_limit_upper )
7579 pbounds = {'x' : (0 , 6 ), 'y' : (0 , 6 )}
7680
7781 optimizer = BayesianOptimization (
7882 f = target_function ,
79- constraint = conmod ,
83+ constraint = constraint ,
8084 pbounds = pbounds ,
8185 verbose = 0 ,
8286 random_state = 1 ,
8387 )
8488
89+ assert optimizer .constraint .lb == constraint .lb
90+ assert optimizer .constraint .ub == constraint .ub
91+
8592 optimizer .maximize (
8693 init_points = 2 ,
8794 n_iter = 10 ,
8895 )
8996
97+ # Check limits
98+ assert constraint_function (** optimizer .max ["params" ]) <= constraint_limit_upper
99+ assert constraint_function (** optimizer .max ["params" ]) >= constraint_limit_lower
100+
101+
90102 # Exclude the last sampled point, because the constraint is not fitted on that.
91103 res = np .array ([[r ['target' ], r ['constraint' ], r ['params' ]['x' ], r ['params' ]['y' ]] for r in optimizer .res [:- 1 ]])
92104
93105 xy = res [:, [2 , 3 ]]
94106 x = res [:, 2 ]
95107 y = res [:, 3 ]
96108
97- assert constraint_function (x , y ) == approx (conmod .approx (xy ), rel = 1e-5 , abs = 1e-5 )
109+ # Check accuracy of approximation for sampled points
110+ assert constraint_function (x , y ) == approx (optimizer .constraint .approx (xy ), rel = 1e-5 , abs = 1e-5 )
98111 assert constraint_function (x , y ) == approx (optimizer .space .constraint_values [:- 1 ], rel = 1e-5 , abs = 1e-5 )
99-
112+
100113
101114def test_multiple_constraints ():
102115
@@ -109,9 +122,10 @@ def constraint_function_2_dim(x, y):
109122 - np .cos (x ) * np .cos (- y ) + np .sin (x ) * np .sin (- y )
110123 ])
111124
112- constraint_limit = np .array ([0.6 , 0.6 ])
125+ constraint_limit_lower = np .array ([- np .inf , - np .inf ])
126+ constraint_limit_upper = np .array ([0.6 , 0.6 ])
113127
114- conmod = ConstraintModel (constraint_function_2_dim , constraint_limit )
128+ conmod = NonlinearConstraint (constraint_function_2_dim , constraint_limit_lower , constraint_limit_upper )
115129 pbounds = {'x' : (0 , 6 ), 'y' : (0 , 6 )}
116130
117131 optimizer = BayesianOptimization (
@@ -127,14 +141,13 @@ def constraint_function_2_dim(x, y):
127141 n_iter = 10 ,
128142 )
129143
130- assert np .all (
131- constraint_function_2_dim (
132- ** optimizer .max ["params" ]) <= constraint_limit )
144+ constraint_at_max = constraint_function_2_dim (** optimizer .max ["params" ])
145+ assert np .all ((constraint_at_max <= constraint_limit_upper ) & (constraint_at_max >= constraint_limit_lower ))
133146
134147 params = optimizer .res [0 ]["params" ]
135148 x , y = params ['x' ], params ['y' ]
136149
137- assert constraint_function_2_dim (x , y ) == approx (conmod .approx (np .array ([x , y ])), rel = 1e-5 , abs = 1e-5 )
150+ assert constraint_function_2_dim (x , y ) == approx (optimizer . constraint .approx (np .array ([x , y ])), rel = 1e-5 , abs = 1e-5 )
138151
139152
140153def test_kwargs_not_the_same ():
@@ -145,14 +158,14 @@ def target_function(x, y):
145158 def constraint_function (a , b ):
146159 return np .cos (a ) * np .cos (b ) - np .sin (a ) * np .sin (b )
147160
148- constraint_limit = 0.5
161+ constraint_limit_upper = 0.5
149162
150- conmod = ConstraintModel (constraint_function , constraint_limit )
163+ constraint = NonlinearConstraint (constraint_function , - np . inf , constraint_limit_upper )
151164 pbounds = {'x' : (0 , 6 ), 'y' : (0 , 6 )}
152165
153166 optimizer = BayesianOptimization (
154167 f = target_function ,
155- constraint = conmod ,
168+ constraint = constraint ,
156169 pbounds = pbounds ,
157170 verbose = 0 ,
158171 random_state = 1 ,
@@ -161,4 +174,4 @@ def constraint_function(a, b):
161174 optimizer .maximize (
162175 init_points = 2 ,
163176 n_iter = 10 ,
164- )
177+ )
0 commit comments