class Polytope(object): def __init__(self, halfspaces=None, vertices=None): if halfspaces is not None: self.halfspaces = halfspaces self.dim = halfspaces[0][0].dim self.poly = self.poly_from_constraints(halfspaces) self.vertices = self.vertices_from_poly() elif vertices is not None: v = vertices.pop() self.dim = v.dim vertices.add(v) self.poly = self.poly_from_vertices(vertices) self.vertices = self.vertices_from_poly() self.hyperplanes = self.hyperplanes_from_poly() self.halfspaces = zip(self.hyperplanes, [1] * len(self.hyperplanes)) else: self.hyperplanes = [] self.halfspaces = [] self.vertices = [] self.poly = C_Polyhedron(0) def as_convex_hull(self): vertices = np.array([vertex.coordinates for vertex in self.vertices]) convex_hull = ConvexHull(vertices, qhull_options='Pp') return convex_hull def get_vertex_coordinates(self): return np.array([v.coordinates for v in self.vertices]) def vertices_from_poly(self): # Get vertices of polytope resulting from intersection. only points not rays return np.array([Vertex(pt) for pt in self.poly.minimized_generators() if pt.is_point()]) def poly_from_constraints(self, halfspaces): # Create PPL variables. x = [Variable(i) for i in range(self.dim)] # Init constraint system. constraints = Constraint_System() # Add polytope facets to constraint systems. # Format of ConvexHull.equations: [a1 a2 .. b] => a1*x1 + a2*x2 + .. + b <= 0. for hyp, orient in halfspaces: if orient == -1: constraints.insert(sum(hyp.a[i] * x[i] for i in range(self.dim)) + hyp.b <= 0) elif orient == 1: constraints.insert(sum(hyp.a[i] * x[i] for i in range(self.dim)) + hyp.b >= 0) elif orient == 0: constraints.insert(sum(hyp.a[i] * x[i] for i in range(self.dim)) + hyp.b == 0) # Build PPL polyhedra. return C_Polyhedron(constraints) def poly_from_vertices(self, vertices): # Create PPL variables. x = [Variable(i) for i in range(self.dim)] # Init constraint system. generators = Generator_System() # ppl needs coordinates in form of point(sum(a_i *x_i), denom) with a_i integers for vertex in vertices: generators.insert(vertex.ppl) # Build PPL polyhedra. return C_Polyhedron(generators) def hyperplanes_from_poly(self): logging.debug('<nr generators: {}>, <nr constraints: {}>' .format(len(self.poly.generators()), len(self.poly.constraints()))) hyperplanes = [] # constraints in ppl are saved as of the form ax + b >= 0 for constraint in self.poly.minimized_constraints(): a = np.array(constraint.coefficients()) b = constraint.inhomogeneous_term() hyperplane = Hyperplane(a, b) hyperplanes.append(hyperplane) return hyperplanes def add_constraint(self, halfspace): # Create PPL variables. x = [Variable(i) for i in range(self.dim)] if halfspace[1] == -1: self.poly.add_constraint( sum(halfspace[0].a[i] * x[i] for i in range(self.dim)) + halfspace[0].b <= 0) elif halfspace[1] == 1: self.poly.add_constraint( sum(halfspace[0].a[i] * x[i] for i in range(self.dim)) + halfspace[0].b >= 0) elif halfspace[1] == 0: self.poly.add_constraint( sum(halfspace[0].a[i] * x[i] for i in range(self.dim)) + halfspace[0].b == 0) self.hyperplanes = self.hyperplanes_from_poly() self.halfspaces.append(halfspace) self.vertices = self.vertices_from_poly() def point_in_poly(self, point): return self.poly.relation_with(point.ppl).implies(Poly_Gen_Relation.subsumes())
import numpy as np from bellpolytope import BellPolytope from bellscenario import BellScenario from bellpolytopewithonewaycomm import BellPolytopeWithOneWayCommunication from ppl import Variable, Generator_System, C_Polyhedron, point from sequentialbellpolytope import SequentialBellPolytope from sequentialbellscenario import SequentialBellScenario if __name__ == '__main__': outputsAliceSeq = [[2, 2], [2, 2]] outputsBob = [2, 2] scenario = SequentialBellScenario(outputsAliceSeq, outputsBob) variables = [Variable(i) for i in range(len(scenario.getTuplesOfEvents()))] gs = Generator_System() for v in BellPolytopeWithOneWayCommunication( SequentialBellPolytope(scenario)).getGeneratorForVertices(): prob = v.getProbabilityList() gs.insert(point(sum(prob[i] * variables[i] for i in range(len(prob))))) poly = C_Polyhedron(gs) constraints = poly.constraints() for constraint in constraints: inequality = str(constraint.inhomogeneous_term().__float__()) + ' ' for coef in constraint.coefficients(): inequality = inequality + str(-coef.__float__()) + ' ' print(inequality)