Пример #1
0
def test_space_from_yaml():
    with NamedTemporaryFile() as tmp:
        tmp.write(b"""
        Space:
            - Real:
                low: 0.0
                high: 1.0
            - Integer:
                low: -5
                high: 5
            - Categorical:
                categories:
                - a
                - b
                - c
            - Real:
                low: 1.0
                high: 5.0
                prior: log-uniform
            - Categorical:
                categories:
                - e
                - f
        """)
        tmp.flush()

        space = Space([(0.0, 1.0),
                       (-5, 5),
                       ("a", "b", "c"),
                       (1.0, 5.0, "log-uniform"),
                       ("e", "f")])

        space2 = Space.from_yaml(tmp.name)
        assert_equal(space, space2)
def test_check_constraints():
    space = Space([(0.0,5.0),(1.0,5.0)])
    cons_list = Single(0,1,'integer')

    # Constraints_list must be a list
    with raises(TypeError):
        check_constraints(space,cons_list)

    # Constraints dimension must be less than number of dimensions in space
    cons_list = [Single(2,1,'integer')]
    with raises(IndexError):
        check_constraints(space,cons_list)

    # Constraints dimension_types must be the same as corresponding dimension in space
    space = Space([(0.0,5.0),(0,5),['a','b','c']])
    cons_list = [Single(2,1,'integer')]
    with raises(TypeError):
        check_constraints(space,cons_list)
    cons_list = [Single(1,1.0,'real')]
    with raises(TypeError):
        check_constraints(space,cons_list)
    cons_list = [Single(0,'a','categorical')]
    with raises(TypeError):
        check_constraints(space,cons_list)

    # Only one Single constraint per dimension
    cons_list = [Single(0,1.0,'real'),Single(0,2.0,'real')]
    with raises(IndexError):
        check_constraints(space,cons_list)
Пример #3
0
def test_space_from_space():
    # can you pass a Space instance to the Space constructor?
    space = Space([(0.0, 1.0), (-5, 5),
                   ("a", "b", "c"), (1.0, 5.0, "log-uniform"), ("e", "f")])

    space2 = Space(space)

    assert_equal(space, space2)
Пример #4
0
def test_lhs():
    SPACE = Space([
        Integer(-20, 20),
        Real(-10.5, 100),
        Categorical(list('abc'))]
    )
    samples = SPACE.lhs(10)
    assert len(samples) == 10
    assert len(samples[0]) == 3
def test_acquisition_per_second(acq_func):
    X = np.reshape(np.linspace(4.0, 8.0, 10), (-1, 1))
    y = np.vstack((np.ones(10), np.ravel(np.log(X)))).T
    cgpr = ConstantGPRSurrogate(Space(((1.0, 9.0), )))
    cgpr.fit(X, y)

    X_pred = np.reshape(np.linspace(1.0, 11.0, 20), (-1, 1))
    indices = np.arange(6)
    vals = _gaussian_acquisition(X_pred, cgpr, y_opt=1.0, acq_func=acq_func)
    for fast, slow in zip(indices[:-1], indices[1:]):
        #assert_greater(vals[slow], vals[fast])
        pass
        # TODO: I have commented this test out as it broke when implementing different lenght scale bounds.
        # I'm not sure how this test works and what it actually tests for and therefore i was not able to fix
        # it. -SC

    acq_wo_time = _gaussian_acquisition(X,
                                        cgpr.estimators_[0],
                                        y_opt=1.2,
                                        acq_func=acq_func[:2])
    acq_with_time = _gaussian_acquisition(X,
                                          cgpr,
                                          y_opt=1.2,
                                          acq_func=acq_func)
    assert_array_almost_equal(acq_wo_time / acq_with_time, np.ravel(X), 2)
def test_minimizer_with_space(minimizer):
    # check we can pass a Space instance as dimensions argument and get same
    # result
    n_calls = 4
    n_random_starts = 2

    space = Space([(-5.0, 10.0), (0.0, 15.0)])
    space_result = minimizer(branin,
                             space,
                             n_calls=n_calls,
                             n_random_starts=n_random_starts,
                             random_state=1)

    check_minimizer_api(space_result, n_calls)
    check_minimizer_bounds(space_result, n_calls)

    dimensions = [(-5.0, 10.0), (0.0, 15.0)]
    result = minimizer(branin,
                       dimensions,
                       n_calls=n_calls,
                       n_random_starts=n_random_starts,
                       random_state=1)

    assert_array_almost_equal(space_result.x_iters, result.x_iters)
    assert_array_almost_equal(space_result.func_vals, result.func_vals)
