"""
return self._rank
-class SnClan(NormalDecomposition):
+class MatrixClan(NormalDecomposition):
+ r"""
+ A clan arising from a T-algebra of Hermitian matrices.
+ """
+ def from_matrix(self, x):
+ r"""
+ Construct an element of this clan from a Hermitian matrix.
+
+ EXAMPLES::
+
+ sage: C = SnClan(2)
+ sage: X = matrix(QQ, [[2,1],
+ ....: [1,4]])
+ sage: C.from_matrix(X).lift().lift()
+ [2 1]
+ [1 4]
+
+ ::
+
+ sage: from mjo.hurwitz import ComplexMatrixAlgebra
+ sage: C = HnClan(2)
+ sage: A = ComplexMatrixAlgebra(2, QQbar, QQ)
+ sage: X = A([ [ 2, 1 + 2*I],
+ ....: [ 1 - 2*I, -1] ])
+ sage: C.from_matrix(X).lift().lift()
+ ┌──────────┬─────────┐
+ │ 2 │ 2*I + 1 │
+ ├──────────┼─────────┤
+ │ -2*I + 1 │ -1 │
+ └──────────┴─────────┘
+
+ """
+ if not x.base_ring() == self.base_ring():
+ raise ValueError(f"base ring of matrix ({x.base_ring()})"
+ " does not match clan ({self.base_ring()})")
+ if not x == x.conjugate_transpose():
+ raise ValueError("matrix is not Hermitian")
+ if not self.rank() == x.nrows():
+ raise ValueError(f"matrix must have {self.rank()} rows/columns")
+
+ try:
+ # HurwitzMatrixAlgebra
+ return self.sum_of_terms( (idx, x[idx])
+ for idx in self.indices() )
+ except IndexError:
+ # MatrixSpace
+ return self.sum_of_terms( ((i,j,k), x[i,j])
+ for (i,j,k) in self.indices() )
+
+
+
+
+ def from_list(self, l):
+ r"""
+ Construct an element of this clan from a list.
+
+ This is a shortcut for :meth:`from_matrix`, as the clan knows
+ what the ambient matrix space was.
+
+ EXAMPLES::
+
+ sage: C = HnClan(2)
+ sage: X = C.from_list([[0,I],[-I,0]])
+ sage: X.lift().lift()
+ ┌────┬───┐
+ │ 0 │ I │
+ ├────┼───┤
+ │ -I │ 0 │
+ └────┴───┘
+
+ This relies on the ambient vector space to convert a list to a
+ matrix, so in the real case, we can use one long list (as
+ opposed to a list of lists):
+
+ sage: C = SnClan(3)
+ sage: X = C.from_list([2,6,10,6,10,14,10,14,18])
+ sage: X.lift().lift()
+ [ 2 6 10]
+ [ 6 10 14]
+ [10 14 18]
+
+ """
+ return self.from_matrix(self._vector_space.ambient()(l))
+
+
+class SnClan(MatrixClan):
r"""
The normally-decomposed clan of real symmetric matrices of a
given size with the clan product and lower-triangular basis
return f"Clan S^{self.rank()} over {self.base_ring()}"
- def from_matrix(self, x):
- r"""
- Construct an element of this clan from a symmetric matrix.
-
- EXAMPLES::
-
- sage: C = SnClan(2)
- sage: X = matrix(QQ, [[2,1],
- ....: [1,4]])
- sage: C.from_matrix(X).lift().lift()
- [2 1]
- [1 4]
-
- """
- if not x.base_ring() == self.base_ring():
- raise ValueError
- if not x == x.transpose():
- raise ValueError
- if not self.rank() == x.nrows():
- raise ValueError
- return self.sum_of_terms( ((i,j,k), x[i,j])
- for (i,j,k) in self.indices() )
-
-
- def from_list(self, l):
- r"""
- Construct an element of this clan from a list.
-
- This is a shortcut for :meth:`from_matrix`, as the clan knows
- what the ambient matrix space was.
-
- EXAMPLES::
-
- sage: C = SnClan(3)
- sage: X = C.from_list([2,6,10,6,10,14,10,14,18])
- sage: X.lift().lift()
- [ 2 6 10]
- [ 6 10 14]
- [10 14 18]
-
- """
- return self.from_matrix(self._vector_space.ambient()(l))
-
-
-
-class HnClan(NormalDecomposition):
+class HnClan(MatrixClan):
r"""
The normally-decomposed clan of complex Hermitian matrices of a
given size with the clan product and lower-triangular basis
return sum( p[i,i,one] for i in range(n) )
super().__init__(Hn, cp, ip, **kwargs)
+
+
+ def __repr__(self) -> str:
+ r"""
+ The string representation of this clan.
+
+ EXAMPLES::
+
+ sage: HnClan(1)
+ Clan H^1 over Rational Field
+
+ """
+ return f"Clan H^{self.rank()} over {self.base_ring()}"