def test_hash_is_same_for_same_point(self): args = (np.ones(4), 3.5) f1 = FunctionPoint(*args) f2 = FunctionPoint(*args) hash1 = hash(f1) hash2 = hash(f2) self.assertEqual(hash1, hash2)
def test_raises_error_if_points_not_all_same_dimension(self): n_dim = 3 n_points = n_dim + 1 points = np.random.standard_normal((n_points, n_dim)) values = np.random.standard_normal(n_points + 1) correct_function_points = make_function_points(points[:-1], values[:-1]) incorrect_function_point = FunctionPoint(points[-1, :-1], values[-1]) function_points = correct_function_points + [incorrect_function_point] self.assertRaises(ValueError, Simplex, function_points)
def test_simplex_branch_on_interior_point_returns_correct_number(self): np.random.seed(1104) dimension = 3 simplex = make_simplex(dimension) new_point = np.random.standard_normal((dimension, )) new_value = np.random.standard_normal((1, )) new_function_point = FunctionPoint(new_point, new_value) branched_simplices = simplex.branch_on_interior_point( new_function_point) self.assertEqual(len(branched_simplices), dimension + 1) for branched_simplex in branched_simplices: self.assertIsInstance(branched_simplex, Simplex)
def test_triangulate_function_points_returns_simplices(self): np.random.seed(1400) npoints = 25 ndim = 5 points = np.random.randn(npoints, ndim) values = np.random.randn(npoints) function_points = [FunctionPoint(p, v) for p, v in zip(points, values)] simplices = triangulate.triangulate_function_points_into_simplices( function_points) for simplex in simplices: self.assertIsInstance(simplex, Simplex)
def test_triangulate_function_points_uses_all_points(self): np.random.seed(1400) npoints = 25 ndim = 5 points = np.random.randn(npoints, ndim) values = np.random.randn(npoints) function_points = [FunctionPoint(p, v) for p, v in zip(points, values)] simplices = triangulate.triangulate_function_points_into_simplices( function_points) for function_point in function_points: point_in_simplex_i = [ function_point in s.function_points for s in simplices] self.assertTrue(any(point_in_simplex_i))
def test_triangulation_of_triangulate_function_on_hyperrectangle(self): bounds = np.array([[0, 1], [0, 1]]) f = lambda x: np.sum(x) triangulation = triangulate.triangulate_function_on_hyperrectangle( f, bounds) points = np.array([ [0, 0], [0, 1], [1, 0], [1, 1]]) correct_function_points = set([FunctionPoint(p, f(p)) for p in points]) calculated_function_points = set( [fp for s in triangulation for fp in s.function_points]) self.assertEqual(calculated_function_points, correct_function_points)
def test_simplex_branch_on_interior_point_keeps_d_old_simplices(self): np.random.seed(1104) dimension = 3 simplex = make_simplex(dimension) new_point = np.random.standard_normal((dimension, )) new_value = np.random.standard_normal((1, )) new_function_point = FunctionPoint(new_point, new_value) branched_simplices = simplex.branch_on_interior_point( new_function_point) old_function_points = simplex.function_points for branched_simplex in branched_simplices: count = 0 these_function_points = branched_simplex.function_points for op in old_function_points: if any([op is tfp for tfp in these_function_points]): count += 1 self.assertEqual(count, dimension)
def test_evaluate_objective_function_stores_min_found_function_value(self): np.random.seed(1359) objective_function = square_distance_from_center ndim = 7 points = np.random.randn(ndim + 1, ndim) function_points = [ FunctionPoint(p, objective_function(p)) for p in points] initial_simplices = [Simplex(function_points)] simplex_bound_calculator = make_simplex_bound_calculator() optimizer = BranchBoundOptimizer( objective_function, initial_simplices, simplex_bound_calculator) assert optimizer.current_min_function_point.value > 0 global_min_x = np.zeros(ndim) global_min_fp = optimizer._evaluate_function_point(global_min_x) assert global_min_fp.value == 0 self.assertEqual(optimizer.current_min_function_point.value, 0)
def make_realistic_optimizer_with_function_call_counter(dimension=7): objective_function = FunctionCallCounter(square_distance_from_center) # We want the simplex to enclose the global minimum, which is at 0 # So we make a simplex centered at the origin points_uncentered = np.random.randn(dimension + 1, dimension) center = points_uncentered.mean(axis=0).reshape(1, -1) points = points_uncentered - center function_points = [ FunctionPoint(p, objective_function(p)) for p in points] initial_simplices = [Simplex(function_points)] simplex_bound_calculator = MaxPointSimplexBoundCalculator( OrdinaryPointBoundCalculator(np.inf, 2)) optimizer = BranchBoundOptimizer( objective_function, initial_simplices, simplex_bound_calculator) objective_function.counter *= 0 return optimizer
def triangulate_function_on_hyperrectangle(function, bounds): points = _produce_points_at_corners_of_hyperrectangle(bounds) function_points = [ FunctionPoint(point, function(point)) for point in points ] return triangulate_function_points_into_simplices(function_points)
def test_is_local_minimum_default_to_false(self): function_point = FunctionPoint(np.ones(4), 3.5) self.assertFalse(function_point.is_local_minimum)
def test_eq_when_same(self): point = np.ones(4) value = 3.5 function_point = FunctionPoint(point, value) self.assertEqual(function_point, function_point)
def test_eq_for_different_point(self): f1 = FunctionPoint(np.ones(4), 3.5) f2 = FunctionPoint(np.zeros(4), 3.5) self.assertNotEqual(f1, f2)
def test_hash_is_different_for_different_points(self): f1 = FunctionPoint(np.ones(4), 3.5) f2 = FunctionPoint(np.zeros(4), 3.5) hash1 = hash(f1) hash2 = hash(f2) self.assertNotEqual(hash1, hash2)
def test_eq_for_same_point(self): args = (np.ones(4), 3.5) f1 = FunctionPoint(*args) f2 = FunctionPoint(*args) self.assertEqual(f1, f2)
def test_repr(self): function_point = FunctionPoint(np.ones(4), 3.5, is_local_minimum=True) the_repr = repr(function_point) self.assertIn('FunctionPoint', the_repr) self.assertIn('1', the_repr) self.assertIn(', 3.5)', the_repr)
def test_is_local_minimum_stores_when_set_to_true(self): function_point = FunctionPoint(np.ones(4), 3.5, is_local_minimum=True) self.assertTrue(function_point.is_local_minimum)
def _evaluate_function_point(self, point): value = self.objective_function(point) function_point = FunctionPoint(point, value) if value < self.current_min_function_point.value: self.current_min_function_point = function_point return function_point
def test_stores_point_and_value(self): point = np.ones(4) value = 3.5 function_point = FunctionPoint(point, value) self.assertEqual(function_point.value, value) self.assertTrue(np.all(function_point.point == point))
def make_function_points(points, values): return [FunctionPoint(p, v) for p, v in zip(points, values)]
def test_eq_when_different(self): function_point1 = FunctionPoint(np.ones(4), 3.5) function_point2 = FunctionPoint(np.ones(4) * 2, 1.5) self.assertNotEqual(function_point1, function_point2)