- In the references, the cones are always assumed to be proper. We
- do not impose this restriction.
-
- .. seealso::
-
- :meth:`is_proper`
-
- 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.
-
- .. [Orlitzky/Gowda] M. Orlitzky and M. S. Gowda. The Lyapunov Rank of an
- Improper Cone. Work in-progress.
-
- .. [Rudolf et al.] 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 et al.]_::
-
- 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/Gowda]_::
-
- 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 et al.]_::
-
- 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 et al.]_::
-
- 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/Gowda]_::
-
- 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/Gowda]_::
-
- 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()*codim(K)
- 19
-
- The Lyapunov rank should be additive on a product of proper cones
- [Rudolf et al.]_::
-
- 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)