]> gitweb.michael.orlitzky.com - sage.d.git/commitdiff
mjo/clan/normal_decomposition.py: add test for principal decomp
authorMichael Orlitzky <michael@orlitzky.com>
Fri, 27 Mar 2026 15:25:26 +0000 (11:25 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Fri, 27 Mar 2026 15:25:26 +0000 (11:25 -0400)
We get a principal decomposition of a non-unital clan if we "delete"
the r'th idempotent from the normal decomposition of a unital clan,
but this isn't obvious. Let's test it.

mjo/clan/normal_decomposition.py

index fb9d8bf61ad89eb1d6b63f4357a9c3b822daf14b..5cfd2a1f4d02a7a8028cc752dba735d656dc07d9 100644 (file)
@@ -10,6 +10,47 @@ class NormalDecomposition(Clan):
     the entire section is devoted to clans with a unit. Rather than
     try to figure out what parts of that are essential, we assume a
     unit element too.
+
+    SETUP::
+
+        sage: from mjo.clan.vinberg_clan import VinbergClan
+        sage: from mjo.clan.jordan_spin_clan import JordanSpinClan
+        sage: from mjo.clan.t_algebra_clan import (ComplexHermitianClan,
+        ....:                                      RealSymmetricClan)
+
+    TESTS:
+
+    If we start with a normal decomposition of a clan of rank ``r``
+    and if we "delete" the ``r``th idempotent, the result should still
+    be a (non unital) clan in its principal decomposition: a unital
+    clan of rank ``r-1`` plus what's left of the ``r``th column. (This
+    is stated without proof in my "Automorphisms of hyperbolic
+    polynomials" paper.) But rather than create a true, non-unital
+    subclan, we can just set the coordinates of the ``r``th idempotent
+    to zero. We then check the defining property of a principal
+    decomposition::
+
+        sage: clans = [VinbergClan(),
+        ....:          RealSymmetricClan(4),
+        ....:          ComplexHermitianClan(3),
+        ....:          JordanSpinClan(5)]
+        sage: def subunit(C):
+        ....:     # Unit of the subclan
+        ....:     r = C.rank()
+        ....:     return sum(C.idempotent(i) for i in range(r-1))
+        sage: def subelt(C):
+        ....:     # random subclan element
+        ....:     r = C.rank()
+        ....:     x = C.random_element()
+        ....:     return x - x.coefficient((r-1,r-1,1))*C.idempotent(r-1)
+        sage: all(
+        ....:     x.leftreg().trace() == u.inner_product_vinberg(x)
+        ....:     for C in clans
+        ....:     for x in [subelt(C) for _ in range(10)]
+        ....:     if (u := subunit(C))
+        ....: )
+        True
+
     """
     from mjo.clan.normal_decomposition_element import (
         NormalDecompositionElement as Element