def test_testcdd2(number_type, assert_matrix_equal): mat = cdd.Matrix([[7,-3,-0],[7,0,-3],[1,1,0],[1,0,1]], number_type=number_type) mat.rep_type = cdd.RepType.INEQUALITY assert_matrix_equal( list(mat), [(7,-3,-0),(7,0,-3),(1,1,0),(1,0,1)]) gen = cdd.Polyhedron(mat).get_generators() assert gen.rep_type == cdd.RepType.GENERATOR assert_matrix_equal( list(gen), [(1, Fraction(7, 3), -1), (1, -1, -1,), (1, -1, Fraction(7, 3)), (1, Fraction(7, 3), Fraction(7, 3))]) # add an equality and an inequality mat.extend([[7, 1, -3]], linear=True) mat.extend([[7, -3, 1]]) assert_matrix_equal( list(mat), [(7,-3,-0),(7,0,-3),(1,1,0),(1,0,1),(7,1,-3),(7,-3,1)]) assert list(mat.lin_set) == [4] gen2 = cdd.Polyhedron(mat).get_generators() assert gen2.rep_type == cdd.RepType.GENERATOR assert_matrix_equal( list(gen2), [(1, -1, 2), (1, 0, Fraction(7, 3))])
def __init__(self, cddinner, cddouter): """Default constructor, uses cdd representation of inner/outer for initialization cddinner: cdd matrix for the initial inner approximation cddouter: cdd matrix for the initial outer approximation""" polyinner = cdd.Polyhedron(cddinner) polyouter = cdd.Polyhedron(cddouter) self.inner = Polygon( np.array(polyinner.get_generators())[:, 1:], np.array(polyinner.get_inequalities())) self.outer = Polygon( np.array(polyouter.get_generators())[:, 1:], np.array(polyouter.get_inequalities())) self.correspondences = [None] * self.inner.vertices.shape[0] for i, v in enumerate(self.inner.vertices): dists = [] for j, e in enumerate(self.outer.edges): ineq = self.outer.inequalities[e[0], :] dist = abs(ineq[0] + v.dot(ineq[1:])) dists.append((j, dist)) j_min, dist = min(dists, key=lambda x: x[1]) assert dist < 1e-7, "No inequality matches this vertex : {}".format( v) self.correspondences[i] = j_min print(self.correspondences) assert (all([c is not None for c in self.correspondences]))
def __computeHRepresentation(self, polygon): # transform this intersection into half-space representation (A x <= b) using Pycddlib package x_partition_polygon, y_partition_polygon = polygon.exterior.xy x_partition_polygon.pop(0) # remove the first element since it is equal to the last one y_partition_polygon.pop(0) # remove the first element since it is equal to the last one # The Pycddlib asks to put a flag equal to "1" in the begining along with the x-y coordinates # of each point. points = [[1, x_partition_polygon[i], y_partition_polygon[i]] for i in range(len(x_partition_polygon))] matrix_cdd = cdd.Matrix(points, number_type='float') matrix_cdd.rep_type = cdd.RepType.GENERATOR poly_cdd = cdd.Polyhedron(matrix_cdd) polygon_halfspace = poly_cdd.get_inequalities() # this function returns the half-space representation one Matrix object with [b -A] elements inside b = np.empty([polygon_halfspace.row_size, 1]) A = np.empty([polygon_halfspace.row_size, polygon_halfspace.col_size - 1]) for row_index in range(polygon_halfspace.row_size): row = polygon_halfspace.__getitem__(row_index) b[row_index] = row[0] A[row_index, :] = [-1 * x for x in row[1:polygon_halfspace.col_size]] return A, b
def cdd_invalidate_vreps(backend, poly): offset = poly.offsets[-1] direction = poly.directions[-1] keys = [] for key, vrep in poly.vrep_dic.items(): try: valid = all(offset + vrep[:, 1:].dot(direction.T) < 0) except IndexError as e: print("Error :( ") valid = True if not valid: keys.append(key) if key in poly.hrep_dic: poly.hrep_dic[key].extend(np.hstack((offset, -direction))) for key in keys: if key in poly.hrep_dic: A_e = poly.hrep_dic[key] else: A_e = poly.outer.copy() A_e.extend(cdd.Matrix(-line.reshape(1, line.size))) A_e.canonicalize() poly.hrep_dic[key] = A_e vol = backend.volume_convex(A_e) poly.volume_dic[key] = vol volumes.append(vol) poly.vrep_dic[key] = np.array(cdd.Polyhedron(A_e).get_generators())
def span_to_face(V): """ Convert a polyhedral cone from span form C = {Vz | z >= 0}. to face form C = {x | Ax <= 0} """ # V-representation [t V], where t=0 for rays tV = np.hstack([np.zeros((V.shape[1], 1)), V.T]) mat = cdd.Matrix(tV, number_type='float') mat.rep_type = cdd.RepType.GENERATOR P = cdd.Polyhedron(mat) # H-representation [b -A], where Ax <= b ineq = P.get_inequalities() H = np.array(ineq) #assert np.all(H[:,0] == 0), "Ax <= b, but b is nonzero!" A = [] for i in xrange(H.shape[0]): if i not in ineq.lin_set: A.append(-H[i, 1:]) return np.asarray(A)
def __init__(self, varsid): start = time.time() # krelu on variables in varsid self.varsid = varsid self.k = len(varsid) cdd_hrepr = self.get_ineqs(varsid) check_pt1 = time.time() cdd_hrepr = cdd.Matrix(cdd_hrepr, number_type='fraction') cdd_hrepr.rep_type = cdd.RepType.INEQUALITY pts = self.get_orthant_points(cdd_hrepr) # Generate extremal points in the space of variables before and # after relu pts = [([1] + row + [x if x > 0 else 0 for x in row]) for row in pts] cdd_vrepr = cdd.Matrix(pts, number_type='fraction') cdd_vrepr.rep_type = cdd.RepType.GENERATOR # Convert back to H-repr. cons = cdd.Polyhedron(cdd_vrepr).get_inequalities() cons = np.asarray(cons, dtype=np.float64) # normalize constraints for numerical stability # more info: http://files.gurobi.com/Numerics.pdf absmax = np.absolute(cons).max(axis=1) self.cons = cons / absmax[:, None] end = time.time() return
def determine_H_rep(self): if not self.in_V_rep: raise ValueError( 'Cannot determine H representation: no V representation') if not self.is_full_dimensional or self.n < 2: # TODO: fix this # Use cdd, which handles this case. # cdd needs a column of ones to the left of V (zeros indicate rays): V_cdd = cdd.Matrix(np.hstack((np.ones((self.nV, 1)), self.V)), number_type='float') V_cdd.rep_type = cdd.RepType.GENERATOR # specifies that this is V-rep P_cdd = cdd.Polyhedron(V_cdd) H_cdd = P_cdd.get_inequalities() H_bmA = np.array(H_cdd) # cdd's format of H is [b, -A] # Find the indices of inequalities Ax <= b (i_ineq_rows) and equations # Ax = b (i_eq_rows). lin_set is a a frozenset with indices of # equalities/equations Ax = b. i_ineq_rows = list(set(range(H_cdd.col_size)) - H_cdd.lin_set) i_eq_rows = list(H_cdd.lin_set) A_ineq = H_bmA[i_ineq_rows, 1:] b_ineq = H_bmA[[i_ineq_rows], [0]].T A_eq = H_bmA[i_eq_rows, 1:] b_eq = H_bmA[[i_eq_rows], [0]].T A = np.vstack((A_ineq, A_eq, -A_eq)) b = np.vstack((b_ineq, b_eq, -b_eq)) self._set_Ab(A, b) else: # use Qhull H = ConvexHull(self.V).equations # Qhull's format of H is [A, -b] A, b_negative = np.split(H, [-1], axis=1) self._set_Ab(A, -b_negative)
def test_make_vertex_adjacency_list(number_type): # The following lines test that poly.get_adjacency_list() # returns the correct adjacencies. # We start with the H-representation for a cube mat = cdd.Matrix([[1, 1, 0 ,0], [1, 0, 1, 0], [1, 0, 0, 1], [1, -1, 0, 0], [1, 0, -1, 0], [1, 0, 0, -1]], number_type=number_type) mat.rep_type = cdd.RepType.INEQUALITY poly = cdd.Polyhedron(mat) adjacency_list = poly.get_adjacency() # Family size should equal the number of vertices of the cube (8) assert len(adjacency_list) == 8 # All the vertices of the cube should be connected by three other vertices assert [len(adj) for adj in adjacency_list] == [3]*8 # The vertices must be numbered consistently # The first vertex is adjacent to the second, fourth and eighth # (note the conversion to a pythonic numbering system) adjacencies = [[1, 3, 7], [0, 2, 6], [1, 3, 4], [0, 2, 5], [2, 5, 6], [3, 4, 7], [1, 4, 7], [0, 5, 6]] for i in range(8): assert list(adjacency_list[i]) == adjacencies[i]
def determine_V_rep(self): # also determines rays R (not implemented) # Vertex enumeration from halfspace representation using cdd. # TODO: shift the polytope to the center? (centroid? Chebyshev center?) # cdd uses the halfspace representation [b, -A] | b - Ax >= 0 ==> Ax <= b. if not self.in_H_rep: raise ValueError( 'Cannot determine V representation: no H representation') b_mA = np.hstack((self.b, -self.A)) # [b, -A] H = cdd.Matrix(b_mA, number_type='float') H.rep_type = cdd.RepType.INEQUALITY # specifies that this is H-rep H_P = cdd.Polyhedron(H) # From the get_generators() documentation: For a polyhedron described as # P = conv(v_1, ..., v_n) + nonneg(r_1, ..., r_s), # the V-representation matrix is [t V] where t is the column vector with # n ones followed by s zeroes, and V is the stacked matrix of n vertex # row vectors on top of s ray row vectors. P_tV = H_P.get_generators() # type(P_tV): <class 'cdd.Matrix'> tV = np.array(P_tV[:]) if tV.any(): # tV == [] if the Polytope is empty V_rows = tV[:, 0] == 1 # bool array of which rows contain vertices R_rows = tV[:, 0] == 0 # and which contain rays (~ V_rows) V = tV[V_rows, 1:] # array of vertices (one per row) R = tV[R_rows, 1:] # and of rays if R_rows.any(): raise NotImplementedError('Support for rays not implemented') else: V = np.empty((0, self.n)) self._set_V(V)
def face_to_span(A): """ Convert a polyhedral cone from face form C = {x | Ax <= 0} to span form C = {Vz | z >= 0}. """ # H-representation [b -A], where Ax <= b H = np.hstack([np.zeros((A.shape[0], 1)), -A]) mat = cdd.Matrix(H, number_type='float') mat.rep_type = cdd.RepType.INEQUALITY P = cdd.Polyhedron(mat) # V-representation [t V], where t=0 for rays g = P.get_generators() tV = np.array(g) assert np.all(tV[:, 0] == 0), "Not a cone!" rays = [] for i in range(tV.shape[0]): if i not in g.lin_set: rays.append(tV[i, 1:]) V = np.asarray(rays).T return V
def compute_polytope_halfspaces(vertices): """ Compute the halfspace representation (H-rep) of a polytope defined as convex hull of a set of vertices: .. math:: A x \\leq b \\quad \\Leftrightarrow \\quad x \\in \\mathrm{conv}(\\mathrm{vertices}) Parameters ---------- vertices : list of arrays List of polytope vertices. Returns ------- A : array, shape=(m, k) Matrix of halfspace representation. b : array, shape=(m,) Vector of halfspace representation. """ V = vstack(vertices) t = ones((V.shape[0], 1)) # first column is 1 for vertices tV = hstack([t, V]) mat = cdd.Matrix(tV, number_type='float') mat.rep_type = cdd.RepType.GENERATOR P = cdd.Polyhedron(mat) bA = array(P.get_inequalities()) if bA.shape == (0, ): # bA == [] return bA # the polyhedron is given by b + A x >= 0 where bA = [b|A] b, A = array(bA[:, 0]), -array(bA[:, 1:]) return (A, b)
def compute_polytope_vertices(A, b): """ Compute the vertices of a polytope given in halfspace representation by :math:`A x \\leq b`. Parameters ---------- A : array, shape=(m, k) Matrix of halfspace representation. b : array, shape=(m,) Vector of halfspace representation. Returns ------- vertices : list of arrays List of polytope vertices. """ b = b.reshape((b.shape[0], 1)) mat = cdd.Matrix(hstack([b, -A]), number_type='float') mat.rep_type = cdd.RepType.INEQUALITY P = cdd.Polyhedron(mat) g = P.get_generators() V = array(g) vertices = [] for i in range(V.shape[0]): if V[i, 0] != 1: # 1 = vertex, 0 = ray raise Exception("Polyhedron is not a polytope") elif i not in g.lin_set: vertices.append(V[i, 1:]) return vertices
def qhull_volume_convex(hrep): gen = np.array(cdd.Polyhedron(hrep).get_generators()) #If the polygon is empty or degenerate, return 0 if gen.shape[0] < 3: return 0 points = gen[:, 1:].tolist() return convexVolume(points)
def update_in_interval(self): H_rep = np.zeros((0, self.nn.image_size + 1)) for layer_idx, neuron_idx in self.nn.active_relus: eq = self.nn.layers[layer_idx]['in_sym'].upper[neuron_idx] b, A = -eq[-1], eq[:-1] H_rep = np.vstack((H_rep, np.hstack((-b, A)))) try: for layer_idx, neuron_idx in self.nn.inactive_relus: eq = self.nn.layers[layer_idx]['in_sym'].upper[neuron_idx] b, A = -eq[-1], eq[:-1] H_rep = np.concatenate((H_rep, np.hstack((b, -A)).reshape( (1, 6))), axis=0) self.MAX_DEPTH = 2 A = cdd.Matrix(H_rep) A.rep_type = 1 p = cdd.Polyhedron(A) vertices = np.array(p.get_generators())[:, 1:] hrect_min = np.min(vertices, axis=0).reshape((-1, 1)) hrect_max = np.max(vertices, axis=0).reshape((-1, 1)) new_bound = np.hstack((hrect_min, hrect_max)) new_bound[:, 1] = np.minimum(new_bound[:, 1], self.orig_net.input_bound[:, 1]) new_bound[:, 0] = np.maximum(new_bound[:, 0], self.orig_net.input_bound[:, 0]) except Exception as e: new_bound = self.nn.input_bound return new_bound
def describe_workload_space_as_halfspaces(workload_mat): """ Returns the workload space as the intersection of halfspaces. It starts building the V-cone description as the nonnegative spanning of the workload vectors: P = nonneg(Xi^T). Then it transforms to its equivalent H-cone description as the intersection of halfspaces: P = {x | A x >= 0}. :param workload_mat: Workload matrix. :return halfspaces: Matrix with rows representing vector normals to each of the hyperplanes. """ num_buffers = workload_mat.shape[1] # Build V-cone: P = nonneg(\Xi^T). generator = np.hstack((np.zeros((num_buffers, 1)), workload_mat.T)) matrix = cdd.Matrix(generator) matrix.rep_type = cdd.RepType.GENERATOR poly = cdd.Polyhedron(matrix) # Transform to H-cone: P = {x | A x <= 0}. b_vec_neg_a_mat = np.array( poly.get_inequalities()) # Get the matrix [b -A]. if b_vec_neg_a_mat.size > 0: halfspaces = b_vec_neg_a_mat[:, 1:] # Get -A such that -A x >= 0. else: halfspaces = None return halfspaces
def build_cone(nr_generators, mu, axis, offset_angle=0): origin = np.array([[0, 0, 0]]) angles = [ offset_angle + 2 * np.pi * i / nr_generators for i in range(nr_generators) ] local_points = [ np.array([[mu * np.cos(x), mu * np.sin(x), 1.]]).T for x in angles ] zaxis = np.array([[0., 0., 1.]]).T R = rotate_axis(zaxis, axis) points = np.vstack([(R.dot(p)).T for p in local_points]) all_points = np.vstack((origin, points)) vertextypes = np.vstack([np.ones((1, 1)), np.zeros((points.shape[0], 1))]) cdd_points = np.hstack((vertextypes, all_points)) mat = cdd.Matrix(cdd_points) mat.rep_type = cdd.RepType.GENERATOR poly = cdd.Polyhedron(mat) ineqs = np.array(poly.get_inequalities())[:-1, :] return ineqs
def test_vertex_incidence_cube(number_type): # The following lines test that poly.get_vertex_incidence() # returns the correct incidences. # We start with the H-representation for a cube mat = cdd.Matrix([[1, 1, 0, 0], [1, 0, 1, 0], [1, 0, 0, 1], [1, -1, 0, 0], [1, 0, -1, 0], [1, 0, 0, -1]], number_type=number_type) mat.rep_type = cdd.RepType.INEQUALITY poly = cdd.Polyhedron(mat) incidence = poly.get_incidence() # Family size should equal the number of vertices of the cube (8) assert len(incidence) == 8 # All the vertices of the cube should mark the incidence of 3 facets assert [len(inc) for inc in incidence] == [3] * 8 # The vertices must be numbered consistently # The first vertex is adjacent to the second, fourth and eighth # (note the conversion to a pythonic numbering system) incidence_list = [[1, 2, 3], [1, 3, 5], [3, 4, 5], [2, 3, 4], [0, 4, 5], [0, 2, 4], [0, 1, 5], [0, 1, 2]] for i in range(8): assert sorted(list(incidence[i])) == incidence_list[i]
def project_polytope_cdd(A, b, C, d, E, f): """ Project a polytope using cdd. The initial polytope is defined by: A * x <= b C * x == d (optional, disabled by setting C or d to None) The output (projection) is computed from: y = E * x + f See <http://www.roboticsproceedings.org/rss11/p28.pdf> for details. """ b = b.reshape((b.shape[0], 1)) # the input [b, -A] to cdd.Matrix represents (b - A * x >= 0) # see ftp://ftp.ifor.math.ethz.ch/pub/fukuda/cdd/cddlibman/node3.html linsys = cdd.Matrix(hstack([b, -A]), number_type='float') linsys.rep_type = cdd.RepType.INEQUALITY if C and d: # the input [d, -C] to cdd.Matrix.extend represents (d - C * x == 0) # see ftp://ftp.ifor.math.ethz.ch/pub/fukuda/cdd/cddlibman/node3.html d = d.reshape((d.shape[0], 1)) linsys.extend(hstack([d, -C]), linear=True) # Convert from H- to V-representation linsys.canonicalize() P = cdd.Polyhedron(linsys) generators = P.get_generators() # if generators.lin_set: # print "Generators have linear set:", generators.lin_set V = array(generators) # Project output wrenches to 2D set vertices, rays = [], [] free_coordinates = [] for i in xrange(V.shape[0]): # f_gi = dot(Gs, V[i, 1:])[:3] if generators.lin_set and i in generators.lin_set: free_coordinates.append(list(V[i, 1:]).index(1.)) elif V[i, 0] == 1: # vertex # p_Z = (z_Z - z_G) * f_gi / (- mass * 9.81) + p_G p_Z = dot(E, V[i, 1:]) + f vertices.append(p_Z) else: # ray # r_Z = (z_Z - z_G) * f_gi / (- mass * 9.81) r_Z = dot(E, V[i, 1:]) rays.append(r_Z) # print "Computed area (cdd): %d vertices, %d rays, %d free coordinates" \ # % (len(vertices), len(rays), len(free_coordinates)) # if free_coordinates: # print "Free coordinates: ", free_coordinates return vertices, rays
def qhull_convexify_polyhedron(hrep): gen = np.array(cdd.Polyhedron(hrep).get_generators()) #If the polygon is empty or degenerate, return 0 if gen.shape[0] < 3: return 0 points = gen[:, 1:].tolist() pout = convexHull(points) return np.array(pout)
def verts2ineqs(verts): 'computes (dense) inequalities from vertices' v = np.array(verts) # prepend 1 to denote vertices v = np.hstack((np.ones((v.shape[0], 1)), v)) V = cdd.Matrix(v, number_type=NT) V.rep_type = cdd.RepType.GENERATOR H = cdd.Polyhedron(V).get_inequalities() return np.array(H)
def ineqs2verts(ineqs): 'computes (dense) inequalities from vertices' h = np.array(ineqs) H = cdd.Matrix(h, number_type=NT) H.rep_type = cdd.RepType.INEQUALITY V = cdd.Polyhedron(H).get_generators() v, r = split_gens(V) assert r.size == 0, 'generating rays found: %s' % V return v
def check_all_inequalities(self, com_positions, poly): V = hstack([ones((len(poly), 1)), array(poly)]) M = cdd.Matrix(V, number_type='float') M.rep_type = cdd.RepType.GENERATOR P = cdd.Polyhedron(M) H = array(P.get_inequalities()) b, A = H[:, 0], H[:, 1:] for com in com_positions: if not all(dot(A, com[:2]) + b >= 0): raise Exception("Unstable CoM")
def cgal_convexify_polyhedron(hrep): gen = np.array(cdd.Polyhedron(hrep).get_generators()) #If the polygon is empty or degenerate, return 0 if gen.shape[0] < 3: return 0 points = [Point_3(x, y, z) for x, y, z in gen[:, 1:]] poly = Polyhedron_3() convex_hull_3(points, poly) lines = [np.array([as_list(p)]) for p in poly.points()] return np.vstack(lines)
def test_set_float_polyhedron_rep_type(): mat = cdd.Matrix([[1, 0, 1], [1, 1, 0], [1, 1, 1], [1, 0, 0]], number_type='float') mat.rep_type = cdd.RepType.GENERATOR poly = cdd.Polyhedron(mat) poly.rep_type = cdd.RepType.INEQUALITY assert(poly.rep_type == cdd.RepType.INEQUALITY) poly.rep_type = cdd.RepType.GENERATOR assert(poly.rep_type == cdd.RepType.GENERATOR)
def _test_sampleh1(number_type=None, assert_matrix_equal=None): mat = cdd.Matrix([[2, -1, -1, 0], [0, 1, 0, 0], [0, 0, 1, 0]], number_type=number_type) mat.rep_type = cdd.RepType.INEQUALITY poly = cdd.Polyhedron(mat) ext = poly.get_generators() nose.tools.assert_equal(ext.rep_type, cdd.RepType.GENERATOR) assert_matrix_equal(list(ext), [(1, 0, 0, 0), (1, 2, 0, 0), (1, 0, 2, 0), (0, 0, 0, 1)]) # note: first row is 0, so fourth row is 3 nose.tools.assert_equal(list(ext.lin_set), [3])
def find_direction(self, poly, plot=False): self.build_polys(poly) volumes = [] try: ineq = np.array(cdd.Polyhedron(poly.inner).get_inequalities()) except RuntimeError: raise SteppingException('Numerical inconsistency found') for line in ineq: key = hashlib.sha1(line).hexdigest() if key in poly.volume_dic: volumes.append(poly.volume_dic[key]) else: if key in poly.hrep_dic: A_e = poly.hrep_dic[key] else: A_e = poly.outer.copy() A_e.extend(cdd.Matrix(-line.reshape(1, line.size))) A_e.canonicalize() poly.hrep_dic[key] = A_e if plot: poly.reset_fig() poly.plot_polyhedrons() poly.plot_polyhedron(A_e, 'm', 0.5) poly.show() vol = self.volume_convex(A_e) poly.volume_dic[key] = vol volumes.append(vol) poly.vrep_dic[key] = np.array( cdd.Polyhedron(A_e).get_generators()) maxv = max(volumes) alli = [i for i, v in enumerate(volumes) if v == maxv] i = random.choice(alli) key = hashlib.sha1(ineq[i, :]).hexdigest() self.last_hrep = poly.hrep_dic[key] return -ineq[i, 1:]
def test_from_points(): A = np.array([[1, 0, 0], [1, 1, 0], [1, 0, 1]]) mat = cdd.Matrix(A.tolist(), number_type='fraction') mat.rep_type = cdd.RepType.GENERATOR cdd_poly = cdd.Polyhedron(mat) ineq = np.array(cdd_poly.get_inequalities()) ppl_poly = pyparma.Polyhedron(hrep=ineq) assert (equal_sorted(A, ppl_poly.vrep()))
def area_convex(hrep): try: gen = np.array(cdd.Polyhedron(hrep).get_generators()) except RuntimeError: # Whenever numerical inconsistency is found return 0 #If the polygon is empty or degenerate, return 0 if gen.shape[0] < 3: return 0 p = np.vstack([gen, gen[0, :]]) x, y = p[:, 1], p[:, 2] poly = geom.Polygon(list(zip(x, y))) return poly.convex_hull.area
def H_to_V(A, b): """ Converts a polyhedron in H-representation to one in V-representation using pycddlib. """ # define cdd problem and convert representation if len(b.shape) == 1: b = np.expand_dims(b, axis=1) mat_np = np.concatenate([b, -A], axis=1) if mat_np.dtype in [np.int32, np.int64]: nt = 'fraction' else: nt = 'float' mat_list = mat_np.tolist() mat_cdd = cdd.Matrix(mat_list, number_type=nt) mat_cdd.rep_type = cdd.RepType.INEQUALITY poly = cdd.Polyhedron(mat_cdd) gen = poly.get_generators() # convert the cddlib output data structure to numpy V_list = [] R_list = [] lin_set = gen.lin_set V_lin_idx = [] R_lin_idx = [] for i in range(gen.row_size): g = gen[i] g_type = g[0] g_vec = g[1:] if i in lin_set: is_linear = True else: is_linear = False if g_type == 1: V_list.append(g_vec) if is_linear: V_lin_idx.append(len(V_list) - 1) elif g_type == 0: R_list.append(g_vec) if is_linear: R_lin_idx.append(len(R_list) - 1) else: raise ValueError('Generator data structure is not valid.') V = np.asarray(V_list) R = np.asarray(R_list) # by convention of cddlib, those rays assciated with R_lin_idx # are not constrained to non-negative coefficients if len(R) > 0: R = np.concatenate([R, -R[R_lin_idx, :]], axis=0) return V, R
def get_v_representation(self, A, b): h_rep = np.append(b, -A, axis=1) #cdd needs [b -A] mat = cdd.Matrix(h_rep, number_type='float') mat.rep_type = cdd.RepType.INEQUALITY poly = cdd.Polyhedron(mat) dd = poly.get_generators() V = np.asarray(dd) return (V[:, 0] > 0.5), V[:, 1:]