r"""
A clan arising from a T-algebra of Hermitian matrices.
"""
+ @staticmethod
+ def _up_hat(x):
+ r"""
+ The "up-hat" function on a T-algebra.
+
+ This is the "top half" of a matrix, in the sense that we keep
+ the strictly upper-triangular part, and keep half of the
+ diagonal (so that ``up_hat(x) + down_hat(x) == x``. It is
+ defined by Vinberg on page 381, and is used to construct a
+ clan whose associated cone equals that of the the T-algebra.
+ """
+ one = x.base_ring().one()
+ two = 2*one
+ return x.parent().sum_of_terms(
+ (idx, a*c)
+ for (idx, c) in x.items()
+ if idx[0] <= idx[1]
+ if (a := one - (idx[0] == idx[1])/two)
+ )
+
+ @staticmethod
+ def _down_hat(x):
+ r"""
+ The "down-hat" function on a T-algebra.
+
+ This is the "lower half" of a matrix, in the sense that we
+ keep the strictly lower-triangular part, and keep half of the
+ diagonal (so that ``up_hat(x) + down_hat(x) == x``. It is
+ defined by Vinberg on page 381, and is used to construct a
+ clan whose associated cone equals that of the the T-algebra.
+ """
+ return MatrixClan._up_hat(x.transpose()).transpose()
+
+ @staticmethod
+ def _cp(x,y):
+ r"""
+ The clan product associated with a T-algebra.
+
+ This is defined by Vinberg on page 381 (as Delta), who then
+ proceeds to explain, over the course of the next few pages,
+ why it results in a clan when the we take the underlying set
+ to be the subspace of symmetric elements.
+
+ .. WARNING:
+
+ We use Ishi's version of this product that reverses
+ the indices.
+
+ """
+ # First we lift x,y out of the clan and into
+ # the general matrix space.
+ H = x.parent()
+ x = x.lift()
+ y = y.lift()
+
+ # Note: within a Hermitian matrix space we can't represent the
+ # (non-Hermitian) intermediate terms _down_hat(x) and _up_hat(x)!
+ return H(MatrixClan._down_hat(x)*y + y*MatrixClan._up_hat(x))
+
+ @staticmethod
+ def _ip(x,y):
+ r"""
+ The Ishi inner product (NOT the canonical one) on a clan.
+ """
+ two = x.base_ring()(2)
+ p = MatrixClan._cp(x,y) / two
+ return sum( p[idx]
+ for idx in p.monomial_coefficients()
+ if idx[0] == idx[1] )
+
def from_matrix(self, x):
r"""
Construct an element of this clan from a Hermitian matrix.
support_order=b.keys(),
ambient=Mn)
- def up_hat(x):
- r"""
- The "up-hat" function on a T-algebra.
-
- This is the "top half" of a matrix, in the sense that we keep the
- strictly upper-triangular part, and keep half of the diagonal (so
- that ``up_hat(x) + down_hat(x) == x``. It is defined by Vinberg on
- page 381, and is used to construct a clan whose associated cone
- equals that of the the T-algebra.
-
- """
- def l(i,j):
- if i < j:
- return x[i,j]
- if i == j:
- return x[i,j]/scalar_field(2)
- else:
- return 0
- return Mn(l)
-
- def down_hat(x):
- r"""
- The "down-hat" function on a T-algebra.
-
- This is the "lower half" of a matrix, in the sense that we keep
- the strictly lower-triangular part, and keep half of the diagonal
- (so that ``up_hat(x) + down_hat(x) == x``. It is defined by
- Vinberg on page 381, and is used to construct a clan whose
- associated cone equals that of the the T-algebra.
- """
- return up_hat(x.T).T
-
- def cp(x,y):
- r"""
- The clan product associated with a T-algebra.
-
- This is defined by Vinberg on page 381 (as Delta), who
- then proceeds to explain, over the course of the next few
- pages, why it results in a clan when the we take the
- underlying set to be the subspace of symmetric elements.
-
- .. WARNING:
-
- We use Ishi's version of this product that reverses
- the indices.
-
- """
- x = x.lift()
- y = y.lift()
- return Sn(down_hat(x)*y + y*up_hat(x))
-
- def ip(x,y):
- p = cp(x,y) / scalar_field(2)
- return sum( p[(i,i,1)] for i in range(n) )
-
- super().__init__(Sn, cp, ip, **kwargs)
+ super().__init__(Sn, MatrixClan._cp, MatrixClan._ip, **kwargs)
def __repr__(self) -> str:
support_order=b.keys(),
ambient=Mn)
- def up_hat(x):
- return Mn.sum_of_terms(
- ((i,j,k), a*c)
- for ((i,j,k),c) in x.items()
- if i <= j
- if (a := 1 - (i == j)/scalar_field(2))
- )
-
- def down_hat(x):
- return up_hat(x.transpose()).transpose()
-
- def cp(x,y):
- x = x.lift()
- y = y.lift()
- return Hn(down_hat(x)*y + y*up_hat(x))
-
- def ip(x,y):
- p = cp(x,y) / scalar_field(2)
- one = QQbar(1) # weird indexing in Hurwitz matrix algebras
- return sum( p[i,i,one] for i in range(n) )
-
- super().__init__(Hn, cp, ip, **kwargs)
+ super().__init__(Hn, MatrixClan._cp, MatrixClan._ip, **kwargs)
def __repr__(self) -> str: