]> gitweb.michael.orlitzky.com - sage.d.git/commitdiff
mjo/clan: get inner products working; implement one() for SnClan
authorMichael Orlitzky <michael@orlitzky.com>
Thu, 15 Jan 2026 03:07:38 +0000 (22:07 -0500)
committerMichael Orlitzky <michael@orlitzky.com>
Thu, 15 Jan 2026 03:07:38 +0000 (22:07 -0500)
mjo/clan/clan_element.py
mjo/clan/unital_clan.py

index 1d358efcbf36ed9a5ba05069b147838c000d9648..2b578a197834d0b36afc15c22a4336727c4d1786 100644 (file)
@@ -16,3 +16,27 @@ class ClanElement(IndexedFreeModuleElement):
         will be needed to get the actual matrix.
         """
         return self.parent()._vector_space.sum_of_terms(self.items())
+
+
+    def inner_product(self, other):
+        r"""
+        The inner product of this element with ``other``.
+
+        EXAMPLES:
+
+        In the clan of real symmetric matrices under the Ishi norm,
+        it is easy to check that the idempotents all have norm 1/2::
+
+            sage: from mjo.clan.unital_clan import SnClan
+            sage: C = SnClan(3)
+            sage: all( e_ii.inner_product(e_ii) == 1/2
+            ....:      for i in range(C.rank())
+            ....:      if (e_ii := C.basis()[(i,i)]) )
+            True
+
+        """
+        return sum(
+            xi*yj*self.parent().inner_product_on_basis(bi, bj)
+            for (bi, xi) in self.items()
+            for (bj, yj)  in other.items()
+        )
index 37aa8abb241a47c94bb5647f10baefa7688c0358..e576d52143076bc2c707e5d3fdd6a7cf3a5e9306 100644 (file)
@@ -34,6 +34,12 @@ class UnitalClan(CombinatorialFreeModule):
                           for j in basis.keys() }
                      for i in basis.keys() }
 
+        # And inner product table. We assume the supplied inner
+        # product is symmetric.
+        self._ipt = { i: { j : inner_product(basis[i], basis[j])
+                           for j in basis.keys() if j <= i }
+                      for i in basis.keys() }
+
         # Use the vector_space basis keys so we can convert
         # easily between them.
         CombinatorialFreeModule.__init__(self,
@@ -64,6 +70,18 @@ class UnitalClan(CombinatorialFreeModule):
         return None
 
 
+    def inner_product_on_basis(self, i, j):
+        r"""
+        Return the inner product of the `i` and `j`th basis elements.
+
+        This completely defines the inner product.
+        """
+        if j <= i:
+            return self._ipt[i][j]
+        else:
+            return self._ipt[j][i]
+
+
     def product_on_basis(self, i, j):
         r"""
         Returns the Jordan product of the `i` and `j`th basis elements.
@@ -74,6 +92,7 @@ class UnitalClan(CombinatorialFreeModule):
         """
         return self._mt[i][j]
 
+
     def rank(self) -> int:
         r"""
         The rank of this clan. Not implemented by default,
@@ -84,9 +103,10 @@ class UnitalClan(CombinatorialFreeModule):
 
 class SnClan(UnitalClan):
     r"""
-    The clan of real symmetric matrices of a given size with the
-    clan product and lower-triangular basis ordering of Ishi,
-    based on the up-hat and down-hat products of Vinberg.
+    The normally-decomposed clan of real symmetric matrices of a
+    given size with the clan product and lower-triangular basis
+    ordering of Ishi, based on the up-hat and down-hat products of
+    Vinberg.
 
     EXAMPLES:
 
@@ -137,6 +157,7 @@ class SnClan(UnitalClan):
     def __init__(self, n, scalar_field=QQ, **kwargs):
         self._rank = n
 
+        from sage.matrix.matrix_space import MatrixSpace
         Mn = MatrixSpace(scalar_field, n)
         b = Mn.basis()
 
@@ -227,3 +248,23 @@ class SnClan(UnitalClan):
 
         """
         return f"Clan S^{self.rank()} over {self._vector_space().base_ring()}"
+
+
+    def one(self):
+        r"""
+        Return the unit element of this clan.
+
+        EXAMPLES::
+
+            sage: C = SnClan(4)
+            sage: I = C.one()
+            sage: I.lift().lift()
+            [1 0 0 0]
+            [0 1 0 0]
+            [0 0 1 0]
+            [0 0 0 1]
+            sage: all( I*b == b and b*I == b for b in C.basis() )
+            True
+
+        """
+        return sum( self.basis()[i,i] for i in range(self.rank()) )