def test_constraints_rvs():
    space = Space([
        Real(1, 10),
        Real(1, 10),
        Real(1, 10),
        Integer(0, 10),
        Integer(0, 10),
        Integer(0, 10),
        Categorical(list('abcdefg')),
        Categorical(list('abcdefg')),
        Categorical(list('abcdefg'))
    ])
    
    cons_list = [Single(0,5.0,'real'),
            Inclusive(1,(3.0,5.0),'real'),
            Exclusive(2,(3.0,5.0),'real'),
            Single(3,5,'integer'),
            Inclusive(4,(3,5),'integer'),
            Exclusive(5,(3,5),'integer'),
            Single(6,'b','categorical'),
            Inclusive(7,('c','d','e'),'categorical'),
            Exclusive(8,('c','d','e'),'categorical'),
            # Note that two constraints are being added to dimension 4 and 5
            Inclusive(4,(7,9),'integer'),
            Exclusive(5,(7,9),'integer'),
    ]

    # Test lenght of samples
    constraints = Constraints(cons_list,space)
    samples = constraints.rvs(n_samples = 100)
    assert_equal(len(samples),100)
    assert_equal(len(samples[0]),space.n_dims)
    assert_equal(len(samples[-1]),space.n_dims)
    
    # Test random state
    samples_a = constraints.rvs(n_samples = 100,random_state = 1)
    samples_b = constraints.rvs(n_samples = 100,random_state = 1)
    samples_c = constraints.rvs(n_samples = 100,random_state = 2)
    assert_equal(samples_a,samples_b)
    assert_not_equal(samples_a,samples_c)

    # Test invalid constraint combinations
    space = Space([Real(0, 1)])
    cons_list = [Exclusive(0,(0.3,0.7),'real'), Inclusive(0,(0.5,0.6),'real')]
    constraints = Constraints(cons_list,space)
    with raises(RuntimeError):
        samples = constraints.rvs(n_samples = 10)
Пример #8
0
def test_space_api():
    space = Space([(0.0, 1.0), (-5, 5),
                   ("a", "b", "c"), (1.0, 5.0, "log-uniform"), ("e", "f")])

    cat_space = Space([(1, "r"), (1.0, "r")])
    assert isinstance(cat_space.dimensions[0], Categorical)
    assert isinstance(cat_space.dimensions[1], Categorical)

    assert_equal(len(space.dimensions), 5)
    assert_true(isinstance(space.dimensions[0], Real))
    assert_true(isinstance(space.dimensions[1], Integer))
    assert_true(isinstance(space.dimensions[2], Categorical))
    assert_true(isinstance(space.dimensions[3], Real))
    assert_true(isinstance(space.dimensions[4], Categorical))

    samples = space.rvs(n_samples=10, random_state=0)
    assert_equal(len(samples), 10)
    assert_equal(len(samples[0]), 5)

    assert_true(isinstance(samples, list))
    for n in range(4):
        assert_true(isinstance(samples[n], list))

    assert_true(isinstance(samples[0][0], numbers.Real))
    assert_true(isinstance(samples[0][1], numbers.Integral))
    assert_true(isinstance(samples[0][2], str))
    assert_true(isinstance(samples[0][3], numbers.Real))
    assert_true(isinstance(samples[0][4], str))

    samples_transformed = space.transform(samples)
    assert_equal(samples_transformed.shape[0], len(samples))
    assert_equal(samples_transformed.shape[1], 1 + 1 + 3 + 1 + 1)

    # our space contains mixed types, this means we can't use
    # `array_allclose` or similar to check points are close after a round-trip
    # of transformations
    for orig, round_trip in zip(samples,
                                space.inverse_transform(samples_transformed)):
        assert space.distance(orig, round_trip) < 1.e-8

    samples = space.inverse_transform(samples_transformed)
    assert_true(isinstance(samples[0][0], numbers.Real))
    assert_true(isinstance(samples[0][1], numbers.Integral))
    assert_true(isinstance(samples[0][2], str))
    assert_true(isinstance(samples[0][3], numbers.Real))
    assert_true(isinstance(samples[0][4], str))

    for b1, b2 in zip(space.bounds,
                      [(0.0, 1.0), (-5, 5),
                       np.asarray(["a", "b", "c"]), (1.0, 5.0),
                       np.asarray(["e", "f"])]):
        assert_array_equal(b1, b2)

    for b1, b2 in zip(space.transformed_bounds,
                      [(0.0, 1.0), (-5, 5), (0.0, 1.0), (0.0, 1.0), (0.0, 1.0),
                       (np.log10(1.0), np.log10(5.0)), (0.0, 1.0)]):
        assert_array_equal(b1, b2)
def test_get_constraints():
    # Test that the get_constraints() function returns the constraints that were set byt set_constraints()
    space = Space([Real(1, 10)])
    cons_list = [Single(0,5.0,'real')]
    cons = Constraints(cons_list,space)
    opt = Optimizer(space, "ET")
    opt.set_constraints(cons)
    assert_equal(cons,opt.get_constraints())
