This module implements the double description algorithm for extremal vertex enumeration in a pointed cone following [FukudaProdon]. With a little bit of preprocessing (see double_description_inhomogeneous) this defines a backend for polyhedral computations. But as far as this module is concerned, inequality always means without a constant term and the origin is always a point of the cone.
EXAMPLES:
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
sage: A = matrix(QQ, [(1,0,1), (0,1,1), (-1,-1,1)])
sage: alg = StandardAlgorithm(A); alg
Pointed cone with inequalities
(1, 0, 1)
(0, 1, 1)
(-1, -1, 1)
sage: DD, _ = alg.initial_pair(); DD
Double description pair (A, R) defined by
[ 1 0 1] [ 2/3 -1/3 -1/3]
A = [ 0 1 1], R = [-1/3 2/3 -1/3]
[-1 -1 1] [ 1/3 1/3 1/3]
The implementation works over any exact field that is embedded in
, for example:
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
sage: A = matrix(AA, [(1,0,1), (0,1,1), (-AA(2).sqrt(),-AA(3).sqrt(),1),
....: (-AA(3).sqrt(),-AA(2).sqrt(),1)])
sage: alg = StandardAlgorithm(A)
sage: alg.run().R
((-0.4177376677004119?, 0.5822623322995881?, 0.4177376677004119?),
(-0.2411809548974793?, -0.2411809548974793?, 0.2411809548974793?),
(0.07665629029830300?, 0.07665629029830300?, 0.2411809548974793?),
(0.5822623322995881?, -0.4177376677004119?, 0.4177376677004119?))
REFERENCES:
[FukudaProdon] | (1, 2) Komei Fukuda , Alain Prodon: Double Description Method Revisited, Combinatorics and Computer Science, volume 1120 of Lecture Notes in Computer Science, page 91-111. Springer (1996) |
Bases: sage.structure.sage_object.SageObject
Base class for a double description pair
Warning
You should use the Problem.initial_pair() or Problem.run() to generate double description pairs for a set of inequalities, and not generate DoubleDescriptionPair instances directly.
INPUT:
TESTS:
sage: from sage.geometry.polyhedron.double_description import \
....: DoubleDescriptionPair, Problem
sage: A = matrix(QQ, [(1,0,1), (0,1,1), (-1,-1,1)])
sage: alg = Problem(A)
sage: DoubleDescriptionPair(alg,
....: [(1, 0, 1), (0, 1, 1), (-1, -1, 1)],
....: [(2/3, -1/3, 1/3), (-1/3, 2/3, 1/3), (-1/3, -1/3, 1/3)])
Double description pair (A, R) defined by
[ 1 0 1] [ 2/3 -1/3 -1/3]
A = [ 0 1 1], R = [-1/3 2/3 -1/3]
[-1 -1 1] [ 1/3 1/3 1/3]
Classify the rays into those that are positive, zero, and negative on .
INPUT:
OUTPUT:
A triple consisting of the rays (columns of ) that are
positive, zero, and negative on
. In that order.
EXAMPLES:
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
sage: A = matrix(QQ, [(1,0,1), (0,1,1), (-1,-1,1)])
sage: DD, _ = StandardAlgorithm(A).initial_pair()
sage: DD.R_by_sign(vector([1,-1,0]))
([(2/3, -1/3, 1/3)], [(-1/3, -1/3, 1/3)], [(-1/3, 2/3, 1/3)])
sage: DD.R_by_sign(vector([1,1,1]))
([(2/3, -1/3, 1/3), (-1/3, 2/3, 1/3)], [], [(-1/3, -1/3, 1/3)])
Return whether the two rays are adjacent.
INPUT:
OUTPUT:
Boolean. Whether the two rays are adjacent.
EXAMPLES:
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
sage: A = matrix(QQ, [(0,1,0), (1,0,0), (0,-1,1), (-1,0,1)])
sage: DD = StandardAlgorithm(A).run()
sage: DD.are_adjacent(DD.R[0], DD.R[1])
True
sage: DD.are_adjacent(DD.R[0], DD.R[2])
True
sage: DD.are_adjacent(DD.R[0], DD.R[3])
False
Return the cone defined by .
This method is for debugging only. Assumes that the base ring
is .
OUTPUT:
The cone defined by the inequalities as a Polyhedron(), using the PPL backend.
EXAMPLES:
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
sage: A = matrix(QQ, [(1,0,1), (0,1,1), (-1,-1,1)])
sage: DD, _ = StandardAlgorithm(A).initial_pair()
sage: DD.cone().Hrepresentation()
(An inequality (-1, -1, 1) x + 0 >= 0,
An inequality (0, 1, 1) x + 0 >= 0,
An inequality (1, 0, 1) x + 0 >= 0)
Return the dual.
OUTPUT:
For the double description pair this method returns
the dual double description pair
EXAMPLES:
sage: from sage.geometry.polyhedron.double_description import Problem
sage: A = matrix(QQ, [(0,1,0), (1,0,0), (0,-1,1), (-1,0,1)])
sage: DD, _ = Problem(A).initial_pair()
sage: DD
Double description pair (A, R) defined by
[ 0 1 0] [0 1 0]
A = [ 1 0 0], R = [1 0 0]
[ 0 -1 1] [1 0 1]
sage: DD.dual()
Double description pair (A, R) defined by
[0 1 1] [ 0 1 0]
A = [1 0 0], R = [ 1 0 -1]
[0 0 1] [ 0 0 1]
Restrict to the first coordinate plane.
OUTPUT:
A new double description pair with the constraint
added.
EXAMPLES:
sage: A = matrix([(1, 1), (-1, 1)])
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
sage: DD, _ = StandardAlgorithm(A).initial_pair()
sage: DD
Double description pair (A, R) defined by
A = [ 1 1], R = [ 1/2 -1/2]
[-1 1] [ 1/2 1/2]
sage: DD.first_coordinate_plane()
Double description pair (A, R) defined by
[ 1 1]
A = [-1 1], R = [ 0]
[-1 0] [1/2]
[ 1 0]
Return the inner product matrix between the rows of
and the columns of
.
OUTPUT:
A matrix over the base ring. There is one row for each row of
and one column for each column of
.
EXAMPLES:
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
sage: A = matrix(QQ, [(1,0,1), (0,1,1), (-1,-1,1)])
sage: alg = StandardAlgorithm(A)
sage: DD, _ = alg.initial_pair()
sage: DD.inner_product_matrix()
[1 0 0]
[0 1 0]
[0 0 1]
Test whether the ray is extremal.
EXAMPLES:
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
sage: A = matrix(QQ, [(0,1,0), (1,0,0), (0,-1,1), (-1,0,1)])
sage: DD = StandardAlgorithm(A).run()
sage: DD.is_extremal(DD.R[0])
True
Validate the double description pair.
This method used the PPL backend to check that the double
description pair is valid. An assertion is triggered if it is
not. Does nothing if the base ring is not .
EXAMPLES:
sage: from sage.geometry.polyhedron.double_description import \
....: DoubleDescriptionPair, Problem
sage: A = matrix(QQ, [(1,0,1), (0,1,1), (-1,-1,1)])
sage: alg = Problem(A)
sage: DD = DoubleDescriptionPair(alg,
....: [(1, 0, 3), (0, 1, 1), (-1, -1, 1)],
....: [(2/3, -1/3, 1/3), (-1/3, 2/3, 1/3), (-1/3, -1/3, 1/3)])
sage: DD.verify()
Traceback (most recent call last):
...
assert A_cone == R_cone
AssertionError
Return the zero set (active set) .
INPUT:
OUTPUT:
A tuple containing the inequality vectors that are zero on ray.
EXAMPLES:
sage: from sage.geometry.polyhedron.double_description import Problem
sage: A = matrix(QQ, [(1,0,1), (0,1,1), (-1,-1,1)])
sage: DD, _ = Problem(A).initial_pair()
sage: r = DD.R[0]; r
(2/3, -1/3, 1/3)
sage: DD.zero_set(r)
((0, 1, 1), (-1, -1, 1))
Bases: sage.structure.sage_object.SageObject
Base class for implementations of the double description algorithm
It does not make sense to instantiate the base class directly, it just provides helpers for implementations.
INPUT:
TESTS:
sage: A = matrix([(1, 1), (-1, 1)])
sage: from sage.geometry.polyhedron.double_description import Problem
sage: Problem(A)
Pointed cone with inequalities
(1, 1)
(-1, 1)
Return the rows of the defining matrix .
OUTPUT:
The matrix whose rows are the inequalities.
EXAMPLES:
sage: A = matrix([(1, 1), (-1, 1)])
sage: from sage.geometry.polyhedron.double_description import Problem
sage: Problem(A).A()
((1, 1), (-1, 1))
Return the defining matrix .
OUTPUT:
Matrix whose rows are the inequalities.
EXAMPLES:
sage: A = matrix([(1, 1), (-1, 1)])
sage: from sage.geometry.polyhedron.double_description import Problem
sage: Problem(A).A_matrix()
[ 1 1]
[-1 1]
Return the base field.
OUTPUT:
A field.
EXAMPLES:
sage: A = matrix(AA, [(1, 1), (-1, 1)])
sage: from sage.geometry.polyhedron.double_description import Problem
sage: Problem(A).base_ring()
Algebraic Real Field
Return the ambient space dimension.
OUTPUT:
Integer. The ambient space dimension of the cone.
EXAMPLES:
sage: A = matrix(QQ, [(1, 1), (-1, 1)])
sage: from sage.geometry.polyhedron.double_description import Problem
sage: Problem(A).dim()
2
Return an initial double description pair.
Picks an initial set of rays by selecting a basis. This is probably the most efficient way to select the initial set.
INPUT:
OUTPUT:
A pair consisting of a DoubleDescriptionPair instance and the tuple of remaining unused inequalities.
EXAMPLES:
sage: A = matrix([(-1, 1), (-1, 2), (1/2, -1/2), (1/2, 2)])
sage: from sage.geometry.polyhedron.double_description import Problem
sage: DD, remaining = Problem(A).initial_pair()
sage: DD.verify()
sage: remaining
[(1/2, -1/2), (1/2, 2)]
alias of DoubleDescriptionPair
Bases: sage.geometry.polyhedron.double_description.Problem
Standard implementation of the double description algorithm
See [FukudaProdon] for the definition of the “Standard Algorithm”.
EXAMPLES:
sage: A = matrix(QQ, [(1, 1), (-1, 1)])
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
sage: DD = StandardAlgorithm(A).run()
sage: DD.R # the extremal rays
((1/2, 1/2), (-1/2, 1/2))
alias of StandardDoubleDescriptionPair
Run the Standard Algorithm.
OUTPUT:
A double description pair of all inequalities as a
DoubleDescriptionPair. By virtue of the double
description algorithm, the columns of
are the extremal
rays.
EXAMPLES:
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
sage: A = matrix(QQ, [(0,1,0), (1,0,0), (0,-1,1), (-1,0,1)])
sage: StandardAlgorithm(A).run()
Double description pair (A, R) defined by
[ 0 1 0] [0 0 1 1]
A = [ 1 0 0], R = [1 0 1 0]
[ 0 -1 1] [1 1 1 1]
[-1 0 1]
Bases: sage.geometry.polyhedron.double_description.DoubleDescriptionPair
Double description pair for the “Standard Algorithm”.
See StandardAlgorithm.
TESTS:
sage: A = matrix([(-1, 1, 0), (-1, 2, 1), (1/2, -1/2, -1)])
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
sage: DD, _ = StandardAlgorithm(A).initial_pair()
sage: type(DD)
<class 'sage.geometry.polyhedron.double_description.StandardDoubleDescriptionPair'>
Return a new double description pair with the inequality added.
INPUT:
OUTPUT:
A new StandardDoubleDescriptionPair instance.
EXAMPLES:
sage: A = matrix([(-1, 1, 0), (-1, 2, 1), (1/2, -1/2, -1)])
sage: from sage.geometry.polyhedron.double_description import StandardAlgorithm
sage: DD, _ = StandardAlgorithm(A).initial_pair()
sage: newDD = DD.add_inequality(vector([1,0,0])); newDD
Double description pair (A, R) defined by
[ -1 1 0] [ 1 1 0 0]
A = [ -1 2 1], R = [ 1 1 1 1]
[ 1/2 -1/2 -1] [ 0 -1 -1/2 -2]
[ 1 0 0]
Random collections of inequalities for testing purposes.
INPUT:
OUTPUT:
A random set of inequalites as a StandardAlgorithm instance.
EXAMPLES:
sage: from sage.geometry.polyhedron.double_description import random_inequalities
sage: P = random_inequalities(5, 10)
sage: P.run().verify()