From: Michael Orlitzky Date: Tue, 1 Jul 2025 23:15:23 +0000 (-0400) Subject: mjo/cone: more linear ismorphism tests X-Git-Url: https://gitweb.michael.orlitzky.com/?a=commitdiff_plain;ds=sidebyside;p=sage.d.git mjo/cone: more linear ismorphism tests --- diff --git a/mjo/cone/isomorphism.py b/mjo/cone/isomorphism.py index 6751051..d57787a 100644 --- a/mjo/cone/isomorphism.py +++ b/mjo/cone/isomorphism.py @@ -79,23 +79,20 @@ def linear_isomorphisms(K1, K2): 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: 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 - sage: next(linear_isomorphisms(K1,K2)) - [1 0] - [0 1] 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 - 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: set(linear_isomorphisms(K1,K1)) + sage: G = set(linear_isomorphisms(K1,K1)); G {[-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]} + 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: @@ -172,9 +199,9 @@ def linear_isomorphisms(K1, K2): ....: and ....: g.is_immutable() ....: and - ....: Cone(K1.rays()*g).is_equivalent(K2) + ....: Cone(K1.rays()*g, K1.lattice()).is_equivalent(K2) ....: 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 @@ -310,6 +337,15 @@ def is_linearly_isomorphic(K1,K2): 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)