def test_Constraints_init():
    space = Space([
        Real(1, 10),
        Real(1, 10),
        Real(1, 10),
        Integer(0, 10),
        Integer(0, 10),
        Integer(0, 10),
        Categorical(list('abcdefg')),
        Categorical(list('abcdefg')),
        Categorical(list('abcdefg'))
    ])
    
    cons_list = [Single(0,5.0,'real'),
            Inclusive(1,(3.0,5.0),'real'),
            Exclusive(2,(3.0,5.0),'real'),
            Single(3,5,'integer'),
            Inclusive(4,(3,5),'integer'),
            Exclusive(5,(3,5),'integer'),
            Single(6,'b','categorical'),
            Inclusive(7,('c','d','e'),'categorical'),
            Exclusive(8,('c','d','e'),'categorical'),
            # Note that two ocnstraints are being added to dimension 4 and 5
            Inclusive(4,(7,9),'integer'),
            Exclusive(5,(7,9),'integer'),
    ]

    cons = Constraints(cons_list,space)

    # Test that space and constriants_list are being saved in object
    assert_equal(cons.space, space)
    assert_equal(cons.constraints_list, cons_list)

    # Test that a correct list of single constraints have been made
    assert_equal(len(cons.single),space.n_dims)
    assert_equal(cons.single[1], None)
    assert_equal(cons.single[-1], None)
    assert_not_equal(cons.single[0], None)
    assert_not_equal(cons.single[6],None)

    # Test that a correct list of inclusive constraints have been made
    assert_equal(len(cons.inclusive),space.n_dims)
    assert_equal(cons.inclusive[0],[])
    assert_equal(cons.inclusive[2],[])
    assert_not_equal(not cons.inclusive[1],[])
    assert_not_equal(not cons.inclusive[7],[])
    assert_equal(len(cons.inclusive[4]),2)

    # Test that a correct list of exclusive constraints have been made
    assert_equal(len(cons.exclusive),space.n_dims)
    assert_equal(cons.exclusive[3],[])
    assert_equal(cons.exclusive[7],[])
    assert_not_equal(cons.exclusive[2],[])
    assert_not_equal(cons.exclusive[5],[])
    assert_equal(len(cons.exclusive[5]),2)
def test_lhs_with_constraints():
    # Test that constraints cant be set when lhs is active and that it can be set once the points are exhausted.
    space = Space([Real(1, 10)])
    cons_list = [Single(0,5.0,'real')]
    cons = Constraints(cons_list,space)
    opt = Optimizer(space, "ET",lhs = True,n_initial_points = 2)
    opt.tell([1],0) # Use one initial point so that one is still left
    with raises(RuntimeError): # Error should be thrown when tryin got set constraints
        opt.set_constraints(cons)
    opt = Optimizer(space, "ET",lhs = True,n_initial_points = 2)
    opt.tell([[1],[1]],[0,0]) # Use all of the two initial points
    opt.set_constraints(cons) # Now it should be possible to set constraints
def test_acquisition_per_second_gradient(acq_func):
    rng = np.random.RandomState(0)
    X = rng.randn(20, 10)
    # Make the second component large, so that mean_grad and std_grad
    # do not become zero.
    y = np.vstack((X[:, 0], np.abs(X[:, 0])**3)).T

    for X_new in [rng.randn(10), rng.randn(10)]:
        gpr = cook_estimator("GP", Space(((-5.0, 5.0), )), random_state=0)
        mor = MultiOutputRegressor(gpr)
        mor.fit(X, y)
        check_gradient_correctness(X_new, mor, acq_func, 1.5)
def test_Sum():
    # Test that Sym type constraintcan be initialized
    Sum((1,2,3),5,less_than = False)
    Sum([3,2,1],-10.0,less_than = True)

    with raises(TypeError):
        Sum('a',5)
    # `less_than` should be a bool
    with raises(TypeError):
        Sum((1,2,3),5,less_than = 1)
    # Value should be int or float
    with raises(TypeError):
        Sum((1,2,3),True)
    # Dimensions should be of lenght > 1
    with raises(ValueError):
        Sum([0],True)
    # Dimensions can not be a negative int
    with raises(ValueError):
        Sum([-10,1,2],True)

    space = Space([[0.0,10.0],[0,10],['abcdef']])
    # A dimension value of 4 is out of bounds for a space with only 3 dimensions
    cons_list = [Sum((4,3),5)]
    with raises(IndexError):
        Constraints(cons_list,space)
    # Cannot apply sum constraint to categorical dimensions
    cons_list = [Sum((1,2),5)]
    with raises(ValueError):
        Constraints(cons_list,space)
    
    # Check that validate_sample validates samples correctly
    cons = Constraints([Sum((0,1),6)],space)
    assert_false(cons.validate_sample([0.0,7,'a']))
    assert_false(cons.validate_sample([7.0,0,'a']))
    assert_false(cons.validate_sample([3.00001,3,'a']))
    assert_true(cons.validate_sample([2.99999,3,'a']))

    # Check that validate_sample validates samples correctly for less_than = False
    cons = Constraints([Sum((0,1),6,less_than = False)],space)
    assert_true(cons.validate_sample([0.0,7,'a']))
    assert_true(cons.validate_sample([7.0,0,'a']))
    assert_true(cons.validate_sample([3.00001,3,'a']))
    assert_false(cons.validate_sample([2.99999,3,'a']))

    # Check that only valid samples are drawn
    samples = cons.rvs(n_samples = 1000)
    for sample in samples:
        assert_true(cons.validate_sample(sample))
