- The inner product `\left< L\left(x\right), s \right>` is zero for
- every pair `\left( x,s \right)` in the discrete complementarity set
- of the cone::
-
- sage: K = random_cone(max_dim=8, max_rays=10)
- sage: C_of_K = discrete_complementarity_set(K)
- sage: l = [ (L*x).inner_product(s) for (x,s) in C_of_K for L in LL(K) ]
- sage: sum(map(abs, l))
- 0
-
- Try the formula in my paper::
-
- sage: K = random_cone(max_dim=15, max_rays=25)
- sage: actual = lyapunov_rank(K)
- sage: K_S = project_span(K)
- sage: J_T1 = project_span(K, K_S.dual())
- sage: J_T2 = project_span(K_S.dual()).dual()
- sage: J_T2 = Cone(J_T2.rays(), lattice=J_T1.lattice())
- sage: J_T1 == J_T2
- True
- sage: J_T = J_T1
- 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
+ Each positive operator generator should send the generators of the
+ cone into the cone::
+
+ sage: set_random_seed()
+ sage: K = random_cone(max_ambient_dim=4)
+ sage: pi_of_K = positive_operator_gens(K)
+ sage: all([ K.contains(P*x) for P in pi_of_K for x in K ])
+ True
+
+ Each positive operator generator should send a random element of the
+ cone into the cone::
+
+ sage: set_random_seed()
+ sage: K = random_cone(max_ambient_dim=4)
+ sage: pi_of_K = positive_operator_gens(K)
+ sage: all([ K.contains(P*K.random_element(QQ)) for P in pi_of_K ])
+ True
+
+ A random element of the positive operator cone should send the
+ generators of the cone into the cone::
+
+ sage: set_random_seed()
+ sage: K = random_cone(max_ambient_dim=4)
+ sage: pi_of_K = positive_operator_gens(K)
+ sage: L = ToricLattice(K.lattice_dim()**2)
+ sage: pi_cone = Cone([ g.list() for g in pi_of_K ],
+ ....: lattice=L,
+ ....: check=False)
+ sage: P = matrix(K.lattice_dim(), pi_cone.random_element(QQ).list())
+ sage: all([ K.contains(P*x) for x in K ])
+ True
+
+ A random element of the positive operator cone should send a random
+ element of the cone into the cone::
+
+ sage: set_random_seed()
+ sage: K = random_cone(max_ambient_dim=4)
+ sage: pi_of_K = positive_operator_gens(K)
+ sage: L = ToricLattice(K.lattice_dim()**2)
+ sage: pi_cone = Cone([ g.list() for g in pi_of_K ],
+ ....: lattice=L,
+ ....: check=False)
+ sage: P = matrix(K.lattice_dim(), pi_cone.random_element(QQ).list())
+ sage: K.contains(P*K.random_element(ring=QQ))
+ True
+
+ The lineality space of the dual of the cone of positive operators
+ can be computed from the lineality spaces of the cone and its dual::
+
+ sage: set_random_seed()
+ sage: K = random_cone(max_ambient_dim=4)
+ sage: pi_of_K = positive_operator_gens(K)
+ sage: L = ToricLattice(K.lattice_dim()**2)
+ sage: pi_cone = Cone([ g.list() for g in pi_of_K ],
+ ....: lattice=L,
+ ....: check=False)
+ sage: actual = pi_cone.dual().linear_subspace()
+ sage: U1 = [ vector((s.tensor_product(x)).list())
+ ....: for x in K.lines()
+ ....: for s in K.dual() ]
+ sage: U2 = [ vector((s.tensor_product(x)).list())
+ ....: for x in K
+ ....: for s in K.dual().lines() ]
+ sage: expected = pi_cone.lattice().vector_space().span(U1 + U2)