- ALGORITHM:
-
- The codimension formula from the second reference is used. We find
- all pairs `(x,s)` in the complementarity set of `K` such that `x`
- and `s` are rays of our cone. It is known that these vectors are
- sufficient to apply the codimension formula. Once we have all such
- pairs, we "brute force" the codimension formula by finding all
- linearly-independent `xs^{T}`.
-
- REFERENCES:
-
- .. [Gowda/Tao] M.S. Gowda and J. Tao. On the bilinearity rank of
- a proper cone and Lyapunov-like transformations. Mathematical
- Programming, 147 (2014) 155-170.
-
- M. Orlitzky. The Lyapunov rank of an improper cone.
- http://www.optimization-online.org/DB_HTML/2015/10/5135.html
-
- G. Rudolf, N. Noyan, D. Papp, and F. Alizadeh, Bilinear
- optimality constraints for the cone of positive polynomials,
- Mathematical Programming, Series B, 129 (2011) 5-31.
-
- EXAMPLES:
-
- The nonnegative orthant in `\mathbb{R}^{n}` always has rank `n`
- [Rudolf]_::
-
- sage: positives = Cone([(1,)])
- sage: lyapunov_rank(positives)
- 1
- sage: quadrant = Cone([(1,0), (0,1)])
- sage: lyapunov_rank(quadrant)
- 2
- sage: octant = Cone([(1,0,0), (0,1,0), (0,0,1)])
- sage: lyapunov_rank(octant)
- 3
-
- The full space `\mathbb{R}^{n}` has Lyapunov rank `n^{2}`
- [Orlitzky]_::
-
- sage: R5 = VectorSpace(QQ, 5)
- sage: gs = R5.basis() + [ -r for r in R5.basis() ]
- sage: K = Cone(gs)
- sage: lyapunov_rank(K)
- 25
-
- The `L^{3}_{1}` cone is known to have a Lyapunov rank of one
- [Rudolf]_::
-
- sage: L31 = Cone([(1,0,1), (0,-1,1), (-1,0,1), (0,1,1)])
- sage: lyapunov_rank(L31)
- 1
-
- Likewise for the `L^{3}_{\infty}` cone [Rudolf]_::
-
- sage: L3infty = Cone([(0,1,1), (1,0,1), (0,-1,1), (-1,0,1)])
- sage: lyapunov_rank(L3infty)
- 1
-
- A single ray in `n` dimensions should have Lyapunov rank `n^{2} - n
- + 1` [Orlitzky]_::
-
- sage: K = Cone([(1,0,0,0,0)])
- sage: lyapunov_rank(K)
- 21
- sage: K.lattice_dim()**2 - K.lattice_dim() + 1
- 21
-
- A subspace (of dimension `m`) in `n` dimensions should have a
- Lyapunov rank of `n^{2} - m\left(n - m)` [Orlitzky]_::
-
- sage: e1 = (1,0,0,0,0)
- sage: neg_e1 = (-1,0,0,0,0)
- sage: e2 = (0,1,0,0,0)
- sage: neg_e2 = (0,-1,0,0,0)
- sage: z = (0,0,0,0,0)
- sage: K = Cone([e1, neg_e1, e2, neg_e2, z, z, z])
- sage: lyapunov_rank(K)
- 19
- sage: K.lattice_dim()**2 - K.dim()*K.codim()
- 19
-
- The Lyapunov rank should be additive on a product of proper cones
- [Rudolf]_::
-
- sage: L31 = Cone([(1,0,1), (0,-1,1), (-1,0,1), (0,1,1)])
- sage: octant = Cone([(1,0,0), (0,1,0), (0,0,1)])
- sage: K = L31.cartesian_product(octant)
- sage: lyapunov_rank(K) == lyapunov_rank(L31) + lyapunov_rank(octant)
- True