def test_check_bounds():
    # Check that no error is raised when using valid bounds
    space = Space([(0.0,5.0),(0,5),['a','b','c',1,1.0]])
    check_bounds(space.dimensions[0],(1.0,2.0))
    check_bounds(space.dimensions[1],(1,3))
    check_bounds(space.dimensions[2],('a','b'))
    check_bounds(space.dimensions[2],('a',1.0))
    # Check that error is raised when using invalid bounds
    with raises(ValueError):
        check_bounds(space.dimensions[0],(-1.0,2.0))
    with raises(ValueError):
        check_bounds(space.dimensions[0],(2.0,10.0))
    with raises(ValueError):
        check_bounds(space.dimensions[1],(-1,2))
    with raises(ValueError):
        check_bounds(space.dimensions[1],(2,10))
    with raises(ValueError):
        check_bounds(space.dimensions[2],('k',-1.0))
    with raises(ValueError):
        check_bounds(space.dimensions[2],('a','b','c',1.2))
def test_check_value():
    # Test that no error is raised when using a valid value
    space = Space([(0.0,5.0),(0,5),['a','b','c',1,1.0]])
    check_value(space.dimensions[0],1.0)
    check_value(space.dimensions[1],1)
    check_value(space.dimensions[2],'b')
    check_value(space.dimensions[2],1)
    check_value(space.dimensions[2],1.0)

    # Test that error is raised when using an invalid value
    with raises(ValueError):
        check_value(space.dimensions[0],10.0)
    with raises(ValueError):
        check_value(space.dimensions[0],-1.0)
    with raises(ValueError):
        check_value(space.dimensions[1],10)
    with raises(ValueError):
        check_value(space.dimensions[1],-1)
    with raises(ValueError):
        check_value(space.dimensions[2],'wow')
    with raises(ValueError):
        check_value(space.dimensions[2],1.2)
def test_constraints_equality():
    # Same constraints should be equal
    space_a = Space([(0.0,5.0),(1.0,5.0)])
    space_b = Space([(0.0,5.0),(1.0,5.0)])
    cons_list_a = [Single(0,4.0,'real'),Single(1,4.0,'real')]
    cons_list_b = [Single(0,4.0,'real'),Single(1,4.0,'real')]
    cons_a = Constraints(cons_list_a,space_a)
    cons_b = Constraints(cons_list_b,space_b)
    assert_equal(cons_a, cons_b)

    # Different lengths of constraints_list should not be equal
    space_a = Space([(0.0,5.0)])
    space_b = Space([(0.0,5.0),(1.0,5.0)])
    cons_list_a = [Single(0,4.0,'real')]
    cons_list_b = [Single(0,4.0,'real'),Single(1,4.0,'real')]
    cons_a = Constraints(cons_list_a,space_a)
    cons_b = Constraints(cons_list_b,space_b)
    assert_not_equal(cons_a, cons_b)

    # Different dimension types in constraints_list should not be equal
    space_a = Space([(0.0,5.0)])
    space_b = Space([(0,5)])
    cons_list_a = [Single(0,4.0,'real')]
    cons_list_b = [Single(0,4,'integer')]
    cons_a = Constraints(cons_list_a,space_a)
    cons_b = Constraints(cons_list_b,space_b)
    assert_not_equal(cons_a, cons_b)

    # Different values in constraints should not be equal
    space_a = Space([(0.0,5.0)])
    space_b = Space([(0.0,5.0)])
    cons_list_a = [Single(0,4.0,'real')]
    cons_list_b = [Single(0,4.1,'real')]
    cons_a = Constraints(cons_list_a,space_a)
    cons_b = Constraints(cons_list_b,space_b)
    assert_not_equal(cons_a, cons_b)
