def test_dimension_is_correct(self): n_dim = 3 points = np.random.standard_normal((n_dim + 1, n_dim)) values = np.random.standard_normal(points.shape[:1]) function_points = make_function_points(points, values) simplex = Simplex(function_points) self.assertEqual(simplex.dimension, n_dim)
def triangulate_function_points_into_simplices(function_points): points = [fp.point for fp in function_points] triangulation = Delaunay(np.asarray(points)) simplices = [] for indices in triangulation.simplices: these_points = [function_points[i] for i in indices] simplices.append(Simplex(these_points)) return simplices
def test_vertex_with_min_value(self): n_dim = 3 points = np.random.standard_normal((n_dim + 1, n_dim)) values = np.random.standard_normal(points.shape[:1]) function_points = make_function_points(points, values) simplex = Simplex(function_points) min_function_point = simplex.vertex_with_min_value self.assertEqual(min_function_point.value, values.min())
def branch_on_candidate(self, simplex): # choose 2 vertices to branch off vertices_old = simplex.function_points vertex_max = simplex.vertex_with_max_value index_farthest = np.argmax( [np.linalg.norm(vertex_max.point - v.point) for v in vertices_old]) vertex_farthest = vertices_old[index_farthest] other_vertices = [ v for v in vertices_old if v not in [vertex_farthest, vertex_max] ] # branch off the midpoint of those 2 vertices midpoint = 0.5 * (vertex_max.point + vertex_farthest.point) vertex_midpoint = self._evaluate_function_point(midpoint) new_candidates = (Simplex(other_vertices + [vertex_midpoint, vertex_max]), Simplex(other_vertices + [vertex_midpoint, vertex_farthest])) return new_candidates
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 make_simplex(dimension=3): points = np.random.standard_normal((dimension + 1, dimension)) values = np.random.standard_normal((dimension + 1,)) function_points = make_function_points(points, values) return Simplex(function_points)