Esempio n. 1
0
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())
Esempio n. 2
0
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)