Пример #17
0
def test_space_consistency():
    # Reals (uniform)

    s1 = Space([Real(0.0, 1.0)])
    s2 = Space([Real(0.0, 1.0)])
    s3 = Space([Real(0, 1)])
    s4 = Space([(0.0, 1.0)])
    s5 = Space([(0.0, 1.0, "uniform")])
    s6 = Space([(0, 1.0)])
    s7 = Space([(np.float64(0.0), 1.0)])
    s8 = Space([(0, np.float64(1.0))])
    a1 = s1.rvs(n_samples=10, random_state=0)
    a2 = s2.rvs(n_samples=10, random_state=0)
    a3 = s3.rvs(n_samples=10, random_state=0)
    a4 = s4.rvs(n_samples=10, random_state=0)
    a5 = s5.rvs(n_samples=10, random_state=0)
    assert_equal(s1, s2)
    assert_equal(s1, s3)
    assert_equal(s1, s4)
    assert_equal(s1, s5)
    assert_equal(s1, s6)
    assert_equal(s1, s7)
    assert_equal(s1, s8)
    assert_array_equal(a1, a2)
    assert_array_equal(a1, a3)
    assert_array_equal(a1, a4)
    assert_array_equal(a1, a5)

    # Reals (log-uniform)
    s1 = Space([Real(10**-3.0, 10**3.0, prior="log-uniform")])
    s2 = Space([Real(10**-3.0, 10**3.0, prior="log-uniform")])
    s3 = Space([Real(10**-3, 10**3, prior="log-uniform")])
    s4 = Space([(10**-3.0, 10**3.0, "log-uniform")])
    s5 = Space([(np.float64(10**-3.0), 10**3.0, "log-uniform")])
    a1 = s1.rvs(n_samples=10, random_state=0)
    a2 = s2.rvs(n_samples=10, random_state=0)
    a3 = s3.rvs(n_samples=10, random_state=0)
    a4 = s4.rvs(n_samples=10, random_state=0)
    assert_equal(s1, s2)
    assert_equal(s1, s3)
    assert_equal(s1, s4)
    assert_equal(s1, s5)
    assert_array_equal(a1, a2)
    assert_array_equal(a1, a3)
    assert_array_equal(a1, a4)

    # Integers
    s1 = Space([Integer(1, 5)])
    s2 = Space([Integer(1.0, 5.0)])
    s3 = Space([(1, 5)])
    s4 = Space([(np.int64(1.0), 5)])
    s5 = Space([(1, np.int64(5.0))])
    a1 = s1.rvs(n_samples=10, random_state=0)
    a2 = s2.rvs(n_samples=10, random_state=0)
    a3 = s3.rvs(n_samples=10, random_state=0)
    assert_equal(s1, s2)
    assert_equal(s1, s3)
    assert_equal(s1, s4)
    assert_equal(s1, s5)
    assert_array_equal(a1, a2)
    assert_array_equal(a1, a3)

    # Categoricals
    s1 = Space([Categorical(["a", "b", "c"])])
    s2 = Space([Categorical(["a", "b", "c"])])
    s3 = Space([["a", "b", "c"]])
    a1 = s1.rvs(n_samples=10, random_state=0)
    a2 = s2.rvs(n_samples=10, random_state=0)
    a3 = s3.rvs(n_samples=10, random_state=0)
    assert_equal(s1, s2)
    assert_array_equal(a1, a2)
    assert_equal(s1, s3)
    assert_array_equal(a1, a3)

    s1 = Space([(True, False)])
    s2 = Space([Categorical([True, False])])
    s3 = Space([np.array([True, False])])
    assert s1 == s2 == s3
def test_gaussian_acquisition_check_inputs():
    model = ConstantGPRSurrogate(Space(((1.0, 9.0), )))
    with pytest.raises(ValueError) as err:
        vals = _gaussian_acquisition(np.arange(1, 5), model)
    assert ("it must be 2-dimensional" in err.value.args[0])
