- The calculation of the Lyapunov rank of an improper cone can be
- reduced to that of a proper cone [Orlitzky/Gowda]_::
-
- sage: K = random_cone(max_dim=15, solid=False, strictly_convex=False)
- sage: actual = lyapunov_rank(K)
- sage: (phi1, _) = span_iso(K)
- sage: K_S = phi1(K)
- sage: (phi2, _) = span_iso(K_S.dual())
- sage: J_T = phi2(K_S.dual()).dual()
- sage: l = K.linear_subspace().dimension()
- sage: codim = K.lattice_dim() - K.dim()
- sage: expected = lyapunov_rank(J_T) + K.dim()*(l + codim) + codim**2
- sage: actual == expected
+ Technically we could test this, but for now only closed convex cones
+ are supported as our ``K`` argument::
+
+ sage: L = identity_matrix(3)
+ sage: K = [ vector([2,2,-1]), vector([5,4,-3]) ]
+ sage: is_lyapunov_like_on(L,K)
+ Traceback (most recent call last):
+ ...
+ TypeError: K must be a Cone.
+
+ We can't give reliable answers over inexact rings::
+
+ sage: K = Cone([(1,2,3), (4,5,6)])
+ sage: L = identity_matrix(RR,3)
+ sage: is_lyapunov_like_on(L,K)
+ Traceback (most recent call last):
+ ...
+ ValueError: The base ring of L is neither SR nor exact.
+
+ An operator is Lyapunov-like on a cone if and only if both the
+ operator and its negation are cross-positive on the cone::
+
+ sage: K = random_cone(max_ambient_dim=5)
+ sage: R = K.lattice().vector_space().base_ring()
+ sage: L = random_matrix(R, K.lattice_dim())
+ sage: actual = is_lyapunov_like_on(L,K) # long time
+ sage: expected = (is_cross_positive_on(L,K) and # long time
+ ....: is_cross_positive_on(-L,K)) # long time
+ sage: actual == expected # long time