The cdd module¶
Enums¶
- class cdd.RepType(value)¶
Bases:
IntEnumRepresentation. Use
INEQUALITYfor H-representation andGENERATORfor V-representation.
Classes¶
- class cdd.Matrix¶
A set of inequalities/equalities (H-representation) or a set of non-linear/linear generators (V-representation) described by an array \([b \quad A]\) and a row index set \(L\).
For this class,
rep_typedetermines the representation type,arraydetermines the array \([b \quad A]\), andlin_setdetermines the row index set \(L\).The H-representation corresponds to a polyhedron \(P\) formed by all points \(x\) satisfying
\[\begin{split}0&\le b_i + A_i x \qquad \forall i\notin L \\ 0&= b_i + A_i x \qquad \forall i\in L \\\end{split}\]where \(A_i\) denotes the \(i\)-th row of \(A\).
To understand the V-representation, first we need the concept of a halfspace. For any real number \(z_0\) and column vector \(z\), we define a halfspace as follows:
\[H_{z_0,z}^{\ge}=\{x\colon z_0+x^T z\ge 0\}\]Note that \(z\) is allowed to be the zero vector, in which case the halfspace is either the complete space (if \(z_0\ge 0\)) or the empty space (if \(z_0<0\)).
The V-representation corresponds to the polyhedron formed by the intersection of all halfspaces \(H_{z_0,z}^{\ge}\) satisfying
\[\begin{split}0&\le b_i z_0 + A_i z \qquad \forall i\notin L \\ 0&= b_i z_0 + A_i z \qquad \forall i\in L\end{split}\]A halfspace that satisfies these constraints is called feasible. The set of feasible halfspaces forms a convex cone, denoted \(Z\), in the \((z_0,z)\)-space. This cone has a dual:
\[Z^*=\{(x_0,x)\colon x_0z_0+x^Tz\ge 0\, \forall z\in Z\}\]In other words, the polyhedron described by the V-representation is the intersection of the dual cone \(Z^*\) and the hyperplane determined by \(x_0=1\):
\[P=Z^*\cap\{(x_0,x)\colon x_0=1\}\]To make this easier to visualize, by convention, each equation is divided by \(b_i\) if \(b_i\neq 0\), i.e.
\[\begin{split}[t_i \quad V_i]= \begin{cases} [0 \quad A_i]\text{ if }b_i=0 \\ [1 \quad A_i/b_i]\text{ if }b_i\neq 0 \end{cases}\end{split}\]This then leads to an array \([t \quad V]\), representing the same polyhedron \(P\) as \([b \quad A]\): indeed, \(H_{z_0,z}^{\ge}\) is feasible if and only if
\[\begin{split}0\le t_i z_0 + V_i z \qquad &\forall i\notin L \\ 0= t_i z_0 + V_i z \qquad &\forall i\in L\end{split}\]For any point of the form \(x=\sum_i \lambda_i V_i^T\), with \(\sum_i \lambda_i t_i=1\) and \(\lambda_i\ge 0\) for all \(i\notin L\), we have that \(x\) belongs to the polyhedron, because in that case
\[\begin{split}z_0+x^T z &= z_0 + \sum_i \lambda_i V_i z \\ &=\sum_i \lambda_i (t_i z_0 + V_i z) &\ge 0\end{split}\]It can be shown that this describes the entire polyhedron, i.e. the polyhedron in the V-representation is the set of points
\[P=\left\{ \sum_i \lambda_i V_i\colon \sum_{i} \lambda_i t_i=1 \text{ and } \forall i\notin L\colon\lambda_i\ge 0 \right\}\]For this reason, the \(V_i\) are called the generators of the polyhedron. By the Minkowski-Weyl theorem, without loss of generality, it can be assumed that \(i\notin L\) whenever \(t_i=1\). In that case,
\[P= \mathrm{conv}\{V_i\colon t_i=1\} +\mathrm{span}_{\ge}\{V_i\colon t_i=0,i\not\in L\} +\mathrm{span}\{V_i\colon t_i=0,i\in L\}\]where \(\mathrm{conv}\) is the convex hull operator, \(\mathrm{span}_{\ge}\) is the linear span operator with non-negative coefficients, and \(\mathrm{span}\) is the linear span operator with free coefficients.
The library will always output V-representations in this form, i.e. so that all components of the first column are zero or one, and so that \(L\) does not contain rows whose first component is one.
- class cdd.LinProg¶
A linear program: a set of inequalities and an objective function to optimize.
- array: Sequence[Sequence[float]]¶
The array representing the linear program. More specifically, the constraints \(0\le b+Ax\) and objective function \(\gamma + c^T x\) are stored as an array as follows:
\[\begin{split}\begin{array}{cc} b & A \\ \gamma & c \end{array}\end{split}\]i.e. the constraints are stored as a H-representation (with inequalities only), and the objective function is stored in the final row. Only inequality constraints are represented. Equality constraints can be represented by two opposing inequalities.
- dual_solution: Sequence[tuple[int, float]]¶
The optimal value of the dual variables, after solving. Only the non-basic components are given (the basic components are zero). They are returned as index-value pairs.
- solver: LPSolverType¶
The solver used when last solving the linear program.
- status: LPStatusType¶
The status of the linear program, after solving.
Factories¶
- cdd.matrix_from_array(array: Sequence[Sequence[SupportsFloat]], lin_set: Container[int] = (), rep_type: RepType = RepType.UNSPECIFIED, obj_type: LPObjType = LPObjType.NONE, obj_func: Sequence[SupportsFloat] | None = None) Matrix¶
Construct a matrix with the given attributes.
See
cdd.Matrix.arrayfor an explanation of how array must be laid out. This function also accepts 2-dimensional numpy arrays.
- cdd.linprog_from_array(array: Sequence[Sequence[SupportsFloat]], obj_type: LPObjType) LinProg¶
Construct a linear program from array.
See
cdd.LinProg.arrayfor an explanation of how array must be laid out. This function also accepts 2-dimensional numpy arrays.Added in version 3.0.0.
- cdd.linprog_from_matrix(mat: Matrix) LinProg¶
Convert mat into a linear program. Note that mat must have the H-representation, and its objective type must be set, otherwise a
ValueErroris raised.
- cdd.polyhedron_from_matrix(mat: Matrix, row_order: RowOrderType | None = None) Polyhedron¶
Run the double description method to convert mat into a polyhedron, using row_order if specified.
Added in version 3.0.0: The row_order parameter.
Basic Operations¶
- cdd.matrix_append_to(mat1: Matrix, mat2: Matrix) None¶
Append mat2 to mat1.
A
ValueErroris raised if the column sizes are unequal.
Adjacencies¶
- cdd.matrix_adjacency(mat: Matrix) Sequence[Set[int]]¶
Generate the input adjacency of the polyhedron represented by mat.
H-representation: For each face, list adjacent faces. V-representation: For each vertex, list adjacent vertices.
Note
The implementation uses linear programming, instead of the double description method, so this function should work for large scale problems.
See also
The
copy_input_adjacency()function performs a similar operation, using the double description method.Warning
This function assumes that the matrix has no redundancies. Call
matrix_canonicalize()first if need be.Added in version 3.0.0.
- cdd.matrix_weak_adjacency(mat: Matrix) Sequence[Set[int]]¶
Generate the weak input adjacency of the polyhedron represented by mat.
H-representation: For each face, list adjacent faces. V-representation: For each vertex, list adjacent vertices.
Note
The implementation uses linear programming, instead of the double description method, so this function should work for large scale problems.
See also
The
copy_input_adjacency()function performs a similar operation, using the double description method.Warning
This function assumes that the matrix has no redundancies. Call
matrix_canonicalize()first if need be.Added in version 3.0.0.
Canonicalization¶
- cdd.matrix_canonicalize(mat: Matrix) tuple[Set[int], Set[int], Sequence[int | None]]¶
Transform to canonical representation by recognizing all implicit linearities and all redundancies. These are returned as a pair of sets of row indices, along with a sequence of new row positions (
Nonefor removed rows).This function has the same effect as calling
matrix_canonicalize_linearity()followed bymatrix_redundancy_remove().Added in version 1.0.3.
Changed in version 3.0.0: Also return new row positions.
- cdd.matrix_canonicalize_linearity(mat: Matrix) tuple[Set[int], Sequence[int | None]]¶
Add all implicit linearities to the
lin_set, and then remove all redundant linearities (e.g. everything inlin_set), by finding a basis for the linearity rows.Returns implicit linearities as a sets of row indices, along with a sequence of new row positions (
Nonefor removed rows).Added in version 3.0.0.
Redundancy Checks¶
- cdd.redundant(mat: Matrix, row: int) Sequence[float] | None¶
A certificate in case row is not redundant for mat, otherwise
None.A row is redundant in the H- or V-representation if its removal does not affect the polyhedron.
For the H-representation, the “no redundancy” certificate \(x\) is a solution that satisfies all constraints but violates row, i.e.
\[\begin{split}0&> b_j+A_j x \\ 0&\le b_i+A_i x \qquad\forall i\notin L,\,i\neq j \\ 0&= b_i+A_i x \qquad\forall i\in L,\,i\neq j\end{split}\]For the V-representation, the “no redundancy” certificate \((z_0,z)\) is a halfspace \(H_{z_0,z}^{\ge}\) that contains all generators but does not contain row, i.e.
\[\begin{split}0&> b_j z_0 + A_j z \\ 0&\le b_i z_0 + A_i z \qquad\forall i\notin L,\,i\neq j \\ 0&= b_i z_0 + A_i z \qquad\forall i\in L,\,i\neq j\end{split}\]Warning
Linearity rows are not checked i.e. row should not be in the
lin_set.Added in version 3.0.0.
- cdd.s_redundant(mat: Matrix, row: int) Sequence[float] | None¶
A certificate in case row is not strongly redundant for mat, otherwise
None.A row is strongly redundant in the H-representation if every point in the polyhedron satisfies it with strict inequality. A row is strongly redundant in the V-representation if it is in the relative interior of the polyhedron.
For the H-representation, the “no strong redundancy” certificate \(x\) is a feasible solution satisfying the constraint row with equality, i.e.
\[\begin{split}0&= b_j+A_j x \\ 0&\le b_i+A_i x \qquad\forall i\notin L,\,i\neq j \\ 0&= b_i+A_i x \qquad\forall i\in L,\,i\neq j\end{split}\]For the V-representation, the “no strong redundancy” certificate \((z_0,z)\) is a feasible halfspace \(H_{z_0,z}^{\ge}\) that contains the generator row on its edge, i.e.
\[\begin{split}0&= b_j z_0 + A_j z \\ 0&\le b_i z_0 + A_i z \qquad\forall i\notin L,\,i\neq j \\ 0&= b_i z_0 + A_i z \qquad\forall i\in L,\,i\neq j\end{split}\]Warning
Linearity rows are not checked i.e. row should not be in the
lin_set.Added in version 3.0.0.
- cdd.implicit_linearity(mat: Matrix, row: int) Sequence[float] | None¶
A certificate in case row is not implicitly linear for mat, otherwise
None.A row is implicitly linear in the H- or V-representation if adding it to the linearity set
lin_setdoes not affect the polyhedron.For the H-representation, the “no implicit linearity” certificate \(x\) is a feasible solution satisfying inequality row with strict inequality, i.e.
\[\begin{split}0&< b_j+A_j x \\ 0&\le b_i+A_i x \qquad\forall i\notin L,\,i\neq j \\ 0&= b_i+A_i x \qquad\forall i\in L,\,i\neq j\end{split}\]For the V-representation, the “no implicit linearity” certificate \((z_0,z)\) is a feasible halfspace \(H_{z_0,z}^{\ge}\) that strictly contains the generator row, i.e.
\[\begin{split}0&< b_j z_0 + A_j z \\ 0&\le b_i z_0 + A_i z \qquad\forall i\notin L,\,i\neq j \\ 0&= b_i z_0 + A_i z \qquad\forall i\in L,\,i\neq j\end{split}\]Warning
Linearity rows are not checked i.e. row should not be in the
lin_set.Added in version 3.0.0.
- cdd.redundant_rows(mat: Matrix) Set[int]¶
Returns all non-linearity rows that are redundant for mat.
Added in version 3.0.0.
Linear Programming¶
- cdd.linprog_solve(lp: LinProg, solver: LPSolverType = LPSolverType.DUAL_SIMPLEX) None¶
Solve the linear program lp using solver.
Polyhedron Operations¶
- cdd.copy_input(poly: Polyhedron) Matrix¶
Returns the original matrix that the polyhedron was constructed from.
Added in version 3.0.0.
- cdd.copy_output(poly: Polyhedron) Matrix¶
Returns the dual representation of the original matrix. If the original was a H-representation, this will return its V-representation, and vice versa.
Note
The output is not guaranteed to be minimal, that is, it can still contain redundancy. Use
matrix_canonicalize()on the output to remove redundancies.Added in version 3.0.0.
- cdd.copy_inequalities(poly: Polyhedron) Matrix¶
Copy a H-representation of the inequalities.
- cdd.copy_generators(poly: Polyhedron) Matrix¶
Copy a V-representation of all the generators.
- cdd.copy_adjacency(poly: Polyhedron) Sequence[Set[int]]¶
Get the adjacencies.
H-representation: For each vertex, list adjacent vertices. V-representation: For each face, list adjacent faces.
Added in version 2.1.1.
- cdd.copy_incidence(poly: Polyhedron) Sequence[Set[int]]¶
Get the incidences.
H-representation: For each vertex, list adjacent faces. V-representation: For each face, list adjacent vertices.
Added in version 2.1.1.
- cdd.copy_input_adjacency(poly: Polyhedron) Sequence[Set[int]]¶
Get the input adjacencies.
H-representation: For each face, list adjacent faces. V-representation: For each vertex, list adjacent vertices.
See also
The
matrix_adjacency()andmatrix_weak_adjacency()functions perform a similar operation, using linear programming.Added in version 2.1.1.
- cdd.copy_input_incidence(poly: Polyhedron) Sequence[Set[int]]¶
Get the input incidences.
H-representation: For each face, list adjacent vertices. V-representation: For each vertex, list adjacent faces.
Added in version 2.1.1.
Elimination¶
- cdd.fourier_elimination(mat: Matrix) Matrix¶
Eliminate the last variable from the system of linear inequalities mat.
Warning
This implementation can only handle inequality constraints. If your system has equality constraints, either convert them into pairs of inequalities first, or use
block_elimination()instead.Note
The output is not guaranteed to be minimal, that is, it can still contain redundancy. Use
matrix_canonicalize()on the output to remove redundancies.Added in version 3.0.0.
- cdd.block_elimination(mat: Matrix, col_set: Container[int]) Matrix¶
Eliminate the variables col_set from the system of linear inequalities mat. It does this by using the generators of the dual linear system, where the generators are calculated using the double description algorithm.
Note
The output is not guaranteed to be minimal, that is, it can still contain redundancy. Use
matrix_canonicalize()on the output to remove redundancies.Added in version 3.0.0.