def test_Conditional():
    # Test conditional constraints
    space = Space([list('ab'),list('ab'),list('ab'),[1,4],[1,4],[1,4]])
    condition = Single(0,'a','categorical')
    if_true = Inclusive(3,[1,2],'integer')
    if_false = Exclusive(3,[1,2],'integer')

    # Test init of constriants
    Conditional(condition, if_true, if_false)
    Conditional(condition, if_true = if_true, if_false = if_false)
    cons_list = [Conditional(condition, if_true = if_true, if_false = if_false)]
    cons = Constraints(cons_list,space)
    
    # Check that only valid samples are being drawn
    samples = cons.rvs(n_samples = 100)
    for sample in samples:
        if sample[0] == 'a':
            assert_true(sample[3] < 3)
        else:
            assert_true(sample[3] > 2)

    # Test that validate_sample works
    assert_false(cons.validate_sample(['a','a','a',3,3,3]))
    assert_true(cons.validate_sample(['a','a','a',2,3,3]))
    assert_false(cons.validate_sample(['b','a','a',2,3,3]))
    assert_true(cons.validate_sample(['b','a','a',3,3,3]))

    # Test list of constraints
    cons = Constraints([
        Conditional(
            Single(0,'a','categorical'),
            if_true = [Single(1,'a','categorical'),Single(2,'a','categorical')],
            if_false = [Single(1,'b','categorical'),Single(2,'b','categorical')]
        )
    ],space)
    assert_false(cons.validate_sample(['a','a','b',3,3,3]))
    assert_true(cons.validate_sample(['a','a','a',3,3,3]))
    assert_false(cons.validate_sample(['b','a','b',3,3,3]))
    assert_true(cons.validate_sample(['b','b','b',3,3,3]))

    # Test nested contraints
    cons = Constraints([
        Conditional(
            Inclusive(3,[1,2],'integer'),
            Conditional(
                Single(0,'a','categorical'),
                if_true = [Single(1,'a','categorical'),Single(2,'a','categorical')],
                if_false = [Single(1,'b','categorical'),Single(2,'b','categorical')]
            ),
            Conditional(
                Single(0,'a','categorical'),
                if_true = [Single(1,'b','categorical'),Single(2,'b','categorical')],
                if_false = [Single(1,'a','categorical'),Single(2,'a','categorical')]
            ),
        )
    ],space)

    assert_false(cons.validate_sample(['a','a','b',2,3,3]))
    assert_true(cons.validate_sample(['a','a','a',2,3,3]))
    assert_false(cons.validate_sample(['b','a','b',2,3,3]))
    assert_true(cons.validate_sample(['b','b','b',2,3,3]))
    
    assert_true(cons.validate_sample(['a','b','b',3,3,3]))
    assert_false(cons.validate_sample(['a','a','a',3,3,3]))
    assert_true(cons.validate_sample(['b','a','a',3,3,3]))
    assert_false(cons.validate_sample(['b','b','b',3,3,3]))
    
    samples = cons.rvs(n_samples = 100)
    for sample in samples:
        assert_true(cons.validate_sample(sample))
