]> gitweb.michael.orlitzky.com - sage.d.git/commitdiff
mjo/cone: more linear ismorphism tests master
authorMichael Orlitzky <michael@orlitzky.com>
Tue, 1 Jul 2025 23:15:23 +0000 (19:15 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Tue, 1 Jul 2025 23:15:23 +0000 (19:15 -0400)
mjo/cone/isomorphism.py

index 675105133e6c2206008efbaefc3aee5374c62a6c..d57787acb2d887354842a7dabdacc91721263717 100644 (file)
@@ -79,23 +79,20 @@ def linear_isomorphisms(K1, K2):
     EXAMPLES:
 
     In this example, the lower half-space is obtained from the upper
     EXAMPLES:
 
     In this example, the lower half-space is obtained from the upper
-    half space by flipping the y-coordinate::
+    half space by flipping the y-coordinate. Note that the x-axis is
+    mapped to the x-axis via the canonical basis (the ``1`` in the
+    top-left corner), but any other non-zero number would suffice
+    there. This is discussed in the description of the algorithm::
 
         sage: K1 = Cone([(0,1),(1,0),(-1,0)])
         sage: K2 = Cone([(0,-1),(1,0),(-1,0)])
 
         sage: K1 = Cone([(0,1),(1,0),(-1,0)])
         sage: K2 = Cone([(0,-1),(1,0),(-1,0)])
-        sage: next(linear_isomorphisms(K1,K2))
-        [ 1  0]
-        [ 0 -1]
-
-    Two different descriptions of the plane should be isomorphic::
-
-        sage: K1 = Cone([(1,0), (-1,0), (0,1), (0,-1)])
-        sage: K2 = Cone([(1,1), (-1,1), (0,-1)])
-        sage: K1.is_equivalent(K2)
+        sage: set(linear_isomorphisms(K1,K2))
+        {[ 1  0]
+         [ 0 -1]}
+        sage: A = matrix(QQ, [[-6, 0],
+        ....:                 [ 0,-1]])
+        sage: Cone(K1.rays()*A).is_equivalent(K2)
         True
         True
-        sage: next(linear_isomorphisms(K1,K2))
-        [1 0]
-        [0 1]
 
     A randomly-generated example constructed to be isomorphic::
 
 
     A randomly-generated example constructed to be isomorphic::
 
@@ -112,14 +109,14 @@ def linear_isomorphisms(K1, K2):
         sage: Cone(K1.rays()*g).is_equivalent(K2)
         True
 
         sage: Cone(K1.rays()*g).is_equivalent(K2)
         True
 
-    Automorphisms can be obtained by passing ``K2 == K1``. In this
-    case, there are many duplicates so we use ``set()`` to obtain
-    distinct transformations. Gowda and Trott [GowdaTrott2014]_ have
-    computed the automorphism group of this cone, and we recover them
-    all up to a positive scalar::
+    Automorphisms can be obtained by passing ``K2 == K1``. There are
+    often many duplicates, so we use ``set()`` to obtain distinct
+    transformations. Gowda and Trott [GowdaTrott2014]_ have computed
+    the automorphism groups of these cone, and we recover them all up
+    to a positive scalar::
 
         sage: K1 = Cone([(1,0,1), (-1,0,1), (0,1,1), (0,-1,1)])
 
         sage: K1 = Cone([(1,0,1), (-1,0,1), (0,1,1), (0,-1,1)])
-        sage: set(linear_isomorphisms(K1,K1))
+        sage: G = set(linear_isomorphisms(K1,K1)); G
         {[-1  0  0]
          [ 0 -1  0]
          [ 0  0  1],
         {[-1  0  0]
          [ 0 -1  0]
          [ 0  0  1],
@@ -144,6 +141,36 @@ def linear_isomorphisms(K1, K2):
          [1 0 0]
          [0 1 0]
          [0 0 1]}
          [1 0 0]
          [0 1 0]
          [0 0 1]}
+        sage: K2 = Cone([(1,1,1), (-1,1,1), (-1,-1,1), (1,-1,1)])
+        sage: H = set(linear_isomorphisms(K2,K2))
+        sage: G == H
+        True
+
+    Up to a positive row-scalings, the automorphism group of the
+    nonnegative orthant is the set of all permutation matrices. Only
+    the permutations (not the scalar factors) are returned; this is
+    discussed in the description of the algorithm::
+
+        sage: K1 = cones.nonnegative_orthant(3)
+        sage: set(linear_isomorphisms(K1,K1))
+        {[0 0 1]
+         [0 1 0]
+         [1 0 0],
+         [0 0 1]
+         [1 0 0]
+         [0 1 0],
+         [0 1 0]
+         [0 0 1]
+         [1 0 0],
+         [0 1 0]
+         [1 0 0]
+         [0 0 1],
+         [1 0 0]
+         [0 0 1]
+         [0 1 0],
+         [1 0 0]
+         [0 1 0]
+         [0 0 1]}
 
     TESTS:
 
 
     TESTS:
 
@@ -172,9 +199,9 @@ def linear_isomorphisms(K1, K2):
         ....:   and
         ....:   g.is_immutable()
         ....:   and
         ....:   and
         ....:   g.is_immutable()
         ....:   and
-        ....:   Cone(K1.rays()*g).is_equivalent(K2)
+        ....:   Cone(K1.rays()*g, K1.lattice()).is_equivalent(K2)
         ....:   and
         ....:   and
-        ....:   Cone(K2.rays()*g.inverse()).is_equivalent(K1)
+        ....:   Cone(K2.rays()*g.inverse(), K2.lattice()).is_equivalent(K1)
         ....:   for g in linear_isomorphisms(K1,K2)
         ....: )
         True
         ....:   for g in linear_isomorphisms(K1,K2)
         ....: )
         True
@@ -310,6 +337,15 @@ def is_linearly_isomorphic(K1,K2):
 
     EXAMPLES:
 
 
     EXAMPLES:
 
+    Two different descriptions of the plane should be isomorphic::
+
+        sage: K1 = Cone([(1,0), (-1,0), (0,1), (0,-1)])
+        sage: K2 = Cone([(1,1), (-1,1), (0,-1)])
+        sage: K1.is_equivalent(K2)
+        True
+        sage: is_linearly_isomorphic(K1,K2)
+        True
+
     All simplicial cones with the same number of rays are isomorphic::
 
         sage: K1 = random_cone(max_ambient_dim=5)
     All simplicial cones with the same number of rays are isomorphic::
 
         sage: K1 = random_cone(max_ambient_dim=5)