SETUP::
sage: from mjo.clan.t_algebra_clan import (
- ....: ComplexHermitianClan,
....: RealSymmetricClan
....: )
- sage: from mjo.hurwitz import ComplexMatrixAlgebra
EXAMPLES::
[2 1]
[1 4]
- ::
-
- sage: C = ComplexHermitianClan(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()})"
sage: C.one()
0
+ Special cases for the entry algebra of the ambient matrix space::
+
+ sage: C = ComplexHermitianClan(2, scalar_field=AA)
+ sage: C.entry_algebra
+ Algebraic Field
+ sage: C = ComplexHermitianClan(2, scalar_field=RR)
+ sage: C.entry_algebra
+ Complex Field with 53 bits of precision
+ sage: C = ComplexHermitianClan(2, scalar_field=RDF)
+ sage: C.entry_algebra
+ Complex Double Field
+
"""
from sage.rings.rational_field import QQ
def __init__(self, n, scalar_field=QQ, **kwargs):
from mjo.hurwitz import ComplexMatrixAlgebra
- from sage.rings.qqbar import QQbar
- Mn = ComplexMatrixAlgebra(n, QQbar, scalar_field)
+ from sage.rings.polynomial.polynomial_ring import polygen
+
+ # The way we construct the underlying vector space is finicky.
+ # We need the entries of our matrix to have a conjugate() method,
+ # but sometimes (most of the time) the quadratic extension below
+ # returns something wacky. Here we handle two special cases where
+ # the extension field is known.
+ from sage.rings.qqbar import AA
+ from sage.rings.real_mpfr import RR
+ from sage.rings.real_double import RDF
+ if scalar_field is AA:
+ from sage.rings.qqbar import QQbar
+ self.entry_algebra = QQbar
+ elif scalar_field is RR:
+ from sage.rings.cc import CC
+ self.entry_algebra = CC
+ elif scalar_field is RDF:
+ from sage.rings.complex_double import CDF
+ self.entry_algebra = CDF
+ else:
+ # Works for QQ, but not much else.
+ x = polygen(scalar_field, 'x')
+ self.entry_algebra = scalar_field.extension(x**2 + 1,
+ names=['I'])
+
+ Mn = ComplexMatrixAlgebra(n, self.entry_algebra, scalar_field)
b = Mn.basis()
from sage.sets.family import Family
"""
return f"Clan H^{self.rank()} over {self.base_ring()}"
+
+ def from_matrix(self, x):
+ r"""
+ Construct an element of this clan from a Hermitian matrix.
+
+ A special case is needed for matrices with complex entries,
+ to ensure that the entry algebras agree.
+
+ SETUP::
+
+ sage: from mjo.clan.t_algebra_clan import (
+ ....: ComplexHermitianClan
+ ....: )
+ sage: from mjo.hurwitz import ComplexMatrixAlgebra
+
+ EXAMPLES::
+
+ The entry algebra must be a quadratic extension of the scalar
+ field; if you pass in a matrix whose entries come from the
+ wrong algebra, it won't work::
+
+ sage: C = ComplexHermitianClan(2)
+ sage: A = ComplexMatrixAlgebra(2, QQbar, QQ)
+ sage: X = A([ [ 2, 1 + 2*I],
+ ....: [ 1 - 2*I, -1] ])
+ sage: C.from_matrix(X)
+ Traceback (most recent call last):
+ ...
+ ValueError: entry algebra of matrix (Algebraic Field) does
+ not match clan (Number Field in I with defining polynomial
+ x^2 + 1)
+
+ The easy way to obtain the correct entry algebra is to borrow
+ it from the clan::
+
+ sage: C = ComplexHermitianClan(2)
+ sage: A = ComplexMatrixAlgebra(2, C.entry_algebra, C.base_ring())
+ 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 │
+ └──────────┴─────────┘
+
+ """
+ ea = x.parent().entry_algebra()
+ if not ea == self.entry_algebra:
+ raise ValueError(f"entry algebra of matrix ({ea}) does not"
+ f" match clan ({self.entry_algebra})")
+ return super().from_matrix(x)