def test_Constraints_validate_sample():
    space = Space([
        Real(1, 10),
        Real(1, 10),
        Real(1, 10),
        Integer(0, 10),
        Integer(0, 10),
        Integer(0, 10),
        Categorical(list('abcdefg')),
        Categorical(list('abcdefg')),
        Categorical(list('abcdefg'))
    ])
    
    # Test validation of single constraints
    cons_list = [Single(0,5.0,'real')]
    cons = Constraints(cons_list,space)
    sample = [0]*space.n_dims
    sample[0] = 5.0
    assert_true(cons.validate_sample(sample))
    sample[0] = 5.00001
    assert_false(cons.validate_sample(sample))
    sample[0] = 4.99999
    assert_false(cons.validate_sample(sample))

    cons_list = [Single(3,5,'integer')]
    cons = Constraints(cons_list,space)
    sample = [0]*space.n_dims
    sample[3] = 5
    assert_true(cons.validate_sample(sample))
    sample[3] = 6
    assert_false(cons.validate_sample(sample))
    sample[3] = -5
    assert_false(cons.validate_sample(sample))
    sample[3] = 5.000001
    assert_false(cons.validate_sample(sample))

    cons_list = [Single(6,'a','categorical')]
    cons = Constraints(cons_list,space)
    sample = [0]*space.n_dims
    sample[6] = 'a'
    assert_true(cons.validate_sample(sample))
    sample[6] = 'b'
    assert_false(cons.validate_sample(sample))
    sample[6] = -5
    assert_false(cons.validate_sample(sample))
    sample[6] = 5.000001
    assert_false(cons.validate_sample(sample))

    # Test validation of inclusive constraints
    cons_list = [Inclusive(0,(5.0,7.0),'real')]
    cons = Constraints(cons_list,space)
    sample = [0]*space.n_dims
    sample[0] = 5.0
    assert_true(cons.validate_sample(sample))
    sample[0] = 7.0
    assert_true(cons.validate_sample(sample))
    sample[0] = 7.00001
    assert_false(cons.validate_sample(sample))
    sample[0] = 4.99999
    assert_false(cons.validate_sample(sample))
    sample[0] = -10
    assert_false(cons.validate_sample(sample))

    cons_list = [Inclusive(3,(5,7),'integer')]
    cons = Constraints(cons_list,space)
    sample = [0]*space.n_dims
    sample[3] = 5
    assert_true(cons.validate_sample(sample))
    sample[3] = 6
    assert_true(cons.validate_sample(sample))
    sample[3] = 7
    assert_true(cons.validate_sample(sample))
    sample[3] = 8
    assert_false(cons.validate_sample(sample))
    sample[3] = 4
    assert_false(cons.validate_sample(sample))
    sample[3] = -4
    assert_false(cons.validate_sample(sample))

    cons_list = [Inclusive(6,('c','d','e'),'categorical')]
    cons = Constraints(cons_list,space)
    sample = [0]*space.n_dims
    sample[6] = 'c'
    assert_true(cons.validate_sample(sample))
    sample[6] = 'e'
    assert_true(cons.validate_sample(sample))
    sample[6] = 'f'
    assert_false(cons.validate_sample(sample))
    sample[6] = -5
    assert_false(cons.validate_sample(sample))
    sample[6] = 3.3
    assert_false(cons.validate_sample(sample))
    sample[6] = 'a'
    assert_false(cons.validate_sample(sample))

    # Test validation of exclusive constraints
    cons_list = [Exclusive(0,(5.0,7.0),'real')]
    cons = Constraints(cons_list,space)
    sample = [0]*space.n_dims
    sample[0] = 5.0
    assert_false(cons.validate_sample(sample))
    sample[0] = 7.0
    assert_false(cons.validate_sample(sample))
    sample[0] = 7.00001
    assert_true(cons.validate_sample(sample))
    sample[0] = 4.99999
    assert_true(cons.validate_sample(sample))
    sample[0] = -10
    assert_true(cons.validate_sample(sample))

    cons_list = [Exclusive(3,(5,7),'integer')]
    cons = Constraints(cons_list,space)
    sample = [0]*space.n_dims
    sample[3] = 5
    assert_false(cons.validate_sample(sample))
    sample[3] = 6
    assert_false(cons.validate_sample(sample))
    sample[3] = 7
    assert_false(cons.validate_sample(sample))
    sample[3] = 8
    assert_true(cons.validate_sample(sample))
    sample[3] = 4
    assert_true(cons.validate_sample(sample))
    sample[3] = -4
    assert_true(cons.validate_sample(sample))

    cons_list = [Exclusive(3,(5,5),'integer')]
    cons = Constraints(cons_list,space)
    sample = [0]*space.n_dims
    sample[3] = 5
    assert_false(cons.validate_sample(sample))

    cons_list = [Exclusive(6,('c','d','e'),'categorical')]
    cons = Constraints(cons_list,space)
    sample = [0]*space.n_dims
    sample[6] = 'c'
    assert_false(cons.validate_sample(sample))
    sample[6] = 'e'
    assert_false(cons.validate_sample(sample))
    sample[6] = 'f'
    assert_true(cons.validate_sample(sample))
    sample[6] = -5
    assert_true(cons.validate_sample(sample))
    sample[6] = 3.3
    assert_true(cons.validate_sample(sample))
    sample[6] = 'a'
    assert_true(cons.validate_sample(sample))

    # Test more than one constraint per dimension
    cons_list = [Inclusive(0,(1.0,2.0),'real'),Inclusive(0,(3.0,4.0),'real'),Inclusive(0,(5.0,6.0),'real')]
    cons = Constraints(cons_list,space)
    sample = [0]*space.n_dims
    sample[0] = 1.3
    assert_true(cons.validate_sample(sample))
    sample[0] = 6.0
    assert_true(cons.validate_sample(sample))
    sample[0] = 5.0
    assert_true(cons.validate_sample(sample))
    sample[0] = 3.0
    assert_true(cons.validate_sample(sample))
    sample[0] = 4.0
    assert_true(cons.validate_sample(sample))
    sample[0] = 5.5
    assert_true(cons.validate_sample(sample))
    sample[0] = 2.1
    assert_false(cons.validate_sample(sample))
    sample[0] = 4.9
    assert_false(cons.validate_sample(sample))
    sample[0] = 7.0
    assert_false(cons.validate_sample(sample))

    cons_list = [Exclusive(0,(1.0,2.0),'real'),Exclusive(0,(3.0,4.0),'real'),Exclusive(0,(5.0,6.0),'real')]
    cons = Constraints(cons_list,space)
    sample = [0]*space.n_dims
    sample[0] = 1.3
    assert_false(cons.validate_sample(sample))
    sample[0] = 6.0
    assert_false(cons.validate_sample(sample))
    sample[0] = 5.0
    assert_false(cons.validate_sample(sample))
    sample[0] = 3.0
    assert_false(cons.validate_sample(sample))
    sample[0] = 4.0
    assert_false(cons.validate_sample(sample))
    sample[0] = 5.5
    assert_false(cons.validate_sample(sample))
    sample[0] = 2.1
    assert_true(cons.validate_sample(sample))
    sample[0] = 4.9
    assert_true(cons.validate_sample(sample))
    sample[0] = 7.0
    assert_true(cons.validate_sample(sample))
