- sage: K = Cone([(2,2,4), (-1,9,0), (2,0,6)])
- sage: lyapunov_rank(K) == lyapunov_rank(K.dual())
- True
-
- TESTS:
-
- The Lyapunov rank should be additive on a product of proper cones
- [Rudolf et al.]_::
-
- sage: set_random_seed()
- sage: K1 = random_cone(max_dim=8, strictly_convex=True, solid=True)
- sage: K2 = random_cone(max_dim=8, strictly_convex=True, solid=True)
- sage: K = K1.cartesian_product(K2)
- sage: lyapunov_rank(K) == lyapunov_rank(K1) + lyapunov_rank(K2)
- True
-
- The Lyapunov rank is invariant under a linear isomorphism
- [Orlitzky/Gowda]_::
-
- sage: K1 = random_cone(max_dim = 8)
- sage: A = random_matrix(QQ, K1.lattice_dim(), algorithm='unimodular')
- sage: K2 = Cone( [ A*r for r in K1.rays() ], lattice=K1.lattice())
- sage: lyapunov_rank(K1) == lyapunov_rank(K2)
- True
-
- Just to be sure, test a few more::
-
- sage: K1 = random_cone(max_dim=8, strictly_convex=True, solid=True)
- sage: A = random_matrix(QQ, K1.lattice_dim(), algorithm='unimodular')
- sage: K2 = Cone( [ A*r for r in K1.rays() ], lattice=K1.lattice())
- sage: lyapunov_rank(K1) == lyapunov_rank(K2)
- True
-
- ::
-
- sage: K1 = random_cone(max_dim=8, strictly_convex=True, solid=False)
- sage: A = random_matrix(QQ, K1.lattice_dim(), algorithm='unimodular')
- sage: K2 = Cone( [ A*r for r in K1.rays() ], lattice=K1.lattice())
- sage: lyapunov_rank(K1) == lyapunov_rank(K2)
- True
-
- ::
-
- sage: K1 = random_cone(max_dim=8, strictly_convex=False, solid=True)
- sage: A = random_matrix(QQ, K1.lattice_dim(), algorithm='unimodular')
- sage: K2 = Cone( [ A*r for r in K1.rays() ], lattice=K1.lattice())
- sage: lyapunov_rank(K1) == lyapunov_rank(K2)
- True
-
- ::
-
- sage: K1 = random_cone(max_dim=8, strictly_convex=False, solid=False)
- sage: A = random_matrix(QQ, K1.lattice_dim(), algorithm='unimodular')
- sage: K2 = Cone( [ A*r for r in K1.rays() ], lattice=K1.lattice())
- sage: lyapunov_rank(K1) == lyapunov_rank(K2)
- True
-
- The dual cone `K^{*}` of ``K`` should have the same Lyapunov rank as ``K``
- itself [Rudolf et al.]_::
-
- sage: set_random_seed()
- sage: K = random_cone(max_dim=8)
- sage: lyapunov_rank(K) == lyapunov_rank(K.dual())
- True
-
- Make sure we exercise the non-strictly-convex/non-solid case::
-
- sage: set_random_seed()
- sage: K = random_cone(max_dim=8, strictly_convex=False, solid=False)
- sage: lyapunov_rank(K) == lyapunov_rank(K.dual())
- True
-
- Let's check the other permutations as well, just to be sure::
-
- sage: set_random_seed()
- sage: K = random_cone(max_dim=8, strictly_convex=False, solid=True)
- sage: lyapunov_rank(K) == lyapunov_rank(K.dual())
- True
-
- ::
-
- sage: set_random_seed()
- sage: K = random_cone(max_dim=8, strictly_convex=True, solid=False)
- sage: lyapunov_rank(K) == lyapunov_rank(K.dual())
- True
-
- ::
-
- sage: set_random_seed()
- sage: K = random_cone(max_dim=8, strictly_convex=True, solid=True)
- sage: lyapunov_rank(K) == lyapunov_rank(K.dual())
- True
-
- The Lyapunov rank of a proper polyhedral cone in `n` dimensions can
- be any number between `1` and `n` inclusive, excluding `n-1`
- [Gowda/Tao]_. By accident, the `n-1` restriction will hold for the
- trivial cone in a trivial space as well. However, in zero dimensions,
- the Lyapunov rank of the trivial cone will be zero::
-
- sage: set_random_seed()
- sage: K = random_cone(max_dim=8, strictly_convex=True, solid=True)
- sage: b = lyapunov_rank(K)
- sage: n = K.lattice_dim()
- sage: (n == 0 or 1 <= b) and b <= n
+ sage: K = Cone([(1,0),(0,1)])
+ sage: Z_transformation_gens(K)
+ [
+ [ 0 -1] [ 0 0] [-1 0] [1 0] [ 0 0] [0 0]
+ [ 0 0], [-1 0], [ 0 0], [0 0], [ 0 -1], [0 1]
+ ]
+ sage: K = Cone([(1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1)])
+ sage: all([ z[i][j] <= 0 for z in Z_transformation_gens(K)
+ ....: for i in range(z.nrows())
+ ....: for j in range(z.ncols())
+ ....: if i != j ])