]> gitweb.michael.orlitzky.com - sage.d.git/blobdiff - mjo/cone/rearrangement.py
cone/permutation_invariant.py: use xrange in two places.
[sage.d.git] / mjo / cone / rearrangement.py
index 6ea993c3b1b441980e648ee2e1a6d4ebaf964c57..b2ccfcb58f8aa58b52a8d724ca42725593ed7463 100644 (file)
@@ -1,10 +1,3 @@
-# Sage doesn't load ~/.sage/init.sage during testing (sage -t), so we
-# have to explicitly mangle our sitedir here so that "mjo.cone"
-# resolves.
-from os.path import abspath
-from site import addsitedir
-addsitedir(abspath('../../'))
-
 from sage.all import *
 
 def rearrangement_cone(p,n):
@@ -35,6 +28,10 @@ def rearrangement_cone(p,n):
     A polyhedral closed convex cone object representing a rearrangement
     cone of order ``p`` in ``n`` dimensions.
 
+    SETUP::
+
+        sage: from mjo.cone.rearrangement import rearrangement_cone
+
     EXAMPLES:
 
     The rearrangement cones of order one are nonnegative orthants::
@@ -53,12 +50,35 @@ def rearrangement_cone(p,n):
         sage: rearrangement_cone(5,5).lineality()
         4
 
+    All rearrangement cones are proper::
+
+        sage: all( rearrangement_cone(p,n).is_proper()
+        ....:              for n in range(10)
+        ....:              for p in range(n) )
+        True
+
+    The Lyapunov rank of the rearrangement cone of order ``p`` in ``n``
+    dimensions is ``n`` for ``p == 1`` or ``p == n`` and one otherwise::
+
+        sage: all( rearrangement_cone(p,n).lyapunov_rank() == n
+        ....:              for n in range(2, 10)
+        ....:              for p in [1, n-1] )
+        True
+        sage: all( rearrangement_cone(p,n).lyapunov_rank() == 1
+        ....:              for n in range(3, 10)
+        ....:              for p in range(2, n-1) )
+        True
+
     TESTS:
 
-    todo.
-    should be permutation invariant.
-    should have the expected lyapunov rank.
-    just loop through them all for n <= 10 and p < n?
+    The rearrangement cone is permutation-invariant::
+
+        sage: n = ZZ.random_element(2,10).abs()
+        sage: p = ZZ.random_element(1,n)
+        sage: K = rearrangement_cone(p,n)
+        sage: P = SymmetricGroup(n).random_element().matrix()
+        sage: all( K.contains(P*r) for r in K )
+        True
 
     """
 
@@ -70,3 +90,58 @@ def rearrangement_cone(p,n):
     V = VectorSpace(QQ, n)
     G = V.basis() + [ d(j) for j in range(n) ]
     return Cone(G)
+
+
+def has_rearrangement_property(v, p):
+    r"""
+    Test if the vector ``v`` has the "rearrangement property."
+
+    The rearrangement cone of order ``p`` in `n` dimensions has its
+    members vectors of length `n`. The "rearrangement property,"
+    satisfied by its elements, is to have its smallest ``p`` components
+    sum to a nonnegative number.
+
+    We believe that we have a description of the extreme vectors of the
+    rearrangement cone: see ``rearrangement_cone()``. This function is
+    used to test that conic combinations of those extreme vectors are in
+    fact elements of the rearrangement cone. We can't test all conic
+    combinations, obviously, but we can test a random one.
+
+    To become more sure of the result, generate a bunch of vectors with
+    ``random_element()`` and test them with this function.
+
+    INPUT:
+
+    - ``v`` -- An element of a cone suspected of being the rearrangement
+               cone of order ``p``.
+
+    - ``p`` -- The suspected order of the rearrangement cone.
+
+    OUTPUT:
+
+    If ``v`` has the rearrangement property (that is, if its smallest ``p``
+    components sum to a nonnegative number), ``True`` is returned. Otherwise
+    ``False`` is returned.
+
+    SETUP::
+
+        sage: from mjo.cone.rearrangement import (has_rearrangement_property,
+        ....:                                     rearrangement_cone)
+
+    EXAMPLES:
+
+    Every element of a rearrangement cone should have the property::
+
+        sage: set_random_seed()
+        sage: all( has_rearrangement_property(
+        ....:        rearrangement_cone(p,n).random_element(),
+        ....:        p
+        ....:      )
+        ....:      for n in range(2, 10)
+        ....:      for p in range(1, n-1)
+        ....: )
+        True
+
+    """
+    components = sorted(v)[0:p]
+    return sum(components) >= 0