def test_optimizer_with_constraints(acq_optimizer):
    base_estimator = 'GP'
    space = Space([
        Real(1, 10),
        Real(1, 10),
        Real(1, 10),
        Integer(0, 10),
        Integer(0, 10),
        Integer(0, 10),
        Categorical(list('abcdefg')),
        Categorical(list('abcdefg')),
        Categorical(list('abcdefg'))
    ])

    cons_list = [Single(0,5.0,'real'),Single(3,5,'integer')]
    cons_list_2 = [Single(0,4.0,'real'),Single(3,4,'integer')]
    cons = Constraints(cons_list,space)
    cons_2 = Constraints(cons_list_2,space)

    # Test behavior when not adding constraitns
    opt = Optimizer(space, base_estimator, acq_optimizer=acq_optimizer,n_initial_points = 5)

    # Test that constraint is None when no constraint has been set so far
    assert_equal(opt._constraints,None)

    # Test constraints are still None
    for _ in range(6):
        next_x= opt.ask()
        f_val = np.random.random()*100
        opt.tell(next_x, f_val)
    assert_equal(opt._constraints,None)
    opt.remove_constraints()
    assert_equal(opt._constraints,None)

    # Test behavior when adding constraints in an optimization setting
    opt = Optimizer(space, base_estimator, acq_optimizer=acq_optimizer,n_initial_points = 3)
    opt.set_constraints(cons)
    assert_equal(opt._constraints,cons)
    next_x= opt.ask()
    assert_equal(next_x[0],5.0)
    assert_equal(next_x[3],5)
    f_val = np.random.random()*100
    opt.tell(next_x, f_val)
    assert_equal(opt._constraints,cons)
    opt.set_constraints(cons_2)
    next_x= opt.ask()
    assert_equal(opt._constraints,cons_2)
    assert_equal(next_x[0],4.0)
    assert_equal(next_x[3],4)
    f_val = np.random.random()*100
    opt.tell(next_x, f_val)
    assert_equal(opt._constraints,cons_2)
    opt.remove_constraints()
    assert_equal(opt._constraints,None)
    next_x= opt.ask()
    assert_not_equal(next_x[0],4.0)
    assert_not_equal(next_x[0],5.0)
    f_val = np.random.random()*100
    opt.tell(next_x, f_val)
    assert_equal(opt._constraints,None)

    # Test that next_x is changed when adding constraints
    opt = Optimizer(space, base_estimator, acq_optimizer=acq_optimizer,n_initial_points = 3)
    assert_false(hasattr(opt,'_next_x'))
    for _ in range(4): # We exhaust initial points
        next_x= opt.ask()
        f_val = np.random.random()*100
        opt.tell(next_x, f_val)
    assert_true(hasattr(opt,'_next_x')) # Now next_x should be in optimizer
    assert_not_equal(next_x[0],4.0)
    assert_not_equal(next_x[0],5.0)
    next_x = opt._next_x
    opt.set_constraints(cons)
    assert_not_equal(opt._next_x,next_x) # Check that next_x has been changed
    assert_equal(opt._next_x[0],5.0)
    assert_equal(opt._next_x[3],5)
    next_x = opt._next_x
    opt.set_constraints(cons_2)
    assert_not_equal(opt._next_x,next_x)
    assert_equal(opt._next_x[0],4.0)
    assert_equal(opt._next_x[3],4)

    # Test that adding a Constraint or constraint_list gives the same
    opt = Optimizer(space, base_estimator, acq_optimizer=acq_optimizer,n_initial_points = 3)
    opt.set_constraints(cons_list)
    opt2 = Optimizer(space, base_estimator, acq_optimizer=acq_optimizer,n_initial_points = 3)
    opt2.set_constraints(cons)
    assert_equal(opt._constraints,opt2._constraints)

    # Test that constraints are satisfied
    opt = Optimizer(space, base_estimator, acq_optimizer=acq_optimizer,n_initial_points = 2)
    opt.set_constraints(cons)
    next_x= opt.ask()
    assert_equal(next_x[0],5.0)

    opt = Optimizer(space, base_estimator, acq_optimizer=acq_optimizer,n_initial_points = 2)
    next_x= opt.ask()
    assert_not_equal(next_x[0],5.0)
    f_val = np.random.random()*100
    opt.tell(next_x, f_val)
    opt.set_constraints(cons)
    next_x= opt.ask()
    assert_equal(next_x[0],5.0)
    assert_equal(next_x[3],5)
    opt.set_constraints(cons)
    next_x= opt.ask()
    f_val = np.random.random()*100
    opt.tell(next_x, f_val)
    opt.set_constraints(cons_2)
    next_x= opt.ask()
    assert_equal(next_x[0],4.0)
    assert_equal(next_x[3],4)
    f_val = np.random.random()*100
    opt.tell(next_x, f_val)
    assert_equal(next_x[0],4.0)
    assert_equal(next_x[3],4)