class ComplexMatrixEJA(MatrixEJA):
+ # A manual dictionary-cache for the complex_extension() method,
+ # since apparently @classmethods can't also be @cached_methods.
+ _complex_extension = {}
+
+ @classmethod
+ def complex_extension(cls,field):
+ r"""
+ The complex field that we embed/unembed, as an extension
+ of the given ``field``.
+ """
+ if field in cls._complex_extension:
+ return cls._complex_extension[field]
+
+ # Sage doesn't know how to adjoin the complex "i" (the root of
+ # x^2 + 1) to a field in a general way. Here, we just enumerate
+ # all of the cases that I have cared to support so far.
+ if field is AA:
+ # Sage doesn't know how to embed AA into QQbar, i.e. how
+ # to adjoin sqrt(-1) to AA.
+ F = QQbar
+ elif not field.is_exact():
+ # RDF or RR
+ F = field.complex_field()
+ else:
+ # Works for QQ and... maybe some other fields.
+ R = PolynomialRing(field, 'z')
+ z = R.gen()
+ F = field.extension(z**2 + 1, 'I', embedding=CLF(-1).sqrt())
+
+ cls._complex_extension[field] = F
+ return F
+
@staticmethod
def dimension_over_reals():
return 2
blocks = []
for z in M.list():
- a = z.list()[0] # real part, I guess
- b = z.list()[1] # imag part, I guess
- blocks.append(matrix(field, 2, [[a,b],[-b,a]]))
+ a = z.real()
+ b = z.imag()
+ blocks.append(matrix(field, 2, [ [ a, b],
+ [-b, a] ]))
return matrix.block(field, n, blocks)
super(ComplexMatrixEJA,cls).real_unembed(M)
n = ZZ(M.nrows())
d = cls.dimension_over_reals()
-
- # If "M" was normalized, its base ring might have roots
- # adjoined and they can stick around after unembedding.
- field = M.base_ring()
- R = PolynomialRing(field, 'z')
- z = R.gen()
-
- # Sage doesn't know how to adjoin the complex "i" (the root of
- # x^2 + 1) to a field in a general way. Here, we just enumerate
- # all of the cases that I have cared to support so far.
- if field is AA:
- # Sage doesn't know how to embed AA into QQbar, i.e. how
- # to adjoin sqrt(-1) to AA.
- F = QQbar
- elif not field.is_exact():
- # RDF or RR
- F = field.complex_field()
- else:
- # Works for QQ and... maybe some other fields.
- F = field.extension(z**2 + 1, 'I', embedding=CLF(-1).sqrt())
+ F = cls.complex_extension(M.base_ring())
i = F.gen()
# Go top-left to bottom-right (reading order), converting every
return cls(n, **kwargs)
class QuaternionMatrixEJA(MatrixEJA):
+
+ # A manual dictionary-cache for the quaternion_extension() method,
+ # since apparently @classmethods can't also be @cached_methods.
+ _quaternion_extension = {}
+
+ @classmethod
+ def quaternion_extension(cls,field):
+ r"""
+ The quaternion field that we embed/unembed, as an extension
+ of the given ``field``.
+ """
+ if field in cls._quaternion_extension:
+ return cls._quaternion_extension[field]
+
+ Q = QuaternionAlgebra(field,-1,-1)
+
+ cls._quaternion_extension[field] = Q
+ return Q
+
@staticmethod
def dimension_over_reals():
return 4
# Use the base ring of the matrix to ensure that its entries can be
# multiplied by elements of the quaternion algebra.
- field = M.base_ring()
- Q = QuaternionAlgebra(field,-1,-1)
+ Q = cls.quaternion_extension(M.base_ring())
i,j,k = Q.gens()
# Go top-left to bottom-right (reading order), converting every