]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/cone/faces.py
cone/permutation_invariant.py: add test for the nonnegative orthant.
[sage.d.git] / mjo / cone / faces.py
index a6820164999e55d6396d5d1b081419e57f5c791b..5573a9728d2611463e32120cf6390ba0b6c28875 100644 (file)
@@ -53,7 +53,7 @@ def face_generated_by(K,S):
 
         sage: set_random_seed()
         sage: K = random_cone(max_ambient_dim=8, max_rays=10)
-        sage: S = [K.random_element() for idx in range(0,5)]
+        sage: S = ( K.random_element() for idx in range(0,5) )
         sage: F = face_generated_by(K, S)
         sage: F.is_face_of(K)
         True
@@ -62,9 +62,9 @@ def face_generated_by(K,S):
 
         sage: set_random_seed()
         sage: K = random_cone(max_ambient_dim=8, max_rays=10)
-        sage: S = [K.random_element() for idx in range(0,5)]
+        sage: S = ( K.random_element() for idx in range(0,5) )
         sage: F = face_generated_by(K, S)
-        sage: all([F.contains(x) for x in S])
+        sage: all(F.contains(x) for x in S)
         True
 
     The generators of a proper cone are all extreme vectors of the cone,
@@ -75,7 +75,7 @@ def face_generated_by(K,S):
         ....:                 max_rays=10,
         ....:                 strictly_convex=True,
         ....:                 solid=True)
-        sage: all([face_generated_by(K, [r]) == Cone([r]) for r in K])
+        sage: all(face_generated_by(K, [r]) == Cone([r]) for r in K)
         True
 
     For any point ``x`` in ``K`` and any face ``F`` of ``K``, we have
@@ -123,7 +123,7 @@ def face_generated_by(K,S):
 
     """
     face_lattice = K.face_lattice()
-    candidates = [F for F in face_lattice if all([F.contains(x) for x in S])]
+    candidates = [F for F in face_lattice if all(F.contains(x) for x in S)]
 
     # K itself is a face of K, so unless we were given a set S that
     # isn't a subset of K, the candidates list will be nonempty.
@@ -143,13 +143,17 @@ def dual_face(K,F):
 
     REFERENCES:
 
+    .. [HilgertHofmannLawson] Joachim Hilgert, Karl Heinrich Hofmann, and Jimmie
+       D. Lawson. Lie groups, convex cones and semigroups. Oxford Mathematical
+       Monographs. Clarendon Press, Oxford, 1989. ISBN 9780198535690.
+
     .. [Tam] Bit-Shun Tam. On the duality operator of a convex cone. Linear
        Algebra and its Applications, 64:33-56, 1985, doi:10.1016/0024-3795(85)
        90265-4.
 
     SETUP::
 
-        sage: from mjo.cone.faces import dual_face
+        sage: from mjo.cone.faces import (dual_face, face_generated_by)
 
     EXAMPLES:
 
@@ -171,7 +175,7 @@ def dual_face(K,F):
         sage: set_random_seed()
         sage: K = random_cone(max_ambient_dim=8, max_rays=10)
         sage: K_dual = K.dual()
-        sage: lKd_gens = [ dir*l for dir in [1,-1] for l in K_dual.lines() ]
+        sage: lKd_gens = ( dir*l for dir in [1,-1] for l in K_dual.lines() )
         sage: linspace_K_dual = Cone(lKd_gens, K_dual.lattice())
         sage: dual_face(K,K).is_equivalent(linspace_K_dual)
         True
@@ -189,10 +193,33 @@ def dual_face(K,F):
         sage: dual_face(K,trivial_face).is_equivalent(K.dual())
         True
 
+    The dual of the cone of ``K`` at ``y`` is the dual face of the face
+    of ``K`` generated by ``y`` ([Tam]_ Corollary 3.2)::
+
+        sage: set_random_seed()
+        sage: K = random_cone(max_ambient_dim=8, max_rays=10)
+        sage: y = K.random_element()
+        sage: S = [y]
+        sage: phi_y = face_generated_by(K,S)
+        sage: points_cone_gens = list(K.rays()) + [-z for z in phi_y.rays()]
+        sage: points_cone = Cone(points_cone_gens, K.lattice())
+        sage: points_cone.dual().is_equivalent(dual_face(K, phi_y))
+        True
+
+    Since all faces of a polyhedral cone are exposed, the dual face of a
+    dual face should be the original face [HilgertHofmannLawson]_::
+
+        sage: set_random_seed()
+        sage: def check_prop(K,F):
+        ....:     return dual_face(K.dual(), dual_face(K,F)).is_equivalent(F)
+        sage: K = random_cone(max_ambient_dim=8, max_rays=10)
+        sage: all(check_prop(K,F) for F in K.face_lattice())
+        True
+
     """
     # Ensure that F is actually a face of K before continuing.
     if not F.is_face_of(K):
         raise ValueError("%s is not a face of %s" % (F,K))
 
-    span_F = Cone([c*g for c in [1,-1] for g in F], F.lattice())
+    span_F = Cone((c*g for c in [1,-1] for g in F), F.lattice())
     return K.dual().intersection(span_F.dual())